path traversal 공격은 들어보신 분도 계실 겁니다. spring boot로 만든 간단한 프로그램을 가지고 테스트를 해 보도록 하겠습니다.

 


 먼저, 프로젝트 구조는 다음과 같습니다. application.properties를 보겠습니다.

 

 

 server의 포트를 7778로 설정하였습니다. 다음에, default controller를 보겠습니다.

 

 

 뭔가 복잡해 보이는데요. path가 /data입니다. 이것은, 파라미터로 file name을 보내면, 해당 파일에 있는 내용을 출력해서 응답합니다. 별 문제는 없어 보입니다. 저는 클라이언트가 보내준 값만 믿겠습니다.

 

 

 저는 우분투를 이용하므로, 방화벽을 설정해 줄 건데요. 포트를 7778을 쓰므로, 172.30.1.0/24에 대해서만 허용해 줍니다. 왜 그런지는 밑에서 계속 언급하도록 하겠습니다.

 

 

 ufw numbered를 입력해 봅시다. 그러면, 포트 7778에 대한 규칙이 추가되었음을 알 수 있습니다.

 


 이 프로그램을 jar 파일로 떨궈서, 서버에 올렸습니다.

 

 

 서버에 있는 jar 파일의 위치는 jo_test 밑에 DirectoryPath 밑에 있는데요. 여기에 보시면, jar 파일과 1.txt가 있습니다. 1.txt를 보면, chogahui, run이 있습니다.

 

 

 postman으로 request를 날려보면, chogahui run이 정상적으로 출력됨을 알 수 있어요. 그런데, 악의적인 사용자는 다음과 같이 쿼리를 입력할 수도 있습니다. "../"은 매우 중요한데요. 이것은 현재 있는 위치로부터 상위 디렉토리를 의미합니다. 예를 들어서, 현재 내가 있는 절대 경로가 /home/cho/jo_test라고 해 보겠습니다.

 

 

 여기서 "../"가 들어오면 상위 디렉토리의 의미인데요. jo_test의 상위 디렉토리는 cho입니다.

 

 

 그러면, jo_test의 상위의 상위의 상위의 ... 상위 디렉토리는 결국 /로 오게 될 겁니다. 이걸 이용해서 공격을 해 보도록 하겠습니다. 먼저, /etc/passwd는 리눅스 계정 정보를 알려줍니다. shadow는 실제 암호를 가지고 있어요. 그래서, passwd나 shadow는 꽤 중요한 것 중 하나입니다.

 

 

 그런데, 꽤 쉽게 볼 수 있음을 알 수 있어요. 다음에 볼 것은 /var/log 밑에 있는 auth.log입니다. 이것은 인증 로그와 관련된 파일입니다. ssh로 접속했을 때 성공했다. 실패 했다 등이 여기에 저장이 됩니다.

 

 

 이것도, 클라이언트가 볼 수 있었습니다. 꽤 민감한 정보 중 하나입니다. 저는 이 2개 파일을 예로 들었지만, 생각보다 더 많은 정보를 얻어낼 수 있습니다. 당장 cheat sheet만 쳐도 이렇게 중요한 파일이 많았었나 싶을 정도로, 함부로 공개되면 안 되는 것이 매우 많음을 알 수 있습니다.

 

 


 고려할 수 있는 방법 중 하나는, 입력값을 필터링 하는 것입니다. 위 예제는, /과 \을 빈 문자열로 치환해 버립니다.

 

 

 이 경우에는 ................etcpasswd로 치환이 됩니다. 한 가지 다른 점은 /etc/passwd에 있던 내용이 출력되지 않았다는 것입니다. 이 글에서는 사용자의 입력을 믿지 말라는 것과, path traversal이 무슨 공격인지 정도만 알고 넘어가셔도 좋을 듯 싶습니다.