파일 · 권한 · 사용자 관리 04 / 50 · Part 1. Linux 파일 관리 기초
실습 환경: Rocky Linux 9.8 · Ubuntu 24.04.5 (Docker 격리 컨테이너, 테스트 계정 analyst)
기초편 연계: 「리눅스 시스템 기초」 12. 절대경로와 상대경로

1. 들어가며

경로는 Linux에서 파일을 가리키는 주소다. 명령어 대부분이 경로를 인자로 받기 때문에 너무 익숙해서 가볍게 넘기기 쉽지만, 보안 관점에서 경로는 두 가지 공격과 직접 연결된다.

  1. 경로 조작 (Path Traversal) — ../../../etc/passwd처럼 ..을 이용해 허용된 디렉터리 밖의 파일에 접근
  2. 명령어 하이재킹 (PATH Hijacking) — PATH 탐색 순서를 이용해 정상 명령 대신 가짜 명령을 실행

이번 글에서는 절대경로·상대경로·특수 기호가 커널과 쉘 중 누가, 어떻게 해석하는지 를 정리하고, 두 공격의 원리를 테스트 계정으로 재현한다.


2. 핵심 개념

2-1. 절대경로와 상대경로

구분형태기준점예
절대경로/로 시작루트 디렉터리/etc/ssh/sshd_config
상대경로/ 이외로 시작프로세스의 현재 작업 디렉터리(cwd)conf/app.yml, ../logs

같은 상대경로라도 어느 디렉터리에서 실행했는지 에 따라 전혀 다른 파일을 가리킨다. 그래서 cron·systemd·스크립트처럼 실행 위치가 보장되지 않는 곳에서는 절대경로를 쓰는 것이 원칙이다.

2-2. 특수 기호

기호의미해석 주체
.현재 디렉터리커널 (실제 디렉터리 엔트리)
..상위 디렉터리커널 (실제 디렉터리 엔트리, /의 ..은 / 자신)
~현재 사용자의 홈 ($HOME)쉘
~user해당 사용자의 홈쉘 (/etc/passwd 조회)
- (cd -)직전 디렉터리 ($OLDPWD)쉘

~는 커널이 모르는 기호다. 그래서 C 프로그램이나 설정 파일에 ~/.ssh라고 쓰면 동작하지 않을 수 있다. 쉘이 먼저 /home/analyst/.ssh로 바꿔 준 것이다.

2-3. PATH 환경변수

명령어를 이름만으로 실행하면(ls) 쉘은 PATH에 나열된 디렉터리를 왼쪽부터 순서대로 검색해 처음 발견한 실행 파일을 실행한다.


3. 동작 원리

경로 해석과 PATH 탐색 순서

3-1. 커널의 경로 해석 (path walk)

커널은 경로를 / 단위로 나누어 한 칸씩 따라간다. 각 단계에서 해당 디렉터리의 x(통과) 권한 을 검사한다. 그래서 /home/analyst/secret/a.txt를 읽으려면 a.txt의 r 권한만이 아니라 /, /home, /home/analyst, /home/analyst/secret 모두에 x가 있어야 한다 (22편).

..은 문자열 처리가 아니라 디렉터리 안의 실제 엔트리 다. 따라서 /var/www/html/../../../etc/passwd는 커널 입장에서 완전히 정상적인 경로이며 /etc/passwd로 해석된다. 웹 애플리케이션이 사용자 입력을 경로에 그대로 붙이면 이 동작 때문에 Path Traversal이 발생한다.

3-2. 쉘의 명령 탐색

bash는 명령 이름을 다음 순서로 찾는다.

  1. alias → 2. 함수 → 3. builtin(cd, echo) → 4. hash 캐시 → 5. PATH 순서 검색

PATH에 .(현재 디렉터리)나 누구나 쓸 수 있는 디렉터리가 앞쪽에 있으면, 공격자가 그 위치에 ls, sudo, ps 같은 이름의 파일을 두는 것만으로 정상 명령 대신 실행된다. 특히 root가 그 디렉터리에서 명령을 실행하면 가짜 명령이 root 권한으로 실행된다.


4. 명령어 실습

# 1) 절대경로 / 상대경로
mkdir -p ~/lab04/app/conf && cd ~/lab04/app/conf
pwd
ls ../../                         # 두 단계 위
cd ~/lab04 && ls -l ./app/conf/../conf

# 2) .. 이 정규화되는 결과 (Path Traversal 원리)
realpath -m /var/www/html/../../../etc/passwd

# 3) PATH 와 명령 탐색
echo $PATH
type ls cd passwd

# 4) PATH 하이재킹 재현 (테스트 디렉터리에서만)
printf '#!/bin/bash\necho "[!] fake ls executed as $(id -un)"\n' > ls && chmod +x ls
export PATH=.:$PATH               # 위험: 현재 디렉터리를 PATH 맨 앞에 추가
ls                                # 진짜 ls 대신 가짜가 실행됨
export PATH=${PATH#.:}            # 원복
type ls
명령의미
realpath -m경로를 정규화해 최종 절대경로 출력 (-m: 파일이 없어도 계산)
type명령이 alias·builtin·파일 중 무엇이고 어디 있는지 표시
${PATH#.:}PATH 문자열 앞의 .: 제거 (bash 매개변수 확장)

하이재킹 재현은 테스트 계정의 테스트 디렉터리 에서만, 현재 쉘 안에서만 진행한다. ~/.bashrc나 /etc/profile에 .을 추가하지 않는다.


5. 실행 결과

실제 실행 결과 — Rocky Linux 9.8 · analyst@rocky9-lab — 경로 해석과 PATH 하이재킹

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

[analyst@rocky9-lab ~]$ mkdir -p ~/lab04/app/conf && cd ~/lab04/app/conf
[analyst@rocky9-lab conf]$ pwd
/home/analyst/lab04/app/conf
[analyst@rocky9-lab conf]$ ls ../../
app
[analyst@rocky9-lab conf]$ cd ~/lab04 && ls -l ./app/conf/../conf
total 0
[analyst@rocky9-lab lab04]$ realpath -m /var/www/html/../../../etc/passwd
/etc/passwd
[analyst@rocky9-lab lab04]$ echo $PATH
/home/analyst/.local/bin:/home/analyst/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin
[analyst@rocky9-lab lab04]$ type ls cd passwd
ls is hashed (/usr/bin/ls)
cd is a shell builtin
passwd is /usr/bin/passwd
[analyst@rocky9-lab lab04]$ printf '#!/bin/bash\necho "[!] fake ls executed as $(id -un)"\n' > ls && chmod +x ls
[analyst@rocky9-lab lab04]$ export PATH=.:$PATH
[analyst@rocky9-lab lab04]$ ls
[!] fake ls executed as analyst
[analyst@rocky9-lab lab04]$ export PATH=${PATH#.:}
[analyst@rocky9-lab lab04]$ type ls
ls is /usr/bin/ls

6. 결과 해석

출력해석
/home/analyst/lab04/app/confpwd는 항상 절대경로로 현재 위치를 보여 준다
ls ../../ → appconf에서 두 단계 위(lab04)의 내용
./app/conf/../conf → total 0.과 ..이 섞여도 결국 같은 conf 디렉터리 (빈 디렉터리)
realpath → /etc/passwd/var/www/html에서 .. 세 번이면 루트. 웹 루트 밖으로 탈출 한다
PATH 앞쪽 /home/analyst/.local/bin:/home/analyst/binRocky의 기본 사용자 PATH에는 사용자 홈 아래 디렉터리가 시스템 경로보다 앞 에 있다
ls is hashed (/usr/bin/ls)이전에 찾은 경로를 캐시에서 사용
cd is a shell builtincd는 파일이 아니라 쉘 내부 명령 (06편)
[!] fake ls executed as analystPATH 맨 앞의 .에 있던 가짜 ls가 실행됨 → 하이재킹 성공
원복 후 ls is /usr/bin/lsPATH에서 . 제거 후 정상 명령으로 돌아옴

두 번째 type ls 결과가 hashed가 아닌 이유는 PATH를 바꾸면 bash가 hash 캐시를 비우기 때문이다.

PATH 해석에서 한 가지 더 볼 점이 있다. ~/.local/bin과 ~/bin이 /usr/bin보다 앞에 있으므로, 사용자 계정을 탈취한 공격자는 ~/bin/sudo 같은 가짜 명령을 만들어 그 사용자가 입력하는 sudo 비밀번호를 가로챌 수 있다. 계정 탈취 후 권한 상승으로 이어지는 실제 기법이다.


7. 보안 관점

공격원리방어
Path Traversal입력값의 ..이 허용 디렉터리 밖으로 이동입력 검증, 정규화 후 기준 디렉터리 포함 여부 확인, chroot/컨테이너 격리
PATH에 . 포함현재 디렉터리의 동명 파일이 먼저 실행PATH에 .·상대경로·빈 항목(::) 금지
사용자 bin 우선~/bin/sudo로 비밀번호 탈취계정 탈취 대응 시 ~/bin, ~/.local/bin, alias 점검
스크립트의 상대 명령 호출root cron 스크립트가 tar만 호출 → PATH 조작스크립트에서 절대경로 사용, 스크립트 상단에서 PATH 고정
sudo의 PATHsudo 실행 시 PATH가 바뀔 수 있음sudoers secure_path 사용 (42편)

realpath 결과가 /etc/passwd라고 해서 곧바로 취약점은 아니다. 실제로 그 경로를 읽는 프로그램이 사용자 입력을 검증 없이 경로로 쓰는지 가 취약점 여부를 결정한다.


8. 보안관제 관점

탐지 대상데이터 소스탐지 아이디어
Path Traversal 시도웹 액세스 로그../, ..%2f, %2e%2e/, ..\ 패턴 + 응답 코드 200
PATH 조작쉘 히스토리, auditd execveexport PATH=., PATH=/tmp: 형태
사용자 bin에 시스템 명령명 생성파일 무결성 모니터링~/bin/sudo, ~/.local/bin/ls 생성
root가 사용자 쓰기 경로의 파일 실행auditd execve + euid=0실행 파일 경로가 /home, /tmp 아래
[Detection]   웹 로그: GET /download?file=../../../../etc/passwd  200  1.9KB
     ↓
[판단]        200 + 응답 크기가 passwd 파일 크기와 유사 → 실제 노출 가능성
     ↓
[Evidence]    같은 IP의 다른 요청 (/etc/shadow, .ssh/id_rsa 시도 여부)
     ↓
[Response]    취약 파라미터 차단, 노출된 파일 범위 확인, 계정 비밀번호·키 교체 검토

탐지 시에는 시도(4xx)와 성공 가능성(200 + 응답 크기) 을 구분한다. ../ 문자열이 로그에 있다는 것만으로 침해가 확정되지 않는다.


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

실수결과예방
cron 스크립트에서 상대경로 사용cron의 cwd는 홈 디렉터리 → 파일을 못 찾음스크립트 안에서 절대경로
편하려고 PATH에 . 추가하이재킹 위험./script.sh처럼 명시적으로 실행
~가 어디서나 동작한다고 생각설정 파일·프로그램에서 실패$HOME 또는 절대경로 사용
문자열로 ..만 제거해 검증....// 같은 우회 가능realpath로 정규화한 뒤 기준 경로 비교
rm -rf $DIR/에서 변수가 빈 값rm -rf /로 확장${DIR:?} 사용, 실행 전 echo로 확인

10. 실습 체크리스트

[ ] 절대경로와 상대경로의 기준점 차이를 설명할 수 있다
[ ] . 과 .. 은 커널, ~ 은 쉘이 해석한다는 것을 이해했다
[ ] realpath 로 Path Traversal 결과 경로를 확인했다
[ ] type 으로 명령의 실제 위치를 확인했다
[ ] PATH 앞의 . 이 하이재킹을 일으키는 것을 테스트 디렉터리에서 재현했다
[ ] PATH 를 원래대로 복구했다

11. 핵심 정리

  • 절대경로는 /부터, 상대경로는 현재 작업 디렉터리 부터 해석된다.
  • .과 ..은 실제 디렉터리 엔트리이고, ~와 cd -는 쉘이 치환하는 기호다.
  • 커널은 경로의 각 단계마다 디렉터리 x 권한을 검사한다.
  • .. 정규화 때문에 사용자 입력을 경로에 그대로 붙이면 Path Traversal 이 발생한다.
  • 쉘은 PATH를 왼쪽부터 검색하므로 앞쪽에 쓰기 가능한 경로가 있으면 PATH Hijacking 이 가능하다.
  • 자동 실행 스크립트는 절대경로와 고정된 PATH를 사용한다.
  • 로그의 ../ 문자열은 "시도"이고, 성공 여부는 응답 코드·크기로 판단한다.

12. 다음 편 예고

다음 글 「05. pwd와 ls로 파일 구조 확인」 에서는 pwd의 논리 경로와 물리 경로 차이, 그리고 ls의 주요 옵션(-l, -a, -h, -i, -d, -t)을 분석가가 실제로 쓰는 조합 중심으로 정리한다.


참고 자료


시리즈 이동

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

0개의 댓글