시스템 보안 · 취약점 › B. 계정 · 인증 보안 강화 · 2/50편 (전체 052/450)
학습 단계: 1단계 · 기본 개념
실습 표기: 이 글의 명령어·출력·로그는 로컬 VMware 테스트 VM(Rocky Linux 9 / Ubuntu 22.04) 기준의 「실습 예시」이며, IP·계정·호스트명은 가상의 값입니다.
/etc/passwd의 구조 자체는 기존 06편에서 다뤘습니다. 이 편은 각 필드를 "공격자가 바꾸면 무엇이 달라지는가" 관점으로 다시 읽습니다.
devops:x:1002:1002:DevOps Engineer:/home/devops:/bin/bash
① ② ③ ④ ⑤ ⑥ ⑦
① 계정명 : 시스템 계정처럼 위장(sysbak, systemd-net)
② 패스워드 : 'x'가 아니라 해시가 직접 들어가면 shadow 우회
③ UID : 0이면 root 권한, 기존 UID와 중복이면 권한 공유
④ GID : 0(root 그룹)·특권 그룹 기본 그룹 지정
⑤ GECOS : 설명 필드 — 비어 있거나 위장 문구
⑥ 홈 : /tmp, /dev/shm, /var/www 등 비정상 위치
⑦ 셸 : 서비스 계정에 /bin/bash 부여
| 필드 | 정상 기대값 | 이상 징후 | 확인 명령 |
|---|---|---|---|
| ② 패스워드 | x | $6$... 등 해시 문자열 | awk -F: '$2!="x"{print $1}' /etc/passwd |
| ③ UID | 고유, 사람 계정 1000 이상 | 중복, 0 | cut -d: -f3 /etc/passwd | sort | uniq -d |
| ④ GID | 사용자 전용 그룹 | 0 또는 wheel/sudo GID | awk -F: '$4==0' /etc/passwd |
| ⑥ 홈 | /home/계정, 서비스는 전용 경로 | /tmp, /dev/shm, 존재하지 않는 경로 | awk -F: '$6 ~ /^\/(tmp|dev\/shm|var\/tmp)/' /etc/passwd |
| ⑦ 셸 | 사람: bash, 서비스: nologin | 서비스 계정 bash | awk -F: '$3<1000 && $7 ~ /sh$/' /etc/passwd |
| 무결성 | 형식 오류 없음 | 필드 수 오류·중복 | sudo pwck -r |
# 필드별 이상 징후 일괄 점검 (읽기 전용)
echo "[pw-field]"; awk -F: '$2!="x"{print $1": password field="$2}' /etc/passwd | sed 's/=\$.*/=<hash>/'
echo "[dup-uid]"; cut -d: -f3 /etc/passwd | sort | uniq -d
echo "[gid0]"; awk -F: '$4==0 && $1!="root"{print $1}' /etc/passwd
echo "[odd-home]"; awk -F: '$6 ~ /^\/(tmp|dev\/shm|var\/tmp)/ {print $1, $6}' /etc/passwd
echo "[no-home]"; awk -F: '$3>=1000 {print $1, $6}' /etc/passwd | while read u h; do [ -d "$h" ] || echo "$u $h (없음)"; done
echo "[svc-shell]";awk -F: '$3>0 && $3<1000 && $7 ~ /sh$/ {print $1, $7}' /etc/passwd
sudo pwck -r
해시가 발견되더라도 출력에 그대로 남기지 않도록 <hash>로 가립니다. 분석 보고서에도 해시 원문은 넣지 않는 것이 원칙입니다.
[pw-field]
[dup-uid]
[gid0]
[odd-home]
[no-home]
[svc-shell]
$ sudo pwck -r
$
모든 항목이 비어 있고 pwck가 아무 오류도 보고하지 않는 상태가 정상입니다.
[pw-field]
systemd-net: password field=<hash>
[dup-uid]
48
[odd-home]
systemd-net /dev/shm/.cache
[svc-shell]
systemd-net /bin/bash
$ grep -E ':48:' /etc/passwd | cut -d: -f1,3
apache:48
systemd-net:48
systemd-net이 apache와 같은 UID 48을 사용 → apache 프로세스·파일 권한을 그대로 공유/etc/shadow 점검을 우회/dev/shm/.cache(메모리 기반 숨김 경로) → 디스크 흔적 최소화 의도passwd 파일 변경은 명령으로 바꿨는지, 직접 편집했는지에 따라 남는 로그가 다릅니다(가상의 예시 로그).
[명령 사용 — secure/auth.log]
Oct 2 02:20:11 rocky9-web01 useradd[11301]: new user: name=systemd-net, UID=48, GID=48, home=/dev/shm/.cache, shell=/bin/bash, from=/dev/pts/1
[직접 편집 — audit, 명령 로그 없음]
type=SYSCALL msg=audit(1759339300.410:3201): syscall=82 success=yes auid=1002 uid=0 comm="vi" exe="/usr/bin/vi" key="identity"
type=PATH msg=audit(1759339300.410:3201): item=3 name="/etc/passwd" nametype=CREATE
[Wazuh FIM report_changes]
File '/etc/passwd' modified
What changed:
> systemd-net:<hash 생략>:48:48::/dev/shm/.cache:/bin/bash
| 관찰 | 해석 |
|---|---|
useradd ... UID=48 | -o(중복 허용) 옵션으로 기존 UID 재사용 |
vi로 rename(syscall=82) | 편집기 저장 방식(임시 파일→rename) → 명령 로그 없이 변경 |
FIM diff의 > 줄 | 추가된 정확한 내용 = 판단 근거 |
report_changes="yes"로 diff를 받아 필드 단위로 판단합니다(해시가 포함될 수 있어 Alert 접근 권한 관리 필요).useradd/usermod 로그 없이 passwd가 바뀌면 직접 편집 → 은폐 의도 가능성으로 우선순위를 높입니다.<group name="local,syssec_b,account,">
<rule id="101010" level="12">
<if_sid>550</if_sid>
<field name="file">^/etc/passwd$</field>
<regex type="pcre2">:/(tmp|dev/shm|var/tmp)/|:\$[0-9a-z]+\$</regex>
<description>/etc/passwd에 비정상 홈 경로 또는 패스워드 해시 직접 기록</description>
</rule>
<rule id="101011" level="12">
<match>new user: name=</match>
<regex type="pcre2">UID=(48|33|27|26|0),</regex>
<description>서비스 계정·root UID를 재사용한 계정 생성</description>
</rule>
</group>
UID 48(Rocky apache), 33(Ubuntu www-data), 27(mysql), 26(postgres)은 배포판별로 다르므로 환경에 맞게 조정합니다.
| 필드 | 이상 징후 |
|---|---|
| 패스워드 | x 대신 해시 직접 기록 → shadow 우회 |
| UID | 0 또는 중복(서비스 계정 UID 재사용) |
| 홈 | /tmp, /dev/shm 등 임시·숨김 경로 |
| 셸 | 서비스 계정에 /bin/bash |
| 면접 포인트 | "useradd 로그 없이 passwd가 바뀌면 직접 편집 → 은폐 의도" |
다음 편 053. 계정 · 인증 보안 — /etc/shadow 해시 형식과 비밀번호 상태 판독 에서는 비밀번호 상태가 담긴 /etc/shadow의 해시 형식과 상태 필드를 판독합니다.
이전 편: 051. 계정 · 인증 보안 — Linux 사용자 계정 구조와 인증 흐름 전체 지도
📚 시리즈 전체 보기: 시스템 보안 · 취약점