SpyderSec Challenge VulnHub Writeup

  1. Service Discovery
  2. Initial Recon
  3. Next Steps
  4. Give us your secrets, Mulder
  5. Conclusion

Yummy - a fresh VulnHub image to play with. This one was created by SpyderSec.

Service Discovery

First things first, I run nmap on the host.

nmap -T4 -A -v 10.200.0.103

Starting Nmap 6.49SVN ( https://nmap.org ) at 2015-09-07 23:16 BST
NSE: Loaded 127 scripts for scanning.
NSE: Script Pre-scanning.
Initiating NSE at 23:16
Completed NSE at 23:16, 0.00s elapsed
Initiating NSE at 23:16
Completed NSE at 23:16, 0.00s elapsed
Initiating Ping Scan at 23:16
Scanning 10.200.0.103 [2 ports]
Completed Ping Scan at 23:16, 0.00s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 23:16
Completed Parallel DNS resolution of 1 host. at 23:16, 0.05s elapsed
Initiating Connect Scan at 23:16
Scanning 10.200.0.103 [1000 ports]
Discovered open port 80/tcp on 10.200.0.103
Completed Connect Scan at 23:16, 4.82s elapsed (1000 total ports)
Initiating Service scan at 23:16
Scanning 1 service on 10.200.0.103
Completed Service scan at 23:16, 6.02s elapsed (1 service on 1 host)
NSE: Script scanning 10.200.0.103.
Initiating NSE at 23:16
Completed NSE at 23:16, 0.19s elapsed
Initiating NSE at 23:16
Completed NSE at 23:16, 0.00s elapsed
Nmap scan report for 10.200.0.103
Host is up (0.00059s latency).
Not shown: 998 filtered ports
PORT   STATE  SERVICE VERSION
22/tcp closed ssh
80/tcp open   http    Apache httpd
|_http-favicon: Unknown favicon MD5: 032CC5C2FD1D6AABD91FC08470E0905C
| http-methods:
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache
|_http-title: SpyderSec | Challenge

NSE: Script Post-scanning.
Initiating NSE at 23:16
Completed NSE at 23:16, 0.00s elapsed
Initiating NSE at 23:16
Completed NSE at 23:16, 0.00s elapsed
Read data files from: /usr/local/bin/../share/nmap
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 11.80 seconds

Port 80 is the only port available to us, so let's start digging.

Initial Recon

Upon visiting the page, we're presented with wecome page.

After inspecting the response headers, I note that there's a Cookie being set, which appears to point to a URL.

/v/81JHPbvyEQ8729161jd6aKQ0N4/

After visiting this URL, we're presented with a 401 error. I add it to my list for later.

There's no robots.txt file – so I take a look at the source.

The next thing I notice is a Base64 encoded GIF background image in an inline stylesheet. I decode this and take a look.

background:url(data:image/gif;base64,R0lGODlhGQAZAKU7ABMREhYUFRcVFhkVFhgWFxoWFxkXGBsXGBoYGRwYGRsZGh0ZGhwaGx4aGx0bHB8bHB4cHSAcHR8dHiEdHiAeHyIeHyEfICMfICIgISQgISMhIiUhIiQiIyYiIyUjJCcjJCYkJSgkJSclJiklJigmJyomJyknKCsnKCooKSwoKSspKi0pKiwqKy4qKy0rLC8rLC4sLTAsLS8tLjEtLjIuLzMvMDIwMTQwMTMxMjYyMzk1Nv///////////////////yH5BAEKAD8ALAAAAAAZABkAAAb+QIvHg5FIKBgLQ2ICUUAcCEVDgUAQIA2HRMpqvhSEgwjhyEgiEYZigWgwprfHJNJaJJw6UvXWWO8MTxIKEkMWJF9cHhwcIEYWSGlIGBxVlBwmFFOaX1EUjCQuLHQadRgeUCIMbhAOSRAEChRHciBEeCgiECAOHCxEHlMOU5BtBEcWIhIOb4F5KCoiQiQeKiilHBgEHB4WChokVl8OCuQCGiAYUEwqWyAgFr3KAZ+tWoUmHmoOIu3tQpWEkVDhAR0GARSIiPAg4R0HCRggnLrDQYgFBAyyGSiHAB04KAgeIsBAzQI8AgAMgFDRhAOzLNSMSFPgAUVBGCY4aFmkwcT+NS4YRLi0kEmDCxEUSCiAQMIGDhTxZBG9tlCChRUdInw48SFDhQgbQuQosSHDhQQXNpQ4MOFDhw4fKnQoUeHBhw0dQlQocSFEiw8pYlTYIPdBhAhkQ9Ct0MLuigsdGmQYsSAB3hYdVgiuMGLCgAUVMnyYUOJF3wkZvFoe0bjChwuuIxyoEKLDhhQrRiT4ECJFiQ4pZqDu+6CB5AghYoxwbXvDgxUlfvNOMSHEiBs1ytZVOyFBhQYTRoSgsWHC8w4nSrTg/CLFiRor8Ib4MIJ+jBMtFjTYUGBDjLkhhLDbByWk8EILFyxwQVwTwPbAXnTVEGAEDZTwwAlfTVZWChkRHBYWfS+UUAOBgunQQgkrBAEAOw==);

It vaguely looks like a QR code may be in the image somewhere, but I keep a note of this and move on.

Next I come across a block of obfuscated JS.

eval(function(p,a,c,k,e,d){e=function(c){return c.toString(36)};if(!''.replace(/^/,String)){while(c--){d[c.toString(a)]=k[c]||c.toString(a)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('7:0:1:2:8:6:3:5:4:0:a:1:2:d:c:b:f:3:9:e',16,16,'6c|65|72|27|75|6d|28|61|74|29|64|62|66|2e|3b|69'.split('|'),0,{}))

Using a simple JS snippet, this is decoded to alert a string – ‘mulder.fbi'. Added to my word list.

(function(p,a,c,k,e,d){e=function(c){return c.toString(36)};if(!''.replace(/^/,String)){while(c--){d[c.toString(a)]=k[c]||c.toString(a)}k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--){if(k[c]){p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c])}}return p}('7:0:1:2:8:6:3:5:4:0:a:1:2:d:c:b:f:3:9:e',16,16,'6c|65|72|27|75|6d|28|61|74|29|64|62|66|2e|3b|69'.split('|'),0,{})).split(":").map(function(chr){return String.fromCharCode(parseInt(chr, 16))}).join("")
"alert('mulder.fb')"

In addition to the above string, I find a hidden element with the following content.

<span class="truth">Believe to Understand</span> The truth is out there.  </p>

I'm starting to see a theme here.

Next Steps

After downloading all of the assets, I start to look for anything of interest.

In the image ‘Challenge.png', there is a comment of hex numbers.

35:31:3a:35:33:3a:34:36:3a:35:37:3a:36:34:3a:35:38:3a:33:35:3a:37:31:3a:36:34:3a:34:35:3a:36:37:3a:36:61:3a:34:65:3a:37:61:3a:34:39:3a:33:35:3a:36:33:3a:33:30:3a:37:38:3a:34:32:3a:34:66:3a:33:32:3a:36:37:3a:33:30:3a:34:61:3a:35:31:3a:33:64:3a:33:64

Using the same method as before, we can convert this to another set of hex characters.

"35:31:3a:35:33:3a:34:36:3a:35:37:3a:36:34:3a:35:38:3a:33:35:3a:37:31:3a:36:34:3a:34:35:3a:36:37:3a:36:61:3a:34:65:3a:37:61:3a:34:39:3a:33:35:3a:36:33:3a:33:30:3a:37:38:3a:34:32:3a:34:66:3a:33:32:3a:36:37:3a:33:30:3a:34:61:3a:35:31:3a:33:64:3a:33:64".split(":").map(function(chr){return String.fromCharCode(parseInt(chr, 16))}).join("")
"51:53:46:57:64:58:35:71:64:45:67:6a:4e:7a:49:35:63:30:78:42:4f:32:67:30:4a:51:3d:3d"

Once more unto the breach, my friends.

"51:53:46:57:64:58:35:71:64:45:67:6a:4e:7a:49:35:63:30:78:42:4f:32:67:30:4a:51:3d:3d".split(":").map(function(chr){return String.fromCharCode(parseInt(chr, 16))}).join("")
  "QSFWdX5qdEgjNzI5c0xBO2g0JQ=="

Now we've got a Base64 string. This decodes to a set of characters – looks like a nice password. Noted for later.

A!Vu~jtH#729sLA;h4%

Give us your secrets, Mulder

After running dirbuster, I come up with a single interesting match. A file named ‘mulder.fbi' under the directory ‘/v/81JHPbvyEQ8729161jd6aKQ0N4/'.

This appears to be an MP4 file. After viewing the file and listening to the sound track, I didn't hear anything out of the ordinary, although after inverting the right hand track and mixing to the left, I did notice only very small differences in the tracks.

After a bit of time staring at this file, I took a step back and took note of what I had.

  • A password-like string
  • An MP4 video

After a little Googling, I found this article about hiding data within TrueCrypt volumes, inside MP4 files.

After installing TrueCrypt and mounting the MP4 file as a volume, and providing the password as ‘A!Vu~jtH#729sLA;h4%', we're presented with a new volume mounted.

Within this volume is a single file named ‘Flag.txt'.

Congratulations!

You are a winner.

Please leave some feedback on your thoughts regarding this challenge. Was it fun? Was it hard enough or too easy? What did you like or dislike, what could be done better?

https://www.spydersec.com/feedback

Conclusion

This one threw me a bit – I initially stumbled when decoding the hex strings, and discarded them as red herrings, but after re-visiting it made significant headway as outlined above.

The TrueCrypt volume was a nice addition – I expected some sort of steganography to be utilized in the MP4 or the underlying audio track. I was rather shocked that I hit on the TC volume so easily, but I guess I just got lucky.

Thank you SpyderSec for a fun challenge, and of course thank you VulnHub for hosting these images!