시스템 보안 · 취약점 › I. 지속성 · 재침투 징후 · 31/50편 (전체 431/450)
학습 단계: 백도어·재침투 경로 탐지
실습 표기: 이 글의 명령어·출력·로그는 로컬 VMware 테스트 VM(Rocky Linux 9 / Ubuntu 22.04) 기준의 「실습 예시」이며, IP·계정·호스트명은 가상의 값입니다.
웹셸은 웹 서버에 올려 둔 스크립트로, HTTP 요청만으로 명령을 실행하게 해 줍니다(T1505.003). 계정·키를 모두 정리해도 웹셸이 남아 있으면 브라우저 하나로 다시 들어올 수 있습니다.
웹셸 재침투 흔적 3종
① 파일 : 웹 루트에 신규 .php/.jsp, 업로드 디렉터리의 실행 파일
② 웹 로그 : 특정 파일로의 POST 반복, 낯선 UA, 200 응답
③ 프로세스: httpd/php-fpm → sh → id/uname/curl (웹서버가 셸 생성)
↓
①+②+③이 같은 시간대에 겹치면 웹셸 재침투 확정
핵심: 웹 로그만, 프로세스만 보면 오탐이 많다 — 셋을 묶는다
웹 보안 시리즈에서 웹셸 업로드를 다뤘다면, 이번 편은 근절 이후 웹셸이 다시 쓰이는 재침투를 시스템 로그 쪽에서 확인하는 방법을 다룹니다.
| 확인 | 명령 / 로그 | 포인트 |
|---|---|---|
| 신규 파일 | find /var/www -newer <기준> -name '*.php' | 최근 생성 |
| 의심 함수 | grep -rlE 'eval(|system(|base64_decode' /var/www | 실행 함수 |
| 웹 로그 | awk '$6~/POST/' access_log | 특정 파일 POST |
| 계보 | ausearch -k exec_web -i | 부모 httpd·php-fpm |
# 웹셸 재침투 점검 (분석 방법)
sudo find /var/www -type f -name '*.ph*' -newer /root/baseline/persist-* -ls 2>/dev/null
sudo grep -rlE 'eval\(|assert\(|system\(|passthru\(|shell_exec\(|base64_decode\(' /var/www 2>/dev/null | head
# 같은 파일로의 POST 반복과 출발지
sudo awk '$6=="\"POST" {print $1, $7}' /var/log/httpd/access_log | sort | uniq -c | sort -rn | head
# 웹서버가 셸을 생성한 기록
sudo ausearch -k exec_web -i 2>/dev/null | grep -E 'exe=/usr/bin/(ba)?sh|exe=/usr/bin/(id|whoami|uname|curl|wget)' | head
웹 루트 신규 파일: 배포 시각(CHG-1101)과 일치
POST 상위: /login.php, /api/order (정상 기능)
웹서버 자식 셸: 없음
웹 루트 변경이 배포 기록과 일치하고, POST가 정상 기능에 분포하며, 웹서버가 셸을 생성하지 않는 상태가 정상입니다.
/var/www/html/uploads/thumb.php (03:10 생성, eval(base64_decode(...)))
access_log: 203.0.113.50 "POST /uploads/thumb.php" 200 × 46
execve: ppid=php-fpm uid=apache exe=/usr/bin/bash a0=sh a1=-c a2=id
웹셸 재침투 결합 분석 흐름입니다(가상의 예시).
[파일] 웹 루트 신규·변경 파일 + 의심 함수
↓ (파일명)
[웹 로그] 그 파일로의 요청 · 출발지 · 시각
↓ (시각)
[프로세스] 같은 시각 웹서버 자식 execve
↓
[파급] 실행된 명령 → 추가 지속성·권한 상승 여부
| 증거 | 역할 |
|---|---|
| 파일 | 웹셸 존재 |
| 웹 로그 | 사용 시점·출발지 |
| execve | 실제 명령 |
웹 로그의 요청 시각과 execve 시각을 초 단위로 맞추면, POST 하나하나가 어떤 명령으로 실행되었는지 대응시킬 수 있습니다.
<!-- 실습 예시 룰: 적용 전 wazuh-logtest 및 테스트 환경 검증 필요 -->
<group name="local,syssec_i,persistence,">
<rule id="108300" level="14">
<if_sid>108000</if_sid>
<field name="audit.key">exec_web</field>
<field name="audit.uid" type="pcre2">^(apache|www-data|nginx|48|33)$</field>
<field name="audit.exe" type="pcre2">/(ba)?sh$|/(id|whoami|uname|curl|wget|nc)$</field>
<description>웹서버 계정의 셸·정찰 명령 실행(웹셸 재침투 의심)</description>
<mitre><id>T1505.003</id></mitre>
</rule>
</group>
웹서버 계정 UID로 실행된 execve를 exec_web 키로 감사하고, 셸·정찰 명령이면 경보합니다. 웹 로그 기반 탐지와 같은 시간대로 상관하면 확신도가 올라갑니다.
| 증거 | 확인 |
|---|---|
| 파일 | 신규 스크립트·eval |
| 웹 로그 | 반복 POST |
| 프로세스 | 웹서버 → 셸 |
| 판정 | 세 증거 결합 |
| 면접 포인트 | "웹셸은 계정 정리와 무관한 뒷문 — 파일·웹 로그·프로세스를 시각으로 묶는다" |
다음 편 432. 지속성·재침투 — C2 비컨 재연결 패턴 탐지 에서는 지속성 악성코드가 C2 서버에 주기적으로 접속하는 비컨 패턴을 간격·크기·목적지 지표로 분석해 재침투 채널을 탐지하는 방법을 다룹니다.
이전 편: 430. 지속성·재침투 — 바인드 셸·백도어 리스너 탐지
📚 시리즈 전체 보기: 시스템 보안 · 취약점