目前我正在試圖通過一個老蟒蛇CTF挑戰的工作,提供了服務器的腳本,這個想法是正確的數據發送到該服務器,我應該如何解讀這些數據/這些字符串
#!/usr/bin/env python3
# from dis import dis
import socketserver
import types
class RequestHandler(socketserver.BaseRequestHandler):
def handle(self):
self.request.sendall(b'PyDRM Proof of Concept version 0.7\n')
self.request.sendall(
b'Submit the secret password to retrieve the flag:\n')
user_input_bytes = self.request.recv(4096).strip()
user_input = user_input_bytes.decode('utf-8', 'ignore')
if validate_password(user_input):
self.request.sendall(read_flag())
else:
self.request.sendall(b'Invalid password\n')
class RequestServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
pass
def read_flag():
with open('flag.txt', 'rb') as fh:
return fh.read()
def generate_validation_function():
code_obj = types.CodeType(
1,
0,
5,
32,
67,
b'd\x01\x00d\x02\x00d\x03\x00d\x04\x00d\x05\x00d\x06\x00d\x05\x00d\x07'
b'\x00d\x08\x00d\x05\x00d\t\x00d\x08\x00d\n\x00d\x01\x00d\x07\x00d\x07'
b'\x00d\x01\x00d\x0b\x00d\x08\x00d\x07\x00d\x0c\x00d\r\x00d\x0e\x00d'
b'\x08\x00d\x05\x00d\x0f\x00d\x03\x00d\x04\x00d\x05\x00d\x06\x00d\x05'
b'\x00d\x07\x00g \x00}\x01\x00g\x00\x00}\x02\x00x+\x00|\x01\x00D]#\x00'
b'}\x03\x00|\x02\x00j\x00\x00t\x01\x00t\x02\x00|\x03\x00\x83\x01\x00d'
b'\x10\x00\x18\x83\x01\x00\x83\x01\x00\x01qs\x00Wd\x11\x00j\x03\x00|'
b'\x02\x00\x83\x01\x00}\x04\x00|\x00\x00|\x04\x00k\x02\x00r\xb9\x00d'
b'\x12\x00Sd\x13\x00S',
(None, '\x87', '\x9a', '\x92', '\x8e', '\x8b', '\x85', '\x96', '\x81',
'\x95', '\x84', '\x94', '\x8a', '\x83', '\x90', '\x8f', 34, '', True,
False),
('append', 'chr', 'ord', 'join'),
('a', 'b', 'c', 'd', 'e'),
'drm.py',
'validate_password',
5,
b'\x00\x01$\x01$\x01\x1e\x01\x06\x01\r\x01!\x01\x0f\x01\x0c\x01\x04'
b'\x01',
(),
()
)
func_obj = types.FunctionType(code_obj, globals())
return func_obj
def main():
setattr(__import__(__name__), 'validate_password',
generate_validation_function())
server = RequestServer(('0.0.0.0', 8765), RequestHandler)
try:
server.serve_forever()
except (SystemExit, KeyboardInterrupt):
server.shutdown()
server.server_close()
if __name__ == '__main__':
main()
編輯
我明白了,是怎麼回事到如此地步,一個validate_password功能通過使用CODETYPE和函數類型對象創建。我也明白,如果validate_password(user_input)評估爲True,該標誌將被髮送。這意味着返回類型必須是布爾值。 CodeType的文檔以及服務器腳本也顯示validate_password只有一個參數。
我的實際問題
源包含編譯蟒蛇字節碼。例如,b'd\x01\x00d\x02\x00d\x03\x00d\x04\x00d\x05\x00d\x06\x00d\x05\x00d\x07'
。我嘗試了許多方法來解碼/編碼這些字符串以獲取一些有意義的數據,我設法提取的唯一數據是十六進制數據。
如何將此數據轉換爲實際代碼,因此能夠重建validate_password
函數。
我曾嘗試
- 我試圖基本上做這樣的回答表明,但在倒車時,我要麼不理解正確的話,還是這不起作用
binascii。 b2a_hex() - 這是我如何設法將字符串轉換爲十六進制,就像我之前說過的那樣,我不能從這個十六進制產生utf-8數據。
struct.unpack() - 這個方法已經取得了一些成功,但是在validate_password函數的上下文中數據意味着什麼,我只能用這個方法獲得整數。 (除非我誤解)
謝謝你幫助我解決這個問題。沒有必要道歉,很高興有一個有價值的工具仍然保持,通過點成功更新,所以一切都已完成,以保持包最新:) @ das-g提供了豐富的答案,有大量的證據等,但是,這方法基本上自動化了我爲其方法執行的步驟。 – RandomHash
爲了澄清,上述方法奏效。我不會破壞它爲通過這個CTF的其他人。但仔細看看PEP文檔也會給你密碼:) – RandomHash