Dreamhack | proxy-1
Dreamhack proxy-1
본 문제는 Dreamhack을 통해서 풀어 보실 수 있습니다.
해답을 이해하며 생각을 해보면서 풀이 해보시길 바랍니다.
문제 내용
해당 문제에서는 어떠한 취약점을 이용해서 문제 풀이하는지 서술되어 있지 않다.
하지만 Raw Socket Sender 서비스를 보았을 때 소켓 통신을 이용한 문제인 것을 짐작할 수 있다.
app.py
#!/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)
/socket을 봤을 때 파라미터로 전달 받는 것이 host, port, data 세 개가 존재하는 것을 알 수 있고, host, port를 통해 소켓을 연결하고 data를 모두 보내는 서비스임을 짐작할 수 있다.
/admin에서는 요청하는 HOST가 LOCAL이어야 하고 이외에는 헤더와 쿠키의 값을 조작하며 바디에는 userid=admin이 포함되어야 FLAG를 return해주는 것을 알 수 있다.
문제 풀이
Raw Socket Sender (Done)를 들어가보면 예상한대로 3개의 입력 값을 받는 form이 존재하는 것을 확인할 수 있습니다.
HOST는 LOCAL, PORT는 명시되어있는 8000으로 접근할 것이며 DATA는 Raw Socket 통신이라 했으므로 HTTP 헤더, 바디를 구성하여 보내면 될 것으로 예상이 됩니다.
어떠한 메소드를 어느 페이지에 어떠한 HTTP 방식을 사용할 건지에 대한
POST /admin HTTP/1.1
어떤 서버에 보내는지 도메인 네임에 해당하는
Host: host3.dreamhack.games
사용자가 어떤 클라이언트를 이용하여 요청을 보냈는지
User-Agent:Admin Browser
임의의 헤더 값을 위한
DreamhackUser:admin
클라이언트의 쿠키를 설정하는
Cookie:admin=true
컨텐츠 타입과 문자열 인코딩을 알려주는
Content-Type: application/x-www-form-urlencoded
바디에 포함된 메시지의 크기를 바이트 단위로 알려주는(총 12byte이기 때문)
Content-Length: 12
서버의 응답 값을 받을 때 image, text, gif 등 어떤 것을 받을지 컨텐츠 압축 방식은 어떤 것으로 할 지 인코딩 방식을 지정해주는
-
Accept: */* -
Accept-Encoding: gzip, deflate -
Accept-Language: ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7
HTTP 1.0과 HTTP 1.1 차이에서 해당 연결을 지속적으로 할 것인지에 대한
-
Connection: close- 해당 부분은 HTTP 1.1을 주로 사용하면서
keep-alive옵션이 Default가 되지만 의미가 없어지는 추세
- 해당 부분은 HTTP 1.1을 주로 사용하면서
임의의 userid를 바디에 담으며 해당 값을 admin으로 지정
userid=admin
해당 내용을 정리해서 Send하면 응답 값으로 플래그가 넘어오는 것을 확인할 수 있다.