이번글의 목적은 앞서 정리한 BPFDoor의 핵심 개념 정리와 주요기능 다음으로 변종BPFDoor(2025.04)를 기반으로한 대응 전략 및 점검 가이드에 대해 다뤄보고자 함.
BPFDoor 점검을 위한 쉘 스크립트는 [KISA의 보안 점검 가이드]를 인용하였음
점검 명령어는 관리자(root) 계정 또는 권한(sudo)으로 실행해야함
특정 경로에 생성되는 뮤텍스/락 파일을 점검하여 악성코드 실행 여부를 점검
/var/run/*.pid
또는 /var/run/*.lock
경로에 0바이트 크기의 파일이 존재하는지 확인
의심 파일 권한 : 644 (-rw-r--r--)
sudo ls -l /var/run*.pid | awk '$5 == 0 { print $9 }'
sudo ls -l /var/run*.lock | awk '$5 == 0 { print $9 }'
sudo stat -c "%a %s %n" /var/run/*.pid /var/run/*.lock 2>/dev/null | awk '$1=="644" && $2==0 { print $3 }'
락 파일의 크기(0 byte)와 권한(644)을 함께 확인하면 오탐을 줄일 수 있음
악성코드가 부팅 시 자동 실행되도록 스크립트에 등록되었는지 확인
오진 가능성 존재 : 파일 대상 초동 점검(8️⃣) 및 YARA 기반 점검 필요(9️⃣)
$ sudo grep -Er '\[\s*-f\s+/[^]]+\]\s*&&\s*/' /etc/sysconfig/
$ sudo find /etc/sysconfig/ -type f -exec egrep '\[\s*-f\s+/[^]]+\]\s*&&\s*/' {} +
[ -f 경로 ] && 경로
형태는 감염 후 악성파일 존재 여부 확인 후 실행하는 조건문BPFDoor가 설정한 BPF 필터 내에 매직 시퀀스 존재 여부 확인
# 명령어 1 : 서버에 등록된 BPF 필터 확인(비정상 필터 유무 점검)
# (-p : 프로세스 포함, -b : BPF 사용 포함, -0 : 아무 플래그 없는 기본 소켓)
$ sudo ss -0pb
# BPF 필터 내 매직넘버(Magic Sequences) 확인 → 악성코드 감염 의심
# 명령어 2
# "-E" : 매직넘버(시그니처)값이 포함된 필터를 식별
$ sudo ss -0pb | grep -E "21139|29269|960051513|36204|40783"
# 명령어 3 : 명령어 2로 확인 불가 시 사용
# "-B1" : 매치된 라인 이전의 라인 1줄도 함께 출력(검색 결과 앞의 1줄)
$ sudo ss -0pb | grep -EB1 "$((0x5293))|$((0x7255))|$((0x39393939))|$((0x8D6
C))|$((0x9F4F))"
악성코드 감염 시 출력되는 BPF 값 : 붉은색 숫자 확인
bpfdoor_bpf.sh
)#!/bin/bash
echo "[*] Detecting processes with active BPF usage..."
# 1. ss -0pb : 소켓 정보를 출력
# grep -oP 'pid=\k[0-9]+' : 숫자(PID)만 추출
# sort -u : 중복 제거 후 정렬
sudo ss -0pb | grep -oP 'pid=\k[0-9]+' | sort -u | while read pid; do
# 2. 해당 PID의 /proc 디렉토리가 존재하는지 확인
# (존재하지 않으면 종료된 프로세스일 수 있음)
if [[ -e "/proc/$pid" ]]; then
#readlink -f /proc/$pid/exe : 실행 파일의 실제 경로 추출
exe_path=$(readlink -f /proc/$pid/exe 2>dev/null)
# /proc/$pid/comm : 프로세스의 이름 추출
proc_name=$(cat /proc/$pid/comm 2>/dev/null)
echo ""
echo "Process Name : ${proc_name:-Unknown}, PID: $pid"
echo " → Executable : ${exe_path:-Not found}"
fi
done
BPFDoor는
SOCK_RAW
,SOCK_DGRAM
을 사용하는 은닉 통신 활용
오진 가능성 존재 : 파일 대상 초동 점검(8️⃣) 및 YARA 기반 점검 필요(9️⃣)
$ sudo lsof 2>/dev/null | grep -E "IP type=SOCK_RAW | IP type=SOCK_DGRAW" | awk '{ print $2 }' | sort -u | xargs -r ps -fp
$ sudo awk '$4=="0800" && $5=="0" { print $9 }' /proc/net/packet | while read inode;
do sudo grep -r "ino:\s$inode" /proc*/fdinfo/ 2>/dev/null | awk -F/ '{ print $3 }' | sort -u | xargs -r sudo ps -fp;
done
$ sudo ss -apn | grep -E ":1 |:6 |:17 "
악성코드가 셸(Shell) 연결 시 사용하는 환경변수를 점검
조작된 환경변수 사용 여부 확인
오진 가능성 존재 : 파일 대상 초동 점검(8️⃣) 및 YARA 기반 점검 필요(9️⃣)
HOME=/tmp
HISTFILE=/dev/null
MYSQL_HISTFILE=/dev/null
/proc/<PID>/environ
파일에서 환경변수를 추출하여 검증#!/bin/bash
echo "echo [*] Detecting processes with BPFDoor environment variable manipulation..."
echo "Target : HOME=/tmp, HISTFILE=/dev/null,MYSQL_HISTFILE=/dev/null"
# 점검할 의심 환경변수 목록 배열
CHECK_ENV=("HOME=/tmp" "HISTFILE=/dev/null" "MYSQL_HISTFILE=/dev/null")
# Process scanning (/proc 내 존재하는 모든 PID 대상으로 스캔)
for pid in $(ls /proc/ | grep -E '^[0-9]+$'); do
# 해당 PID의 환경변수 파일이 읽기 가능한지 확인
if [ -r /proc/$pid/environ ]; then
# null 문자(\0)를 줄바꿈(\n)으로 바꿔 환경변수 내용을 라인 단위로 추출
env_data=$(tr '\0' '\n' < /proc/$pid/environ)
match_all=true
# CHECK_ENV 배열의 각 항목이 모두 존재하는지 확인
for check_item in "${CHECK_ENV[@]}"; do
if ! echo "$env_data" | grep -q "$check_item"; then
match_all=false
break
fi
done
# 모든 의심 환경변수가 포함된 경우 경고 출력
if [ "$match_all" = true ]; then
echo "Warning: Process with all suspicious environment variables detected
(PID: $pid)"
# ps 명령으로 프로세스 상세 정보 출력
echo " → $(ps -p $pid -o user=,pid=,ppid=,cmd=)"
echo ""
fi
fi
done
결과
의심 프로세스의 파일 경로 확인
$ sudo ls -l /proc/<PID>/exe
# 결과
lrwxrwxrwx. 1 root root 0 4월 28 12:31 /proc/4076/exe -> /dev/shm/smartadm
BPFDoor가 사용하는 특정 포트 또는 트래픽 시그니처 존재 여부 점검
오진 가능성 존재 : 파일 대상 초동 점검(8️⃣) 및 YARA 기반 점검 필요(9️⃣)
# 명령어 1
$ sudo netstat -tulpn
$ sudo netstat -tulpn 2>/dev/null | awk '
{
match($0, /:([0-9]+)/, a);
if ((a[1] >= 42391 && a[1] <= 43390) || $0 ~ /:8000([^0-9]|$)/)
print $0
}'
$ sudo netstat -tulpn 2>/dev/null | awk '
$1=="tcp"&&($6=="LISTEN"||$6=="ESTABLISHED") {
lp=substr($4,index($4,":")+1);
rp=substr($5,index($5,":")+1);
if((lp>=42391&&lp<=43390)||lp==8000||
(rp>=42391&&rp<=43390)||rp==8000)
print
}'
# 명령어 2
$ sudo ls -l /proc/<PID>/exe
BPFDoor는 특정한 포맷의 매직 패킷을 이용해 통신을 수행함
- 패킷 크기 및 페이로드, 시퀀스, 문자열 패턴 등으로 탐지 가능
ℹ️ 주요 특징
전송 패킷의 크기 (전체가 아닌 Payload 기준)
: UDP/TCP
(24byte), ICMP
(44byte), TCP:HTTP POST
(100byte 이하)
페이로드 내 문자열
비밀번호 예시 → justforfun
매직 시퀀스 값
프로토콜 | 시퀀스 값 |
---|---|
UDP/ICMP | 0x7255 , 0x9F4F |
TCP | 0x5293 , 0x39393939 , 0x8D6C |
HTTP 요청 위장 (TCP)
: HTTP POST
요청의 URI에 특정 마커 존재
9999
문자열 포함📄 예시 패턴
/admin/login.aspx?id=99990
/admin_login.aspx?id=99990
/Admin/Default.aspx?=99990
/UploadFile.aspx?id=099990
/user/admin.php?id=0099991
/uploadfiles.php?id=099991
/uploadfilm.php?id=0099991
/uploadphoto.php?id=099991
/uploadPic.php?id=00099991
Mozilla/5.0 (Windows NT 6.1; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/90.0.5389.90 Safari/537.36
⚠️ 주의
악성코드의 위장 프로세스명을 확인
오진 가능성 존재 : 파일 대상 초동 점검(8️⃣) 및 YARA 기반 점검 필요(9️⃣)
/usr/sbin/abrtd
, /sbin/udevd
, cmathreshd
, /sbin/sgaSolAgent
, /usr/sbin/atd
, pickup
# 명령어 1
$ sudo ps -ef | grep -E '/usr/sbin/abrtd|/sbin/udevd|cmathreshd|/sbin/sgaSolAgen
t|/usr/sbin/atd|pickup'
# 명령어 2
$ sudo ls -l /proc/<PID>/exe
부가 점검 방법(선택)
시스템 내 파일에서 악성 문자열 패턴이 포함된 이진 실행파일 식별
초동 점검은 오진 가능성이 있으며, 반드시 2차 YARA 검증이 필요
# 명령어 1 : 단일 파일(strings) - 권장사항
$ sudo strings -a -n 5 <의심파일 경로> | grep -E '
MYSQL_HISTFILE=/dev/null|
:h:d:l:s:b:t:|
:f:wiunomc|
:f:x:wiuoc|
ttcompat'
# 명령어 2 : 특정 경로(find), filesize(15K~4M), 검색 깊이 1 - 권장하지 않음
# 출력 결과 [파일명]: 매칭 문자열
$ sudo find <의심경로> -maxdepth 1 -type f -size +15k -size -4M -exec sh -c '
strings -a -n5 "$1"|
sed "s|^|$1: |"|
grep -E "MYSQL_HISTFILE=/dev/null|
:h:d:l:s:b:t:|
:f:wiunomc|
:f:x:wiuoc|
ttcompat"
' _ {} \;
KISA 배포 bpfdoor.yar 룰셋
$ yara -r bpfdoor.yar <디렉토리 또는 파일 경로>
이외에소 EDR 솔루션 로그 및 방화역 로그 등 다중 로그 기반 분석 병행 필요
[KISA 보호나라&KrCERT/CC] BPFDoor 악성코드 점검 가이드
[AhnLab] BPFDoor 악성코드 분석 및 안랩 대응 현황
[AhnLab] BPFDoor 악성코드, 해킹 위협 대응을 위한 2차 보안 가이드