๋“ค์–ด์˜ค๋Š” SSH ์—ฐ๊ฒฐ์„ ์œ„ํ•œ ํŠธ๋žฉ(ํƒ€๋ฅดํ•)

์ธํ„ฐ๋„ท์ด ๋งค์šฐ ์ ๋Œ€์ ์ธ ํ™˜๊ฒฝ์ด๋ผ๋Š” ๊ฒƒ์€ ๋น„๋ฐ€์ด ์•„๋‹™๋‹ˆ๋‹ค. ์„œ๋ฒ„๋ฅผ ์˜ฌ๋ฆฌ์ž๋งˆ์ž ์ฆ‰์‹œ ๋Œ€๊ทœ๋ชจ ๊ณต๊ฒฉ๊ณผ ์—ฌ๋Ÿฌ ์ฐจ๋ก€์˜ ์Šค์บ”์„ ๋ฐ›๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๊ฒฝ๋น„์›์˜ ํ—ˆ๋‹ˆํŒŸ ์ด ์“ฐ๋ ˆ๊ธฐ ํŠธ๋ž˜ํ”ฝ์˜ ๊ทœ๋ชจ๋ฅผ ์ถ”์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ํ‰๊ท ์ ์ธ ์„œ๋ฒ„์—์„œ๋Š” ํŠธ๋ž˜ํ”ฝ์˜ 99%๊ฐ€ ์•…์„ฑ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Tarpit์€ ๋“ค์–ด์˜ค๋Š” ์—ฐ๊ฒฐ ์†๋„๋ฅผ ๋Šฆ์ถ”๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ํŠธ๋žฉ ํฌํŠธ์ž…๋‹ˆ๋‹ค. ํƒ€์‚ฌ ์‹œ์Šคํ…œ์ด ์ด ํฌํŠธ์— ์—ฐ๊ฒฐ๋œ ๊ฒฝ์šฐ ์—ฐ๊ฒฐ์„ ๋น ๋ฅด๊ฒŒ ์ข…๋ฃŒํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์‹œ์Šคํ…œ ๋ฆฌ์†Œ์Šค๋ฅผ ๋‚ญ๋น„ํ•˜๊ณ  ์—ฐ๊ฒฐ ์‹œ๊ฐ„์ด ์ดˆ๊ณผ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ๊ฑฐ๋‚˜ ์ˆ˜๋™์œผ๋กœ ์—ฐ๊ฒฐ์„ ์ข…๋ฃŒํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ๋ฐฉ์ˆ˜ํฌ๋Š” ๋ณดํ˜ธ๋ฅผ ์œ„ํ•ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ด ๊ธฐ์ˆ ์€ ์ปดํ“จํ„ฐ ์›œ์œผ๋กœ๋ถ€ํ„ฐ ๋ณดํ˜ธํ•˜๊ธฐ ์œ„ํ•ด ์ฒ˜์Œ ๊ฐœ๋ฐœ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ ์ด๋Š” ๋ชจ๋“  IP ์ฃผ์†Œ๋ฅผ ์—ฐ์†์ ์œผ๋กœ ๊ด‘๋ฒ”์œ„ํ•˜๊ฒŒ ์Šค์บ๋‹ํ•˜๋Š” ์ŠคํŒจ๋จธ์™€ ์—ฐ๊ตฌ์›์˜ ์‚ถ์„ ๋ง์น˜๋Š” ๋ฐ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(Habrรฉ์˜ ์˜ˆ: ์˜ค์ŠคํŠธ๋ฆฌ์•„, ์šฐํฌ๋ผ์ด๋‚˜).

Chris Wellons๋ผ๋Š” ์‹œ์Šคํ…œ ๊ด€๋ฆฌ์ž ์ค‘ ํ•œ ๋ช…์€ ๋ถ„๋ช…ํžˆ ์ด ์ˆ˜์น˜๋ฅผ ์ง€์ผœ๋ณด๋Š” ๋ฐ ์ง€์ณค์œผ๋ฉฐ ์ž‘์€ ํ”„๋กœ๊ทธ๋žจ์„ ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค. ๋์—†๋Š”, ๋“ค์–ด์˜ค๋Š” ์—ฐ๊ฒฐ ์†๋„๋ฅผ ๋Šฆ์ถ”๋Š” SSH์šฉ tarpit์ž…๋‹ˆ๋‹ค. ํ”„๋กœ๊ทธ๋žจ์€ ํฌํŠธ(ํ…Œ์ŠคํŠธ์šฉ ๊ธฐ๋ณธ ํฌํŠธ๋Š” 2222)๋ฅผ ์—ด๊ณ  SSH ์„œ๋ฒ„์ธ ์ฒ™ํ•˜์ง€๋งŒ ์‹ค์ œ๋กœ๋Š” ๋“ค์–ด์˜ค๋Š” ํด๋ผ์ด์–ธํŠธ๊ฐ€ ํฌ๊ธฐํ•  ๋•Œ๊นŒ์ง€ ๋์—†๋Š” ์—ฐ๊ฒฐ์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋–จ์–ด์งˆ ๋•Œ๊นŒ์ง€ ๋ฉฐ์น  ์ด์ƒ ๊ณ„์†๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์œ ํ‹ธ๋ฆฌํ‹ฐ ์„ค์น˜:

$ make
$ ./endlessh &
$ ssh -p2222 localhost

์ ์ ˆํ•˜๊ฒŒ ๊ตฌํ˜„๋œ ํƒ€ํ•์€ ์‚ฌ์šฉ์ž๋ณด๋‹ค ๊ณต๊ฒฉ์ž๋กœ๋ถ€ํ„ฐ ๋” ๋งŽ์€ ๋ฆฌ์†Œ์Šค๋ฅผ ์†Œ๋ชจํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ž์›์˜ ๋ฌธ์ œ๋„ ์•„๋‹™๋‹ˆ๋‹ค. ์ž‘๊ฐ€ ๊ธฐ๋กํ”„๋กœ๊ทธ๋žจ์ด ์ค‘๋…์„ฑ์ด ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ˜„์žฌ 27๋ช…์˜ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๊ฐ‡ํ˜€ ์žˆ๊ณ  ๊ทธ ์ค‘ ์ผ๋ถ€๋Š” ๋ช‡ ์ฃผ ๋™์•ˆ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ํ™œ๋™์ด ์ตœ๊ณ ์กฐ์— ๋‹ฌํ–ˆ์„ ๋•Œ 1378๋ช…์˜ ํด๋ผ์ด์–ธํŠธ๊ฐ€ 20์‹œ๊ฐ„ ๋™์•ˆ ๊ฐ‡ํ˜€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค!

์ž‘๋™ ๋ชจ๋“œ์—์„œ๋Š” ํ›Œ๋ฆฌ๊ฑด์ด ํ•œ๊บผ๋ฒˆ์— ๋…ธํฌํ•˜๋Š” ์ผ๋ฐ˜ ํฌํŠธ 22์— Endlessh ์„œ๋ฒ„๋ฅผ ์„ค์น˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ‘œ์ค€ ๋ณด์•ˆ ๊ถŒ์žฅ ์‚ฌํ•ญ์€ ํ•ญ์ƒ SSH๋ฅผ ๋‹ค๋ฅธ ํฌํŠธ๋กœ ์ด๋™ํ•˜์—ฌ ๋กœ๊ทธ ํฌ๊ธฐ๋ฅผ ์ฆ‰์‹œ ์ค„์ผ ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค.

Chris Wellons๋Š” ์ž์‹ ์˜ ํ”„๋กœ๊ทธ๋žจ์ด ์‚ฌ์–‘์˜ ํ•œ ๋‹จ๋ฝ์„ ํ™œ์šฉํ•œ๋‹ค๊ณ  ๋งํ•ฉ๋‹ˆ๋‹ค. RFC 4253 SSH ํ”„๋กœํ† ์ฝœ์—. TCP ์—ฐ๊ฒฐ์ด ์„ค์ •๋œ ์งํ›„, ์•”ํ˜ธํ™”๊ฐ€ ์ ์šฉ๋˜๊ธฐ ์ „์— ์–‘ ๋‹น์‚ฌ์ž๋Š” ์‹๋ณ„ ๋ฌธ์ž์—ด์„ ๋ณด๋‚ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ฐธ๊ณ  ์‚ฌํ•ญ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. "์„œ๋ฒ„๋Š” ๋ฒ„์ „ ํ–‰์„ ๋ณด๋‚ด๊ธฐ ์ „์— ๋‹ค๋ฅธ ๋ฐ์ดํ„ฐ ํ–‰์„ ๋ณด๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.". ๊ทธ๋ฆฌ๊ณ  ์ œํ•œ ์—†์Œ ์ด ๋ฐ์ดํ„ฐ์˜ ์–‘์— ๋”ฐ๋ผ ๊ฐ ์ค„์„ ๋‹ค์Œ์œผ๋กœ ์‹œ์ž‘ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. SSH-.

์ด๊ฒƒ์ด ๋ฐ”๋กœ Endlessh ํ”„๋กœ๊ทธ๋žจ์ด ํ•˜๋Š” ์ผ์ž…๋‹ˆ๋‹ค. ๋ณด๋ƒ„ ๋์ด์—†๋Š” ๋ฌด์ž‘์œ„๋กœ ์ƒ์„ฑ๋œ ๋ฐ์ดํ„ฐ ์ŠคํŠธ๋ฆผ, RFC 4253์„ ์ค€์ˆ˜ํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ์ธ์ฆ ์ „์— ์ „์†ก๋˜๋ฉฐ ๊ฐ ์ค„์€ ๋‹ค์Œ์œผ๋กœ ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค. SSH- ์ค„ ๋ ๋ฌธ์ž๋ฅผ ํฌํ•จํ•˜์—ฌ 255์ž๋ฅผ ์ดˆ๊ณผํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ๋ชจ๋“  ๊ฒƒ์ด ํ‘œ์ค€์— ๋”ฐ๋ฆ…๋‹ˆ๋‹ค.

๊ธฐ๋ณธ์ ์œผ๋กœ ํ”„๋กœ๊ทธ๋žจ์€ ํŒจํ‚ท ์ „์†ก ์‚ฌ์ด์— 10์ดˆ๋ฅผ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์‹œ๊ฐ„ ์ดˆ๊ณผ๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์˜์›ํžˆ ๊ฐ‡ํžˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์•”ํ˜ธํ™”๊ฐ€ ์ ์šฉ๋˜๊ธฐ ์ „์— ๋ฐ์ดํ„ฐ๊ฐ€ ์ „์†ก๋˜๋ฏ€๋กœ ํ”„๋กœ๊ทธ๋žจ์ด ๋งค์šฐ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. ์•”ํ˜ธ๋ฅผ ๊ตฌํ˜„ํ•  ํ•„์š”๊ฐ€ ์—†์œผ๋ฉฐ ์—ฌ๋Ÿฌ ํ”„๋กœํ† ์ฝœ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

์ž‘์„ฑ์ž๋Š” ์œ ํ‹ธ๋ฆฌํ‹ฐ๊ฐ€ ์ตœ์†Œํ•œ์˜ ๋ฆฌ์†Œ์Šค๋ฅผ ์†Œ๋น„ํ•˜๊ณ  ์‹œ์Šคํ…œ์—์„œ ์™„์ „ํžˆ ๋ˆˆ์— ๋„์ง€ ์•Š๊ฒŒ ์ž‘๋™ํ•˜๋„๋ก ๋…ธ๋ ฅํ–ˆ์Šต๋‹ˆ๋‹ค. ์ตœ์‹  ๋ฐ”์ด๋Ÿฌ์Šค ๋ฐฑ์‹  ๋ฐ ๊ธฐํƒ€ "๋ณด์•ˆ ์‹œ์Šคํ…œ"๊ณผ ๋‹ฌ๋ฆฌ ์ปดํ“จํ„ฐ ์†๋„๊ฐ€ ๋Š๋ ค์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋Š” ์•ฝ๊ฐ„ ๋” ๊ต๋ฌ˜ํ•œ ์†Œํ”„ํŠธ์›จ์–ด ๊ตฌํ˜„์œผ๋กœ ์ธํ•ด ํŠธ๋ž˜ํ”ฝ๊ณผ ๋ฉ”๋ชจ๋ฆฌ ์†Œ๋น„๋ฅผ ๋ชจ๋‘ ์ตœ์†Œํ™”ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‹จ์ˆœํžˆ ์ƒˆ ์—ฐ๊ฒฐ์—์„œ ๋ณ„๋„์˜ ํ”„๋กœ์„ธ์Šค๋ฅผ ์‹œ์ž‘ํ•˜๋Š” ๊ฒฝ์šฐ ์ž ์žฌ์ ์ธ ๊ณต๊ฒฉ์ž๋Š” ์—ฌ๋Ÿฌ ์—ฐ๊ฒฐ์„ ์—ด์–ด ์‹œ์Šคํ…œ์˜ ๋ฆฌ์†Œ์Šค๋ฅผ ์†Œ์ง„์‹œ์ผœ DDoS ๊ณต๊ฒฉ์„ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฐ๊ฒฐ๋‹น ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋„ ์ตœ์„ ์˜ ์„ ํƒ์ด ์•„๋‹™๋‹ˆ๋‹ค. ์ปค๋„์ด ์Šค๋ ˆ๋“œ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐ ๋ฆฌ์†Œ์Šค๋ฅผ ๋‚ญ๋น„ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

์ด๊ฒƒ์ด ๋ฐ”๋กœ Chris Wellons๊ฐ€ Endlessh๋ฅผ ์œ„ํ•ด ๊ฐ€์žฅ ๊ฐ€๋ฒผ์šด ์˜ต์…˜์ธ ๋‹จ์ผ ์Šค๋ ˆ๋“œ ์„œ๋ฒ„๋ฅผ ์„ ํƒํ•œ ์ด์œ ์ž…๋‹ˆ๋‹ค. poll(2)์—ฌ๊ธฐ์„œ ํŠธ๋žฉ์˜ ํด๋ผ์ด์–ธํŠธ๋Š” ์ปค๋„์˜ ์†Œ์ผ“ ๊ฐœ์ฒด์™€ Endlessh์—์„œ ์ถ”์ ํ•˜๊ธฐ ์œ„ํ•œ ์ถ”๊ฐ€ 78๋ฐ”์ดํŠธ๋ฅผ ๊ณ„์‚ฐํ•˜์ง€ ์•Š๊ณ  ์‚ฌ์‹ค์ƒ ์ถ”๊ฐ€ ๋ฆฌ์†Œ์Šค๋ฅผ ์†Œ๋น„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ฐ ํด๋ผ์ด์–ธํŠธ์— ๋Œ€ํ•ด ์ˆ˜์‹  ๋ฐ ์†ก์‹  ๋ฒ„ํผ๋ฅผ ํ• ๋‹นํ•  ํ•„์š”๊ฐ€ ์—†๋„๋ก Endlessh๋Š” ์ง์ ‘ ์•ก์„ธ์Šค ์†Œ์ผ“์„ ์—ด๊ณ  ๊ฑฐ์˜ ์ „์ฒด ์šด์˜ ์ฒด์ œ TCP/IP ์Šคํƒ์„ ์šฐํšŒํ•˜์—ฌ TCP ํŒจํ‚ท์„ ์ง์ ‘ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋“ค์–ด์˜ค๋Š” ๋ฐ์ดํ„ฐ์— ๊ด€์‹ฌ์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— ๋“ค์–ด์˜ค๋Š” ๋ฒ„ํผ๋Š” ์ „ํ˜€ ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ €์ž๋Š” ํ”„๋กœ๊ทธ๋žจ ๋‹น์‹œ์— ์ด๋ ‡๊ฒŒ ๋งํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ชฐ๋ž๋‹ค. Python์˜ asycio ๋ฐ ๊ธฐํƒ€ tarpit์˜ ์กด์žฌ์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๊ฐ€ asycio์— ๋Œ€ํ•ด ์•Œ๊ณ  ์žˆ๋‹ค๋ฉด Python์—์„œ ๋‹จ 18์ค„๋งŒ์œผ๋กœ ์œ ํ‹ธ๋ฆฌํ‹ฐ๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

import asyncio
import random

async def handler(_reader, writer):
try:
while True:
await asyncio.sleep(10)
writer.write(b'%xrn' % random.randint(0, 2**32))
await writer.drain()
except ConnectionResetError:
pass

async def main():
server = await asyncio.start_server(handler, '0.0.0.0', 2222)
async with server:
await server.serve_forever()

asyncio.run(main())

Asyncio๋Š” ํƒ€ํ• ์ž‘์„ฑ์— ์ด์ƒ์ ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์ด ํ›„ํฌ๋Š” Firefox, Chrome ๋˜๋Š” HTTP ์„œ๋ฒ„์— ์—ฐ๊ฒฐ์„ ์‹œ๋„ํ•˜๋Š” ๊ธฐํƒ€ ํด๋ผ์ด์–ธํŠธ๋ฅผ ๋ช‡ ์‹œ๊ฐ„ ๋™์•ˆ ์ •์ง€์‹œํ‚ต๋‹ˆ๋‹ค.

import asyncio
import random

async def handler(_reader, writer):
writer.write(b'HTTP/1.1 200 OKrn')
try:
while True:
await asyncio.sleep(5)
header = random.randint(0, 2**32)
value = random.randint(0, 2**32)
writer.write(b'X-%x: %xrn' % (header, value))
await writer.drain()
except ConnectionResetError:
pass

async def main():
server = await asyncio.start_server(handler, '0.0.0.0', 8080)
async with server:
await server.serve_forever()

asyncio.run(main())

Tarpit์€ ์˜จ๋ผ์ธ ๊ดด๋กญํž˜์„ ์ฒ˜๋ฒŒํ•˜๋Š” ํ›Œ๋ฅญํ•œ ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. ์‚ฌ์‹ค, ๋ฐ˜๋Œ€๋กœ ํŠน์ • ์„œ๋ฒ„์˜ ๋น„์ •์ƒ์ ์ธ ๋™์ž‘์— ์ฃผ์˜๋ฅผ ๋Œ ์œ„ํ—˜์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์–ด๋–ค ์‚ฌ๋žŒ ๋ณต์ˆ˜๋ฅผ ์ƒ๊ฐํ• ์ง€๋„ ๋ชฐ๋ผ ๊ทธ๋ฆฌ๊ณ  ๊ท€ํ•˜์˜ IP์— ๋Œ€ํ•œ ํ‘œ์  DDoS ๊ณต๊ฒฉ. ๊ทธ๋Ÿฌ๋‚˜ ์ง€๊ธˆ๊นŒ์ง€ ๊ทธ๋Ÿฌํ•œ ์‚ฌ๋ก€๋Š” ์—†์—ˆ์œผ๋ฉฐ ํƒ€ํ•์€ ํ›Œ๋ฅญํ•˜๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

ํ—ˆ๋ธŒ:
Python, ์ •๋ณด๋ณด์•ˆ, ์†Œํ”„ํŠธ์›จ์–ด, ์‹œ์Šคํ…œ ๊ด€๋ฆฌ

ํƒœ๊ทธ :
SSH, Endlessh, ํƒ€๋ฅดํ•, ํƒ€๋ฅดํ•, ํŠธ๋žฉ, ์•„์‹œ์‹œ์˜ค
๋“ค์–ด์˜ค๋Š” SSH ์—ฐ๊ฒฐ์„ ์œ„ํ•œ ํŠธ๋žฉ(ํƒ€๋ฅดํ•)

์ธํ„ฐ๋„ท์ด ๋งค์šฐ ์ ๋Œ€์ ์ธ ํ™˜๊ฒฝ์ด๋ผ๋Š” ๊ฒƒ์€ ๋น„๋ฐ€์ด ์•„๋‹™๋‹ˆ๋‹ค. ์„œ๋ฒ„๋ฅผ ์˜ฌ๋ฆฌ์ž๋งˆ์ž ์ฆ‰์‹œ ๋Œ€๊ทœ๋ชจ ๊ณต๊ฒฉ๊ณผ ์—ฌ๋Ÿฌ ์ฐจ๋ก€์˜ ์Šค์บ”์„ ๋ฐ›๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๊ฒฝ๋น„์›์˜ ํ—ˆ๋‹ˆํŒŸ ์ด ์“ฐ๋ ˆ๊ธฐ ํŠธ๋ž˜ํ”ฝ์˜ ๊ทœ๋ชจ๋ฅผ ์ถ”์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ํ‰๊ท ์ ์ธ ์„œ๋ฒ„์—์„œ๋Š” ํŠธ๋ž˜ํ”ฝ์˜ 99%๊ฐ€ ์•…์„ฑ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Tarpit์€ ๋“ค์–ด์˜ค๋Š” ์—ฐ๊ฒฐ ์†๋„๋ฅผ ๋Šฆ์ถ”๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ํŠธ๋žฉ ํฌํŠธ์ž…๋‹ˆ๋‹ค. ํƒ€์‚ฌ ์‹œ์Šคํ…œ์ด ์ด ํฌํŠธ์— ์—ฐ๊ฒฐ๋œ ๊ฒฝ์šฐ ์—ฐ๊ฒฐ์„ ๋น ๋ฅด๊ฒŒ ์ข…๋ฃŒํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์‹œ์Šคํ…œ ๋ฆฌ์†Œ์Šค๋ฅผ ๋‚ญ๋น„ํ•˜๊ณ  ์—ฐ๊ฒฐ ์‹œ๊ฐ„์ด ์ดˆ๊ณผ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ๊ฑฐ๋‚˜ ์ˆ˜๋™์œผ๋กœ ์—ฐ๊ฒฐ์„ ์ข…๋ฃŒํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ๋ฐฉ์ˆ˜ํฌ๋Š” ๋ณดํ˜ธ๋ฅผ ์œ„ํ•ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ด ๊ธฐ์ˆ ์€ ์ปดํ“จํ„ฐ ์›œ์œผ๋กœ๋ถ€ํ„ฐ ๋ณดํ˜ธํ•˜๊ธฐ ์œ„ํ•ด ์ฒ˜์Œ ๊ฐœ๋ฐœ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ ์ด๋Š” ๋ชจ๋“  IP ์ฃผ์†Œ๋ฅผ ์—ฐ์†์ ์œผ๋กœ ๊ด‘๋ฒ”์œ„ํ•˜๊ฒŒ ์Šค์บ๋‹ํ•˜๋Š” ์ŠคํŒจ๋จธ์™€ ์—ฐ๊ตฌ์›์˜ ์‚ถ์„ ๋ง์น˜๋Š” ๋ฐ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(Habrรฉ์˜ ์˜ˆ: ์˜ค์ŠคํŠธ๋ฆฌ์•„, ์šฐํฌ๋ผ์ด๋‚˜).

Chris Wellons๋ผ๋Š” ์‹œ์Šคํ…œ ๊ด€๋ฆฌ์ž ์ค‘ ํ•œ ๋ช…์€ ๋ถ„๋ช…ํžˆ ์ด ์ˆ˜์น˜๋ฅผ ์ง€์ผœ๋ณด๋Š” ๋ฐ ์ง€์ณค์œผ๋ฉฐ ์ž‘์€ ํ”„๋กœ๊ทธ๋žจ์„ ์ž‘์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค. ๋์—†๋Š”, ๋“ค์–ด์˜ค๋Š” ์—ฐ๊ฒฐ ์†๋„๋ฅผ ๋Šฆ์ถ”๋Š” SSH์šฉ tarpit์ž…๋‹ˆ๋‹ค. ํ”„๋กœ๊ทธ๋žจ์€ ํฌํŠธ(ํ…Œ์ŠคํŠธ์šฉ ๊ธฐ๋ณธ ํฌํŠธ๋Š” 2222)๋ฅผ ์—ด๊ณ  SSH ์„œ๋ฒ„์ธ ์ฒ™ํ•˜์ง€๋งŒ ์‹ค์ œ๋กœ๋Š” ๋“ค์–ด์˜ค๋Š” ํด๋ผ์ด์–ธํŠธ๊ฐ€ ํฌ๊ธฐํ•  ๋•Œ๊นŒ์ง€ ๋์—†๋Š” ์—ฐ๊ฒฐ์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋–จ์–ด์งˆ ๋•Œ๊นŒ์ง€ ๋ฉฐ์น  ์ด์ƒ ๊ณ„์†๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์œ ํ‹ธ๋ฆฌํ‹ฐ ์„ค์น˜:

$ make
$ ./endlessh &
$ ssh -p2222 localhost

์ ์ ˆํ•˜๊ฒŒ ๊ตฌํ˜„๋œ ํƒ€ํ•์€ ์‚ฌ์šฉ์ž๋ณด๋‹ค ๊ณต๊ฒฉ์ž๋กœ๋ถ€ํ„ฐ ๋” ๋งŽ์€ ๋ฆฌ์†Œ์Šค๋ฅผ ์†Œ๋ชจํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ž์›์˜ ๋ฌธ์ œ๋„ ์•„๋‹™๋‹ˆ๋‹ค. ์ž‘๊ฐ€ ๊ธฐ๋กํ”„๋กœ๊ทธ๋žจ์ด ์ค‘๋…์„ฑ์ด ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ˜„์žฌ 27๋ช…์˜ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๊ฐ‡ํ˜€ ์žˆ๊ณ  ๊ทธ ์ค‘ ์ผ๋ถ€๋Š” ๋ช‡ ์ฃผ ๋™์•ˆ ์—ฐ๊ฒฐ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ํ™œ๋™์ด ์ตœ๊ณ ์กฐ์— ๋‹ฌํ–ˆ์„ ๋•Œ 1378๋ช…์˜ ํด๋ผ์ด์–ธํŠธ๊ฐ€ 20์‹œ๊ฐ„ ๋™์•ˆ ๊ฐ‡ํ˜€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค!

์ž‘๋™ ๋ชจ๋“œ์—์„œ๋Š” ํ›Œ๋ฆฌ๊ฑด์ด ํ•œ๊บผ๋ฒˆ์— ๋…ธํฌํ•˜๋Š” ์ผ๋ฐ˜ ํฌํŠธ 22์— Endlessh ์„œ๋ฒ„๋ฅผ ์„ค์น˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ‘œ์ค€ ๋ณด์•ˆ ๊ถŒ์žฅ ์‚ฌํ•ญ์€ ํ•ญ์ƒ SSH๋ฅผ ๋‹ค๋ฅธ ํฌํŠธ๋กœ ์ด๋™ํ•˜์—ฌ ๋กœ๊ทธ ํฌ๊ธฐ๋ฅผ ์ฆ‰์‹œ ์ค„์ผ ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค.

Chris Wellons๋Š” ์ž์‹ ์˜ ํ”„๋กœ๊ทธ๋žจ์ด ์‚ฌ์–‘์˜ ํ•œ ๋‹จ๋ฝ์„ ํ™œ์šฉํ•œ๋‹ค๊ณ  ๋งํ•ฉ๋‹ˆ๋‹ค. RFC 4253 SSH ํ”„๋กœํ† ์ฝœ์—. TCP ์—ฐ๊ฒฐ์ด ์„ค์ •๋œ ์งํ›„, ์•”ํ˜ธํ™”๊ฐ€ ์ ์šฉ๋˜๊ธฐ ์ „์— ์–‘ ๋‹น์‚ฌ์ž๋Š” ์‹๋ณ„ ๋ฌธ์ž์—ด์„ ๋ณด๋‚ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ฐธ๊ณ  ์‚ฌํ•ญ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. "์„œ๋ฒ„๋Š” ๋ฒ„์ „ ํ–‰์„ ๋ณด๋‚ด๊ธฐ ์ „์— ๋‹ค๋ฅธ ๋ฐ์ดํ„ฐ ํ–‰์„ ๋ณด๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.". ๊ทธ๋ฆฌ๊ณ  ์ œํ•œ ์—†์Œ ์ด ๋ฐ์ดํ„ฐ์˜ ์–‘์— ๋”ฐ๋ผ ๊ฐ ์ค„์„ ๋‹ค์Œ์œผ๋กœ ์‹œ์ž‘ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. SSH-.

์ด๊ฒƒ์ด ๋ฐ”๋กœ Endlessh ํ”„๋กœ๊ทธ๋žจ์ด ํ•˜๋Š” ์ผ์ž…๋‹ˆ๋‹ค. ๋ณด๋ƒ„ ๋์ด์—†๋Š” ๋ฌด์ž‘์œ„๋กœ ์ƒ์„ฑ๋œ ๋ฐ์ดํ„ฐ ์ŠคํŠธ๋ฆผ, RFC 4253์„ ์ค€์ˆ˜ํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ์ธ์ฆ ์ „์— ์ „์†ก๋˜๋ฉฐ ๊ฐ ์ค„์€ ๋‹ค์Œ์œผ๋กœ ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค. SSH- ์ค„ ๋ ๋ฌธ์ž๋ฅผ ํฌํ•จํ•˜์—ฌ 255์ž๋ฅผ ์ดˆ๊ณผํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ๋ชจ๋“  ๊ฒƒ์ด ํ‘œ์ค€์— ๋”ฐ๋ฆ…๋‹ˆ๋‹ค.

๊ธฐ๋ณธ์ ์œผ๋กœ ํ”„๋กœ๊ทธ๋žจ์€ ํŒจํ‚ท ์ „์†ก ์‚ฌ์ด์— 10์ดˆ๋ฅผ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์‹œ๊ฐ„ ์ดˆ๊ณผ๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์˜์›ํžˆ ๊ฐ‡ํžˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์•”ํ˜ธํ™”๊ฐ€ ์ ์šฉ๋˜๊ธฐ ์ „์— ๋ฐ์ดํ„ฐ๊ฐ€ ์ „์†ก๋˜๋ฏ€๋กœ ํ”„๋กœ๊ทธ๋žจ์ด ๋งค์šฐ ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. ์•”ํ˜ธ๋ฅผ ๊ตฌํ˜„ํ•  ํ•„์š”๊ฐ€ ์—†์œผ๋ฉฐ ์—ฌ๋Ÿฌ ํ”„๋กœํ† ์ฝœ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

์ž‘์„ฑ์ž๋Š” ์œ ํ‹ธ๋ฆฌํ‹ฐ๊ฐ€ ์ตœ์†Œํ•œ์˜ ๋ฆฌ์†Œ์Šค๋ฅผ ์†Œ๋น„ํ•˜๊ณ  ์‹œ์Šคํ…œ์—์„œ ์™„์ „ํžˆ ๋ˆˆ์— ๋„์ง€ ์•Š๊ฒŒ ์ž‘๋™ํ•˜๋„๋ก ๋…ธ๋ ฅํ–ˆ์Šต๋‹ˆ๋‹ค. ์ตœ์‹  ๋ฐ”์ด๋Ÿฌ์Šค ๋ฐฑ์‹  ๋ฐ ๊ธฐํƒ€ "๋ณด์•ˆ ์‹œ์Šคํ…œ"๊ณผ ๋‹ฌ๋ฆฌ ์ปดํ“จํ„ฐ ์†๋„๊ฐ€ ๋Š๋ ค์ง€์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋Š” ์•ฝ๊ฐ„ ๋” ๊ต๋ฌ˜ํ•œ ์†Œํ”„ํŠธ์›จ์–ด ๊ตฌํ˜„์œผ๋กœ ์ธํ•ด ํŠธ๋ž˜ํ”ฝ๊ณผ ๋ฉ”๋ชจ๋ฆฌ ์†Œ๋น„๋ฅผ ๋ชจ๋‘ ์ตœ์†Œํ™”ํ–ˆ์Šต๋‹ˆ๋‹ค. ๋‹จ์ˆœํžˆ ์ƒˆ ์—ฐ๊ฒฐ์—์„œ ๋ณ„๋„์˜ ํ”„๋กœ์„ธ์Šค๋ฅผ ์‹œ์ž‘ํ•˜๋Š” ๊ฒฝ์šฐ ์ž ์žฌ์ ์ธ ๊ณต๊ฒฉ์ž๋Š” ์—ฌ๋Ÿฌ ์—ฐ๊ฒฐ์„ ์—ด์–ด ์‹œ์Šคํ…œ์˜ ๋ฆฌ์†Œ์Šค๋ฅผ ์†Œ์ง„์‹œ์ผœ DDoS ๊ณต๊ฒฉ์„ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฐ๊ฒฐ๋‹น ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋„ ์ตœ์„ ์˜ ์„ ํƒ์ด ์•„๋‹™๋‹ˆ๋‹ค. ์ปค๋„์ด ์Šค๋ ˆ๋“œ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐ ๋ฆฌ์†Œ์Šค๋ฅผ ๋‚ญ๋น„ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

์ด๊ฒƒ์ด ๋ฐ”๋กœ Chris Wellons๊ฐ€ Endlessh๋ฅผ ์œ„ํ•ด ๊ฐ€์žฅ ๊ฐ€๋ฒผ์šด ์˜ต์…˜์ธ ๋‹จ์ผ ์Šค๋ ˆ๋“œ ์„œ๋ฒ„๋ฅผ ์„ ํƒํ•œ ์ด์œ ์ž…๋‹ˆ๋‹ค. poll(2)์—ฌ๊ธฐ์„œ ํŠธ๋žฉ์˜ ํด๋ผ์ด์–ธํŠธ๋Š” ์ปค๋„์˜ ์†Œ์ผ“ ๊ฐœ์ฒด์™€ Endlessh์—์„œ ์ถ”์ ํ•˜๊ธฐ ์œ„ํ•œ ์ถ”๊ฐ€ 78๋ฐ”์ดํŠธ๋ฅผ ๊ณ„์‚ฐํ•˜์ง€ ์•Š๊ณ  ์‚ฌ์‹ค์ƒ ์ถ”๊ฐ€ ๋ฆฌ์†Œ์Šค๋ฅผ ์†Œ๋น„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ฐ ํด๋ผ์ด์–ธํŠธ์— ๋Œ€ํ•ด ์ˆ˜์‹  ๋ฐ ์†ก์‹  ๋ฒ„ํผ๋ฅผ ํ• ๋‹นํ•  ํ•„์š”๊ฐ€ ์—†๋„๋ก Endlessh๋Š” ์ง์ ‘ ์•ก์„ธ์Šค ์†Œ์ผ“์„ ์—ด๊ณ  ๊ฑฐ์˜ ์ „์ฒด ์šด์˜ ์ฒด์ œ TCP/IP ์Šคํƒ์„ ์šฐํšŒํ•˜์—ฌ TCP ํŒจํ‚ท์„ ์ง์ ‘ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋“ค์–ด์˜ค๋Š” ๋ฐ์ดํ„ฐ์— ๊ด€์‹ฌ์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— ๋“ค์–ด์˜ค๋Š” ๋ฒ„ํผ๋Š” ์ „ํ˜€ ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ €์ž๋Š” ํ”„๋กœ๊ทธ๋žจ ๋‹น์‹œ์— ์ด๋ ‡๊ฒŒ ๋งํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ชฐ๋ž๋‹ค. Python์˜ asycio ๋ฐ ๊ธฐํƒ€ tarpit์˜ ์กด์žฌ์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๊ฐ€ asycio์— ๋Œ€ํ•ด ์•Œ๊ณ  ์žˆ๋‹ค๋ฉด Python์—์„œ ๋‹จ 18์ค„๋งŒ์œผ๋กœ ์œ ํ‹ธ๋ฆฌํ‹ฐ๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

import asyncio
import random

async def handler(_reader, writer):
try:
while True:
await asyncio.sleep(10)
writer.write(b'%xrn' % random.randint(0, 2**32))
await writer.drain()
except ConnectionResetError:
pass

async def main():
server = await asyncio.start_server(handler, '0.0.0.0', 2222)
async with server:
await server.serve_forever()

asyncio.run(main())

Asyncio๋Š” ํƒ€ํ• ์ž‘์„ฑ์— ์ด์ƒ์ ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์ด ํ›„ํฌ๋Š” Firefox, Chrome ๋˜๋Š” HTTP ์„œ๋ฒ„์— ์—ฐ๊ฒฐ์„ ์‹œ๋„ํ•˜๋Š” ๊ธฐํƒ€ ํด๋ผ์ด์–ธํŠธ๋ฅผ ๋ช‡ ์‹œ๊ฐ„ ๋™์•ˆ ์ •์ง€์‹œํ‚ต๋‹ˆ๋‹ค.

import asyncio
import random

async def handler(_reader, writer):
writer.write(b'HTTP/1.1 200 OKrn')
try:
while True:
await asyncio.sleep(5)
header = random.randint(0, 2**32)
value = random.randint(0, 2**32)
writer.write(b'X-%x: %xrn' % (header, value))
await writer.drain()
except ConnectionResetError:
pass

async def main():
server = await asyncio.start_server(handler, '0.0.0.0', 8080)
async with server:
await server.serve_forever()

asyncio.run(main())

Tarpit์€ ์˜จ๋ผ์ธ ๊ดด๋กญํž˜์„ ์ฒ˜๋ฒŒํ•˜๋Š” ํ›Œ๋ฅญํ•œ ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. ์‚ฌ์‹ค, ๋ฐ˜๋Œ€๋กœ ํŠน์ • ์„œ๋ฒ„์˜ ๋น„์ •์ƒ์ ์ธ ๋™์ž‘์— ์ฃผ์˜๋ฅผ ๋Œ ์œ„ํ—˜์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์–ด๋–ค ์‚ฌ๋žŒ ๋ณต์ˆ˜๋ฅผ ์ƒ๊ฐํ• ์ง€๋„ ๋ชฐ๋ผ ๊ทธ๋ฆฌ๊ณ  ๊ท€ํ•˜์˜ IP์— ๋Œ€ํ•œ ํ‘œ์  DDoS ๊ณต๊ฒฉ. ๊ทธ๋Ÿฌ๋‚˜ ์ง€๊ธˆ๊นŒ์ง€ ๊ทธ๋Ÿฌํ•œ ์‚ฌ๋ก€๋Š” ์—†์—ˆ์œผ๋ฉฐ ํƒ€ํ•์€ ํ›Œ๋ฅญํ•˜๊ฒŒ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค.

๋“ค์–ด์˜ค๋Š” SSH ์—ฐ๊ฒฐ์„ ์œ„ํ•œ ํŠธ๋žฉ(ํƒ€๋ฅดํ•)

์ถœ์ฒ˜ : habr.com

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€