๐Ÿชฑ Conficker โ€” ์ตœ๋Œ€ 1,500๋งŒ ๋Œ€๋ฅผ ๊ฐ์—ผ์‹œํ‚ค๊ณ  '๊ตญ์ œ ์—ฐํ•ฉ ๋Œ€์‘'์„ ํƒ„์ƒ์‹œํ‚จ ์ž๊ฐ€ ๋ฐฉ์–ดํ˜• ์›œ (2008)

2026-09-05 ยท Malware Deep-Dive

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

Conficker(๋‹ค์šด์—… Downupยท๋‹ค์šด์–ด๋‹ต Downadupยทํ‚ค๋„ Kido๋กœ๋„ ๋ถˆ๋ฆผ)๋Š” 2008๋…„ 11์›” ์ฒ˜์Œ ๋ชจ์Šต์„ ๋“œ๋Ÿฌ๋‚ด 2009๋…„ 1์›”๊นŒ์ง€ ์ „ ์„ธ๊ณ„ 900๋งŒ~1,500๋งŒ ๋Œ€๋ฅผ ๊ฐ์—ผ์‹œํ‚ค๋ฉฐ 2003๋…„ SQL Slammer ์ดํ›„ ์ตœ๋Œ€ ๊ทœ๋ชจ์˜ ์›œ ๊ฐ์—ผ์œผ๋กœ ๊ธฐ๋ก๋œ Windows ๋Œ€์ƒ ์›œ์ด๋‹ค. 190๊ฐœ๊ตญ ์ด์ƒ์˜ ์ •๋ถ€ยท๊ธฐ์—…ยท๊ฐ€์ • PC๋ฅผ ๊ฐ์—ผ์‹œ์ผฐ๊ณ , "๋งŽ์ด ํผ๋œจ๋ฆฐ ๊ฒƒ"๋ฟ ์•„๋‹ˆ๋ผ ๋ฐฑ์‹ ์„ ์ฃฝ์ด๊ณ , ์—…๋ฐ์ดํŠธ๋ฅผ ๋Š๊ณ , ์ž์‹ ์˜ ํŒŒ์ผ์„ ์ž ๊ทธ๋Š” '์ž๊ฐ€ ๋ฐฉ์–ดํ˜•' ์„ค๊ณ„๋กœ ์ œ๊ฑฐ๋ฅผ ๊ทน๋„๋กœ ์–ด๋ ต๊ฒŒ ๋งŒ๋“  ์ตœ์ดˆ์˜ ๋Œ€ํ˜• ์‚ฌ๋ก€๋‹ค.

2. ๊ฐ์—ผยท์ „ํŒŒ ๊ฒฝ๋กœ โ€” ์–ด๋–ป๊ฒŒ ํผ์กŒ๋‚˜

Conficker๋Š” "์›๊ฒฉ ์ฝ”๋“œ ์‹คํ–‰ ์ทจ์•ฝ์  โ†’ ๊ด€๋ฆฌ์ž ๊ณ„์ • ์‚ฌ์ „ ๋Œ€์ž… โ†’ ์ด๋™์‹ ๋ฏธ๋””์–ด โ†’ P2P"์˜ 4๊ฐœ ์ „ํŒŒ ์ถ•์„ ๋ณ€์ข…๋ณ„๋กœ ์กฐํ•ฉํ•ด, ํŒจ์น˜ ์•ˆ ๋œ PCยท์•ฝํ•œ ๊ณ„์ •ยทUSB ์‚ฌ์šฉ ์กฐ์ง์„ ๊ฐ€๋ฆฌ์ง€ ์•Š๊ณ  ๋‚ด๋ถ€๋ง ๊นŠ์ˆ™์ด ํŒŒ๊ณ ๋“ค์—ˆ๋‹ค.

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

Conficker์˜ ๊ตฌ์กฐ์  ํŠน์ง•์€ "๋ฒˆ์‹(DGAยทP2P) โ€” ์ž๊ฐ€ ๋ฐฉ์–ด(๋ฐฑ์‹  ํ‚ฌยทDNS ์ฐจ๋‹จยทํŒŒ์ผ ์ž ๊ธˆ) โ€” ์„œ๋ช…๋œ ๊ฐฑ์‹ "์˜ 3์ธต ์„ค๊ณ„๋‹ค. ๋‹จ์ˆœํžˆ ํผ์ง€๋Š” ์›œ์ด ์•„๋‹ˆ๋ผ, "ํƒ์ง€ยท๋ถ„์„ยท์ œ๊ฑฐ" ๊ฐ ๋‹จ๊ณ„๋ฅผ ๊ฒจ๋ƒฅํ•œ ๋Œ€์‘์ฑ…์„ ๋‚ด์žฅํ•œ ์ตœ์ดˆ์˜ ๋Œ€ํ˜• ์›œ์œผ๋กœ ํ‰๊ฐ€๋œ๋‹ค.

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

5. PoC โ€” ๊ต์œก์šฉ ๋ชจ์˜ ์ฝ”๋“œ๋กœ ๋™์ž‘ ์›๋ฆฌ ์žฌํ˜„

โš ๏ธ ์•ˆ์ „ ๊ทœ์น™: ์•„๋ž˜ ์ฝ”๋“œ๋Š” ์‹ค์ œ Conficker ๋ฐ”์ด๋„ˆ๋ฆฌ๋‚˜ ์‹ค์ œ MS08-067 ์ต์Šคํ”Œ๋กœ์ž‡์˜ ๋ณต์‚ฌ๋ณธ์ด ์•„๋‹ˆ๋ผ "๋™์ž‘ ์›๋ฆฌ๋งŒ ์žฌํ˜„ํ•œ ๊ต์œก์šฉ ๋ชจ์˜ ์ฝ”๋“œ"๋‹ค. ์‹ค์ œ ์ทจ์•ฝ์  ๊ณต๊ฒฉ, ์‹ค์ œ ์›๊ฒฉ ๊ณต์œ ยท๋„คํŠธ์›Œํฌ ํ†ต์‹ , ์‹ค์ œ ํ”„๋กœ์„ธ์Šค ์ข…๋ฃŒยทDLL ํŒจ์น˜๋Š” ์ผ์ ˆ ํฌํ•จํ•˜์ง€ ์•Š์œผ๋ฉฐ, ๊ณต๊ฒฉ ๋Œ€์ƒ์€ ๊ฐ€์ƒ์˜ ๋กœ์ปฌ ์‹ค์Šต ํ™˜๊ฒฝ(๋ฉ”๋ชจ๋ฆฌ ์† ๊ฐ€์ƒ ๊ฐ์ฒด, ๊ฐ€์ƒ ํ”„๋กœ์„ธ์Šค ํ…Œ์ด๋ธ”, ๊ฐ€์ƒ DNS ํ•ด์„๊ธฐ)์„ ์ „์ œ๋กœ ํ•œ๋‹ค. ์•„๋ž˜ ์ฝ”๋“œ๋Š” ๋ชจ๋‘ ์‹ค์ œ ์‹คํ–‰ํ•ด ์ถœ๋ ฅ์„ ํ™•์ธํ–ˆ๋‹ค.

PoC 1 โ€” DGA(๋„๋ฉ”์ธ ์ƒ์„ฑ ์•Œ๊ณ ๋ฆฌ์ฆ˜)์˜ ํ•ต์‹ฌ ๊ตฌ์กฐ: "๋ชจ๋“  ๊ฐ์—ผ ํ˜ธ์ŠคํŠธ๊ฐ€ ๋‚ ์งœ ์‹œ๋“œ๋กœ ๊ฐ™์€ ๋„๋ฉ”์ธ ๋ชฉ๋ก์„ ๊ณ„์‚ฐํ•œ๋‹ค"๋Š” ์›๋ฆฌ๋ฅผ ์žฌํ˜„ํ•œ๋‹ค. ์‹ค์ œ Conficker์˜ PRNG ๊ทœ์น™๊ณผ๋Š” ๋ฌด๊ด€ํ•˜๋ฉฐ, ์‹ค์ œ C2 ๋„๋ฉ”์ธ๋„ ์ƒ์„ฑํ•˜์ง€ ์•Š๋Š”๋‹ค.

#!/usr/bin/env python3
"""
PoC 1 โ€” Conficker DGA(๋„๋ฉ”์ธ ์ƒ์„ฑ ์•Œ๊ณ ๋ฆฌ์ฆ˜) ๊ตฌ์กฐ ๋ชจ์˜ ์‹คํ—˜ (๊ต์œก์šฉ)

์‹ค์ œ Conficker A๋Š” '๋งค์ผ 250๊ฐœ์˜ ์˜์‚ฌ๋‚œ์ˆ˜ ๋„๋ฉ”์ธ์„ 5๊ฐœ TLD์— ๊ฑธ์ณ ์ƒ์„ฑ'ํ•˜๊ณ ,
์ „ ์„ธ๊ณ„์˜ ๋ชจ๋“  ๊ฐ์—ผ ํ˜ธ์ŠคํŠธ๊ฐ€ ๊ฐ™์€ ๋‚ ์งœ ์‹œ๋“œ๋ฅผ ๊ณต์œ ํ•˜๋ฏ€๋กœ ๊ฐ™์€ ๋ชฉ๋ก์„ ๊ณ„์‚ฐํ•œ๋‹ค.
๊ณต๊ฒฉ์ž๋Š” ๊ทธ์ค‘ ํ•˜๋‚˜์— ํŽ˜์ด๋กœ๋“œ๋ฅผ ์˜ฌ๋ ค๋‘๊ธฐ๋งŒ ํ•˜๋ฉด ๊ฐ์—ผ ํ˜ธ์ŠคํŠธ๊ฐ€ ์Šค์Šค๋กœ ์ฐพ์•„์˜จ๋‹ค.
๋ฐฉ์–ด์ž(Conficker Working Group)๋Š” ๊ทธ ๋„๋ฉ”์ธ๋“ค์„ ์„ ์ œ ๋“ฑ๋ก/์ฐจ๋‹จํ•ด ๊ฐฑ์‹  ํ†ต๋กœ๋ฅผ ๋Š์—ˆ๋‹ค.

์•„๋ž˜ ์ฝ”๋“œ๋Š” ๊ทธ '๋™์ž‘ ์›๋ฆฌ(๋‚ ์งœ ์‹œ๋“œ -> ๊ฒฐ์ •์  ๋„๋ฉ”์ธ ๋ชฉ๋ก)'๋งŒ ๋ชจ์‚ฌํ•œ๋‹ค.
์‹ค์ œ Conficker์˜ PRNG/๋ฌธ์ž ์ƒ์„ฑ ๊ทœ์น™๊ณผ๋Š” ๋ฌด๊ด€ํ•˜๋ฉฐ, ์‹ค์ œ C2 ๋„๋ฉ”์ธ๋„ ๋งŒ๋“ค์ง€ ์•Š๋Š”๋‹ค.
"""
import random
import datetime

TLDS = [".com", ".net", ".org", ".info", ".biz"]  # A ๋ณ€์ข…: 5๊ฐœ TLD

def generate_domains(seed_date: datetime.date, count: int = 250) -> list:
    # ๋งค ๊ฐ์—ผ ํ˜ธ์ŠคํŠธ๊ฐ€ ๊ฐ™์€ ๋ชฉ๋ก์„ ๋งŒ๋“ค๋„๋ก '๋‚ ์งœ'๋กœ๋งŒ ์‹œ๋“œ ๊ณ ์ •
    rng = random.Random(seed_date.strftime("%Y%m%d"))
    alphabet = "abcdefghijklmnopqrstuvwxyz0123456789"
    domains = []
    for _ in range(count):
        length = rng.randint(8, 11)          # A ๋ณ€์ข…์€ 8~11์ž ์ƒ์„ฑ
        name = "".join(rng.choice(alphabet) for _ in range(length))
        tld = rng.choice(TLDS)
        domains.append(name + tld)
    return domains

if __name__ == "__main__":
    day = datetime.date(2009, 1, 15)  # ํ”„๋ž‘์Šค ํ•ด๊ตฐ Intramar๋ง ๊ฐ์—ผ์ผ

    # ํ˜ธ์ŠคํŠธ A์™€ ํ˜ธ์ŠคํŠธ B(๋‹ค๋ฅธ ๋„คํŠธ์›Œํฌ)๊ฐ€ ๊ฐ™์€ ๋‚ ์งœ๋กœ ๊ฐ์ž ๊ณ„์‚ฐ
    host_a = generate_domains(day)
    host_b = generate_domains(day)

    print(f"[{day}] ํ˜ธ์ŠคํŠธ A๊ฐ€ ์ƒ์„ฑํ•œ ์˜ค๋Š˜์˜ ํ›„๋ณด ๋„๋ฉ”์ธ: {len(host_a)}๊ฐœ")
    print("  ์ฒ˜์Œ 10๊ฐœ:", ", ".join(host_a[:10]))
    print(f"[{day}] ํ˜ธ์ŠคํŠธ B๋„ ๋™์ผํ•œ ๋ชฉ๋ก์„ ๊ณ„์‚ฐํ•˜๋Š”๊ฐ€? {host_a == host_b}")
    print("  B์˜ 10๋ฒˆ์งธ ๋„๋ฉ”์ธ:", host_b[9])
    print("  -> ์‹œ๋“œ๊ฐ€ ๊ฐ™์œผ๋ฉด ์ „ ์„ธ๊ณ„ ๊ฐ์—ผ PC๊ฐ€ ๋งค์ผ ๊ฐ™์€ '์ถœ์„๋ถ€'๋ฅผ ๊ณต์œ ํ•œ๋‹ค")
    print("  -> ๋ฐฉ์–ด์ž๊ฐ€ ์ด ๋ชฉ๋ก์˜ ๋“ฑ๋ก์„ ์„ ์ œ ์ฐจ๋‹จํ•˜๋ฉด ๊ฐฑ์‹  ํ†ต๋กœ๊ฐ€ ๋Š๊ธด๋‹ค")
# ์‹คํ–‰ ๊ฒฐ๊ณผ
[2009-01-15] ํ˜ธ์ŠคํŠธ A๊ฐ€ ์ƒ์„ฑํ•œ ์˜ค๋Š˜์˜ ํ›„๋ณด ๋„๋ฉ”์ธ: 250๊ฐœ
  ์ฒ˜์Œ 10๊ฐœ: xezu4dwf.org, pcdtmqtr7bk.com, 4ecse9sz.net, vohym2sot.com, oqc4c0x2.biz, x6kfx8jhme.org, 9rvbcaaap.net, 37qe6wfp.biz, k288ox9u0j.info, y8fh4d7v0d.com
[2009-01-15] ํ˜ธ์ŠคํŠธ B๋„ ๋™์ผํ•œ ๋ชฉ๋ก์„ ๊ณ„์‚ฐํ•˜๋Š”๊ฐ€? True
  B์˜ 10๋ฒˆ์งธ ๋„๋ฉ”์ธ: y8fh4d7v0d.com
  -> ์‹œ๋“œ๊ฐ€ ๊ฐ™์œผ๋ฉด ์ „ ์„ธ๊ณ„ ๊ฐ์—ผ PC๊ฐ€ ๋งค์ผ ๊ฐ™์€ '์ถœ์„๋ถ€'๋ฅผ ๊ณต์œ ํ•œ๋‹ค
  -> ๋ฐฉ์–ด์ž๊ฐ€ ์ด ๋ชฉ๋ก์˜ ๋“ฑ๋ก์„ ์„ ์ œ ์ฐจ๋‹จํ•˜๋ฉด ๊ฐฑ์‹  ํ†ต๋กœ๊ฐ€ ๋Š๊ธด๋‹ค

PoC 2 โ€” ADMIN$ ์‚ฌ์ „ ๋Œ€์ž… ๊ณต๊ฒฉ๊ณผ ๊ณ„์ • ์ž ๊ธˆ ์ •์ฑ…์˜ ํšจ๊ณผ: ๋„คํŠธ์›Œํฌ ํ˜ธ์ถœ ์—†์ด ๊ฐ€์ƒ ๊ณต์œ  ๊ฐ์ฒด๋ฅผ ๋Œ€์ƒ์œผ๋กœ "์•ฝํ•œ ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ๋‚ด๋ถ€๋ง ์ด๋™์„ ํ—ˆ์šฉํ•˜๋Š” ๊ณผ์ •"๊ณผ "์ž ๊ธˆ ์ •์ฑ…ยท๊ฐ•ํ•œ ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ์ด๋ฅผ ๋ฌด๋ ฅํ™”ํ•˜๋Š” ๊ณผ์ •"์„ ๋Œ€์กฐํ•œ๋‹ค.

#!/usr/bin/env python3
"""
PoC 2 โ€” Conficker B์˜ ADMIN$ ๊ณต์œ  '์‚ฌ์ „ ๋Œ€์ž… ๊ณต๊ฒฉ' ๋™์ž‘ ๊ตฌ์กฐ ๋ชจ์˜ (๊ต์œก์šฉ)

Conficker B๋Š” MS08-067 ์™ธ์—, ๊ฐ์—ผ PC์—์„œ ๋‚ด๋ถ€๋ง์˜ ๋‹ค๋ฅธ PC๋กœ
๊ด€๋ฆฌ์ž ๊ณต์œ (ADMIN$/C$)์— ๋Œ€ํ•œ ์‚ฌ์šฉ์ž๋ช…+๋น„๋ฐ€๋ฒˆํ˜ธ ์‚ฌ์ „ ๋Œ€์ž…์„ ์‹œ๋„ํ•ด
'ํŒจ์น˜ ์•ˆ ๋œ ๊ณ„์ •'์„ ํ†ต์งธ๋กœ ์ ๋ นํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์˜†์œผ๋กœ ํผ์กŒ๋‹ค.

์•„๋ž˜ ์ฝ”๋“œ๋Š” ๋„คํŠธ์›Œํฌ ํ˜ธ์ถœ ์—†์ด '๊ฐ€์ƒ์˜ ๋กœ์ปฌ ์‹ค์Šต ๋Œ€์ƒ' ๊ฐ์ฒด์— ๋Œ€ํ•ด
โ‘  ๋ฌด์ž‘์œ„ ๋Œ€์ž…(์Šคํ”„๋ ˆ์ด) โ‘ก ๊ณ„์ • ์ž ๊ธˆ ์ •์ฑ…์˜ ํšจ๊ณผ๋ฅผ ์žฌํ˜„ํ•œ๋‹ค.
์‹ค์ œ ์›๊ฒฉ ๊ณต์œ /์‹ค์ œ ์‹œ์Šคํ…œ์„ ๋Œ€์ƒ์œผ๋กœ ํ•˜์ง€ ์•Š๋Š”๋‹ค.
"""
from dataclasses import dataclass

@dataclass
class FakeShareTarget:
    """์‹ค์Šต์šฉ ๊ฐ€์ƒ ๋Œ€์ƒ: ์‹ค์ œ ์‹œ์Šคํ…œ์ด ์•„๋‹ˆ๋ผ ๋ฉ”๋ชจ๋ฆฌ ์† ๊ฐ์ฒด๋‹ค."""
    hostname: str
    username: str
    password: str
    lockout_threshold: int = 5   # NํšŒ ์‹คํŒจ ์‹œ ๊ณ„์ • ์ž ๊ธˆ (์ •์ฑ… ์„ค์ •๊ฐ’)
    failed: int = 0
    locked: bool = False

# 2008~2009๋…„ ๋‹น์‹œ ์‹ค์ œ๋กœ ๋„๋ฆฌ ์“ฐ์ด๋˜ '์•ฝํ•œ ๊ด€๋ฆฌ์ž ๋น„๋ฐ€๋ฒˆํ˜ธ' ์ „ํ˜•
PASSWORD_LIST = ["", "password", "123456", "admin", "administrator",
                 "P@ssw0rd", "letmein", "changeme", "test", "root"]
USERNAMES = ["administrator", "admin", "guest"]

def try_credential(target: FakeShareTarget, user: str, pwd: str) -> bool:
    if target.locked:
        return False
    if user == target.username and pwd == target.password:
        return True
    target.failed += 1
    if target.failed >= target.lockout_threshold:
        target.locked = True          # ์ž ๊ธˆ ์ •์ฑ… ๋ฐœ๋™
    return False

def spray(target: FakeShareTarget):
    print(f"[*] ๋Œ€์ƒ {target.hostname} ({target.username}) โ€” ์‚ฌ์ „ ๋Œ€์ž… ์‹œ์ž‘ "
          f"(์ž ๊ธˆ ์ž„๊ณ„ {target.lockout_threshold}ํšŒ)")
    for user in USERNAMES:
        for pwd in PASSWORD_LIST:
            if target.locked:
                print(f"    ! {target.failed}ํšŒ ์‹คํŒจ -> ๊ณ„์ • LOCKED. ๋” ์ด์ƒ ์‹œ๋„ ๋ถˆ๊ฐ€ "
                      f"(๋‚จ์€ ํ›„๋ณด {len(PASSWORD_LIST)*len(USERNAMES) - (USERNAMES.index(user)*len(PASSWORD_LIST) + PASSWORD_LIST.index(pwd))}๊ฐœ ํฌ๊ธฐ)")
                return False
            if try_credential(target, user, pwd):
                print(f"    + ์„ฑ๊ณต: {user} / '{pwd or '(๋นˆ ์•”ํ˜ธ)'}' "
                      f"({target.failed}ํšŒ ์‹คํŒจ ํ›„) -> ๊ณต์œ  ์ ๋ น = ๋‚ด๋ถ€๋ง ์ด๋™ ์™„๋ฃŒ")
                return True
    print("    - ์‹คํŒจ: ๋ชฉ๋ก ์ „์ฒด๋ฅผ ์‹œ๋„ํ–ˆ์œผ๋‚˜ ์„ฑ๊ณต ์—†์Œ")
    return False

if __name__ == "__main__":
    print("== ์‹œ๋‚˜๋ฆฌ์˜ค 1: ๊ณ„์ • ์ž ๊ธˆ ์ •์ฑ… ์—†์Œ (์ž„๊ณ„๊ฐ’ 999) ==")
    weak = FakeShareTarget("PC-07", "administrator", "P@ssw0rd", lockout_threshold=999)
    spray(weak)

    print()
    print("== ์‹œ๋‚˜๋ฆฌ์˜ค 2: ์ž ๊ธˆ ์ •์ฑ… ์žˆ์Œ (5ํšŒ) ==")
    hardened = FakeShareTarget("PC-42", "administrator", "Kj9#xQ2!vL", lockout_threshold=5)
    spray(hardened)
    print("    -> ๊ฐ•ํ•œ ๋น„๋ฐ€๋ฒˆํ˜ธ + ์ž ๊ธˆ ์ •์ฑ… = ์‚ฌ์ „ ๋Œ€์ž…์ด '์„œ๋น„์Šค ๊ฑฐ๋ถ€'๋งŒ ๋‚จ๊ธฐ๊ณ  ์‹คํŒจ")
# ์‹คํ–‰ ๊ฒฐ๊ณผ
== ์‹œ๋‚˜๋ฆฌ์˜ค 1: ๊ณ„์ • ์ž ๊ธˆ ์ •์ฑ… ์—†์Œ (์ž„๊ณ„๊ฐ’ 999) ==
[*] ๋Œ€์ƒ PC-07 (administrator) โ€” ์‚ฌ์ „ ๋Œ€์ž… ์‹œ์ž‘ (์ž ๊ธˆ ์ž„๊ณ„ 999ํšŒ)
    + ์„ฑ๊ณต: administrator / 'P@ssw0rd' (5ํšŒ ์‹คํŒจ ํ›„) -> ๊ณต์œ  ์ ๋ น = ๋‚ด๋ถ€๋ง ์ด๋™ ์™„๋ฃŒ

== ์‹œ๋‚˜๋ฆฌ์˜ค 2: ์ž ๊ธˆ ์ •์ฑ… ์žˆ์Œ (5ํšŒ) ==
[*] ๋Œ€์ƒ PC-42 (administrator) โ€” ์‚ฌ์ „ ๋Œ€์ž… ์‹œ์ž‘ (์ž ๊ธˆ ์ž„๊ณ„ 5ํšŒ)
    ! 5ํšŒ ์‹คํŒจ -> ๊ณ„์ • LOCKED. ๋” ์ด์ƒ ์‹œ๋„ ๋ถˆ๊ฐ€ (๋‚จ์€ ํ›„๋ณด 25๊ฐœ ํฌ๊ธฐ)
    -> ๊ฐ•ํ•œ ๋น„๋ฐ€๋ฒˆํ˜ธ + ์ž ๊ธˆ ์ •์ฑ… = ์‚ฌ์ „ ๋Œ€์ž…์ด '์„œ๋น„์Šค ๊ฑฐ๋ถ€'๋งŒ ๋‚จ๊ธฐ๊ณ  ์‹คํŒจ

PoC 3 โ€” ์ž๊ฐ€ ๋ฐฉ์–ด ๋ฃจํ‹ด์˜ ๋กœ์ง: ๊ฐ€์ƒ ์‹œ์Šคํ…œ ๊ฐ์ฒด๋ฅผ ๋Œ€์ƒ์œผ๋กœ โ‘  ๋ฐฑ์‹  ํ”„๋กœ์„ธ์Šค ํƒ์ง€ยท์ข…๋ฃŒ โ‘ก ๋ณด์•ˆ ์„œ๋น„์Šค ๋น„ํ™œ์„ฑํ™” โ‘ข ๋ณด์•ˆ ์—…์ฒด ๋„๋ฉ”์ธ DNS ์ฐจ๋‹จ(DNSAPI ํŒจ์น˜์˜ ๋™์ž‘๋งŒ ๋ชจ์˜)์„ ์ˆœ์„œ๋Œ€๋กœ ๋ณด์—ฌ์ค€๋‹ค. ์‹ค์ œ ์‹œ์Šคํ…œ์—๋Š” ์•„๋ฌด ์˜ํ–ฅ๋„ ์ฃผ์ง€ ์•Š๋Š”๋‹ค.

#!/usr/bin/env python3
"""
PoC 3 โ€” Conficker C/D์˜ '์ž๊ฐ€ ๋ฐฉ์–ด(self-defense)' ๊ตฌ์กฐ ๋ชจ์˜ (๊ต์œก์šฉ)

C/D ๋ณ€์ข…์€ ๊ฐ์—ผ PC์—์„œ ๋ฐœ๊ฐยท์ œ๊ฑฐ๋ฅผ ์–ด๋ ต๊ฒŒ ๋งŒ๋“œ๋Š” ๋ฐฉ์–ด ๋ฃจํ‹ด์„ ๋Œ๋ ธ๋‹ค:
 1) 1์ดˆ ๊ฐ„๊ฒฉ์œผ๋กœ ๋ฐฑ์‹ /์ง„๋‹จ ๋„๊ตฌ ํ”„๋กœ์„ธ์Šค๋ฅผ ํƒ์ง€ยท์ข…๋ฃŒ
 2) Windows ์ž๋™ ์—…๋ฐ์ดํŠธ(wuauserv) ๋“ฑ ๋ณด์•ˆ ๊ด€๋ จ ์„œ๋น„์Šค ๋น„ํ™œ์„ฑํ™”
 3) DNSAPI.DLL์„ ์ธ๋ฉ”๋ชจ๋ฆฌ ํŒจ์น˜ํ•ด ๋ณด์•ˆ ์—…์ฒด ๋„๋ฉ”์ธ ์กฐํšŒ ์ž์ฒด๋ฅผ ์ฐจ๋‹จ

์•„๋ž˜ ์ฝ”๋“œ๋Š” ๊ฐ€์ƒ์˜ ํ”„๋กœ์„ธ์Šค ํ…Œ์ด๋ธ”/์„œ๋น„์Šค ๋ชฉ๋ก/DNS ํ•ด์„๊ธฐ๋ฅผ ๋Œ€์ƒ์œผ๋กœ
๊ทธ '๋กœ์ง'๋งŒ ์žฌํ˜„ํ•œ๋‹ค. ์‹ค์ œ ํ”„๋กœ์„ธ์Šค ์ข…๋ฃŒยท์‹ค์ œ DLL ํŒจ์น˜๋Š” ์ผ์ ˆ ํ•˜์ง€ ์•Š๋Š”๋‹ค.
"""
import time

BLOCKED_PROCESSES = {"avguard.exe", "avgnt.exe", "msmpeng.exe",
                     "ekrn.exe", "bdagent.exe", "savservice.exe"}
BLOCKED_DOMAINS = ("update.antivirus.example", "defender.example",
                   "malware-scanner.example")
SERVICES_TO_DISABLE = {"wuauserv": "Windows Update", "BITS": "Background Intelligent Transfer",
                       "ERSvc": "Error Reporting", "WinDefend": "Windows Defender"}

class FakeSystem:
    """์‹ค์Šต์šฉ ๊ฐ€์ƒ ์‹œ์Šคํ…œ (์‹ค์ œ OS ์•„๋‹˜)."""
    def __init__(self):
        self.procs = {"lsass.exe": 1, "explorer.exe": 2, "avguard.exe": 3,
                      "svchost.exe": 4, "msmpeng.exe": 5, "wuauclt.exe": 6}
        self.services = dict(SERVICES_TO_DISABLE)
        self.dns_cache = {}

    def resolve(self, hostname: str) -> str:
        if any(hostname.endswith(b) for b in BLOCKED_DOMAINS):
            return None                      # DNS ์กฐํšŒ ์ž์ฒด๋ฅผ ์‹คํŒจ๋กœ ์œ„์žฅ
        return "1.2.3.4"

def self_defense_sweep(sys: FakeSystem):
    # 1) 1์ดˆ ๊ฐ„๊ฒฉ '๋ฐฑ์‹  ํ”„๋กœ์„ธ์Šค ํ‚ฌ' ๋ฃจํ”„ (์—ฌ๊ธฐ์„œ๋Š” 1ํšŒ ์Šค์œ•์œผ๋กœ ํ‘œํ˜„)
    killed = [p for p in sys.procs if p.lower() in BLOCKED_PROCESSES]
    for p in killed:
        del sys.procs[p]
    print(f"[1] ํ”„๋กœ์„ธ์Šค ์Šค์œ•: {killed or '๋ฐœ๊ฒฌ ์—†์Œ'}")
    print(f"    ์‚ด์•„๋‚จ์€ ํ”„๋กœ์„ธ์Šค: {sorted(sys.procs)}")

    # 2) ๋ณด์•ˆ ๊ด€๋ จ ์„œ๋น„์Šค ๋น„ํ™œ์„ฑํ™”
    for svc in list(sys.services):
        sys.services[svc] = "DISABLED"
    print(f"[2] ์„œ๋น„์Šค ๋น„ํ™œ์„ฑํ™”: { {k: v for k, v in sys.services.items()} }")

    # 3) ๋ณด์•ˆ ์—…์ฒด ๋„๋ฉ”์ธ DNS ์ฐจ๋‹จ (DNSAPI ์ธ๋ฉ”๋ชจ๋ฆฌ ํŒจ์น˜์˜ ๋™์ž‘๋งŒ ๋ชจ์˜)
    probes = ["www.google.com", "update.antivirus.example", "defender.example", "www.bbc.co.uk"]
    results = {h: sys.resolve(h) for h in probes}
    print(f"[3] DNS ํ•ด์„ ๋ชจ์˜: {results}")
    print("    -> ๋ฐฑ์‹  ์—…๋ฐ์ดํŠธ ์„œ๋ฒ„๊ฐ€ '์—†๋Š” ๋„๋ฉ”์ธ'์ฒ˜๋Ÿผ ๋ณด์—ฌ ์ตœ์‹  ์‹œ๊ทธ๋‹ˆ์ฒ˜๋ฅผ ๋ฐ›์ง€ ๋ชปํ•จ")

if __name__ == "__main__":
    print("๊ฐ์—ผ PC์˜ ์ž๊ฐ€ ๋ฐฉ์–ด ๋ฃจํ‹ด 1ํšŒ ์Šค์œ• (๊ฐ€์ƒ ์‹œ์Šคํ…œ ๋Œ€์ƒ):")
    self_defense_sweep(FakeSystem())
# ์‹คํ–‰ ๊ฒฐ๊ณผ
๊ฐ์—ผ PC์˜ ์ž๊ฐ€ ๋ฐฉ์–ด ๋ฃจํ‹ด 1ํšŒ ์Šค์œ• (๊ฐ€์ƒ ์‹œ์Šคํ…œ ๋Œ€์ƒ):
[1] ํ”„๋กœ์„ธ์Šค ์Šค์œ•: ['avguard.exe', 'msmpeng.exe']
    ์‚ด์•„๋‚จ์€ ํ”„๋กœ์„ธ์Šค: ['explorer.exe', 'lsass.exe', 'svchost.exe', 'wuauclt.exe']
[2] ์„œ๋น„์Šค ๋น„ํ™œ์„ฑํ™”: {'wuauserv': 'DISABLED', 'BITS': 'DISABLED', 'ERSvc': 'DISABLED', 'WinDefend': 'DISABLED'}
[3] DNS ํ•ด์„ ๋ชจ์˜: {'www.google.com': '1.2.3.4', 'update.antivirus.example': None, 'defender.example': None, 'www.bbc.co.uk': '1.2.3.4'}
    -> ๋ฐฑ์‹  ์—…๋ฐ์ดํŠธ ์„œ๋ฒ„๊ฐ€ '์—†๋Š” ๋„๋ฉ”์ธ'์ฒ˜๋Ÿผ ๋ณด์—ฌ ์ตœ์‹  ์‹œ๊ทธ๋‹ˆ์ฒ˜๋ฅผ ๋ฐ›์ง€ ๋ชปํ•จ

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

์ถœ์ฒ˜

ํ•จ๊ป˜ ์ฝ๊ธฐ: โš›๏ธ Stuxnet (2010) โ€” MS08-067์„ ๋ณด์กฐ ์ „ํŒŒ ์ˆ˜๋‹จ์œผ๋กœ ๋ณ‘์šฉํ•œ ๊ตญ๊ฐ€๊ธ‰ ์›œ ยท ๐Ÿ’€ WannaCry (2017) โ€” "์›Œ๋จธ๋ธ” ์ทจ์•ฝ์ ์˜ ์ „๋žต์  ๋น„์ถ• โ†’ ์œ ์ถœ โ†’ ์ „ ์„ธ๊ณ„์  ์›œ"์œผ๋กœ ์ด์–ด์ง„ NSA ๋ฌด๊ธฐ ์—ฐ๊ฒฐ๊ณ ๋ฆฌ ยท ๐Ÿฆ  Mirai (2016) โ€” ๊ธฐ๋ณธ ๋น„๋ฐ€๋ฒˆํ˜ธ ์‚ฌ์ „ ๋Œ€์ž…์ด IoT์—์„œ ์žฌํ˜„๋œ ์‚ฌ๋ก€

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