syurhia 님의 블로그
6. File path traversal, validation of file extension with null byte bypass 본문
6. File path traversal, validation of file extension with null byte bypass
syurhia 2026. 5. 29. 21:21이번에는 개발자가 .png로 끝나는 파일명을 유저에게서 입력받았을 때만 검증을 받고 통과가 되는 코드를 짰을 때를 가정한 문제다.
일명 널바이트 취약점인데(구버전 PHP 5.3미만 환경에서 주로 먹혔던 취약점이라고 한다.), %00이라는 널 바이트를 이용한다.
웹서버와 리눅스OS의 차이점에 의해 쓸 수 있는 공격기법인데, 웹서버는 보통 PHP나 Python, Java같은 고급 언어들을 사용한다. 얘네들은 문자열의 길이를 기억하는 방식으로 문자열을 관리한다. 즉, 문자열이 몇 바이트였는지 그 크기를 기억하는 것이다.
리눅스는 C언어로 되어있는데, C언어뿐만 아니라 C++도 포함해서 문자열의 끝을 구분할 때 \0(NULL이다)이라는 특수 문자로 구별한다. 문자열의 크기는 모르고, NULL인지를 확인하는 것으로 끝부분만 알 수 있다.
이 차이점이 굉장히 큰데, 웹서버에서는 /var/www/html/../../../etc/passwd\0.png라는 값을 입력받아도 .png라는 값을 제대로 받았으니 이 페이로드는 문제없이 통과하게 된다. 그런데, 이 페이로드가 파일탐색 함수에 들어가게 되는 순간 문제가 발생한다.
파일탐색 함수는 OS가 관리하고 C언어이기 때문에, /var/www/html/../../../etc/passwd까지만 읽고 뒷 부분은 \0(NULL)이니까 버리게 된다. 그래서 결론적으로는 /etc/passwd가 불러진다.
이런 문제가 있어서, 고급 언어만 공부하는 게 아니라 저급...언어?(뭔가 어감이 좀 이상한데..찾아보니 로우 레벨 언어이니까 이렇게 부르는 게 맞긴 하다.. 굉장히 껄끄럽네) 도 알아두는 게 좋다.
문제를 풀어보자.

그림 1의 사이트에 path traversal취약점이 존재한다고 한다.
이것만으로는 뭐가 문제인지 모르겠으니 페이지 소스를 보자.

그렇다. 그림2를 보면 알 수 있듯이 이미지 태그에서 서버가 image라는 프로그램을 실행시키는 걸 확인할 수 있다.
filename이라는 변수를 쓰고 있으며 22.jpg라는 값을 전달해주는 것도 확인이 가능하다.
직접적으로 실행하는 것 같으니 여기를 찔러보자.

22.jpg라는 값을 주면 그림 3과 같은 이미지가 반환된다.
그러면 filename의 값을 ../../../etc/passwd%00.jpg로 해서 서버에 요청을 보내보자. (사실 png로 했다가 다시 한 건 안 비밀)

그림 4와 같이 요청을 보내니 /etc/passwd라는 파일이 돌아왔다.
/etc/passwd가 맞는지 서버의 응답을 보는 것을 통해 확인해보자.

음. 맞다.
/etc/passwd가 확실하다.
끝
'보안관련 > PortSwigger' 카테고리의 다른 글
| File path traversal 순서 정리 (0) | 2026.05.29 |
|---|---|
| 5. File path traversal, validation of start of path (0) | 2026.05.29 |
| 4. File path traversal, traversal sequences stripped with superfluous URL-decode (0) | 2026.05.29 |
| 3. File path traversal,traversal sequences stripped non-recursively (0) | 2026.05.29 |
| 2. File path traversal,traversal sequences blocked with absolute path bypass (0) | 2026.05.29 |