文章目录

  • 1、杀毒软件
  • 1.0、杀毒软件的基本等级
  • 1.1、静态查杀
  • 1.1.1、代码中存在的函数
  • 1.1.2、shellcode的特征
  • 1.1.3、文件名称或md5
  • 1.1.4、加密、加壳(可疑)
  • 1.2、动态查杀
  • 1.2.0、基本概念
  • 1.2.1、计算机相关
  • 1.2.2、网络相关
  • 1.2.3、小结以及对编程语言的免杀方式
  • 1.3、Meterpreter源码相关
  • 1.3.1、MSF木马思路的优点
  • 1.3.2、魔改msf的木马
  • 1.3.3、实现
  • 1.4、测试面纱的一些问题
  • 2、CS的面纱
  • 2.0、CS的shellcode
  • 2.1、魔改CS平台
  • 3、面纱平台
  • 3.1、面纱平台的要求
  • 3.1.1、shellcode的随机性(加密函数)
  • 3.2、IAT导出表
  • 3.3、反沙箱
  • 3.4、反反沙箱
  • 3.5、三端分离
  • 3.6、根据自身需求添加功能
  • 3.7、加载器使用冷门语言,或者一些特别的语言,如go
  • 3.8、其他
  • 4、远控
  • 4.1、思考远控的本质
  • 4.1.1、自己写远控的好处:
  • 4.1.2、关于远控代码的一些问题:
  • 4.2、补充
  • 4.2.1、os._exit()和sys.exit()
  • 4.2.2、不要将不同类型的随意拼接输出
  • 4.2.3、测试VT远控吗


1、杀毒软件

1.0、杀毒软件的基本等级

1.无害		、、未匹配到特征

2.可疑		、、一些敏感操作被捕捉,如修改注册表,增加用户,执行powershell等
			、、接下来会一直监控此进程直到,被捕捉到强特征。

3.确认病毒	、、匹配到强特征

1.1、静态查杀

将exe文件反编译,匹配特征库。
1.1.1、代码中存在的函数
Virtualalloc(开辟内存空间),

rtlmovememory(将shellcode放到内存中),

ntcreatthread(创建线程运行shellcode)等
主要都是windowsapi函数,尤其是和内存、堆、线程相关的函数。
	
当然在python中如果存在“cmd”等关键词也是会被识别的:
	
	比如subprocess.popen(“cmd /c”)可以改为subprocess.popen(“命令”)
1.1.2、shellcode的特征
使用CS或MSF生成的shellcode都是有一些比较相似的部分,如开头大多都有0xfc等,
1.1.3、文件名称或md5
比如很早之前某数字杀软,将木马名称改为同类数字,图标也换了即不会查杀。

Md5的话,早期都是直接匹配整个文件的MD5,
	
现在主流的都是模糊匹配,即将一个exe文件拆分为几部分,将这几部分分别提取特征进行md5匹配。
1.1.4、加密、加壳(可疑)
使用加密解密行为或者对文件有额外保护措施,目前主流杀软直接匹配加的壳,
	
只要exe是加过对应的壳不管是不是病毒直接报毒。

1.2、动态查杀

1.2.0、基本概念
到这一步都是静态分析没有问题的,部分杀毒软件会有沙盒。
	
沙盒:也叫启发式查杀,通过模拟计算机的环境执行目标文件再观察特征行为

	这一点国内,某数字杀软的晶核防护是代表者

沙盒模拟的常见特征:

内存较小-->不影响计算机正常运行

时间较快-->沙盒内置的时间速度比现实世界要快,提高查杀速度

进程或文件不完整-->减少杀毒软件运行时对计算机的消耗:aaaaaaaaaaaaaaaaaaa.dll

io设备缺失-->鼠标键盘等事件大部分沙盒都没有

思考:真实的计算机和一个沙盒的计算机他们有什么不同

先说一下什么是方糖:简单理解为CS上线之后,同时发送微信提醒,

写systeminfo对接方糖获取信息,即获取沙河的systeminfo信息发送到自己的放糖。

	通过得到的信息发现,VT的信息都是英文的,因此我们可以在木马上写一个规则,

	即检测到当前系统的信息是英文的就return出去,不让vt执行分析。

注册表显示安装的java版本_注册表显示安装的java版本

1.2.1、计算机相关
  • 杀软会监控敏感的文件/文件夹/服务等,具体如下:
R3就是用户层,杀软会监控(hook)r1、r2的一些关键函数(功能),

当木马触发了这些监控的函数就会被杀软分析,进而被干掉,当然这些hook也是可以绕的。
除此之外,主流杀软一般还会同时监控如下:
	服务、注册表、组策略、防火墙

	敏感程序:
			cmd powershell 
			wmi psexec		、、后渗透常用工具
			bitsadmin		、、远程下载文件
			rundll			、、另一种上线CS的方式
			等等	

	添加,删除,修改用户、用户组等

	增删改敏感文件夹:
		
		C:/windows/system32
		
		C:\Users\Administrator\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup	
		、、开机自启相关
		
		C:\tmp等敏感文件夹
  • 常见的绕过思路
白名单调用这些敏感行为,再导入恶意内容(白加黑)

如:
	
	利用如微软的一些程序去执行一些危险操作。
1.2.2、网络相关
  • IP、域名、证书:
查找通讯的ip或域名是否之前存在攻击行为

比如现在比较火的域前置技术,就是绕过IP/域名的黑名单。
  • 流量内容:
时间特征:扫描等

内容特征:data字段中是否存在命令相关关键词或关键词加密特征

结构特征:是否存在已知远控的通讯结构特征
  • 常见的绕过思路
tcp分段,内容加密,使用合法证书、域前置等
1.2.3、小结以及对编程语言的免杀方式
  • 小结:
不是所有的杀毒软件都有这些,有些比较拉跨,有些比较强,不过总体的思路都是差不多的。
  • 对编程语言的免杀方式:
powershell	--	混淆、加密

c++			--	编译过程、混淆、加密

python		--	混淆、加密

通用			--	启发式查杀

1.3、Meterpreter源码相关

分析msf木马的原理,可以参考:

	https://www.anquanke.com/post/id/238270
1.3.1、MSF木马思路的优点

MSF木马采用的“小马拉大马”思路的好处:

~小马体积小、面纱效果好、

~小马落地体积小、

MSF木马采用回调的好处:

~没有立即建立socks链接释放大马,先循环3次,调高了小马的隐蔽性。

~可以保证小马的执行过程是在内存当中的,相对直接的文件,内存中的查杀相对较难一些。
	
	特别是国内对五落地文件(无文件攻击)的查杀相对比较拉,
1.3.2、魔改msf的木马
  • 去掉多余的功能(回调),保留核心功能在做面纱就非常容易,
    经过测试msf木马的核心代码只需要保留50多行即可。
  • 另外一些关键字都改掉,什么payload、msf等等都替换了,
    这种上传vt也就6~8个可以查杀报毒,且有一些杀软报毒仅仅是误判的。

这里多说一些关于杀软的报毒行为:

目前市面上一些杀软的原理就是宁可错杀100也不能放过1个,
	
大家可以使用如C编译一个hello打包成exe上传,都会有杀软报毒。
以上就是源码级面纱,没有用到shellcode,
	
主要是shellcode上线就很难离开上面提到的几个函数
	
	{ Virtualalloc(开辟内存空间),
	rtlmovememory(将shellcode放到内存中),
	ntcreatthread(创建线程运行shellcode)}

而这些函数又被主流杀软盯的很紧。
1.3.3、实现
使用msf生成py的木马,然后魔改代码,

然后在msf上开启监听,执行代码,正常上线就OK,

没有正常上线的话,多半是缩进的问题,把所有该缩进的地方的“\t”全部换成“空格”。

最后将代码进行base85编码,

注册表显示安装的java版本_python_02

然后再次开启msf的监听,将组合得到的代码执行,成功上线。

注册表显示安装的java版本_网络_03

最后面纱的结果还是比较理想的,

注册表显示安装的java版本_python_04

1.4、测试面纱的一些问题

测试exe面纱的话,尽量不要上传到VT上,
	
不然你的CS服务端在几天的时间内会遭受到类似ddos的假上线行为(上线后exe进程就会被干掉),
	
另外即使上传的样本在当时测试无毒,但是在未来的2~3天内几乎一定会被标记。
	
会有人工在后台慢慢分析之后,打标机。



所以测试面纱,就本地搭建一些杀软(更新最新杀毒库),
	
关闭自动上传样本(实际上同样会上传)且关闭网络之后在测试。

2、CS的面纱

2.0、CS的shellcode

什么是shellcode:
	
	shellcode是一段用于利用软件漏洞而执行的代码,shellcode为16进制的机器码,
	
	因为经常让攻击者获得shell而得名。shellcode常常使用机器语言编写。
	
	可在暂存器eip溢出后,塞入一段可让CPU执行的shellcode机器码,让电脑可以执行攻击者的任意指令。 




看一些前辈的文章发现,比如CS的shellcode都是写死的,他仅仅会替换每次生成不同的IP与端口对应的那段shellcode。
	
	且不同语言对应的shellcode,仅仅是不同语言定义数组形式的不同,本质还是同一段shellcode。




有以上就牵涉到另一个东西,即目前国内主流的查杀还是在静态上,仅仅是md5特征库更新的较快,
	
	所以面纱的话,很多时候从源码上加一些无用的函数进行混淆,改改关键字/函数的名称,
	
	就可以过掉相当多的杀软,当然造成这种现象也是有攻防本身就不对等导致的,
		
	但更多的是国内在这方面还是有较长的路可以进步。

2.1、魔改CS平台



3、面纱平台

在长期的杀软对抗过程中,应该孕育而生一种免杀平台。
	
因为免杀平台的随机性,恰恰是对抗杀软启发式的最好方式。

面纱平台的缺点:

~对开发者的代码水平要求较高
	
	~需要人经常去维护

但是不管是否可以做出来面纱平台,可以理解原理的话也是不错的。

3.1、面纱平台的要求

3.1.1、shellcode的随机性(加密函数)
假设shellcode什么都不做,只要打包成exe,

杀软是可以很容易的使用逆向还原exe的shellcode然后对应特征直接静态干掉。



而加密则可以保证我们过掉静态查杀。在挑选加密算法时,应注意加密算法的随机性,

如base64等非随机加密算法(编码)不建议使用,

因为杀软的特征中几乎可以肯定存在如CS加密后的shellcode特征。

推荐使用如xor等加密算法,此种加密算法提供密钥进行加密,可保证shellcode的随机性。



这里再提一点,其实就是如xor甚至aes这种,在目前的对抗之中几乎也被杀软给保存了特定的特征,

所以相对来说最保险的就是自己写一份加密算法(有能力的话)。

3.2、IAT导出表

注册表显示安装的java版本_杀毒软件_05

一些逆向软件可以很容易就可以得到你的exe调用了哪些函数,

杀软的启发式扫描大部分来源于此,分析导出表使用的函数,查看是否是高危API。

GetProAdress:

减少(敏感)函数的直接调用,而是通过寻址的方式找到函数。

引申一下:

经过GetProAdress之后,整个程序就只剩一个GetProAdress函数了,但是这样同样是不正常的,
	
正常的程序不会仅仅只有一个GetProAdress函数,
	
我们在木马之中还得在加一些正常的无害函数/API来混淆杀软。



当然,面纱平台最强调的就是随机性,我们的混淆函数可以定义如20个,

在木马生成的时候,随机调用其中的5~20个函数运行。

3.3、反沙箱

(1)注册表信息

比如在vmware的虚拟机中,在注册表中搜索"vmware"字样,可以得到特别多的键值

病毒文件会在执行开始去RegOpenKeyExA()对应的虚拟机注册表键值,

如果返回为非0, 则说明在虚拟机环境中。

尤其是注册表中硬件信息,经常被病毒检测使用的:

	HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\services\Disk\Enum

或者直接检测IDE\DISK 会有QEMU,vbox,vmware,virtualhd的字样等等,这种检测技术在样本中很常见。

(2)进程信息

在虚拟机启动后,进程列表可以看到部分虚拟机的进程存在病毒样本常会遍历的虚拟机进程有:
	
	"VBoxTray.exe"
	
	"VBoxService.exe"
	
	"VMwareUser.exe"
	
	"VMwareTray.exe"
	
	"VMUpgradeHelper.exe"
	
	"vmtoolsd.exe"
	
	"vmacthlp.exe"

(3)特殊文件信息

对比正常操作系统与虚拟机的一些特殊文件是真机有,虚拟机没有的。

(4)增加加载shellcode的延时

因为一些在线沙箱他是需要在一段时间内给用户反馈结果的,
	
假设我们在程序运行的20S都没有任何反应,即当沙箱的检测时间过了,在加载shellcode。

(5)判断外设驱动如鼠标键盘等

3.4、反反沙箱

当然有反沙箱,蓝队有反反沙箱。一直是对抗的过程。
  • 当我们有了以上的反沙箱操作,沙箱们一样会完善:

(注册表)

沙箱环境提前hook了注册表信息,当木马获取的时候就返沪正常的注册表信息。

(进程信息)

也是类似的思路,直接过滤掉虚拟机的常见进程,给木马返回真机的进程程序

(特殊文件)

这个就略微难一些,主要沙箱也不知道木马要获取什么文件,

	但是一旦被木马被广泛使用上传VT,VT也会捕捉到木马经常访问的文件。

(延时)

直接加速沙箱的时间,使得木马的延时20S变为2S等
  • 对于上述,木马制作者可以在,“反反反沙箱”:
检查注册表、进程等等有没有被hook,特殊文件多选几个,每次随机访问其中的部分。
	

对于加速时间的,获取一下程序执行的具体时间,在获取一下延时完毕的真实时间,
	
	相减计算得到是否是真的延时了20S等等。



安全本质就是在博弈,在整个过程之中,防御相对攻击整体呈现的比较被动,

所以一些攻击思路出来一段时间后才会被防御掉,对于面纱平台来说,

就得要求人员要隔一段时间就要维护更新沙箱平台的规则等。

3.5、三端分离

加载器,payload,密钥分离。

此方法对木马的使用场景要求较高,对钓鱼而言文件较多,不建议使用此方法。


三端分离的好处在于免被分析,免被溯源,主要这三个文件每一个都是相互独立的,
	
	每一个文件单独出现都不会引发报毒,但是组合出现时就会上线C2。

3.6、根据自身需求添加功能

如添加用户?自启动?自删除?自进程迁移?

3.7、加载器使用冷门语言,或者一些特别的语言,如go

go在程序编译的时候,就会导入什么的包,
	
管你用到用不到的,都导入,这就对杀软的分析造成了一些影响。

3.8、其他

大家有能力最好自己写一个,代码能力不太强的话,懂得原理也不错,
	
另外,多多关注一些GitHub的项目,当然这些开源的项目往往都会在几个月后失效。


多实践,哪怕看看github开源平台的代码学习总结一下,
	
最好可以做到改进。不然很长的时间都是依赖于别人。

4、远控

4.1、思考远控的本质

1.传输消息——>socket连接

2.命令执行——>Runtime类

3.执行结果回传——>IO流
理解木马的原理之后,我们可以使用自己擅长/喜欢的编程语言去实现这个过程,

	比如Java、python等等(都可以打包成exe)。很多代码,网上都是可以找到的。
4.1.1、自己写远控的好处:
因为是少数人使用的,且自己写的代码,几乎没有杀软病毒库的特征,

所以面纱效果极好,这种程序最适合在权限维持阶段使用。



当然,假设你写的远控被很多人使用的话,那么一样会被杀软给标记特征干掉。

这里就可以引申出一个问题就是能过掉Vt其中并不是很难,难得是如何在很多人都是使用的情况下,

木马仍然可以达到免杀的效果。

	
	远控吗正常的使用阶段就是拿到目标权限之后,将此文件写入如启动项,
	
	因为是自己写的远控,正常来说可以在很长一段时间内都面纱,
		
	在之后再次利用当前目标的时候,在通过此远控将CS或者MSF的木马给下载下来。
4.1.2、关于远控代码的一些问题:
  • 为什么写一个while死循环?
因为要达到长连接的作用,不然的话,被控端输入一个数据给传送过来之后,
		
	这个会话就会结束,无法达到长连接的效果。


这里多说一下,假设使用python写的远控,python的socket默认就是用的长链接,

	关闭的话,需要使用“ .close() ”关闭。
  • 如何跳出死循环(关闭当前建立的socket连接)
可以在客户端写代码,

if 接受的数据 == exit:

	return


这里注意的是,有可能接收到的数据是“ exit\n “或者空格的数据,导致服务端输入exit无法退出,
	
	所以客户端接受数据这,最好加一个去除首位空格的函数。
  • 测试时期,不要慌忙打包为exe
这里测试能否直接建立连接的话,不用先打包成exe执行,
	
	先在客户端使用编程语言工具执行,然后服务端使用nc监听,
		
	在服务端输入一些数据,看看客户端能否收到,收到则证明没问题。
		
	这种调试在之后的操作中也可以很方便。
  • Mac测试服务段输入的命令,客户端能否接受并成功执行,
可以输入代码“ open .”打开当前文件夹。
	
Win的话就可以执行“ calc ”这种经典的弹一个计算器了。

当然在这一步都没问题之后,就需要加代码,将客户端执行命令的结果直接返回服务端。

另外其实mac也是可以直接打开计算器的,只是要填写的路径比较长:

	/System/Applications/Calculator.app/Contents/MacOS/Calculator
这里还有一个小坑点是,有可能我们第一次输入命令会正常执行,
	
	但是输入第二条指令的时候,这个第二条指令会与第一条指令的返回值拼接一起执行,
	
	这样的话,程序执行就会出错,也不会我们最初的目的,
		
	这里我们可以在第一条命令执行的结果返回服务端之后关闭流并结束本次循环。
  • 完善远控:
在我们的远程解决了上述问题/功能之后,就要思考一个问题,
		
	客户端接受到正常的命令是没问题的,但是输入了错误的命令,程序要执行出错导致停止运行,
	
	这种结果也是需要解决的。正常可以使用try—catch—的结构来处理这个问题。

另外在调试程序的时候,无法定位到问题就输入打印上一步,看看是什么问题。

4.2、补充

4.2.1、os._exit()和sys.exit()
Python程序有两种退出方式: os._exit() 和 sys.exit()。

简单说一下这两种方式的区别。

	os._exit() 会直接将python程序终止,之后的所有代码都不会执行。

	sys.exit() 会抛出一个异常: SystemExit,如果这个异常没有被捕获,
		
		那么python解释器将会退出。如果有捕获该异常的代码,那么这些代码还是会执行。
另外,sys.exit()  不给参数,默认就是sys.exit(0),

而使用os._exit(),需要手动提供参数0,即os._exit(0),不然程序会报错



但是sys的退出可以这么用“  sys.exit("服务器未开启监听")  ”

而os._exit(0)则不可以这么使用!
4.2.2、不要将不同类型的随意拼接输出
a = 1

print("asd"+a)
这么输出,程序会报错,因为a是int类型,而"asd"是string。

需要将a的类型强转为字符串类型之后,才可以一起正常的输出,python基本语法的问题。
4.2.3、测试VT远控吗

符合预期

注册表显示安装的java版本_注册表显示安装的java版本_06