파일 · 권한 · 사용자 관리 20 / 50 · Part 2. Linux 파일 종류와 속성
실습 환경: Rocky Linux 9.8 · Ubuntu 24.04.5 (Docker 격리 컨테이너, 테스트 계정 analyst)
기초편 연계: 「리눅스 시스템 기초」 30. Linux 명령어를 활용한 보안 점검

1. 들어가며

Part 2의 마지막 글이다. 지금까지 파일의 종류·속성·시간·형식·은닉을 다뤘다. 이제 마지막 질문은 이것이다.

이 파일이 원래 그 파일이 맞는가? 누군가 내용을 바꾸지 않았는가?

두 가지 방법이 있다. 첫째, 임의 파일에 대해 해시(sha256sum) 로 이전 값과 비교한다. 둘째, 시스템 파일이라면 패키지 관리자의 검증 기능 으로 배포판이 설치한 원본과 비교한다. 이번 글에서는 실제로 파일을 변조한 뒤 두 방법으로 탐지해 본다. Rocky는 rpm -V, Ubuntu는 dpkg --verify와 debsums를 사용한다.


2. 핵심 개념

2-1. 해시 기반 검증

명령용도
sha256sum FILE파일의 SHA-256 해시 계산
sha256sum FILE > SHA256SUMS기준값 저장
sha256sum -c SHA256SUMS저장된 기준값과 현재 파일 비교

내용이 1비트라도 바뀌면 해시가 완전히 달라진다. md5는 충돌 공격이 알려져 무결성 검증용으로는 sha256 이상 을 쓴다.

2-2. 패키지 검증

배포판파일→패키지검증
Rocky/RHELrpm -qf FILErpm -V 패키지, 전체는 rpm -Va
Ubuntu/Debiandpkg -S FILEdpkg --verify 패키지, debsums

패키지 관리자는 설치 시점의 파일 해시·권한·크기를 데이터베이스에 저장해 둔다. 검증은 현재 파일을 이 기준값과 비교하는 것이다.

2-3. rpm -V 출력 코드

rpm -V는 변경된 항목만 8자리 코드로 표시한다.

문자위치 의미문자위치 의미
S크기(Size)U소유자(User)
M권한/종류(Mode)G그룹(Group)
5내용 해시(MD5)Tmtime
D장치 번호P능력(capabilities)
L심볼릭 링크.변화 없음

맨 끝의 c는 설정 파일(config), d는 문서 파일을 뜻한다.


3. 동작 원리

파일 무결성 검증 — 해시와 패키지 검증

무결성 검증의 원리는 "현재 값 vs 신뢰할 수 있는 기준값" 비교다. 여기서 가장 중요한 것은 기준값을 어디에 두느냐 다.

  • rpm -V의 기준값은 로컬 rpm 데이터베이스(/var/lib/rpm)에 있다.
  • dpkg --verify의 기준값은 /var/lib/dpkg/info/*.md5sums에 있다.

root 권한을 얻은 공격자는 파일을 바꾸면서 이 기준값도 함께 조작 할 수 있다. 그러면 검증이 통과되어 버린다. 그래서 실무에서는 기준값을 오프라인·원격 에 별도로 보관하고, AIDE 같은 FIM(파일 무결성 모니터링) 도구로 별도 관리 DB를 둔다.


4. 명령어 실습

root 권한으로 시스템 파일을 일부러 변조하는 실습이다. 반드시 격리된 테스트 컨테이너에서만 진행한다.

# 1) 해시 기반 무결성 (임의 파일)
cd /root/lab20
echo "backup-v1" > data.tar && sha256sum data.tar > SHA256SUMS && cat SHA256SUMS
sha256sum -c SHA256SUMS
echo "tampered" >> data.tar && sha256sum -c SHA256SUMS      # 변조 후 검증 실패

# 2) 파일 → 패키지 확인
# Rocky
rpm -qf /usr/bin/ls /usr/bin/passwd /etc/login.defs /usr/bin/chage
# Ubuntu
dpkg -S /usr/bin/ls /usr/bin/passwd

# 3) 정상 상태 검증
# Rocky
rpm -V coreutils shadow-utils ; echo "rpm -V exit=$?"
# Ubuntu
dpkg --verify coreutils passwd login | grep -v ' /usr/share/'

# 4) 시스템 파일 변조 후 재검증
# Rocky
echo "# test" >> /etc/login.defs && printf '\x00' >> /usr/bin/chage && rpm -V shadow-utils
# Ubuntu
echo "# test" >> /etc/login.defs && printf '\x00' >> /usr/bin/chage
dpkg --verify passwd login | grep -v ' /usr/share/'
debsums -as passwd login

5. 실행 결과

Rocky Linux 9.8 — rpm -V

실제 실행 결과 — Rocky Linux 9.8 · root@rocky9-lab — sha256sum 과 rpm -V

Ubuntu 24.04.5 — dpkg --verify / debsums

실제 실행 결과 — Ubuntu 24.04.5 · root@ubuntu-lab — dpkg --verify 와 debsums

텍스트 원본(실제 출력) — Rocky:

[root@rocky9-lab ~]# mkdir -p /root/lab20 && cd /root/lab20
[root@rocky9-lab lab20]# echo "backup-v1" > data.tar && sha256sum data.tar > SHA256SUMS && cat SHA256SUMS
ca307569980dfb082d0eec06ae14123a7ae45c5df0a10d692d291acf586fbe30  data.tar
[root@rocky9-lab lab20]# sha256sum -c SHA256SUMS
data.tar: OK
[root@rocky9-lab lab20]# echo "tampered" >> data.tar && sha256sum -c SHA256SUMS
data.tar: FAILED
sha256sum: WARNING: 1 computed checksum did NOT match
[root@rocky9-lab lab20]# md5sum /usr/bin/ls ; sha256sum /usr/bin/ls
f0d1d5014bbf29cbc00971fa22124331  /usr/bin/ls
86d43a5e35c1571677367b53507e88927bf90e5030df39f701a2e99fac492598  /usr/bin/ls
[root@rocky9-lab lab20]# rpm -qf /usr/bin/ls /usr/bin/passwd /etc/login.defs /usr/bin/chage
coreutils-8.32-41.el9_8.1.x86_64
passwd-0.80-12.el9.x86_64
shadow-utils-4.9-16.el9.x86_64
shadow-utils-4.9-16.el9.x86_64
[root@rocky9-lab lab20]# rpm -V coreutils shadow-utils ; echo "rpm -V exit=$?"
rpm -V exit=0
[root@rocky9-lab lab20]# echo "# test" >> /etc/login.defs && printf '\x00' >> /usr/bin/chage && rpm -V shadow-utils
S.5....T.  c /etc/login.defs
S.5....T.    /usr/bin/chage

텍스트 원본(실제 출력) — Ubuntu:

root@ubuntu-lab:~# mkdir -p /root/lab20 && cd /root/lab20
root@ubuntu-lab:~/lab20# echo "backup-v1" > data.tar && sha256sum data.tar > SHA256SUMS && cat SHA256SUMS
ca307569980dfb082d0eec06ae14123a7ae45c5df0a10d692d291acf586fbe30  data.tar
root@ubuntu-lab:~/lab20# sha256sum -c SHA256SUMS
data.tar: OK
root@ubuntu-lab:~/lab20# echo "tampered" >> data.tar && sha256sum -c SHA256SUMS
data.tar: FAILED
sha256sum: WARNING: 1 computed checksum did NOT match
root@ubuntu-lab:~/lab20# md5sum /usr/bin/ls ; sha256sum /usr/bin/ls
4b49876e854ddf224deeb12358401d9e  /usr/bin/ls
2726eb35864608ff34969fbf45ef4afcbba95eefed5ce5653c9c0124c4cd26cf  /usr/bin/ls
root@ubuntu-lab:~/lab20# dpkg -S /usr/bin/ls /usr/bin/passwd
coreutils: /usr/bin/ls
passwd: /usr/bin/passwd
root@ubuntu-lab:~/lab20# dpkg --verify coreutils passwd login | grep -v ' /usr/share/' ; echo "dpkg --verify exit=${PIPESTATUS[0]}"
dpkg --verify exit=0
root@ubuntu-lab:~/lab20# dpkg -S /etc/login.defs /usr/bin/chage
login: /etc/login.defs
passwd: /usr/bin/chage
root@ubuntu-lab:~/lab20# echo "# test" >> /etc/login.defs && printf '\x00' >> /usr/bin/chage && dpkg --verify passwd login | grep -v ' /usr/share/'
??5??????   /usr/bin/chage
??5?????? c /etc/login.defs
root@ubuntu-lab:~/lab20# debsums -as passwd login
debsums: changed file /usr/bin/chage (from passwd package)
debsums: changed file /etc/login.defs (from login package)

6. 결과 해석

출력해석
data.tar: OK → data.tar: FAILED내용을 추가하자 해시 불일치. sha256sum -c가 변조를 탐지
Rocky rpm -V coreutils shadow-utils 결과 없음 (exit=0)변조 전에는 출력이 없다 = 모두 정상
rpm -qf /usr/bin/chage → shadow-utilschage는 shadow-utils 패키지 소속
Rocky 변조 후 S.5....T. c /etc/login.defsS(크기) 5(해시) T(시간) 변경, c는 설정 파일
S.5....T. /usr/bin/chage바이너리 가 변경됨. 설정 파일이 아닌데 해시가 바뀐 것은 강한 이상 신호
Ubuntu dpkg --verify (변조 전) 출력 없음/usr/share 문서 누락 항목을 필터링하면 실제 변경은 없음
Ubuntu 변조 후 ??5?????? /usr/bin/chagedpkg도 5번째 자리(md5=내용)가 바뀐 것을 표시. ?는 검증 항목이 아니거나 확인 불가
debsums: changed file /usr/bin/chagedebsums는 변경된 파일을 사람이 읽기 쉽게 출력

두 배포판 모두 내용 해시(5번째 자리) 에서 변조를 잡아냈다. 크기(S)와 시간(T)은 조작으로 되돌릴 수 있지만, 내용 해시는 내용을 원본으로 되돌리지 않는 한 일치시킬 수 없다.

참고: Ubuntu의 dpkg --verify는 컨테이너 이미지에서 문서·man 페이지가 제거되어 missing /usr/share/...가 많이 나온다. 실제 바이너리 변조와 구분하기 위해 grep -v ' /usr/share/'로 필터링했다. 일반 서버에서는 이런 누락이 없다.


7. 보안 관점

시나리오탐지주의
시스템 바이너리 백도어(트로이목마)rpm -Va/debsums의 5(해시) 변경설정 파일(c)의 변경은 정상 편집일 수 있음
SUID 바이너리 교체해시 + 권한(M) 변경47편과 연계
라이브러리 변조 (.so)패키지 검증실행 중 프로세스는 재시작 필요
검증 우회기준값(rpm DB) 조작기준값을 오프라인 보관

핵심 원칙 두 가지.

  1. 기준값의 신뢰성: 로컬 검증은 root 공격자가 우회할 수 있다. 초기 설치 직후의 해시를 원격/오프라인 에 저장하고, AIDE 같은 FIM으로 별도 DB를 관리한다.
  2. 설정 파일과 바이너리 구분: c 표시가 있는 파일(/etc/*)은 관리자가 정상적으로 편집해도 변경으로 표시된다. 바이너리 파일의 해시 변경 이 훨씬 강한 침해 신호다.

8. 보안관제 관점

[정기 점검]  rpm -Va 2>/dev/null | grep -E '^..5' | grep -v ' c '   (Rocky, 내용 변경된 비-설정 파일)
             debsums -c 2>/dev/null                                  (Ubuntu, 변경 파일만)
     ↓
[비교]       결과를 오프라인 기준값·이전 스냅샷과 대조
     ↓
[Evidence]   변경 파일: stat(ctime) + sha256sum → 위협 인텔 조회
     ↓
[Timeline]   ctime 을 사고 시각과 대조, 같은 시각 sudo/su 로그(49편)
     ↓
[Response]   패키지 재설치(dnf reinstall / apt install --reinstall), 침입 경로 조사
관점내용
FIMAIDE·Tripwire·Wazuh 등이 기준 DB와 비교해 변경을 탐지한다. DB는 읽기 전용 매체·원격에 보관
Baseline배포판·버전별로 주요 바이너리 해시를 관리 (같은 이름도 버전마다 다름, 12편)
복구변조 확인 시 dnf reinstall <pkg> / apt install --reinstall <pkg>로 원본 복원 후 침입 경로부터 차단
한계 인식로컬 검증만으로는 정교한 공격을 놓칠 수 있다. 원격 로그·네트워크 증거와 결합

9. 실무에서 자주 발생하는 실수

실수결과예방
md5로만 검증충돌 위조 가능sha256 이상
로컬 rpm DB만 신뢰root 공격자가 기준값 조작기준값 오프라인 보관, FIM
설정 파일 변경을 침해로 오판오탐 다수c 표시·바이너리 여부 구분
검증 통과 = 100% 안전으로 판단새 파일·미등록 파일은 검증 대상 아님신규 파일은 별도 탐지
배포판 공통 해시 기준 사용버전 차이로 오탐버전별 기준값

10. 실습 체크리스트

[ ] sha256sum -c 로 변조를 탐지했다
[ ] rpm -qf / dpkg -S 로 파일의 소속 패키지를 확인했다
[ ] 정상 상태에서 rpm -V / dpkg --verify 가 조용한 것을 확인했다
[ ] 시스템 파일 변조 후 5(해시) 자리가 바뀌는 것을 확인했다
[ ] 설정 파일(c)과 바이너리 변경을 구분했다
[ ] 기준값을 오프라인에 둬야 하는 이유를 설명할 수 있다

11. 핵심 정리

  • 무결성 검증은 "현재 값 vs 신뢰할 수 있는 기준값" 비교다.
  • 임의 파일은 sha256sum -c, 시스템 파일은 rpm -V(Rocky) / dpkg --verify·debsums(Ubuntu).
  • 가장 중요한 항목은 내용 해시(rpm -V의 5번째 자리). 크기·시간은 조작 가능하다.
  • 설정 파일(c)의 변경은 정상 편집일 수 있다. 바이너리 해시 변경 이 강한 침해 신호다.
  • 로컬 기준값은 root 공격자가 조작할 수 있으므로 오프라인·원격 보관 + FIM 을 병행한다.
  • 같은 이름의 시스템 파일도 배포판·버전마다 해시가 다르다.

Part 2 정리 — 11~20편에서 파일 종류(7가지), ls -l 해석, inode, 링크, 타임스탬프, stat, 확장자와 형식, Magic Number, 숨김·위장, 무결성 검증까지 파일의 속성 전체 를 다뤘다. Part 3부터는 이 속성 중 권한 을 깊게 파고든다.


12. 다음 편 예고

Part 3 「Linux 파일 권한」을 시작한다. 다음 글 「21. Linux 파일 권한의 기본 구조」 에서는 rwx와 소유자·그룹·기타 3주체, 커널의 권한 검사 순서(처음 일치하는 한 칸만 적용), 그리고 root의 예외를 정리한다.


참고 자료


시리즈 이동

profile
코드에 숨겨진 위협을 읽고 AI로 보안의 미래를 설계합니다. 프론트엔드 개발 경험을 자산 삼아 더 견고하고 지능적인 보안 운영 시스템을 구축해 나가는 과정을 기록합니다

0개의 댓글