请问如何在两个节点之前传递信息,login节点生成的动态url需要传递到PING结点使用,代码如下
session.connect(s_get("GET-LOGIN"))
session.connect(s_get("GET-LOGIN"),s_get("GET-PING"),callback=judge_status)
Boofuzz是Sulley模糊测试框架的一个分支和继承者。除了修复了许多错误,boofuzz还提升了可扩展性。主要特性有以下几点:
ubuntu;基于python2.x
sudo apt-get install python-pip
git clone https://github.com/jtpereyda/boofuzz.git
cd boofuzz
sudo pip install .
windows:
git clone https://github.com/jtpereyda/boofuzz.git
pip install .
pre_send() 发送数据后开始遍历Pgraph结构,并沿途fuzz每个组件。这个例子以'helo' requet开头,一旦完成,将开始fuzz “maiL from” request。它通过在每个测试用例前面加上有效的“helo” request来实现。 接下来,将继续fuzz 'rcpt to’ request。同样,这是通过在每个测试用例前面加上有效的“helo”和“mail from” request来实现的。等到该过程一直到”data” request完成后,又转回到从”ehlo”开始。通过构建的Pgraph将协议分解为单个请求,并fuzz所有可能路径,使其fuzz能力十分的强大。
每个节点都连接起来,组成一幅有状态的图,我们可以在图里的每个节点进行操作,同时也可以定义一些callback回调函数,以实现诸如质询响应系统之类的功能,回调方法必须遵循以下原型:
def callback(target, fuzz_data_logger, session, node, edge, *args, **kwargs)
'fuzz_data_logger'记录测试检查和通过/失败
'session'是一个指向会话实例的指针,它对于阻塞例如session.last_recv的数据很有用
'node'是要发送的节点
'edge'是当前fuzz到node的最后一条路径
我们每次创建测试脚本的时候都会使用Session,session.connect() 用来声明连接,session.fuzz() 发送负载,以及定义会话回调和选择的协议进行交互,例如
session = Session(
target=Target(
connection=SocketConnection("127.0.0.1", 21, proto='tcp')))
session.connect(s_get("xxx"))
session.fuzz()
Request是信息,Blocks是消息中的块,而Primitives是构成块/请求的元素(字节,字符串,数字,校验和等)。
Block和Group是Boofuzz从Sulley继承而来的强大工具。Blocks将独立的primitives组建成有序的块。Groups 中包含了一些特定的primitives,一个Group和一个Block结合后,每次fuzzer调用Block的时候,都会将Group中的数据循环的取出,组成不同的Block。
Group允许你连接一个块到指定的group原语,和一个组关联的block必须为每一个组中的值循环穷尽该block的所有空间,例如,在表示一个有效的opcode列表或一些有相同参数的行为时,组原语是非常有用的,s_group定义一个组,并接受两个必须的参数,第一个参数指定组名称,第二个参数指定一个需要迭代的原始值列表。
例如下面官方给出的http.py中的代码
s_initialize("HTTP VERBS")
s_group("verbs", values=["GET", "HEAD", "POST", "TRACE", "PUT", "DELETE"])
if s_block_start("body", group="verbs"):
s_delim(" ")
s_delim("/")
s_string("index.html ")
s_delim(" ")
s_string("HTTP")
s_delim("/")
s_string("1")
s_delim(".")
s_string("1")
s_block_end()
模块常用语法
s_initialize('grammar')#初始化块请求并命名
s_static("HELLO\r\n")#始终发送此信息
s_static("PROCESS")#在HELLO\r\n之后立即发送
s_delim("")# 使用s_delim()原语代替分割符
s_string("AAAA")# 这是我们的fuzz字符串
s_static("\r\n")# 告诉服务器“done”
target = sessions.target("10.0.0.1", 5168)
target.netmon = pedrpc.client("10.0.0.1", 26001)
target.procmon = pedrpc.client("10.0.0.1", 26002)
target.vmcontrol = pedrpc.client("127.0.0.1", 26003)
target.procmon_options = \
{
"proc_name" : "SpntSvc.exe",
"stop_commands" : ['net stop "trend serverprotect"'],
"start_commands" : ['net start "trend serverprotect"'],
}
sess.add_target(target)
sess.fuzz()
首先是定义目标,加入会话
下面的netmon(网络监控代理) 、procmon(进程监控代理)、vmcontrol(VMware控制代理)为3个agent的子模块,用来监测程序
下面简单介绍一下请求样例:
session.connect(s_get("user"))
session.connect(s_get("user"), s_get("pass"))
session.connect(s_get("pass"), s_get("stor"))
session.connect(s_get("pass"), s_get("retr"))
连接后,我们首先发送用户名请求
在发送用户名后,我们发送密码
只有在发送密码后我们才能发送stor或retr请求
Vulnserver是一个多线程的基于Windows的TCP服务器,它侦听端口9999上的客户端连接(默认情况下),并允许用户运行许多不同的命令,这些命令容易受到各种类型的可利用缓冲区溢出的攻击。它在github的地址为https://github.com/stephenbradshaw/vulnserver
我们启动vulnserver
我们使用nc命令,连接服务端9999端口即可。发出HELP命令(区分大小写),查看程序有哪些功能
from boofuzz import *
def main():
port = 9999
host = '10.211.55.17'
protocol = 'tcp'
session = Session(
target=Target(
connection = SocketConnection(host, port, proto=protocol),
),
)
s_initialize("trun")
s_string("TRUN", fuzzable=False)
s_delim(" ", fuzzable=False)
s_string("FUZZ")
s_static("\r\n")
session.connect(s_get("trun"))
session.fuzz()
if __name__ == "__main__":
main()
首先,我们先设置请求,然后定义命令的名称,空格分隔符和参数,最后发送请求,开始fuzz
在fuzz的时候我们可以打开http://127.0.0.1:26000 上的Web界面中观察fuzz测试进度。这是一个boofuzz内部Web服务器,向我们显示fuzz过程完整性和导致崩溃的输入文件。
我们可以看到程序已经崩溃,但是fuzz的脚本依然在运行,而且无法精确定位漏洞
这时候我们增加一个回调函数
session.connect(s_get("trun"), callback=get_banner)
def get_banner(target, my_logger, session, *args, **kwargs):
banner_template = "Welcome to Vulnerable Server! Enter HELP for help."
try:
banner = target.recv(10000)
except:
print "Unable to connect. Target is down. Exiting."
exit(1)
my_logger.log_check('Receiving banner..')
if banner_template in banner:
my_logger.log_pass('banner received')
else:
my_logger.log_fail('No banner received')
print "No banner received, exiting.."
exit(1)
banner在每次fuzz接收后尝试接收字符串,接收不到报异常"Unable to connect. Target is down. Exiting.",如果接收到的字符能够与正常交互的字符串匹配上,我们记录下然后返回fuzz继续测试,如果不匹配程序结束
我们可以看出,在程序崩溃后,fuzz停止,接下来我们尝试记录程序崩溃,并找到原因
我们先增加日志记录,首先我们创建一个csv文件,然后创建一个my_logger对象,调用FuzzloggerCsv()函数,Fuzz_loggers记录测试数据和结果
csv_log = open('fuzz_results.csv', 'wb')
my_logger = [FuzzLoggerCsv(file_handle=csv_log)]
fuzz_loggers=my_logger,
我们首先在端口26002上侦听本地主机的进程,监视应用程序,然后设置选项,我们把程序和process_monitor.py放在同一目录下
需要注意的是process_monitor.py仅限于在windows使用(为Unix提供process_monitor_unix.py),而且需要安装pydasm和pydbg
procmon=pedrpc.Client(host, 26002),
procmon_options = {
"proc_name" : "vulnserver.exe",
"stop_commands" : ['wmic process where (name="vulnserver") delete'],
"start_commands" : ['vulnserver.exe'],
}
我们运行起来process_monitor.py和fuzz脚本,我们发现EIP被41414141覆盖,并发生崩溃
我们查看一下fuzz_result.csv文件,如果我们使用sulley我们需要找到存储流量的PCAP文件 ,并定位payload,而我们使用boofuzz直接查看csv文件就可以
我们可以清晰的看到payload,我们可以用于复现和利用
下面是完整的fuzz代码:
from boofuzz import *
from sys import exit
def get_banner(target, my_logger, session, *args, **kwargs):
banner_template = "Welcome to Vulnerable Server! Enter HELP for help."
try:
banner = target.recv(10000)
except:
print "Unable to connect. Target is down. Exiting."
exit(1)
my_logger.log_check('Receiving banner..')
if banner_template in banner:
my_logger.log_pass('banner received')
else:
my_logger.log_fail('No banner received')
print "No banner received, exiting.."
exit(1)
def main():
port = 9999
host = '127.0.0.1'
protocol = 'tcp'
s_initialize("Vulnserver")
s_group("verbs", values=["TRUN", "GMON", "KSTET"])
if s_block_start("test", group="verbs"):
s_delim(" ")
s_string("AAA")
s_string("\r\n")
s_block_end("test")
csv_log = open('fuzz_results.csv', 'wb')
my_logger = [FuzzLoggerCsv(file_handle=csv_log)]
session = Session(
target=Target(
connection = SocketConnection(host, port, proto=protocol),
procmon=pedrpc.Client(host, 26002),
procmon_options = {
"proc_name" : "vulnserver.exe",
"stop_commands" : ['wmic process where (name="vulnserver") delete'],
"start_commands" : ['vulnserver.exe'],
}
),
fuzz_loggers=my_logger,
crash_threshold_element= 1,# Crash how much times until stop
)
session.connect(s_get("Vulnserver"), callback=get_banner)
session.fuzz()
if __name__ == "__main__":
main()
本文主要是利用boofuzz发现Vulnserver的漏洞,至于利用部分可以参考http://www.thegreycorner.com/p/vulnserver.html
https://blog.csdn.net/u012397189/article/details/79758931