시스템 보안 · 취약점 › B. 계정 · 인증 보안 강화 · 35/50편 (전체 085/450)
학습 단계: 2단계 · 설정 및 점검
실습 표기: 이 글의 명령어·출력·로그는 로컬 VMware 테스트 VM(Rocky Linux 9 / Ubuntu 22.04) 기준의 「실습 예시」이며, IP·계정·호스트명은 가상의 값입니다.
서비스 계정은 사람이 로그인하지 않는 것이 원칙(034편)이므로, 서비스 계정의 대화형 셸은 거의 항상 비정상입니다. 두 경로로 나타납니다.
① SSH 로그인 : Accepted ... for apache (034편 방어선이 뚫린 경우)
② 프로세스 경유: 웹/DB 프로세스가 셸을 실행
httpd/php-fpm → sh/bash (auid=unset, 부모가 데몬)
mysqld → sh (DB 기능 악용)
→ 로그인 로그 없이 서비스 계정 권한의 셸이 생김
②는 로그인 이벤트가 없어 인증 로그만 봐서는 안 보입니다. 프로세스 계보(부모-자식) 로 탐지합니다.
| 경로 | 탐지 |
|---|---|
| 서비스 계정 SSH 로그인 | Accepted ... for apache(011편 101011) |
| 데몬→셸 계보 | ps 부모 확인, auditd execve(부모=httpd/mysqld, comm=sh) |
| 대화형 여부 | TTY 존재, 자식 프로세스 |
| 네트워크 | 서비스 계정 셸의 외부 연결(F영역) |
| auid | unset(데몬 경유) vs 로그인 사용자 |
# 1) 서비스 계정 SSH 로그인 (있으면 비정상)
sudo grep -E 'Accepted .* for (apache|nginx|www-data|mysql|postgres)' /var/log/secure
# 2) 데몬을 부모로 둔 셸 프로세스 (현재)
ps -eo pid,ppid,user,comm | awk '$4 ~ /^(sh|bash|dash)$/ {print}' | while read pid ppid user comm; do
pcomm=$(ps -o comm= -p "$ppid" 2>/dev/null)
echo "$pcomm -> $comm (user=$user pid=$pid)"
done | grep -E 'httpd|nginx|php|mysqld|postgres'
# 3) audit: 서비스 계정 UID의 셸 실행
sudo ausearch -m EXECVE -i --start today 2>/dev/null | grep -B1 -E 'a0="?(sh|bash)' | grep -E 'uid=(48|33|27|26)' | head
$ (서비스 계정 SSH 로그인)
$ (데몬→셸 계보)
서비스 계정의 SSH 로그인이 없고, 데몬을 부모로 둔 셸이 없는 상태가 정상입니다(데몬은 자신의 워커만 띄움).
$ sudo grep 'Accepted .* for apache' /var/log/secure
02:20:05 Accepted publickey for apache from 192.168.56.77
$ (데몬→셸 계보)
httpd -> bash (user=apache pid=12901)
$ (audit) uid=48 comm="bash" ... ppid=1188(httpd)
apache SSH 로그인(034편 방어선 붕괴 결과)서비스 계정 셸 획득의 두 경로를 비교한 예시입니다(가상의 예시 로그).
[경로① SSH]
02:20:05 sshd: Accepted publickey for apache from 192.168.56.77
type=USER_LOGIN auid=apache ses=20 addr=192.168.56.77
[경로② 프로세스]
type=EXECVE argc=1 a0="bash"
type=SYSCALL ppid=1188 pid=12901 auid=unset uid=48 comm="bash" exe="/usr/bin/bash"
(ppid 1188 = httpd)
| 구분 | 경로① SSH | 경로② 프로세스 |
|---|---|---|
| 로그인 이벤트 | 있음(auid=apache) | 없음(auid=unset) |
| 탐지 로그원 | 인증 로그 | 프로세스/audit |
| 부모 | sshd | httpd |
| 의미 | 발판 마련 | 웹 침해 직후 셸 |
<group name="local,syssec_b,account,">
<rule id="101320" level="12">
<if_group>audit</if_group>
<field name="audit.uid" type="pcre2">^(48|33|27|26|999)$</field>
<field name="audit.exe" type="pcre2">/(ba|da|z)?sh$</field>
<description>서비스 계정 UID의 대화형 셸 실행(웹/DB 침해 가능성)</description>
</rule>
</group>
서비스 계정 UID는 배포판별로 다르므로 환경에 맞게 지정합니다. 011편(101011 서비스 계정 SSH 성공)과 함께 운영하면 두 경로를 모두 덮습니다. 프로세스 계보 기반 상세 탐지는 F영역에서 확장합니다.
| 경로 | 탐지 수단 |
|---|---|
| SSH 로그인 | Accepted for 서비스계정(인증 로그) |
| 프로세스 경유 | 데몬→셸 계보(auid=unset, 부모=httpd/mysqld) |
| 공통 | 서비스 계정 셸은 거의 항상 비정상 |
| 후속 | 권한 상승(D영역)·지속성(031·057편) |
| 면접 포인트 | "서비스 계정 셸은 웹/DB 침해의 결과물 — 두 로그원으로 본다" |
다음 편 086. 계정 · 인증 보안 — 공유 계정·기본 계정 위험 분석 에서는 여러 사람이 함께 쓰는 공유 계정·기본 계정 위험 분석을 다룹니다.
이전 편: 084. 계정 · 인증 보안 — 서비스 계정 관리와 로그인 차단
📚 시리즈 전체 보기: 시스템 보안 · 취약점