파일 · 권한 · 사용자 관리 32 / 50 · Part 4. 사용자와 그룹 관리
실습 환경: Rocky Linux 9.8 · Ubuntu 24.04.5 (Docker 격리 컨테이너, 테스트 계정analyst)
기초편 연계: 「리눅스 시스템 기초」 18. Linux 사용자와 그룹
31편에서 계정이 UID·사용자명·GID·홈·셸로 이루어진다고 했다. 이 정보가 실제로 저장되는 파일이 /etc/passwd다.
이름과 달리 /etc/passwd에는 비밀번호가 들어 있지 않다. 옛 유닉스에서는 여기에 해시를 뒀지만, 이 파일이 누구나 읽을 수 있어야 하기 때문에(이름↔UID 변환에 필요) 해시를 여기 두면 오프라인 크래킹에 노출된다. 그래서 현대 리눅스는 해시를 /etc/shadow로 분리했다(33편).
이번 글에서는 /etc/passwd의 7개 필드를 한 칸씩 해석하고, 이 파일에서 읽어 낼 수 있는 계정 이상 신호를 정리한다.
root:x:0:0:root:/root:/bin/bash를 :로 나누면:
| # | 필드 | 예 | 의미 |
|---|---|---|---|
| 1 | 사용자명 | root | 로그인 이름 |
| 2 | 비밀번호 | x | x = /etc/shadow 참조 |
| 3 | UID | 0 | 사용자 번호 |
| 4 | GID | 0 | 기본 그룹 번호 |
| 5 | GECOS | root | 설명·실명·연락처(콤마 구분) |
| 6 | 홈 디렉터리 | /root | 로그인 후 위치 |
| 7 | 로그인 셸 | /bin/bash | 로그인 시 실행 프로그램 |
| 값 | 의미 |
|---|---|
x | 해시가 /etc/shadow에 있음 (정상) |
* 또는 ! | 로그인 불가 (비밀번호 없음) |
| (빈 값) | 비밀번호 없이 로그인 가능 — 매우 위험 |
| 해시 문자열 | shadow를 안 쓰는 구식·위험 설정 |
/etc/passwd는 644 root:root다. 누구나 읽을 수 있고 root만 쓸 수 있다. 읽기 권한이 필요한 이유는 ls -l이 UID를 이름으로 바꾸는 등 일상적으로 참조되기 때문이다.

/etc/passwd가 공개 파일이라는 점이 보안 설계의 핵심이다. 누구나 읽을 수 있으므로 비밀 정보(해시)는 절대 여기 두지 않는다. 대신 UID·GID·홈·셸 같은 "공개돼도 되는" 정보만 담는다.
이 파일에 쓰기(수정)는 root만 가능하다. 그래서 계정 추가·변경은 곧 root 권한을 요구한다. 공격자가 root를 얻으면 가장 먼저 하는 일 중 하나가 이 파일에 UID 0 백도어 계정 을 추가하는 것이다. UID가 0이면 이름이 무엇이든 root 권한을 가지므로(31편), getent passwd에서 UID 0 계정이 root 외에 있는지 점검하는 것이 기본 탐지다.
# 1) 필드 확인
getent passwd root analyst
# 2) 필드 분해 (root)
getent passwd root | awk -F: '{print "1 username: "$1"\n2 password: "$2" (x = shadow 참조)\n3 UID: "$3"\n4 GID: "$4"\n5 GECOS: "$5"\n6 home: "$6"\n7 shell: "$7}'
# 3) 권한 확인
ls -l /etc/passwd
# 4) 이상 신호 탐색
awk -F: '$3==0 {print "UID 0 계정: "$1}' /etc/passwd # root 뿐이어야 정상
awk -F: '$2!="x" && $2!="*" && $2!="!" {print "비정상 passwd 필드: "$1" -> "$2}' /etc/passwd

텍스트 원본(실제 출력):
[analyst@rocky9-lab ~]$ echo "=== /etc/passwd 필드 7개 ==="
=== /etc/passwd 필드 7개 ===
[analyst@rocky9-lab ~]$ getent passwd root analyst
root:x:0:0:root:/root:/bin/bash
analyst:x:1000:1000::/home/analyst:/bin/bash
[analyst@rocky9-lab ~]$ echo "--- 필드 분해 (root) ---"
--- 필드 분해 (root) ---
[analyst@rocky9-lab ~]$ getent passwd root | awk -F: '{print "1 username: "$1"\n2 password: "$2" (x = shadow 참조)\n3 UID: "$3"\n4 GID: "$4"\n5 GECOS: "$5"\n6 home: "$6"\n7 shell: "$7}'
1 username: root
2 password: x (x = shadow 참조)
3 UID: 0
4 GID: 0
5 GECOS: root
6 home: /root
7 shell: /bin/bash
[analyst@rocky9-lab ~]$ echo "=== 권한 ==="
=== 권한 ===
[analyst@rocky9-lab ~]$ ls -l /etc/passwd
-rw-r--r-- 1 root root 701 Sep 24 14:42 /etc/passwd
[analyst@rocky9-lab ~]$ echo "=== 위험 신호 탐색 ==="
=== 위험 신호 탐색 ===
[analyst@rocky9-lab ~]$ awk -F: '$3==0 {print "UID 0 계정: "$1}' /etc/passwd
UID 0 계정: root
[analyst@rocky9-lab ~]$ awk -F: '$2!="x" && $2!="*" && $2!="!" {print "비정상 passwd 필드: "$1" -> "$2}' /etc/passwd
| 출력 | 해석 |
|---|---|
root:x:0:0:root:/root:/bin/bash | UID·GID 0, 홈 /root, 셸 bash |
analyst:x:1000:1000::/home/analyst:/bin/bash | GECOS 필드가 비어 있음(::) — 정상, 설명 없음 |
| 각 필드 분해 출력 | 2번이 x → 해시는 shadow에 있음 |
-rw-r--r-- root root /etc/passwd | 644. 누구나 읽기, root만 쓰기 |
UID 0 계정: root | UID 0이 root 하나뿐 → 정상 |
| 비정상 passwd 필드 출력 없음 | 모든 계정의 2번 필드가 x/*/! → 정상 |
UID 0 계정: root만 나온 것이 이번 점검의 핵심 결과다. 만약 여기에 toor, admin 같은 계정이 추가로 나온다면 백도어 root 계정 이다.
| 이상 신호 | 위험 | 확인 |
|---|---|---|
| UID 0 계정 2개 이상 | 백도어 root | awk -F: '$3==0' |
| 2번 필드 빈 값 | 비밀번호 없이 로그인 | awk -F: '$2==""' |
| 2번 필드에 해시 직접 | shadow 미사용(구식) | awk -F: 'length($2)>1 && $2!="x"' |
| 서비스 계정에 로그인 셸 | 탈취 시 셸 | 7번 필드 점검 |
| GECOS에 민감정보 | 정보 노출 | 실명·전화번호 등 지양 |
과장 금지: 로그인 불가 셸(nologin)을 가진 서비스 계정이 많은 것은 지극히 정상이다. 진짜 위험은 UID 0 중복과 빈 비밀번호 필드다. 이 둘을 우선 점검한다.
[정기 점검] awk -F: '($3==0){print "UID0:",$1} ($2==""){print "빈PW:",$1}' /etc/passwd
getent passwd | awk -F: '$7 ~ /bash|sh$/ && $3<1000 {print "시스템계정 셸:",$1,$7}'
↓
[비교] Baseline 계정 목록과 diff (31편)
↓
[Evidence] /etc/passwd stat(ctime = 마지막 변경), 백업본과 비교
↓
[Timeline] 변경 시각 ± 로 useradd/vipw 로그, sudo 로그(49편) 대조
↓
[Response] 백도어 계정 잠금(passwd -l)·삭제, 침입 경로 조사
| 관점 | 내용 |
|---|---|
| Detection | /etc/passwd 변경을 FIM으로 감시. useradd·vipw 실행을 auditd로 |
| IOC | UID 0 추가 계정, 빈 비밀번호 필드, 서비스 계정 셸 부여 |
| Evidence | 이 파일의 ctime과 백업본 비교로 "무엇이 언제 추가됐는지" 확인 |
| 실수 | 결과 | 예방 |
|---|---|---|
/etc/passwd 직접 편집 중 오타 | 로그인 불가·계정 손상 | vipw(잠금+문법검사) 사용 |
| UID 0 중복 미점검 | 백도어 방치 | 정기 awk '$3==0' |
| GECOS에 민감정보 기입 | 누구나 읽음 | 최소 정보만 |
| nologin 계정을 모두 의심 | 오탐 | UID 0·빈 PW에 집중 |
| passwd 백업 없이 수정 | 복구 곤란 | 변경 전 백업 |
[ ] /etc/passwd 7개 필드를 순서대로 설명할 수 있다
[ ] 2번 필드 x 가 shadow 참조를 뜻함을 안다
[ ] 권한이 644 인 이유를 설명할 수 있다
[ ] UID 0 계정이 root 뿐인지 점검했다
[ ] 빈 비밀번호 필드를 탐색하는 명령을 안다
[ ] vipw 로 안전하게 편집하는 법을 안다
/etc/passwd는 사용자명·x·UID·GID·GECOS·홈·셸 7개 필드다.x가 /etc/shadow를 가리킨다.644 — 누구나 읽고 root만 쓴다. 그래서 해시를 분리했다.nologin 셸은 정상이다. UID 0 중복·빈 PW를 우선 점검한다.vipw로, 변경은 FIM·auditd로 감시한다.다음 글 「33. /etc/shadow 분석」 에서는 비밀번호 해시가 저장되는 /etc/shadow를 다룬다. 해시 알고리즘 식별($6$ = SHA-512), 계정 잠금 상태(!, *), 비밀번호 만료 정책 필드를 실제 출력으로 해석한다.