리눅스 시스템 기초 · 입문편 — 본문의 "N편"은 입문 과정 번호다. 번호별 글과 전체 250편 구성은 통합 로드맵에서 확인할 수 있다.
리눅스 시스템 기초 13 / 50 · Part 2. 파일·명령어·권한
실습 환경: Rocky Linux 9 (10.0.0.200)
이전 글: 12. 절대경로와 상대경로
🔗 심화 시리즈 — 「파일 · 권한 · 사용자 관리」
이 주제를 더 깊게 다룬 실무형 보안 시리즈: 11. Linux 파일 종류 7가지 · 17. 파일 확장자와 실제 파일 형식 · 18. file 명령어와 Magic Number
1편에서 "Linux는 거의 모든 것을 파일로 다룬다"고 했다. 그런데 이 "파일"에는 여러 종류가 있다. 디스크 장치도, 프로세스 간 통신 통로(소켓, 파이프)도 파일 형태로 존재한다.
또 하나 중요한 사실은 Linux가 확장자로 파일 형식을 판단하지 않는다 는 점이다. thumb.jpg라는 이름이어도 실행 권한만 있으면 실행 파일로 동작할 수 있다. 공격자가 업로드 필터를 우회하거나 악성 파일을 위장할 때 이 점을 이용한다.
이번 글에서 답할 질문:
file, 매직 넘버)ls -l 첫 글자 | 종류 | 설명 | 예 |
|---|---|---|---|
- | 일반 파일 (regular) | 텍스트, 실행 파일, 이미지 등 데이터 | /etc/passwd, /usr/bin/ls |
d | 디렉터리 | 이름 → inode 목록 | /var/log |
l | 심볼릭 링크 | 다른 경로를 가리킴 | /bin -> usr/bin |
c | 문자 장치 | 바이트 단위 입출력 장치 | /dev/null, /dev/tty1 |
b | 블록 장치 | 블록 단위 저장 장치 | /dev/sda, /dev/nvme0n1 |
s | 소켓 | 프로세스 간 통신 (로컬) | /run/systemd/journal/socket |
p | 이름 있는 파이프 (FIFO) | 한쪽이 쓰고 한쪽이 읽는 통로 | mkfifo로 생성 |
file 명령은 파일 앞부분의 바이트 패턴(매직 넘버)과 내용을 규칙 데이터베이스와 비교해 형식을 판단한다.
| 형식 | 매직 넘버 (16진수) | 문자 |
|---|---|---|
| ELF 실행 파일 | 7f 45 4c 46 | .ELF |
| PNG | 89 50 4e 47 | .PNG |
| JPEG | ff d8 ff | |
| ZIP (jar, docx, apk 포함) | 50 4b 03 04 | PK.. |
| gzip | 1f 8b | |
25 50 44 46 | %PDF | |
| 스크립트 | 23 21 | #! (shebang) |

파일 종류(-, d, l …)는 inode에 저장된 모드 값 의 일부다. stat -c %F로 확인할 수 있다.
실행 여부는 이름이 아니라 두 가지로 결정된다.
execve() 시점에 파일 앞부분을 읽어 실행 가능한 형식(ELF 또는 #! 스크립트) 인가그래서 thumb.jpg라는 이름의 ELF 파일에 실행 권한이 있으면 그대로 실행된다. 반대로 웹 서버는 보통 확장자로 처리 방식을 정하기 때문에, 공격자는 shell.php.jpg처럼 이중 확장자를 쓰거나 이미지 헤더 뒤에 코드를 붙이는 방식으로 업로드 검증을 우회하려 한다.
# 1) 파일 종류 한눈에 보기
ls -l /etc/passwd /var /bin /dev/null /dev/sda 2>/dev/null
ls -l /run/systemd/journal/socket
stat -c '%n → %F' /etc/passwd /var /bin /dev/null
# 2) 파이프 만들어 보기
mkfifo ~/lab13.fifo && ls -l ~/lab13.fifo && rm ~/lab13.fifo
# 3) file 명령과 매직 넘버
file /usr/bin/ls /etc/passwd /usr/share/pixmaps/*.png 2>/dev/null | head
xxd -l 16 /usr/bin/ls
head -c 4 /usr/bin/ls | od -An -tx1
# 4) 확장자 위장 재현 (실습용)
cp /usr/bin/true ~/lab13_thumb.jpg
file ~/lab13_thumb.jpg
~/lab13_thumb.jpg; echo "exit=$?" # 실행됨
rm ~/lab13_thumb.jpg
# 5) 종류별 검색
sudo find /tmp /var/tmp /dev/shm -type s -o -type p 2>/dev/null # 임시 경로의 소켓·파이프
sudo find /dev -type f 2>/dev/null # /dev 안의 일반 파일
sudo find / -xdev \( -type b -o -type c \) ! -path '/dev/*' 2>/dev/null # /dev 밖의 장치 파일
아래 출력은 형식 설명용 예시다.
① stat -c '%n → %F'
/etc/passwd → regular file
/var → directory
/bin → symbolic link
/dev/null → character special file
② file로 업로드 디렉터리 확인
logo.jpg: JPEG image data, JFIF standard 1.01
thumb.jpg: ELF 64-bit LSB pie executable, x86-64, dynamically linked
note.png: PHP script, ASCII text
| 파일 | 판단 |
|---|---|
| logo.jpg | 이름과 형식 일치 — 정상 |
| thumb.jpg | 이미지 이름의 실행 파일 — 위장 |
| note.png | 이미지 이름의 PHP 코드 — 웹셸 가능성 |
③ 위치별 이상 기준
| 위치 | 정상 | 이상 |
|---|---|---|
/dev | 장치 파일(c, b), 디렉터리, 링크 | 일반 파일(-) → 은닉 의심 |
/dev 밖 | 장치 파일 거의 없음 | 장치 파일 → 원시 디스크 접근 우회 의심 |
/tmp | 일반 파일, 일부 소켓(X11 등) | 알 수 없는 소켓·FIFO, ELF 파일 |
| 웹 업로드 폴더 | 이미지·문서 | 스크립트, ELF |
| 기법 | 설명 | 탐지 |
|---|---|---|
| 확장자 위장 | 실행 파일·스크립트를 이미지 이름으로 저장 | file로 형식 확인 |
| 이중 확장자 | shell.php.jpg — 서버 설정에 따라 PHP로 실행 | 파일명 패턴 + 형식 |
| 폴리글랏 파일 | 이미지 헤더 뒤에 코드를 붙여 두 형식 모두 만족 | grep -a '<?php' 등 내용 검사 |
/dev 은닉 | 장치 파일 사이에 일반 파일로 도구 저장 | find /dev -type f |
| FIFO·소켓 통신 | 파이프를 이용해 프로세스 간 명령 전달 | 임시 경로의 p, s 파일 |
| 링크 위장 | history를 /dev/null로 링크 (3편) | -type l 검색 |
UP=/var/www/html/upload
# 이미지 확장자인데 이미지가 아닌 파일
find "$UP" -type f \( -iname '*.jpg' -o -iname '*.png' -o -iname '*.gif' \) \
-exec file {} + | grep -viE 'image data'
# 업로드 폴더 안의 스크립트·실행 파일
find "$UP" -type f -exec file {} + | grep -Ei 'script|ELF|executable'
f=/tmp/.x/kw
file "$f" # 형식
sha256sum "$f" # 해시 → 위협 인텔리전스 조회(VirusTotal 등)
stat "$f" # 소유자, 시각
strings -n 8 "$f" | head -50 # 문자열 (IP, 도메인, 명령어 흔적)
strings는 실행하지 않고 파일 안의 읽을 수 있는 문자열만 뽑는다. 의심 파일은 절대 실행하지 않는다.
[Alert] WAF: 이미지 업로드 요청 본문에 스크립트 패턴
↓
[확인] file upload/note.png → PHP script
↓
[IOC] 파일 해시, 업로드 IP, 업로드 시각, 이후 해당 파일로 온 요청(access_log)
↓
[판단] 업로드 후 GET /upload/note.png?cmd=... 요청 존재 → 웹셸 실행 시도
↓
[대응] 파일 격리(복사 후 권한 제거), 업로드 확장자·형식 검증 강화, 실행 권한 제거
ls -l 첫 글자로 7가지 종류를 구분한다: - d l c b s p.file, xxd, od로 실제 형식을 확인한다. ELF는 7f 45 4c 46로 시작한다./dev 안의 일반 파일, /dev 밖의 장치 파일, 임시 경로의 소켓·FIFO, 업로드 폴더의 스크립트·ELF.file → sha256sum → stat → strings 순으로 확인한다.다음 글 「14. inode와 파일 시스템」 에서는 11편부터 계속 등장한 inode를 자세히 본다. 하드 링크와 심볼릭 링크의 차이, 4가지 타임스탬프(atime·mtime·ctime·btime)의 의미, 그리고 이를 이용해 파일 타임라인을 만드는 방법 을 정리한다.