syurhia 님의 블로그
4. File path traversal, traversal sequences stripped with superfluous URL-decode 본문
4. File path traversal, traversal sequences stripped with superfluous URL-decode
syurhia 2026. 5. 29. 21:20이번에는 상대경로와 절대경로를 전부 막아버리는 코드가 작성되어 있는 상황이다.
이 때, 사용 가능한 방법으로써 URL 인코딩이 있다. 웹서버에 GET으로 요청을 보낼 때 URL인코딩으로 보내면 웹서버에서는 자동으로 URL디코딩을 하게 되어있다. 즉, 인코딩을 한 번 해봤자 어차피 웹서버가 디코딩을 해주기 때문에 한 번 인코딩을 한 것으로는 공격에 성공할 수 없다.
그런데 이번 문제는 좀 특이하긴 하다.
애플리케이션(아마도 Image라는 프로그램)이 Path Traversal시퀀스가 포함된 공격을 차단하는데(검증을 한다는 뜻), 검증이 끝난 후에 URL디코딩을 수행하고 이 값을 토대로 파일을 불러온다고 한다. 이럴 경우에 사용 가능한 공격 방법이다.
애초에 왜 이런 구조로 코드를 짠다는 건지 이해가 좀 어려워서 이 글이 Path Traversal중에서 맨 마지막에 쓰게 되었다.
urldecode()같은 함수를 써서 URL디코딩을 하면 입력받은 값에서 %가 들어간 인코딩된 값만 디코딩을 해주는 것이다. 그래서 몇번이고 반복해도 abc.jpg라는 값은 디코딩되지 않고 가만히 있기 때문에 생각없이 코드를 작성하면 이런 문제가 생길 수 있다고 알려주는 것 같다.
즉, 이번 문제는 이런 걸 의미한다. "공격자가 입력한 내용을 나는 이미 검증해봤는데 검증코드를 통과했으니 아무 문제 없을거야. 그러니 혹시 모를 디코딩 덜 된 값을 받게 되면 이 함수로 풀어서 파일을 불러와야지!" 라는 심리인 것 같은데.. 솔직히 이해가 안 가긴 한다. 한글은 디코딩을 해줘야 하긴 하지만..자동해독이 되서 아무런 상관이 없는데 왜 디코딩을 하는걸까.
아마도 생각을 덜하고 대충 짠 게 아닐까 싶다.
얘기는 이 정도로 하고 문제로 들어가보자.

그림 1과 같은 사이트가 있다. ...그림이 좀 혐오스럽지만 넘어가도록 하자.
일단 여기 어딘가에 취약점이 있을테지만 알 수 없으니 페이지 소스를 보도록 하자.

그림 2와 같이 페이지 소스를 보도록 하자.
빨간 동그라미 친 곳이 Image라는 프로그램을 통해서 웹서버가 10.jpg를 불러주는 것 같다.
한 번 Image라는 프로그램에 filename=10.jpg를 넣어서 실행해보자.

그림 3과 같은 메뚜기 사진이 응답으로서 웹서버가 제공해줬다.
filename에 값을 넣으면 웹서버가 이미지를 제공해주는 것 같다. 파일도 가능할 것이다.
filename = ../../../etc/passwd 를 보내보니 "No Such File"이라는 답이 돌아왔다. 검열당한 것이다.
filename = //etc/passwd를 보내보니 "No Such File"이라는 답이 돌아왔다. 마찬가지로 검열당했다.
filename = ....//....//....//....//etc/passwd를 보내보았다. 마찬가지로 "No Such File"이라는 답변이 돌아왔다.
이번에는 .과 /를 한 번만 인코딩해서 ../../../etc/passwd를 보내보자.
filename = %2e%2e%2f%2e%2e%2f%2e%2e%2fetc%2fpasswd를 보내봤지만 마찬가지로 "No Such File"이라는 응답이 돌아왔다.
이번에는 두 번 인코딩을 해보자. 아마 이번 문제의 핵심이 두 번 인코딩이었으니 아마 될 것이다. 문제 설명에서도 입력값을 실제로 사용하기 전에 한 번 더 URL 디코딩을 수행한다고 했으니..

그림 4를 보면 이미지적으로는 깨진 파일이 오긴 했지만 정말 그런지는 확인을 해봐야 한다. 그래도 무언가 온 것에 감사..
서버에서 온 Response를 한 번 살펴보도록 하자.

그림 5를 보아하니 /etc/passwd가 맞다.
확인 완료.
끝!
'보안관련 > PortSwigger' 카테고리의 다른 글
| 6. File path traversal, validation of file extension with null byte bypass (0) | 2026.05.29 |
|---|---|
| 5. File path traversal, validation of start of path (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 |
| 1. File path traversal, simple case (0) | 2026.05.29 |