6月 2nd, 2008从生成器逆向探寻SWF网马加密
从生成器逆向探寻SWF网马加密
作者:Raullen
Adobe Flash漏洞是这段时间的明星漏洞,大街小巷都闹的沸沸扬扬。但除了各别“吃草的”懂得个中奥妙,大多数的马迷们只能望马心叹,及时抓到了16、28、45、47、115等各个版本的恶意SWF也是无从下手。这是因为这个网马不同于传统货,并不以unescape,16进制这些字符串表达形式的变换来取悦于观众,因为溢出构造在Flash内部,赋予了制作者以更多的操作空间,可以通过编程来实现比较复杂的Shellcode加密。这也许也是将来网马的发展方向所在。
今日,在某大侠的blog上发现了该网马的生成器,于是便琢磨着逆向看看,从而进一步的研究SWF网马的构造。顺便说一句,大侠已经提供了手工修改exe地址为明文的方法,这里不再复述,但后文会探究这样修改的原理。
探究过程开始。
首先考虑反汇编看看asm来找到生成算法,从而破解这匹马。无奈PEID提示“WinUpack 0.39 final -> By Dwing”— 一个猛壳,就不想费时间去脱了。方法论是一门很重要的学问。此处,我的白盒测试受阻,迅速转到黑盒测试。
用该大侠的生成器生成三个样本SWF,其中地址分别为http://www.0xxx.cn/1111.exe,http://www.0xxx.cn/2222.exe,http://www.0xxx.cn/3333.exe。然后用WInhex打开这三个SWF比较器十六进制代码,从而定位URL在文件中何处。结果比较结果如下:
1111: 000003beh: 4C 77 4F 77 ; LwOw
2222: 000003beh: 4F 74 4C 74 ; OtLt
3333: 000003beh: 4E 75 4D 75 ; NuMu
从中不难看出两点。第一,加密生成的地址有某种规律可循,如LwOw、OtLt、NuMu,似乎是异或加密(这里做协议分析和解密的同学应该会比较明显的看明白)。第二、看出四个字符的密文对应了四个字符的明文,因此我们可以从地址3beh大胆的往前数strlen(“http://www.0xxx.cn/”)个字符从而找到URL的头字符2E。
定位好了位置便开始着手分析其加密方式,这里需要一点经验和灵感。我用了比较分析的方法得出结果,如下面4行所示。其中行1是我输入的URL地址,这是一个已知量,行2是从地址3abh(往回数,数出来的)起的密文值,供给strlen(“http://www.0xxx.cn/1111.exe”)个字符。行3是行1的ASCII码表示。行4是由行1、2、3推演出来的未知量,也是该马加密的直接密钥。
行1:http://www.0xxx.cn/1111.exe (3aah) 0×60
行2:2E 00 32 05 7C 59 69 00 31 0F 68 49 3E 4E 20 55 25 12 69 4C 77 4F 77 51 23 F8 23
行3:68 74 74 70 3A 2F 2F 77 77 77 2E 30 78 34 66 2E 63 6E 2F 31 31 31 31 2E 65 78 65
行4:46 74 46 75 46 76 46 77 46 78 46 79 46 7A 46 7B 46 7C 46 7D 46 7E 46 7F 46 80 46
但是行4是怎么得出的呢?首先,我认为这是异或加密,因此我作出的尝试是如何将行2的某字符进行某种异或(例如和其之前或之后的字符XOR)从而得到结果行3。类似于一个一元一次方程:行2 ^ X=行3,求X。思路一定,那么就需要提及异或运算一个很重要的性质:如果X^Y=Z,那么X^Z=Y或者Y^Z=X。所以在解上述方程时,我运用了这个性质,将行2和行3的每个字符一次异或就得到了行4。部分算法代码如下:
if (bopen==true)
{
int ifd = (int)*(p+0xfd);
int ilen = (ifd-83)*2;
int varkey = (int)*(p+0×3aa);
int conkey = (int)*(p+0×3a9);
char buff[1024];
memset(buff,0×00,1024);
for (int i=0;i
{
buff[i]=(char)((int)conkey^(int)*(p+0×3ab+i));
}
if (i%2==1)
{
varkey++;
buff[i]=(char)((int)varkey^(int)*(p+0×3ab+i));
}
}
//分析成功
}
else //分析失败
稍作观察便可发现行4是一个很有规律的数列,奇数项从0×74依次递减,步长为一,偶数项恒威0×46。观察网马的Hex,迅速发现0×74来源于行2首字符(0×2E)的前一个字符(0×73)加1,因此我们知道了原来3aah处字符为加密的直接密钥的一部分。而0×46则来源于3aah 的前一个字节3a9h,是直接密钥的另一部分构成。
以上是需要修改的主要地方。另外在这位大侠的某篇文章中提及了如果欲将URL改为明文方式至于网马中,需要将0fdh位修改为0×51。那么说明了这一位与网址加密有某种联系。于是第二次运用黑盒法,作了如下测试;
URL值 0fdh位值 URL长度
http:// 0×56/86 7
http://w 0×57/87 8
http://ww 0×57/87 9
http://www 0×58/88 10
http://wwww 0x 58/88 11
http://wwwww 0x 59/88 12
http://wwwwww 0x 59/88 13
http://wwwwwwwww 0x 5b/91 17
http://qqqqqqqqq 0x 5b/91 17
实验结果是一个简单的数列,稍加分析可以看出0fdh位值的规律:83+strlen(URL)/2 (strlen(URL) 中 奇数-1 偶数不变)。按照这位大侠的说法,若将0fdh改成0×51就相当于异或部分的URL长度为0了,于是变为明文。实在是很巧妙。部分算法代码如下:
综上所述,本文设计了两个巧妙的黑盒测试避开了手动脱壳和反汇编带来的巨大工作量,同时也基本阐述了SWF的构造和解密,随文的是英雄Adobe Flash网马综合分析器。