用内存fuzz来挖掘软件漏洞
该文章内容来自alphafuzzer使用手册《一天学会alpha语言》
这里用2个例子来简单的说一下,内存fuzz如何使用。
例1:简单密码的破解。
源码:
int _tmain(int argc, _TCHAR* argv[])
{
printf("AlphaFuzzer内存fuzz演示例\r\n");
printf("请输入密码:");
scanf("%d",&sn);
printf("您输入的密码是%d,\r\n",sn);
if(cal(sn)==1) printf("恭喜,密码正确\r\n");
else printf("密码错误,程序退出\r\n");
return 0;
}
int cal(int k)
{
if(k==58) return 1;
Else return 0;
}
解析:
该程序运行后,会验证用户输入的密码,密码是58.输入正确返回正确然后退出。输入错误返回错误信息,然后退出。
逆向分析:

代码编写(性能版):
内存控制代码:
GetRegsCC,0040102F,1; SetRegsCC,0040107A,1; SetMemOfAlphaCC,00401075,00403370;
Alpha数据生成代码:
_RangeNum,1,10000,0,32;
测试:
第一步:载入程序,填写测试代码。
第二步:点击开始测试
第三步:command窗口输入trace 点击确定

代码编写(功能版):
GetRegs,,eip,==,0040102f; SetFixedMemOfAlpha,00403370,eip,==,00401075,4; SetRegs,,eip,==,0040107A; MemShow,00403370; Stop,eip,00401065,==,1;
Alpha数据生成代码:
_RangeNum,1,1000,0,32;
测试:
可以勾选右下角的跳过xxx指令选项,这样可以更快更高效的测试,但是稳定性有所下降。

------------
例2:用alphafuzzer内存fuzz模拟的图片解析程序
程序解析:打开文件C:\sample.bmp 并进行简单解析,解析后输出部分解析结构和图片像素值。
该程序可以理解为一个图片解析程序。
反汇编分析:


为了稳定性,多个内存覆盖函数尽量不要挨着。因此我们选择00401003来作为内存覆盖函数.
代码编写:
1 让程序循环执行。我们选择在004011C9选择保存点,在004011CE进行恢复。
也就是如下指令:
GetRegsCC,004011C9,1; SetRegsCC,004011CE,1;
2 我们构造畸形的BMP图片数据之间插入内存中。经过简单分析,内存00403370处即为BMP样本数据。而我们选择解析函数较为开始的地方,00401003处进行内存数据的覆盖。

我们可以用下面一条指令表示:
SetMemOfAlphaCC,00401003,00403370;
3 我们来输入构造bmp数据的alpha指令。
block,structA;
{
_str,BM,,;
_cal,size,32,,1,18;[<all size>]
_num,0,,,32;
_cal,addr,32,,18;
}
block,structB;
{
_cal,size,32,,1,11;
_CountOfArray,32,0,12,1;
_num,16,,,32;
_num,1,,,16;
_num,24,,,16;
_num,0,,,32;
_cal,size,32,,12,12;
_num,4,,,32;
_num,4,,,32;
_num,0,,,32;
_num,1,,,32;
_array,1,100,16,3,1;
}测试:
开始测试-输入指令trace-执行指令
这时候内存fuzz已经开始测试
测试在xp虚拟机内执行,传统的文件格式fuzz,每秒可能只能完成2-5个测试。而内存fuzz如图所示不到6分钟测试了61221个测试用例。1秒测试数量近200个。效率是普通文件fuzz的几十倍。当然,内存fuzz除了可靠的内存控制代码外,还需要较大的cpu资源.

