前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >在渗透测试中使用fuzz技术(附windows安装指南)

在渗透测试中使用fuzz技术(附windows安装指南)

作者头像
FB客服
发布2018-02-02 15:50:17
1.9K0
发布2018-02-02 15:50:17
举报
文章被收录于专栏:FreeBuf

前言:本文翻译自‍‍‍‍sans.org,有删节。在学习sulley的过程中发现中文参考资料很少,所以抛砖引玉翻译一下,希望对学习协议fuzz测试的同学有帮助。本文适合作为学习sulley协议测试过程中参考资料,如果需要学习sulley的使用可以参考其文档。

背景

不久前,我们接到了一个渗透测试的项目。分配任务的时候,团队里有的同学负责无线渗透,有的负责web应用渗透,我分到的任务是对外网开放的网络端口进行测试。我的主要测试范围包括:从外部可以访问的系统接口,不包括客户测的漏洞利用,不包括web应用,不包括外部的资源管理类的攻击(比如域名管理类的攻击),不包括账号密码猜解。

前期的扫描中并没有发现很多有意思的漏洞,这也在意料之中。不过Nmap的扫描也发现了一些有意义的目标。如下图所示。目标部署了一个CheckPoint服务器作为远程V**接入。一共开放了两个端口。

264端口引起了我的兴趣,经过一番查证得知这是CheckPoint V** 客户端用来通信的一个通道,使用的是一种私有协议,叫做SecuRemote。这个协议是没有加密的。网上能找到一些这个协议存在信息泄露的漏洞,不过我们客户这边都是新版本,不存在那些已知的问题。现在我有的资源就是一些协议资料和大把剩余的任务时间,我决定做一下协议fuzzing。

协议分析

做协议fuzz的首要条件就是要熟悉自己测试的协议。SecuRemote作为私有协议,没有详细的文档,而且我也没发现有人作为逆向分析。所以我得通过抓包自己分析协议。在Google上搜索了一下,找到几个别人抓的网络包文件。都是他们抓包让别人帮分析问题的。通过分析这些网络包,我分析出了SecuRemote协议的一些细节。

3次握手之后,CheckPoint客户端会发送两个4字节的小包。对于特定的CheckPoint服务器和客户端来说这两个字节看起来是固定的。在客户端发送第二个包之后,服务端返回了一个4字节的包。跟客户端发的第一个包很像。

第四个包发送字符串"securemote"到服务器。最后是一个NULL的结束字节。开始的4个字节看起来是大端存储的后面字符串的长度。因为0x0b刚好是"securemote0"的长度。第四个包发完之后,服务器返回了一个同样的带字符串长度的包,包含了一些服务器的相关信息。根据之前版本的CheckPoint exp,可以获取更多的协议数据。虽然没法简单的识别出每一个比特位代表的意义。但是根据上面的分析,也可以找到一些有意思的模糊测试目标。

四字节的长度标志。任何时候,在协议中发现了标志长度的字节,一定要对它进行模糊测试。几个固定的\x00的字节。减少了我们进行枚举组合的次数。在字符串结尾使用NULL结束符。因为协议提供了长度标志,所以结束符不是必须的。所以测试一下结束符不存在的情况也是不错的选择。

下一步就是准备测试样例,进行模糊测试了。

工具选择

我比较喜欢的智能模糊器是Sulley,一个用python完成的模糊测试框架。不过开发者Pedram已经不再维护Sulley。使用Peach也是一个不错的选择,peach使用XML进行协议描述,相对来说我更喜欢python的语法。在sulley中,我们使用基本的数据类型:字符串区,数字区,分隔符和静态值来描述协议。每一种类型的数据都可以自动突变来进行模糊测试。Sulley也提供了一些高级的功能来描述复杂协议,比如计算数据段长度和进行摘要校检。更多详细的sulley使用方法可以参考Sulley的项目文档。下面的脚本是对客户端发送的4个字节进行测试。其中使用了s_byte()这个定义一个字节的函数。将下面的脚本保存到sulley的目录就可以开始测试了。

代码语言:javascript
复制
#!/usr/bin/env python
# Fuzzing the initial 4-byte packet from client to CheckPoint V** server.
import time
import sys
from sulley import *
# Time to wait between mutations
SLEEP_TIME=0.5
# Time to wait before claiming a host is unresponsive
TIMEOUT=3
# number of crashes to observe before skipping the remainder of a group
CRASH_THRESHOLD=3
# Initialize the Sulley mutation descriptor
s_initialize("SecuRemote-Initial-Packet")
s_byte("\x51",full_range=True)
s_static("\x00\x00\x00")
print "Total mutations: " + str(s_num_mutations()) + "\n"
print "Minimum time for execution: " + str(round(((s_num_mutations() * (SLEEP_TIME))/3600),2)) + " hours."
print "Press CTRL/C to cancel in ",
for i in range(5):
print str(5 - i) + " ",
sys.stdout.flush()
time.sleep(1)
# For debugging purposes, uncomment these lines to see Sulley's mutations
# in hex dump format
#print "Hex dump mutation output:"
#while s_mutate():
# print s_hex_dump(s_render())
sess = sessions.session(session_filename="SecuRemote-Initial-Packet.sess", sleep_time=SLEEP_TIME, timeout=TIMEOUT, crash_threshold=CRASH_THRESHOLD)
# Tie this session to the SecuRemote-Simple-String fuzzing cases
sess.connect(s_get("SecuRemote-Initial-Packet"))
# Change this IP address to the target system
target = sessions.target("127.0.0.1", 264)
# Add the target to the session (can be repeated for multiple targets)
sess.add_target(target)
# Kick off the fuzzer, monitoring with WebUI on localhost:26000
sess.fuzz()

很不幸的是经过上面的测试,并没有发现有意义的结果。为了更深入的对目标系统进行评估,需要我们的Sulley实现一些协议状态,对协议进行更深入的测试。

对有状态的协议进行测试

在SecuRemote的案例中,从客户端发给V**服务器的头两个包对我们来说并不够吸引人。客户端交换的第四个包才更有趣,包含了一个字符串和长度值,以及NULL结束符。为了测试V**服务器对这个位置的畸形包的返回,我们需要在sulley中先模拟前面的两步。然后再发送这一步的畸形包。Sulley中已经提供了相关的接口。在发送每一个畸形包之前,Sulley会检查一个叫做pre_send的回调函数。通过定义我们自己的回调函数,读写socket,完成初始化的头两个4字节包的发送,然后读取服务器的返回。之后再发送我们的测试畸形包。进行测试的脚本如下:

代码语言:javascript
复制
#!/usr/bin/env python
from sulley import *
SLEEP_TIME=0.5TIMEOUT=3CRASH_THRESHOLD=3# The function Sulley will run prior to sending each mutation.  We leverage
# it to setup the target system with the initial packets and response in the
# protocol exchange prior to our target packet.
def preconn(sock):
    sock.send("\x51\x00\x00\x00")    time.sleep(0.5)
    sock.send("\x00\x00\x00\x21")


    # Set a socket timeout on the recv so we aren't waiting indefinitely if
    # the server crashed from a previous test case.
    sock.settimeout(5)    response = sock.recv(4)
    print "Setup response: ",    for i in response:
        print "%02x" % ord(i),
    print


s_initialize("SecuRemote-Simple-String")


# Create a size field, which is based on the content of the named block
# Sulley uses ">" to indicate big-endian values, "<" is little-endian
s_size("client-name-string", length=4, endian=">")


# This is the block of data used for filling in the s_sizeif s_block_start("client-name-string"):
    # "securemote" is the default string
    s_string("securemote")
    # constant null terminator
    s_byte("\x00")
s_block_end()


sess = sessions.session(session_filename="Securemote-Simple-string.sess", sleep_time=SLEEP_TIME, timeout=TIMEOUT, crash_threshold=CRASH_THRESHOLD)


# Call preconn() before each mutation is sent to setup the target
sess.pre_send = preconn


sess.connect(s_get("SecuRemote-Simple-String"))
target = sessions.target("127.0.0.1", 264)
sess.add_target(target)
sess.fuzz()

通过这种方式,可以继续对其他的请求包进行测试。

成果

我们一共进行了好几个晚上的fuzz测试,通过记录的数据发现,确实发现了一些小问题,一些畸形的数据包会导致V**服务重启,达到Dos的效果。客户对我们的这个报告也很认可。

附录:sulley的windows安装指南

测试环境win7+python2.7

安装MinGW Complilier。

在安装引导界面选择C++ Compiler和ObjC Compiler。这里有个问题就是新版的MinGW已经不支持-mno-cygwin选项了。可以选择老版本的MinGW或者安装最新版,然后patch python代码。这里选择后者。

安装python2.7(x64)

安装Git 工具

更新$PATH环境变量,添加C:\Python27 和 C:\MinGW\bin(根据自己的安装路径填写)

安装pydbg

代码语言:javascript
复制
git clone https://Fitblip@github.com/Fitblip/pydbg.git

C:\sulley_build>git clone https://Fitblip@github.com/Fitblip/pydbg.git
Cloning into 'pydbg'...
remote: Counting objects: 17, done.
remote: Compressing objects: 100% (12/12), done.
remote: Total 17 (delta 4), reused 17 (delta 4)
Unpacking objects: 100% (17/17), done.


C:\sulley_build\pydbg>python setup.py install
running install
running build
running build_py
creating build
creating build\lib
creating build\lib\pydbg
...snip...
running install_egg_info
Removing C:\python27\Lib\site-packages\pydbg-0.0.0-py2.7.egg-info
Writing C:\python27\Lib\site-packages\pydbg-0.0.0-py2.7.egg-info

安装libdasm

下载libdasm

编译扩展并安装。这里需要用到gcc,而gcc4.7.x已经去掉了对-mn0-cygwin的支持。需要先把distutils\cygwinccompiler.py文件中的”-mno-cygwin”删掉。总过4,5个地方的样子。参考http://stackoverflow.com/q/6034390/333353

代码语言:javascript
复制
C:\sulley_build\libdisasm\pydasm>python setup.py build_ext -c mingw32
running build_ext
building 'pydasm' extension
...snip...
C:\sulley_build\libdisasm\pydasm>python setup.py install
running install
running build
running build_ext
running install_lib
copying build\lib.win32-2.7\pydasm.pyd -> C:\python27\Lib\site-packages
running install_egg_info
Writing C:\python27\Lib\site-packages\pydasm-1.5-py2.7.egg-info

下载sulley

代码语言:javascript
复制
C:\sulley_build>git clone https://github.com/OpenRCE/sulley.git
Cloning into 'sulley'...
remote: Counting objects: 148, done.
remote: Compressing objects: 100% (91/91), done.
remote: Total 148 (delta 53), reused 146 (delta 51)
Receiving objects: 100% (148/148), 267.03 KiB, done.
Resolving deltas: 100% (53/53), done.

确认process_monitor.py正常工作。(没有提示缺少模块)

代码语言:javascript
复制
 C:\sulley_build\sulley>python process_monitor.py
 ERR> USAGE: process_monitor.py
     <-c|--crash_bin FILENAME> filename to serialize crash bin class to
     [-p|--proc_name NAME]     process name to search for and attach to
     [-i|--ignore_pid PID]     ignore this PID when searching for the target process
     [-l|--log_level LEVEL]    log level (default 1), increase for more verbosity
     [--port PORT]             TCP port to bind this agent to

下载解压PCapy

下载解压WinPcap Dev Kit,记下文件路径。这里用C:\sulley_build\WpdPack

编译PCap并安装

代码语言:javascript
复制
C:\sulley_build\pcapy-0.10.5>python setup.py build_ext -c mingw32 -I "C:\sulley_build\WpdPack\Include" -L "C:\sulley_build\WpdPack\Lib"
running build_ext
building 'pcapy' extension
creating build
creating build\temp.win32-2.7
creating build\temp.win32-2.7\Release
creating build\temp.win32-2.7\Release\win32
...snip...
C:\sulley_build\pcapy-0.10.5>python setup.py install
running install
running build
running build_ext
running install_lib
copying build\lib.win32-2.7\pcapy.pyd -> C:\python27\Lib\site-packages
running install_data
creating C:\python27\share
creating C:\python27\share\doc
creating C:\python27\share\doc\pcapy
copying README -> C:\python27\share\doc\pcapy
copying LICENSE -> C:\python27\share\doc\pcapy
copying pcapy.html -> C:\python27\share\doc\pcapy
running install_egg_info
Writing C:\python27\Lib\site-packages\pcapy-0.10.5-py2.7.egg-info

安装WinPcap这个相信大家机器上都有。

安装Impacket

安装的时候注意要进入到setup.py的目录敲命令

代码语言:javascript
复制
C:\sulley_build\Impacket-0.9.6.0>python setup.py install
running install
running build
running build_py
creating build
creating build\lib
creating build\lib\impacket
copying impacket\ImpactDecoder.py -> build\lib\impacket
copying impacket\ImpactPacket.py -> build\lib\impacket
copying impacket\nmb.py -> build\lib\impacket
copying impacket\ntlm.py -> build\lib\impacket
copying impacket\smb.py -> build\lib\impacket
copying impacket\structure.py -> build\lib\impacket
copying impacket\uuid.py -> build\lib\impacket
copying impacket\__init__.py -> build\lib\impacket
creating build\lib\impacket\dcerpc
...snip...

确认network_monitor.py正常工作

代码语言:javascript
复制
C:\sulley_build\sulley>python network_monitor.py
ERR> USAGE: network_monitor.py
    <-d|--device DEVICE #>    device to sniff on (see list below)
    [-f|--filter PCAP FILTER] BPF filter string
    [-P|--log_path PATH]      log directory to store pcaps to
    [-l|--log_level LEVEL]    log level (default 1), increase for more verbosity

    [--port PORT]             TCP port to bind this agent to

Network Device List:
    [0] \Device\NPF_GenericDialupAdapter
    [1] {CF0B388B-8DF5-4BC4-8ECF-404F2A1B489C}  10.0.2.64

安装到这里基本就完成了。对于windows平台,还存在几个已知的bug。比如连接需要使用ssl的时候,需要修改sulley/sessions.py的486行。把

代码语言:javascript
复制
if self.ssl:

try:
ssl = socket.ssl(sock)
sock = httplib.FakeSocket(sock, ssl)
except Exception, e:
...

替换成

代码语言:javascript
复制
if self.ssl:
try:
import ssl
sock = ssl.wrap_socket(sock)

except Exception, e:
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2014-05-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 FreeBuf 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • 协议分析
  • 工具选择
  • 对有状态的协议进行测试
  • 成果
  • 附录:sulley的windows安装指南
  • 安装python2.7(x64)
  • 安装Git 工具
  • 更新$PATH环境变量,添加C:\Python27 和 C:\MinGW\bin(根据自己的安装路径填写)
  • 安装pydbg
  • 安装libdasm
  • 下载sulley
  • 确认process_monitor.py正常工作。(没有提示缺少模块)
  • 下载解压PCapy
  • 下载解压WinPcap Dev Kit,记下文件路径。这里用C:\sulley_build\WpdPack
  • 编译PCap并安装
  • 安装WinPcap这个相信大家机器上都有。
  • 安装Impacket
  • 确认network_monitor.py正常工作
相关产品与服务
云服务器
云服务器(Cloud Virtual Machine,CVM)提供安全可靠的弹性计算服务。 您可以实时扩展或缩减计算资源,适应变化的业务需求,并只需按实际使用的资源计费。使用 CVM 可以极大降低您的软硬件采购成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档