beSTORM之DLL Fuzz入门教程首席安全官频道

*本文原创作者:dolphin,首席安全官频道本文属FreeBuf原创奖励计划,未经许可禁止转载

beSTORM简介

beSTORM是一款安全评估工具,在开发周期中,供应商可以使用beSTORM全面分析网络软件应用,发现全新和未知的漏洞。beSTORM通过自动测试数十亿种攻击组合方式,确保产品部署前的安全,为企业节省产品上市后修复安全漏洞产生的成本。以往的安全评估工具使用攻击签名或失败的攻击定位已知的产品漏洞,beSTORM与这些旧式的安全评估工具不同。

无论在认证测试还是开发生命周期中,供应商均可以使用 beSTORM 来测试产品。该软件能够定制现有模块,并且添加新模块,以直观和易于使用的环境实现所有测试功能。

beSTORM 虽然是通用模糊测试框架,但使用时无需任何编程技能。该软件特别适合测试标准协议(如 HTTP、 POP3、 SMTP、 SIP 和其他包含 RFC定义的类似协议)以及标准文件类型(如 BMP、 TGA 等同类文件)。当然,也可以随时定义自己的测试模块以测试专有协议。 

beSTROM可以测试网络协议,也可以测试DLL文件,本文以测试DLL文件为例来介绍。

实验环境

Windows 7 64位操作系统

beSTORM V3.8.8_5063

Visual C++ 6.0

DLL Export Viewer v1.66

DebugView v4.81

准备工作

(1)首先编写测试用的DLL文件,关键代码如下: 

##include "stdafx.h"
#include <stdio.h>
#include <windows.h> 
extern "C"  _declspec(dllexport)  char  *  myfun_returnstring(char *str);
BOOLAPIENTRY DllMain( HANDLE hModule, 
                     DWORD  ul_reason_for_call, 
                     LPVOID lpReserved
               )
{
   return TRUE;
}
char  * myfun_returnstring(char *str)
{
   char strDebug[100];
   sprintf(strDebug, "str = %s\n",str);
   OutputDebugString(strDebug);
   sprintf(str, "%s!", str);
   return str;
}

为了使得Fuzz过程可视化,我们在导出函数myfun_returnstring中调用OutputDebugString函数。导出函数myfun_returnstring主要功能是利用API OutputDebugString输出函数的参数,并且将参数后加一个感叹号后,返回。

(2)为了测试我们的dll函数编写正确,我们再编写一个简单的VC工程调用dll中的myfun_returnstring函数。关键代码如下:

 #include "stdafx.h"
#include <windows.h>
typedef  char *(*pFUN)(char *);
int main(int argc, char* argv[])
{
   char str[]="Hello from Dll";
   HMODULE hModule =::LoadLibrary("DllTest.dll");  
   pFUN p_myfunAdd =(pFUN)::GetProcAddress(hModule,"myfun_returnstring"); 
   if ( p_myfunAdd != NULL)
   {
      char * result = p_myfunAdd(str); 
      printf("The result is: %s \n\n",result); 
   }
   else
   {
      printf("function pointer is NULL!\n\n");
   }
   ::FreeLibrary(hModule);
   return 0;
}

程序执行如下图。myfun_returnstring函数的参数为“Hello from Dll”,调用后返回输出“Hello from Dll!”

cmd.png

cmd.png

至此,我们已经有了用于测试的dll,并且dll功能实现正常。下面我们利用beSTROM来对dll中的导出函数myfun_returnstring进行fuzz测试。

beSTORM DLL Fuzz步骤

(1)执行Minion,并设置密码为1234,默认端口6980不变。

Minion_1.png


Minion_1.png


点击“OK”后,Minion执行界面如下:

Minion_2.png


Minion_2.png


关于Minion是什么?官方解释如下:beSTORM cannot load and execute the DLL directly since a crash inthe DLL will cause the entire parent application to crash (and thereforebeSTORM will crash upon a successful finding). To go around this limitation,beSTORM can use a “Minion” to execute the DLL. This minion communicates with beSTORM over a TCP port and thus can run from a separate machine if needed. 

beSTORM不能直接装载和执行DLL文件,因为DLL如果崩溃了,会导致整个父进程崩溃(因此,beSTORM也会崩溃)。为了绕过这个限制, beSTORM使用“Minion”来执行DLL。这个Minion通过TCP端口同beSTORM通讯,如有必要可以运行在另外一个机器上。 

(2)使用DLL Export Viewer或者IDA Pro等工具可以查看DLL的导出函数。使用DLL Export Viewer查看编写的dll文件。

DLL_Export_Viewer_1.png


DLL_Export_Viewer_1.png


DLLExport Viewer中可以看到dll文件共有三个导出函数。

DLL_Export_Viewer_2.png


DLL_Export_Viewer_2.png


(3)打开beSTROM主程序(beSTORM Client)。点击“NEW PROJECT”

beSTORM_1.png


beSTORM_1.png


在这里填写beSTORM工程的名字和路径,选择“Advanced”。

beSTORM_2.png


beSTORM_2.png


然后选中“Build a DLL(API) Module”, 在Minion Hostname or IP address中填写本机IP地址,127.0.0.1,其他为默认值。然后点击“Build a DLL(API) Module”后的“LEARN”按钮。

beSTORM_3.png

beSTORM_3.png

填写DLL文件的路径(如C:\Users\user\Desktop\beSTORM_dll\DllTest.dll)、DLL中拟测试的导出函数名(如myfun_returnstring),选择返回值类型为“unsigned char *”。并且添加参数类型为unsigned char *,勾选“Fuzz this parameter”,添加到参数列表中。

(这一步最容易出错,请大家仔细!)

beSTORM_4.png

beSTORM_4.png

然后选中参数,点击“ADD”,对话框左下角出现要测试的函数信息。点击“USE”。

beSTORM_Generate_DLL_Module_2.png

beSTORM_Generate_DLL_Module_2.png

默认配置,点击“NEXT”。

beSTORM_4.png

beSTORM_4.png

  这里填写Minion的密码为1234。

beSTORM_5.png

beSTORM_5.png

默认配置,点击“NEXT”。

beSTORM_Wizard_6.png


beSTORM_Wizard_6.png


最后配置完成,点击“FINISH”。

beSTORM_Wizard_7.png

 

beSTORM_Wizard_7.png

 

(4)在正式开始Fuzz测试前,为了可视化正在进行的Fuzz操作,我们使用DebugView查看DLL中使用APIOutputDebugString输出的调试字符串。DebugView为微软出品的调试小工具,可以查看由OutputDebugString输出的所有调试字符串,目前最新版本为v4.81。

启动DebugView后,现在可以点击“START”开始Fuzz测试。

beSTORM_Main_1.png


beSTORM_Main_1.png


因为这里没有用到Monitor,故选择“Yes,this session only”

Minion_is_not_Running.png

Minion_is_not_Running.png

(5)点击START开始Fuzz后,可以在DebugView中看到dll输出的调试字符串。(也可能看到其他应用输出的调试字符串,为了方便Fuzz,可以暂时关闭其他不必要的应用),DebugView输出的字符串如下图所示。

DebugView_1.png


DebugView_1.png


因为在DLL中定义的strDebug字符串长度为100,当发送超过100个字节的参数,程序可能崩溃。

beSTORM_error_info.png

beSTORM_error_info.png

至此,beSTORM成功发现了一个引起DLL崩溃的参数。关于beSTROM中DLLFuzz更深层次的应用,请大家参考手册。 

参考网站

https://technet.microsoft.com/en-us/sysinternals/debugview

*本文原创作者:dolphin,本文属FreeBuf原创奖励计划,未经许可禁止转载

2017-04-28 15:26 阅读:450