Study/Web Hacking

[DreamHeck] web-ssrf

얀 짱 2026. 9. 8. 23:43

계속 시도한 문제에만 있다가.. 못 풀어서 째려본 문제임.

아직 burp suite intruder 사용이 익숙하지 않아서 엄청 찾아보면서 했음. 크래딧도 많이 날렸듬..

 

먼저 그냥 주어진대로 검색해봤음.

 

이렇게 나옴.

 

app.py에서 코드를 확인해 본 결과 얻을 수 있었던 건 두 가지!

#!/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] == "/":
            # localhost랑 127.0.0.1을 막아놓은듯 
            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
)
print(local_port)


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)

 

1. localhost랑 127.0.0.1 은 접근이 불가능함

2. 로컬 포트가 랜덤이긴 하다만 범위가 있음

 

1번은 ssrf를 하던 것처럼 127.0.0.1을 10진수로 우회하면 되지 않을까 하여 시도해봤음.

http://2130706433:8000/static/dream.png

 

잘 뜨는 거 같길래 이런 식으로 하면 우회 가능함을 알게됨.

 

비교해보자면 다음과 같음

http://localhost:8000/static/dream.png

 

이제 static/dream.png 말고 flag.txt를 얻기 위한 url로 접근을 해보겠음

http://2130706433:8000/flag.txt

 

생각한대로 잘 안나와서 랜덤 포트를 건들여봐야겠다 싶었음.

 

-> 이때 1500~1800을 브루트포스로 스캔해보고 싶었는데 이러려면 intruder를 써야 했음.. (찾아보니 그렇던데)

 

근데 문제는 내가 익숙하지 않아서 매우 헤맸다는 것! 무튼 그랬음.

 

어찌저찌 진행을 했음.. 이상한 페이로드는 1692였음. 해당 포트로 다시 접근해 보겠음.

 

http://2130706433:1692/flag.txt

 

이건 줄 알았는데 안되는거임! 그래서 일단.. 개발자 도구로 확인을 해봤음.

 

 

의심되는 부분은 여기였는데 src에 해당하는 부분이 base64로 인코딩 되어 있었음. 이걸 디코딩 해봐야겠다고 생각했음.

 

https://www.base64decode.org/ko/

 

Base64 디코딩 및 인코딩 - 온라인

Base64 형식에서 디코딩해보세요. 아니면 다양한 고급 옵션으로 인코딩해보세요. 저희 사이트에는 데이터 변환하기에 사용하기 쉬운 온라인 도구가 있습니다.

www.base64decode.org

 

드디어 플래그를 얻음!!!