前言
前几天在看Python的shellcode加载器,在网上找了一个,结果加载器自身就过不了火绒,测试发现是火绒对关键语句进行了识别。
所以我们要想办法去掉加载器中明显的特征。
原理及实现
在绕过静态查杀方面,主要就是要隐藏特征,比较常见的就是各种混淆、加密,但加密后的代码到最终还是需要去执行它才行,代码执行这一个操作其实特征也是很明显的,像exec、eval、os.system、subprocess.Popen这种,一眼就能看出来。所以也要想办法隐藏执行这一步的特征,这里就可以利用反序列化。
下面我们来看一段Python反序列化的代码:
import subprocessimport cPickleclass gugu(object):def __reduce__(self):return (subprocess.Popen, (('calc.exe',),))ret = cPickle.dumps(gugu())print repr(ret)cPickle.loads(ret)
程序在执行完毕后输出了序列化后的值,并弹了个计算器,代码中__reduce__的定义如下:
__reduce__(self)
当定义扩展类型时(也就是使用Python的C语言API实现的类型),如果你想pickle它们,你必须告诉Python如何pickle它们。__reduce__被定义之后,当对象被Pickle时就会被调用。它要么返回一个代表全局名称的字符串,Pyhton会查找它并pickle,要么返回一个元组。这个元组包含2到5个元素,其中包括:一个可调用的对象,用于重建对象时调用;一个参数元素,供那个可调用对象使用;被传递给 setstate 的状态(可选);一个产生被pickle的列表元素的迭代器(可选);一个产生被pickle的字典元素的迭代器(可选);
所以核心就是__reduce__这个魔法函数的返回