1. ๋ฐฐ๊ฒฝ/์ญ์ฌ โ ์ธ์ , ๋๊ฐ, ์ ์ ๋ช ํ๊ฐ
SQL ์ฌ๋๋จธ(SQL Slammer)๋ 2003๋ 1์ 25์ผ 05:30(UTC) ๋ฌด๋ ต, ๋ง์ดํฌ๋ก์ํํธ SQL Server 2000 ยท MSDE 2000์ ์ทจ์ฝ์ ์ ๋ ธ๋ฆฌ๊ณ ๋ฑ์ฅํ ์๊ธฐ๋ณต์ ํ ์์ด๋ค. ๋ณ์นญ์ผ๋ก ์ฌํ์ด์ด(Sapphire), ํฌ์ปจ(Helkern)์ด๋ผ๊ณ ๋ ๋ถ๋ ธ๋ค. ์ ์์๋ ์ง๊ธ๊น์ง ๋ฐํ์ง์ง ์์์ง๋ง, ๊ทธ ๊ฒฐ๊ณผ๋ง์ผ๋ก 2003๋ ์ต์ ์ ์ธํฐ๋ท ๋๋์ ์ผ์ผ์ผฐ๋ค.
- ์ทจ์ฝ์ : SQL Server 2000/ MSDE 2000์ Resolution Service(SQL ์ธ์คํด์ค ์กฐํ ์๋น์ค, UDP 1434)์ ์กด์ฌํ๋ ์คํ ๋ฒํผ ์ค๋ฒํ๋ก์ฐ๋ค. ๋ง์ดํฌ๋ก์ํํธ๋ 2002๋ 7์ MS02-039 ๋ณด์ ๊ณต์ง๋ก ์ด๋ฏธ ํจ์น๋ฅผ ๋ฐฐํฌํ๊ณ (CVE-2002-0649), ์ฌ๋๋จธ๋ ํจ์น๊ฐ ๋์จ ์ง ์ฝ 6๊ฐ์ ๋ค์ ๋ํ๋ฌ๋ค. ์ฆ '์๋ ค์ง ์ทจ์ฝ์ '์ด ํ๊ทผ์ด์๋ค.
- ์๋์ ์๋: ์ด๊ธฐ์๋ ์ฝ 8.5์ด๋ง๋ค ๊ฐ์ผ ๋์๊ฐ 2๋ฐฐ๋ก ๋์๊ณ , ๋ฑ์ฅ ์ฝ 3๋ถ ๋ง์ ์ต๋ ์ค์บ๋ฅ ์ ๋๋ฌํด 10๋ถ ์์ ์ต์ 75,000๋์ ์๋ฒ๋ฅผ ๊ฐ์ผ์์ผฐ๋ค. ์ญ์ฌ์ ๊ฐ์ฅ ๋น ๋ฅด๊ฒ ํผ์ง ์์ผ๋ก ๊ผฝํ๋ค.
- ์ ์ ๋ช ํ๊ฐ: โ ์ ์ ์ฒด๊ฐ ๋จ ํ๋์ 376๋ฐ์ดํธ UDP ํจํท์ด์๋ค(ํ์ผ๋, ๋ณ๋ ์ ํ ์ฝ๋๋ ์์ด 'ํจํท ์์ฒด๊ฐ ์'). โก ๋์คํฌ์ ์๋ฌด ํ์ผ๋ ๋ง๋ค์ง ์์ ๋ฉ๋ชจ๋ฆฌ์์๋ง ์ด์๋ค(์ฌ๋ถํ ๋ง์ผ๋ก๋ ์ฌ๋ผ์ง). โข ํ๊ตญ์ ํฌํจํ ์ ์ธ๊ณ ์ธํฐ๋ท ์ธํ๋ผ๋ฅผ ์ค์ ๋ก ๋ง๋น์์ผฐ๋ค.
- ์๋ ๋ฐฐ๊ฒฝ: 2003๋ ์ด์๋ SQL Server 2000์ด ๊ธฐ์ ยท๊ณต๊ณตยทํต์ ๋ง์ ๊น๋ ค ์์๊ณ , ๋ฐ์ดํฐ๋ฒ ์ด์ค ์๋ฒ๊ฐ ์ธํฐ๋ท์ ์ง์ ๋ ธ์ถ๋ ๊ฒฝ์ฐ๋ ๋๋ฌผ์ง ์์๋ค. ํจ์น ๊ด๋ฆฌ ๋ฌธํ๊ฐ ์๋ฆฌ ์ก๊ธฐ ์ ์ด๋ผ, '์ด๋ฏธ ๊ณ ์น ์ ์์๋' ์ทจ์ฝ์ ํ๋๊ฐ ์ธํฐ๋ท ์ ์ฒด์ ๋์ญํญ์ ์ผ์ผฐ๋ค.
2. ๊ฐ์ผยท์ ํ ๊ฒฝ๋ก โ ์ด๋ป๊ฒ ํผ์ก๋
์ฌ๋๋จธ์ ํ์ฐ์ ์ด์ง๋ฝ๊ฒ ๋จ์ํ๋ค. ์ทจ์ฝํ ์๋น์ค์ UDP ํฌํธ๋ก 'ํ ๊ฐ์ ํจํท'์ ๋ณด๋ด๋ฉด ๊ฐ์ผ๋๊ณ , ๊ฐ์ผ๋ ํ๋ก์ธ์ค๊ฐ ์ค์ค๋ก ๊ฐ์ ํจํท์ ์์๋ธ๋ค. ๊ทธ๊ฒ ์ ๋ถ๋ค.
- ๋ฌด์์ ์ค์บ๋(scanning): ๊ฐ์ผ๋ ์๋ฒ๋ IPv4 ์ ์ฒด ์ฃผ์๊ณต๊ฐ(232)์ ๋ฌด์์๋ก ๋์์ผ๋ก ์ผ์ UDP/1434 ํจํท์ ๋ฟ๋ ธ๋ค. ์ผ๋ถ๋ ๊ฐ์ ์๋ธ๋ทยท๊ฐ์ ๋์ญ์ ํธํฅ๋ผ ๋ด๋ถ ํ์ฐ์ ์๋น๊ฒผ์ง๋ง, ๋ณธ์ง์ '์ ์ง๊ตฌ ๋ฌด์์ ์ค์บ'์ด์๋ค.
- ๋ฒกํฐ๋ ๋จ์ผ UDP ๋ฐ์ดํฐ๊ทธ๋จ: ์ฐ๊ฒฐ ์๋ฆฝ(3-way handshake)๋, ์ธ์ฆ๋, ํ์ ๋ํ๋ ์์๋ค. ํ ๊ฐ์ UDP ํจํท๋ง ์ทจ์ฝํ ์๋น์ค์ ๋๋ฌํ๋ฉด ๊ฐ์ผ์ด ์๋ฃ๋๋ค. ๊ทธ๋์ 'Connectionless' ์์ด๋ผ ๋ถ๋ฆฐ๋ค.
- ํ์ผ ๋ฌดํ์ (memory-only): ๋์คํฌ์ ์คํ ํ์ผ์ ๋จ์ด๋จ๋ฆฌ์ง ์๊ณ ์ด๋ฏธ ์คํ ์ค์ธ
sqlservr.exeํ๋ก์ธ์ค์ ๋ฉ๋ชจ๋ฆฌ ์์์๋ง ์ด์๋ค. ๊ทธ๋์ ๋ฐฑ์ ๋, ํ์ผ ์ค์บ๋, ์ฌ๋ถํ ์ ๊น์ง๋ ์กฐ์ฉํ๋ค. ๋ฐ๋๋ก ๋ฉ๋ชจ๋ฆฌ์์๋ง ์ด๊ธฐ์ ์ฌ๋ถํ ๋ง์ผ๋ก๋ ํ์ ์ด ์ฌ๋ผ์ก๋ค. - ํ๋ก์ธ์ค๊ฐ ๊ณง ์ค์บ๋: ๋ณ๋์ ์ ํ ํ๋ก๊ทธ๋จ์ ์ค์นํ๋ ๋์ , ๊ฐ์ผ๋ SQL Server ํ๋ก์ธ์ค๊ฐ ์ค์ค๋ก
ws2_32.dll์ ์ ์ก ํจ์๋ฅผ ํธ์ถํด ๋ค์ ํฌ์์์๊ฒ ๊ฐ์ ํจํท์ ์ฌ์ ์กํ๋ค. '๊ฐ์ผ = ์ฆ์ ํ์ฐ'์ด์๋ค. - ์๊ธฐ ์ ํ์ด ์๋ค: ์ฌ๋๋จธ๋ ํ์ฐ์ ๋ฉ์ถ๋ ์กฐ๊ฑด(์ ํ ์ํยท์ ์ง ์ค์์น)์ด ์์๋ค. ์ทจ์ฝ ํธ์คํธ๊ฐ ์กด์ฌํ๋ ํ, ๋คํธ์ํฌ ๋์ญํญ์ด ๋ฒํฐ์ง ๋ชปํ ๋๊น์ง ๊ณ์ ํผ์ก๋ค.
- ๊ฐ์ผ๋์ง ์๋ ๊ฒฝ์ฐ: SQL Server/MSDE๊ฐ ์ค์ ๋ก ์คํ ์ค์ผ ๋๋ง ์ทจ์ฝ ์ฝ๋๊ฐ ๋ฉ๋ชจ๋ฆฌ์ ์ฌ๋ผ๊ฐ๋ค. ๊ทธ๋์ ์ผ๋ฐ ๋ฐ์คํฌํฑ(์๋์ฐ ์ํฌ์คํ ์ด์ )์ ๋์ฒด๋ก ์์ ํ๊ณ , ํผํด๋ DB๋ฅผ ์ด์ํ๋ ์๋ฒ์ ์ง์ค๋๋ค.
3. ๋์ ์๋ฆฌ ์์ธ ๋ถ์ โ ์ฝ๋/๊ตฌ์กฐ ๋ ๋ฒจ์์
์ฌ๋๋จธ๋ '์ ๋ณธ์ฒด + ์ฌ๋ฌ ๊ฐ์ ์ทจ์ฝ์ '์ด๋ผ๋ ๊ณ ์ ์ ๊ตฌ๋๊ฐ ์๋๋ผ, '์ทจ์ฝ์ ํ๋ = ์ ํ๋'๋ผ๋ ๊ทน๋จ์ ์ผ๋ก ์์ถ๋ ๊ตฌ์กฐ๋ฅผ ํํ๋ค. ๊ทธ๋์ 376๋ฐ์ดํธ ์์ ์ ํ์ ํ์ํ ๋ชจ๋ ๊ฒ์ด ๋ค์ด ์์๋ค.
- โ ํธ๋ฆฌ๊ฑฐ โ 0x04 ๋ฐ์ดํธ: Resolution Service๋ UDP/1434๋ก ์ค๋ ํจํท์ ์ฒซ ๋ฐ์ดํธ๋ฅผ ๋ณด๊ณ ๋์์ ๊ฒฐ์ ํ๋ค.
์ฌ๋๋จธ๋ ์ฒซ ๋ฐ์ดํธ๋ฅผ
0x04(์๋ต/์กฐํ ์๋ต ๊ณ์ด)๋ก ์์ํด, ์๋น์ค๊ฐ ์์ ์ '์ ์ ์์ฒญ'์ผ๋ก ํ์ฑํ๋๋ก ์ ๋ํ๋ค. - โก ์คํ ์ค๋ฒํ๋ก์ฐ: ํด๋น ํธ๋ค๋ฌ๋ ์์ฒญ ๋ฐ์ดํฐ๋ฅผ ๊ธธ์ด ๊ฒ์ฌ ์์ด ๊ณ ์ ํฌ๊ธฐ ์คํ ๋ฒํผ์ ๋ณต์ฌํ๋ค
(
CVE-2002-0649). ์ฌ๋๋จธ์ ์ฝ 376๋ฐ์ดํธ๋ ์ด ๋ฒํผ๋ฅผ ๋๊ฒจ ๋ณต๊ท ์ฃผ์๋ฅผ ์ฅ์ ํ๊ณ , ๊ฒฐ๊ณผ์ ์ผ๋ก ๊ณต๊ฒฉ์ ์ฝ๋๊ฐ SQL Server ํ๋ก์ธ์ค ๊ถํ์ผ๋ก ์คํ๋๋ค. - โข ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ก๋: ์ฃผ์
๋ ์ฝ๋๋
LoadLibrary/GetProcAddress๋กws2_32.dll(์๋์ฐ ์์ผ ๋ผ์ด๋ธ๋ฌ๋ฆฌ)์ ๋ถ๋ฌ์sendto()์ฃผ์๋ฅผ ์ป์๋ค. ๋ณ๋ ํ์ผ ์ค์น๊ฐ ํ์ ์๋๋ก, ๋คํธ์ํฌ ์ ์ก ๋ฅ๋ ฅ์ '์ด๋ฏธ ์๋ DLL'์์ ์ฆ์์ผ๋ก ํ๋ณดํ๋ ๋ฐฉ์์ด๋ค. - โฃ ์ฌ์ ํ ๋ฃจํ: ๊ทธ๋ค์์
GetTickCount๋ฑ์ผ๋ก ์๋๋ฅผ ๋ง๋ ์์ฌ๋์ ์์ฑ๊ธฐ๋ก ๋ค์ ๋ชฉํ IP๋ฅผ ๊ณ์ฐํด, UDP/1434๋ก ์๊ธฐ ์์ ๊ณผ '๋๊ฐ์ 376๋ฐ์ดํธ ํจํท'์ ์ ์กํ๋ค. ์ ํฌ์์๊ฐ ๊ฐ์ผ๋๋ฉด ๊ทธ ํ๋ก์ธ์ค๊ฐ ๊ฐ์ ์ผ์ ๋ฐ๋ณต โ ์ง์์ ํ์ฐ์ด ์์ฑ๋๋ค. - โค ๋ฉ๋ชจ๋ฆฌ ์์ฃผ: ์ ์ฒด ์ ๋ ผ๋ฆฌ๊ฐ ๋จ์ผ ๋ฐ์ดํฐ๊ทธ๋จ์ ํ์ด๋ก๋์ ์์ถ๋ผ ์๊ณ ๋์คํฌ์๋ ์๋ฌด๊ฒ๋ ์ฐ์ง ์์๋ค. '๊ฐ์ผ ์ํ'๋ ํ๋ก์ธ์ค ๋ฉ๋ชจ๋ฆฌ์๋ง ์กด์ฌํ์ผ๋ฏ๋ก, ์๋ฒ ์ฌ๋ถํ ์ด ์ฌ์ค์ ๊ฐ์ฅ ํ์คํ '์ฒญ์' ์๋จ์ด์๋ค.
- โฅ ์ ๋คํธ์ํฌ๊ฐ '์ฃฝ์๋': ์ฌ๋๋จธ๋ ๋ฐ์ดํฐ๋ฅผ ํ๊ดดํ๊ฑฐ๋ ์ํธํํ์ง ์์๋ค. ํผํด๋ ์ค์บ ํธ๋ํฝ ํญ์ฃผ์์ ์๋ค โ ์ด๋น ์์ฒ๋ง ๊ฐ์ ํจํท์ด ํ์ ยท๋ฐฉํ๋ฒฝยท๋ผ์ฐํฐ๋ฅผ ํฌํ์์ผ ์ ์ ํธ๋ํฝ์ด ํต๊ณผํ์ง ๋ชปํ๋ค. ์ฆ '์ ์์ฒด'๋ณด๋ค '์์ด ๋ง๋ ํธ๋ํฝ'์ด ๋ฌด๊ธฐ์๋ค.
- โฆ ์์ถ์ ๋๊ฐ: ๊ฒจ์ฐ 376๋ฐ์ดํธ์๊ธฐ์ ๋ฐฉ์ดํ ์๊ฐ๋ ํจ๊ป ์์ถ๋๋ค. ์ฌ๋๋จธ์ ๊ตํ์ ๋ช ํํ๋ค โ ์์ ์๋(๋ถ ๋จ์)๋ ์ฌ๋์ ํจ์น ์๋(์ผ ๋จ์)๋ฅผ ์๋ํ๋ค.
4. ํผํด ๊ท๋ชจ/์ํฅ โ ์ค์ ์ฌ๋ก ์์น
- ๊ฐ์ผ ์๋ฒ โ 10๋ถ ๋ด 75,000๋ ์ด์: CAIDA(๋ฐ์ด๋น๋ ๋ฌด์ด ๋ฑ)์ ๋ถ์์ ๋ฐ๋ฅด๋ฉด ์ฌ๋๋จธ๋ ์ด๊ธฐ ์ฝ 8.5์ด๋ง๋ค ๊ฐ์ผ ๋์๊ฐ 2๋ฐฐ๋ก ๋์๊ณ , ๋ฑ์ฅ ํ 10๋ถ ์ด๋ด์ ์ ์ธ๊ณ ์ทจ์ฝ ์๋ฒ ๋๋ถ๋ถ์ ๊ฐ์ผ์์ผฐ๋ค.
- ์ต๋ ์ค์บ๋ฅ โ ์ด๋น ์ฝ 5,500๋ง ํจํท: ์ต๊ณ ์กฐ์์ ์ฌ๋๋จธ๋ ์ด๋น 5,500๋ง ๊ฐ์ ๋ฌํ๋ ์ค์บ ํจํท์ ์์๋๋ค. ์ด๋ ๋น์ ์ธํฐ๋ท์ด ๊ฐ๋นํ ์ ์๋ ์์ค์ ๋์ด์ฐ๋ค.
- DNS ๋ฃจํธ ์๋ฒ โ 13๋ ์ค 5๋ ์ํฅ: ์ธํฐ๋ท์ ์ต์์ ์ด๋ฆ ํด์์ ๋ด๋นํ๋ ๋ฃจํธ DNS ์๋ฒ 13๋ ์ค 5๋๊ฐ ์ค์บ ํธ๋ํฝ์ผ๋ก ์ํฅ์ ๋ฐ์๋ค.
- ๊ธ์ตยท๊ตํต ๋ง๋น: ๋ณด๋์ ๋ฐ๋ฅด๋ฉด ๋ฑ ํฌ์ค๋ธ์๋ฉ๋ฆฌ์นด์ ATM ์ผ๋ถ๊ฐ ๋จนํต์ด ๋๊ณ , ์ปจํฐ๋จํ ํญ๊ณต์ ๋ฐ๊ถ ์์คํ ์ด ์ํฅ์ ๋ฐ์์ผ๋ฉฐ, ๋ฏธ๊ตญ ์ผ๋ถ ์ง์ญ์ 911 ์๊ธ ์๋น์ค๋ ํ๊ฒฉ์ ์ ์๋ค.
- ํ๊ตญ ์ธํฐ๋ท ๋๋: ๊ตญ๋ด์์๋ ์ฌ๋๋จธ๋ ์๋๊ถ์ ์ค์ฌ์ผ๋ก ์ธํฐ๋ท ๋๊ท๋ชจ ์ฅ์ ๋ฅผ ์ผ์ผ์ผ, ์๋ฐฑ๋ง ๊ฐ์ ์์ ์ ์์ด ๋๋ ค์ง๊ฑฐ๋ ๋๊ฒผ๋ค. ๋ฐฉ์กยท์ธ๋ก ยท๊ธ์ตยท๊ณต๊ณต๊ธฐ๊ด์ด ์๋ฌ์ ํผํด๋ฅผ ํธ์ํ๋ฉฐ ํ๋ฃจ ์ด์ ๋ณต๊ตฌ์ ๋งค๋ฌ๋ ธ๋ค.
- ์์ ๋คํธ์ํฌ ์นจํด โ ๋ฐ์ด๋น์ค-๋ฒ ์(์คํ์ด์ค): ์ฌ๋๋จธ๋ ์์๋ ฅ๋ฐ์ ์์ ์์ ํ๋ผ๋ฏธํฐ ํ์ ์์คํ (SPDS)์ ์ฝ 5์๊ฐ ๋์ ๋ง๋น์์ผฐ๋ค. ๊ฐ์ผ ๊ฒฝ๋ก๋ ์ธํฐ๋ท์ด ์๋๋ผ, ๋ฐฉํ๋ฒฝ์ ์ฐํํด ์ฐ๊ฒฐ๋ผ ์๋ ํ๋ ฅ์ ์ฒด T1 ํ์ ์ด์๋ค. (์์ ๊ณํต ์์ฒด๋ ์ํฅ์ ๋ฐ์ง ์์์ง๋ง, '์์ด๊ฐญ์ด ์๋๋ค'๋ผ๋ ์ฌ์ค์ ๋ณด์ฌ์ค ์ฌ๋ก๋ก ์ ๋ช ํ๋ค.)
- ๋ณต๊ตฌ์ ํต์ฌ: ํผํด ๋ณต๊ตฌ๋ ํ๋ คํ ๋๊ตฌ๊ฐ ์๋๋ผ โ ๋ฐฉํ๋ฒฝ์์ UDP/1434 ์ฐจ๋จ โก ๊ฐ์ผ ์๋ฒ ์ฌ๋ถํ (๋ฉ๋ชจ๋ฆฌ ์ ๋ฆฌ) โข MS02-039 ํจ์น ์ ์ฉ์ด์๋ค. ์ฆ '์๊ณ ๋ ์ ํ ํจ์น'์ '์ด๋ฆฐ ํฌํธ'๊ฐ ํผํด ๊ท๋ชจ๋ฅผ ๊ฒฐ์ ํ๋ค.
5. PoC โ ๊ต์ก์ฉ ๋ชจ์ ์ฝ๋๋ก ๋์ ์๋ฆฌ ์ฌํ
CVE-2002-0649 ์ต์คํ๋ก์ ์ฝ๋๊ฐ ์๋๋ผ,
"๋์ ์๋ฆฌ๋ง ์ฌํํ ๊ต์ก์ฉ ๋ชจ์ ์ฝ๋"๋ค. ์ค์ ์
์ฑ์ฝ๋ ๋ณต์ฌยท๋ฐฐํฌ, ์ค์ ๋คํธ์ํฌ ์ค์บยท๊ณต๊ฒฉ์ ์ผ์ ํฌํจํ์ง ์์ผ๋ฉฐ,
๊ณต๊ฒฉ ๋์์ ํญ์ ๊ฐ์์ ๋ก์ปฌ ์ค์ต ํ๊ฒฝ(๋ฉ๋ชจ๋ฆฌ ์ ๊ฐ์ ํธ์คํธ / ๊ฐ์ ๋ฉ)์ ์ ์ ๋ก ํ๋ค.
์๋ ์ฝ๋๋ ์ด ๊ธ ์์ฑ ์ ์ค์ ๋ก ์คํํด ์ถ๋ ฅ์ ๊ทธ๋๋ก ์ฎ๊ฒผ๋ค.
PoC 1 โ 'ํญ๋ฐ์ ํ์ฐ ์๋' ์ฌํ: ์ฌ๋๋จธ์ ํ์ฐ ์ญํ(๋ฌด์์ ์ค์บ + ์ด๊ธฐ 8.5์ด๋ง๋ค 2๋ฐฐ)์ ์์์ผ๋ก ๋ชจ์ํ๋ค. ์ฌ๋์ด ํจ์น๋ฅผ ๋ฐฐํฌํ ์๊ฐ์กฐ์ฐจ ์ฃผ์ง ์๋ ์๋๋ฅผ ๋ณด์ฌ์ค๋ค.
#!/usr/bin/env python3
"""
PoC 1 (๊ต์ก์ฉ) โ SQL Slammer(2003)์ 'ํญ๋ฐ์ ํ์ฐ ์๋' ์ฌํ ๋ชจ์.
์ค์ ์ทจ์ฝ์ /ํจํท/์ค์บ๋๊ฐ ์๋๋ผ, Slammer์ ํ์ฐ ์ญํ์ ์์์ผ๋ก ์ฌํํ๋ค.
Slammer๋ UDP/1434๋ก 'ํ ๊ฐ์ ํจํท'์ ๋ณด๋ด ๊ฐ์ผ์ํค๋ ๋๋ค ์ค์บ๋ ์์ด์๋ค.
- ์ฃผ์๊ณต๊ฐ 2^32 (IPv4 ์ ์ฒด)๋ฅผ ๋ฌด์์๋ก ์ค์บ
- ๊ฐ์ผ ํธ์คํธ๋น ์ด๋น ์์ฒ ๊ฐ ํจํท
- ๊ฒฐ๊ณผ: ์ด๊ธฐ 8.5์ด๋ง๋ค ๊ฐ์ผ ๋์ 2๋ฐฐ, 10๋ถ ๋ด ์ทจ์ฝ ํธ์คํธ ๋๋ถ๋ถ ๊ฐ์ผ
๋ชจ๋ '๊ฐ์์ ํธ์คํธ ๊ฐ์ฒด'์ ๋ํ ๊ณ์ฐ์ด๋ฉฐ ์ค์ ๋คํธ์ํฌ ํธ์ถ์ ์๋ค.
"""
import math
N = 75_000 # ์ ์ธ๊ณ ์ทจ์ฝ ํธ์คํธ(๊ฐ์) โ ๋๋ฆฌ ์ธ์ฉ๋๋ ๊ฐ์ผ ๊ท๋ชจ
A = 2 ** 32 # IPv4 ์ ์ฒด ์ฃผ์๊ณต๊ฐ
DOUBLE = 8.5 # ์ด๊ธฐ ๊ฐ์ผ ๋์ 2๋ฐฐ ์ฃผ๊ธฐ(์ด) โ ๋ฌธํ ๋ณด๊ณ ๊ฐ
# ์ด๊ธฐ 1๋๊ฐ 8.5์ด๋ง๋ค 2๋ฐฐ๊ฐ ๋๋๋ก ์ค์บ๋ฅ ์ฐ์ : rate = ln2/DOUBLE = scan*N/A
SCAN_PER_HOST = (math.log(2) / DOUBLE) * A / N # ํธ์คํธ๋น ์ด๋น ์ค์บ ์
AGG_CAP = 55_000_000 # ๊ด์ธก๋ ์ต๋ ์ด ์ค์บ๋ฅ 55M/์ด(๋์ญํญ ํฌํ)
dt = 0.1
S = 1 # ๊ฐ์ผ ๋์ (๋จ์ผ ์๋)
t = 0.0
marks = {}
targets = [0.01, 0.10, 0.50, 0.90, 0.99]
prev = S
doubling_seen = []
while S < N * 0.999 and t < 3600:
per_host = min(SCAN_PER_HOST, AGG_CAP / S) # ํธ์คํธ/๋คํธ์ํฌ ๋์ญํญ ์ํ
p_hit = (N - S) / A # ๋ฌด์์ ์ค์บ์ด '์์ง ์ ๊ฑธ๋ฆฐ ์ทจ์ฝ ํธ์คํธ'๋ฅผ ๋ง์ถ ํ๋ฅ
new = S * per_host * p_hit * dt
S += new
t += dt
if prev > 0 and S >= 2 * prev:
doubling_seen.append(round(t, 1)); prev = S
for f in targets:
if f not in marks and S >= N * f:
marks[f] = round(t, 1)
print("=== SQL Slammer ํ์ฐ ๋ชจ์ (๋จ์ผ ์๋, ์ทจ์ฝ ํธ์คํธ %d๋, ์ฃผ์๊ณต๊ฐ 2^32) ===" % N)
print("ํธ์คํธ๋น ์ด๋น ์ค์บ(์ด๊ธฐ) : %.0f packets/s" % SCAN_PER_HOST)
print("์ด ์ค์บ ๋์ญํญ ์ํ(ํฌํ) : %s packets/s" % format(AGG_CAP, ','))
print("์ด๊ธฐ ๊ฐ์ผ ๋์ 2๋ฐฐ ์ฃผ๊ธฐ : %.1f ์ด" % DOUBLE)
print("-" * 60)
for f in targets:
lbl = {0.01: "์ทจ์ฝ ํธ์คํธ 1% ๊ฐ์ผ", 0.10: "10% ๊ฐ์ผ", 0.50: "50% ๊ฐ์ผ(์ค๊ฐ๊ฐ)",
0.90: "90% ๊ฐ์ผ", 0.99: "99% ๊ฐ์ผ"}[f]
print("%-28s : %6.1f ์ด (%.2f ๋ถ)" % (lbl, marks.get(f, -1), marks.get(f, -1) / 60))
print("-" * 60)
print("์ฒซ 3ํ '2๋ฐฐ ์ฆ๊ฐ'๊น์ง ๊ฑธ๋ฆฐ ์๊ฐ :", doubling_seen[:3], "์ด")
print("90%% ๊ฐ์ผ๊น์ง ๊ฑธ๋ฆฐ ์๊ฐ : %.1f ๋ถ" % (marks[0.90] / 60))
print("\n๊ตํ: ์ ํ๊ฐ '๋ถ ๋จ์'๋ก ๋๋๋ค โ ์ฌ๋์ด ํจ์น๋ฅผ ๋ฐฐํฌํ ์๊ฐ์ด ์๋ค.")
print(" ๋๋ฆฐ(์ฌ๋) ๋์ vs ๋น ๋ฅธ(์) ์ ํ์ ์๋ ๊ฒฝ์์์ ์๋ํยท๋คํธ์ํฌ ์ฐจ๋จ๋ง์ด ์ด๊ธด๋ค.")
์คํ ์ถ๋ ฅ:
=== SQL Slammer ํ์ฐ ๋ชจ์ (๋จ์ผ ์๋, ์ทจ์ฝ ํธ์คํธ 75000๋, ์ฃผ์๊ณต๊ฐ 2^32) ===
ํธ์คํธ๋น ์ด๋น ์ค์บ(์ด๊ธฐ) : 4670 packets/s
์ด ์ค์บ ๋์ญํญ ์ํ(ํฌํ) : 55,000,000 packets/s
์ด๊ธฐ ๊ฐ์ผ ๋์ 2๋ฐฐ ์ฃผ๊ธฐ : 8.5 ์ด
------------------------------------------------------------
์ทจ์ฝ ํธ์คํธ 1% ๊ฐ์ผ : 81.7 ์ด (1.36 ๋ถ)
10% ๊ฐ์ผ : 111.2 ์ด (1.85 ๋ถ)
50% ๊ฐ์ผ(์ค๊ฐ๊ฐ) : 158.3 ์ด (2.64 ๋ถ)
90% ๊ฐ์ผ : 283.9 ์ด (4.73 ๋ถ)
99% ๊ฐ์ผ : 463.6 ์ด (7.73 ๋ถ)
------------------------------------------------------------
์ฒซ 3ํ '2๋ฐฐ ์ฆ๊ฐ'๊น์ง ๊ฑธ๋ฆฐ ์๊ฐ : [8.6, 17.2, 25.8] ์ด
90% ๊ฐ์ผ๊น์ง ๊ฑธ๋ฆฐ ์๊ฐ : 4.7 ๋ถ
๊ตํ: ์ ํ๊ฐ '๋ถ ๋จ์'๋ก ๋๋๋ค โ ์ฌ๋์ด ํจ์น๋ฅผ ๋ฐฐํฌํ ์๊ฐ์ด ์๋ค.
๋๋ฆฐ(์ฌ๋) ๋์ vs ๋น ๋ฅธ(์) ์ ํ์ ์๋ ๊ฒฝ์์์ ์๋ํยท๋คํธ์ํฌ ์ฐจ๋จ๋ง์ด ์ด๊ธด๋ค.
PoC 2 โ 'ํ์ผ ์๋ ๋จ์ผ ํจํท ๋ฉ๋ชจ๋ฆฌ ์'๊ณผ ๊ฒฉ๋ฆฌ: ๋์คํฌ์ ์๋ฌด๊ฒ๋ ๋จ๊ธฐ์ง ์๊ณ ๋ฉ๋ชจ๋ฆฌ์์๋ง ์ฌ๋ ์์ด
๋คํธ์ํฌ ๊ฒฝ๊ณ ํต์ (UDP/1434 egress ์ฐจ๋จ + ์ธ๊ทธ๋ฉํ
์ด์
) ํ ์ค๋ก ๋ฉ์ถ๋ ๋ชจ์ต์ ๋๋นํด ๋ณด์ฌ์ค๋ค.
#!/usr/bin/env python3
"""
PoC 2 (๊ต์ก์ฉ) โ 'ํ์ผ ์๋ ๋จ์ผ ํจํท ๋ฉ๋ชจ๋ฆฌ ์'์ ์ ํ/๊ฒฉ๋ฆฌ ์ฌํ ๋ชจ์.
Slammer์ ๋ ๊ฐ์ง ํน์ง์ ์์ ํ๊ฒ ํ๋ด ๋ธ๋ค:
(1) ๋์คํฌ์ ํ์ผ์ ๋ง๋ค์ง ์๋๋ค โ ์ฝ๋๊ฐ sqlservr.exe '๋ฉ๋ชจ๋ฆฌ ์'์์๋ง ์ฐ๋ค.
(๊ทธ๋์ ์ฌ๋ถํ
๋ง์ผ๋ก๋ ํ์ ์ด ์ฌ๋ผ์ก๋ค.)
(2) 'ํ ๊ฐ์ ํจํท'์ด ๊ณง ์ ๋ณธ์ฒด + ๊ฐ์ผ ์ฝ๋๋ค โ ๋ฐ๋ ์๊ฐ ๊ทธ ํ๋ก์ธ์ค๊ฐ
๋ ๋ค๋ฅธ ์์ ํธ์คํธ๋ก ๊ฐ์ ํจํท์ ๊ณ์ ์ฌ์ ์กํ๋ฉฐ ์ค์ค๋ก ๋ณต์ ๋๋ค.
์ฌ๊ธฐ์๋ ์ค์ ์์ผ/ํจํท์ ์ ํ ์ฐ์ง ์๋๋ค. '๋คํธ์ํฌ'์ 'ํธ์คํธ'๋ ๋ชจ๋
๋ฉ๋ชจ๋ฆฌ ์์ ๊ฐ์ ๊ฐ์ฒด์ด๋ฉฐ, ๊ณต๊ฒฉ ๋์์ ๊ฐ์์ ๋ก์ปฌ ์ค์ต ๋ฉ(10.0.0.0/24)์ด๋ค.
"""
import os, random
random.seed(20030125) # 2003-01-25 (Slammer ๋ฐ์์ผ)
VIRTUAL_WORM = b"SLAM" * 94 # 376๋ฐ์ดํธ ํจํท์ ์์งํ๋ ์๋ฆฌํ์์(์ค์ ํ์ด๋ก๋ ์๋)
SCAN_BURST = 30 # ๊ฐ์ผ 1๋๊ฐ ๋ฟ๋ ์ค์บ ํจํท ์(๋์ ์ค์บ๋ฅ ์ ์์ง)
class FakeHost:
"""๊ฐ์์ ๋ก์ปฌ ์ค์ต ํธ์คํธ. ์ทจ์ฝ ์๋น์ค(UDP:1434)๊ฐ ๋ ์๋ค๊ณ ๊ฐ์ ."""
def __init__(self, ip):
self.ip = ip
self.infected = False
self.mem_payload = None # ๋ฉ๋ชจ๋ฆฌ ์์ฃผ ์(๋์คํฌ ์๋)
self.emitted = 0 # ์ด ํธ์คํธ๊ฐ ๋ฐ์ผ๋ก ๋ณด๋ธ ํจํท ์
def service_1434(self, datagram, lab, egress_blocked):
"""์ทจ์ฝ ์๋น์ค๊ฐ ํจํท์ ๋ฐ์ผ๋ฉด '๊ฒฝ๊ณ๊ฒ์ฌ ์์ด' ๊ทธ๋๋ก ์คํ/์ ํํ๋ค๊ณ ๊ฐ์ ."""
if datagram == VIRTUAL_WORM and not self.infected:
self.infected = True
self.mem_payload = datagram # ํ์ผ๋ก ์ ์ฅํ์ง ์์ โ ๋ฉ๋ชจ๋ฆฌ ์ ์ฉ
self.spread(lab, egress_blocked)
def spread(self, lab, egress_blocked):
"""๊ฐ์ผ ์ฆ์ ๋ฌด์์ ํธ์คํธ๋ก '๊ฐ์ ํจํท'์ ์ฌ๋ฌ ๊ฐ ๋ณด๋ธ๋ค(์ค์บ ํญ์ฃผ)."""
if egress_blocked:
return # ์ธ๊ทธ๋ฉํ
์ด์
/egress ํํฐ๊ฐ ๋ง์ผ๋ฉด ํ์ฐ ์ ์ง
for _ in range(SCAN_BURST):
candidates = [h for h in lab if not h.infected]
if not candidates:
return
target = random.choice(candidates)
self.emitted += 1
target.service_1434(self.mem_payload, lab, egress_blocked)
def run_scenario(egress_blocked):
lab = [FakeHost("10.0.0.%d" % i) for i in (11, 12, 13, 14, 15, 16, 17, 18)]
lab[0].service_1434(VIRTUAL_WORM, lab, egress_blocked) # ์ต์ด 1๊ฐ ํจํท์ด ์๋
infected = [h.ip for h in lab if h.infected]
packets = sum(h.emitted for h in lab)
return infected, packets
print("=== ๊ฐ์ ๋ก์ปฌ ๋ฉ(10.0.0.0/24, ํธ์คํธ 8๋, UDP/1434 ์ทจ์ฝ) ===")
print("์ ๋ณธ์ฒด(๊ฐ์ ํ์ด๋ก๋) ๊ธธ์ด: %d bytes (์ค์ ์
์ฑ์ฝ๋ ์๋, ์๋ฆฌํ์์)\n" % len(VIRTUAL_WORM))
for mode, blocked in [("A. ๊ฒฉ๋ฆฌ/ํํฐ ์์", False),
("B. UDP/1434 egress ์ฐจ๋จ + ์ธ๊ทธ๋ฉํ
์ด์
", True)]:
infected, packets = run_scenario(blocked)
print("[%s]" % mode)
print(" ๊ฐ์ผ ํธ์คํธ : %d / 8 -> %s" % (len(infected), infected))
print(" ๋ฐ์ ํจํท : %d ๊ฐ" % packets)
print(" ๋์คํฌ ํ์ผ : ์์ (๋ฉ๋ชจ๋ฆฌ ์ ์ฉ ์ โ ์ฌ๋ถํ
์ ์๋ฉธ)")
print()
# ๋์คํฌ ํ์ ์ด ์ ๋ง '์์'์ธ์ง ์ค์ ๋ก ํ์ธ (์ค์ต ๋๋ ํฐ๋ฆฌ์ ์ ํ์ผ์ด ์ ์๊ฒผ๋์ง)
dropped = [f for f in os.listdir('.')
if f.lower().startswith(('sqlexp', 'helkern', 'msworm'))]
print("์ค์ต ๋๋ ํฐ๋ฆฌ์์ ๋ฐ๊ฒฌ๋ ์ ํ์ผ:", dropped if dropped else "์์ (์์๋๋ก ๋์คํฌ ๋ฌดํ์ )")
print("\n๊ตํ: ๋คํธ์ํฌ ๊ฒฝ๊ณ ํต์ (1434 egress ์ฐจ๋จ + ์ธ๊ทธ๋ฉํ
์ด์
)๋ง์ด")
print(" '๋ฉ๋ชจ๋ฆฌ ์ ์ฉยท๋จ์ผ ํจํท' ์์ ํ์ฐ์ ์ฆ์ ๋๋๋ค. ํธ์คํธ ๋ฐฑ์ ๋ง์ผ๋ก ๋ฆ๋ค.")
์คํ ์ถ๋ ฅ:
=== ๊ฐ์ ๋ก์ปฌ ๋ฉ(10.0.0.0/24, ํธ์คํธ 8๋, UDP/1434 ์ทจ์ฝ) ===
์ ๋ณธ์ฒด(๊ฐ์ ํ์ด๋ก๋) ๊ธธ์ด: 376 bytes (์ค์ ์
์ฑ์ฝ๋ ์๋, ์๋ฆฌํ์์)
[A. ๊ฒฉ๋ฆฌ/ํํฐ ์์]
๊ฐ์ผ ํธ์คํธ : 8 / 8 -> ['10.0.0.11', '10.0.0.12', '10.0.0.13', '10.0.0.14', '10.0.0.15', '10.0.0.16', '10.0.0.17', '10.0.0.18']
๋ฐ์ ํจํท : 7 ๊ฐ
๋์คํฌ ํ์ผ : ์์ (๋ฉ๋ชจ๋ฆฌ ์ ์ฉ ์ โ ์ฌ๋ถํ
์ ์๋ฉธ)
[B. UDP/1434 egress ์ฐจ๋จ + ์ธ๊ทธ๋ฉํ
์ด์
]
๊ฐ์ผ ํธ์คํธ : 1 / 8 -> ['10.0.0.11']
๋ฐ์ ํจํท : 0 ๊ฐ
๋์คํฌ ํ์ผ : ์์ (๋ฉ๋ชจ๋ฆฌ ์ ์ฉ ์ โ ์ฌ๋ถํ
์ ์๋ฉธ)
์ค์ต ๋๋ ํฐ๋ฆฌ์์ ๋ฐ๊ฒฌ๋ ์ ํ์ผ: ์์ (์์๋๋ก ๋์คํฌ ๋ฌดํ์ )
๊ตํ: ๋คํธ์ํฌ ๊ฒฝ๊ณ ํต์ (1434 egress ์ฐจ๋จ + ์ธ๊ทธ๋ฉํ
์ด์
)๋ง์ด
'๋ฉ๋ชจ๋ฆฌ ์ ์ฉยท๋จ์ผ ํจํท' ์์ ํ์ฐ์ ์ฆ์ ๋๋๋ค. ํธ์คํธ ๋ฐฑ์ ๋ง์ผ๋ก ๋ฆ๋ค.
6. ๋ฐฉ์ด ๋ฐฉ๋ฒ/๊ตํ โ ์ด๋ป๊ฒ ๋ง์๊ณ , ๋ฌด์์ ๋ฐฐ์ฐ๋
- ์ฆ์ ํจ์น๊ฐ '์ธ์ '๊ฐ ์๋๋ผ 'ํ๋์ง'์ ๋ฌธ์ ๋ค: ์ฌ๋๋จธ์ ์ทจ์ฝ์ ์ ์ด๋ฏธ 6๊ฐ์ ์ (MS02-039)์ ํจ์น๊ฐ ๋์ ์์๋ค. ์ฌ๊ณ ๋ '๋ชจ๋ฅด๋ ์ทจ์ฝ์ '์ด ์๋๋ผ ๋ฏธ์ ์ฉ ํจ์น์์ ์๋ค. ํจ์น๋ฅผ '์ ์ฉ ์๋ฃ๊น์ง' ์ถ์ ํ๋ ๊ฒ์ด ํต์ฌ์ด๋ค.
- ๋ ธ์ถ๋ ์๋น์ค ์ต์ํ: DB์ ์ธ์คํด์ค ์กฐํ ์๋น์ค(UDP/1434)๋ฅผ ์ธํฐ๋ท์ ๊ทธ๋๋ก ๋ ธ์ถํ์ง ์๋๋ค. ๋ถํ์ํ ์๋น์ค๋ ๋๊ณ , ์ธ๋ถ ๋ ธ์ถ์ ์ต์ํํ๋ค. (SQL Server 2000 SP3a ์ดํ์๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๋นํ์ฑํ๋๋ค.)
- ๋คํธ์ํฌ ๊ฒฝ๊ณ ํต์ โ ์ตํ์ ๋ฐฉ์ด์ : ๋ค์ ๋งํ์ง๋ง UDP/1434 ingressยทegress ์ฐจ๋จ๊ณผ ์ธ๊ทธ๋ฉํ ์ด์ ๋ง์ผ๋ก๋ ์ด ์์ ๊ตญ์ง์ ์ฌ๊ณ ๋ก ๋๋๋ค(PoC 2). ๋ฉ๋ชจ๋ฆฌ ์ ์ฉยท๋จ์ผ ํจํท ์์ผ์๋ก ํธ์คํธ ๋ฐฑ์ ๋ณด๋ค ๋คํธ์ํฌ ์ฐจ๋จ์ด ๋จผ์ ๋ฃ๋๋ค.
- ๋ฉ๋ชจ๋ฆฌ ์์ ์ฑ๊ณผ ๊ฒฝ๊ณ ๊ฒ์ฌ: ๊ทผ๋ณธ ์์ธ์ ๊ธธ์ด ๊ฒ์ฌ ์๋ ์คํ ๋ณต์ฌ์๋ค. ์ธ๋ถ ์ ๋ ฅ์ ํญ์ ๊ธธ์ดยท๋ฒ์๋ฅผ ๊ฒ์ฆํด์ผ ํ๋ฉฐ, ์ฅ๊ธฐ์ ์ผ๋ก๋ ๋ฉ๋ชจ๋ฆฌ ์์ ์ธ์ด(Rust ๋ฑ)๊ฐ ๊ฐ์ ๋ถ๋ฅ์ ๋ฒ๊ทธ๋ฅผ ๊ตฌ์กฐ์ ์ผ๋ก ์ค์ธ๋ค.
- ๋์ญํญ/๋ ์ดํธ ๋ฆฌ๋ฏธํ : ์ฌ๋๋จธ์ '๋ฌด๊ธฐ'๋ ๋ฐ์ดํฐ ํ๊ดด๊ฐ ์๋๋ผ ํธ๋ํฝ ํญ์ฃผ์๋ค. ์ค์บยท๋ธ๋ก๋์บ์คํธ์ฑ ํธ๋ํฝ์ ์ ํํ๊ณ , ์๋น์ค์ ์ฐ๊ฒฐยท๋ ์ดํธ ์ํ์ ๋์ด ์๊ธฐ ์ฆ์ํ ๋ถํ๋ฅผ ๊ฒฌ๋์ผ ํ๋ค.
- ์๋์ ๋น๋์นญ์ ์ธ์ ํ๋ผ: ์์ '๋ถ' ๋จ์, ์ฌ๋์ '์ผ' ๋จ์๋ก ์์ง์ธ๋ค. ๊ทธ๋์ ๋ฐฉ์ด๋ ์๋ํ๋ ํ์งยท์ฐจ๋จ(๊ฒฝ๊ณ ํํฐ, ๋คํธ์ํฌ ๊ฒฉ๋ฆฌ)์ ์์กดํด์ผ ํ๋ค. ์์ผ๋ก ๋์ํ๋ ์๊ฐ ์ด๋ฏธ ๋ฆ๋๋ค.
- ๊ตํ ์์ฝ:
- '์์ ํจํท'์ด ๊ฑฐ๋ํ ํผํด๋ฅผ ๋ธ๋ค: 376๋ฐ์ดํธ๊ฐ ์ ์ธ๊ณ ๋์ญํญ์ ์ผ์ผฐ๋ค. ์ํ์ ํฌ๊ธฐ์ ์ฝ๋ ์ค ์๋ ๋น๋กํ์ง ์๋๋ค.
- ํ๊ดดํ์ง ์์๋ ์น๋ช ์ ์ด๋ค: ๋ฐ์ดํฐ ์ญ์ ยท์ํธํ ์์ด๋ ํ์ฐ ํธ๋ํฝ๋ง์ผ๋ก ์ธํ๋ผ๋ฅผ ๋ง๋น์ํฌ ์ ์๋ค.
- ์์ ๊ณ๋ณด์ '์๋ ์ฌ๊ฑด': Morris(1988) โ Code Red(2001) โ Slammer(2003) โ Sasser(2004) โ Conficker(2008) โ WannaCry/NotPetya(2017). ์ฌ๋๋จธ๋ ๊ทธ์ค ์ ํ ์๋ ์์ฒด๋ฅผ ๋ฌด๊ธฐ๋ก ๋ง๋ ๋ํ ์ฌ๋ก๋ค.
์ถ์ฒ
- Wikipedia โ SQL slammer โ https://en.wikipedia.org/wiki/SQL_slammer
- Microsoft Security Bulletin MS02-039 (2002-07-24) โ https://learn.microsoft.com/en-us/security-updates/securitybulletins/2002/ms02-039
- NVD โ CVE-2002-0649 (SQL Server Resolution Service ๋ฒํผ ์ค๋ฒํ๋ก์ฐ) โ https://nvd.nist.gov/vuln/detail/CVE-2002-0649
- CAIDA โ The Spread of the Sapphire/Slammer Worm (Moore et al., 2003) โ https://www.caida.org/publications/papers/2003/sapphire/sapphire.html
- SecurityFocus โ Slammer worm crashed Ohio nuke plant network (Kevin Poulsen, 2003-08-19, ์จ์ด๋ฐฑ ์์นด์ด๋ธ) โ https://web.archive.org/web/20030920055617/http://www.securityfocus.com/news/6767
- CAIDA ์ฐ๊ตฌ ์๋ฃ ๋ชจ์ โ Sapphire/Slammer โ https://www.caida.org/catalog/papers/2003_sapphire/
ํจ๊ป ์ฝ๊ธฐ: ๐ Morris Worm (1988) โ ์ต์ด์ ์ธํฐ๋ท ์ ยท ๐ชฑ Conficker (2008) โ SMB ์์ ์ ์ ยท ๐ WannaCry (2017) โ EternalBlue๋ก ์ ์ธ๊ณ๋ฅผ ๊ฐํํ ์