请求参数与请求头FUZZ(参考“我的Web应用安全模糊测试之路“)

https://www.cnblogs.com/wjrblogs/p/13329182.html

参考#

前言#

加一个参数就是一个洞。在挖洞的时候,我注意到一些特殊的请求参数,比如说 outputretypecallbackfunwidthheight 等等,更改其中一些数值,返回包中会出现明显变化。看了大师傅们的文章,才逐渐了解到这些参数以及一些特殊的 http 头的妙用。此文作为一个笔记梳理,并自己尝试写了一个简单脚本(经测试,BUG 巨多😵),以免去使用 BURP 测试那么复杂。

各种类型#

CORS#

众所周知,更改 HTTP 的 Origin 头便可以测试 CORS 漏洞。所以在碰到包含敏感信息的页面的时候,便可以重新发包,加一个 Origin 头。
但是怎么可能这么容易就挖到呢?很多网站在 Origin 头处做了限制,没有匹配其后台规则便不会返回 Access-Control-Allow-Origin 等字段。
常见限制如下:

  
  
Copy
Origin: https://test.com # 白名单,只允许固定的域名 Origin: http://whatever.com # 未做限制 Origin: http://test.com.evil.vom # 域名前缀或必须包含特定域名字符串 Origin: http://sub.test.com # 允许子域名

如果没有匹配上述中的某些规则,网站便不会返回 Access-Control-Allow-Origin 字段,也就无法判断是否存在 CORS
当只测试了一种规则但其没有匹配网站规则,看到没有返回该字段是否就应该放弃?
其实不然,我们可以一个个添加/修改,每一个可能的规则都试一遍。

Content-Type#

不知道师傅们碰到过可修改返回数据类型的参数没有,常见的有 retypeoutputformatdatatype 等。
比如说 output=html、output=json、output=script 或者 retype=1、retype=2、retype=3,1234分别代表不同数据类型
看到下面一个接口的请求包:

  
  
Copy
GET /api.php?kw=<img/src/onerror=alert(!)> HTTP/1.1 Host: test.cn ···

返回包为:

  
  
Copy
HTTP/1.1 200 OK Content-Type: application/json ··· {"wd":"<img/src/οnerrοr=alert(!)>"}

由于严格限定了 Content-Type 头,所以浏览器只会将其作为 json 格式解析。
这个时候是不是没办法了,其实可以尝试添加一些参数
比如说加一个 ?retype=html 参数,返回包可能就会变成 Content-Type: text/html;charset=utf-8
此时浏览器便会将其解析为 html 格式,于是一个反射型 xss 便有了。
当然得承认这个情况很难利用(参数跟值都无法确定),并且也十分少见,但是在 jsonp 劫持的时候就不见得了。

jsonp 劫持#

在请求 json 格式的数据时,请求中常见 callback=testcall=testcb=testfunc=testjsoncallback=test 等参数
且此时返回包数据为 test({"paramer":"value"})
例如:

在这里插入图片描述

可以看到,burp 识别其为 script 格式,当一个个在 burp 中寻找可能的 jsonp 劫持漏洞时,单找 script 格式的数据就会让人疯。因为很多 script 数据内容都是 js 函数
我们再次看到上图,有没有发现在 script 那一栏有两个 JSON 格式的数据?其实很多网站返回信息都为 json 格式。当其中的数据为敏感数据时,由于没有看到回调函数,如 callback 时,是不是这个点就无法利用?
其实此时可以测试能不能利用这些 json 格式的数据造一个 jsonp 劫持呢?此时重点来了:

当请求为:

 
 
Copy
GET /getUser.php HTTP/1.1 Host: test.cn Cookie: xxxxx ···

网站返回一个这样的 json 数据包

 
 
Copy
HTTP/1.1 200 OK Content-Type: application/json ··· {"name":"R0oKi3","phone":"13888888888","addr":"湖南省长沙市···"}

是不是就不能继续测试下一步呢?其实不然:
此时可以修改请求包为:

 
 
Copy
GET /getUser.php?callback=test HTTP/1.1 Host: test.cn Cookie: xxxxx ···

网站便可能会返回:

 
 
Copy
HTTP/1.1 200 OK Content-Type: application/json ··· test({"name":"R0oKi3","phone":"13888888888","addr":"湖南省长沙市···"});

当其他限制(referer、token)不严格时,一个 jsonp 劫持漏洞便有了。

当然,大多 json 格式的数据内容是不包含敏感信息的,那么是不是就没用了?其实也不然。
当用户可控 Content-Type (也就是上一个点)时,并且也能构成不含敏感信息的 jsonp 劫持时,此时便可以考虑构成反射型 xss
http://test.cn/getUser.php?callback=<img/src/onerror=alerrt(1)>&retype=html 便可以形成反射型 xss,因为其返回的数据包中含:Content-Type: text/html;charset=utf-8,浏览器将该数据包解析成了 html 格式

验证码 Dos#

右键打开验证码/二维码等图片的链接,如果看到参数中存在某些键值对,如 width=20&heigth=15 等,并且改变其数值大小时,验证码图片大小也跟着改变时,便可能造成验证码 Dos
当没有这些参数时,便可以考虑自己添加,如 https://test.com/captcha.php?width=2000&height=20000,fuzz 出这些参数,来造成 Dos
并且,当 fuzz 出一个可以控制验证码位数的参数时,如 n=4,也可以将其改为 0 等数字,尝试是否能使验证码失效,或者改为很大的数值,如果图片大小跟验证码位数相关的话,也能造成 Dos

cookie 隐藏参数导致未授权访问#

在 cookie 中添加一些字段,可能会导致未授权访问

 
 
Copy
admin=true access=1 debug=true

具体可见:我的Web应用安全模糊测试之路

小脚本 EasyFuzz.py#

 
 
Copy
""" python3 EasyFuzz.py -u https://test.com -m jsonp -u 或者 -url 指定 url -m 或者 -method 指定要探测的可能漏洞,暂时有的选项有 cors jsonp img 三种漏洞的探测 注意,在传输 url 参数时,url中有 & 符号与要用双引号包裹起来,否则会报错 由于没有采用多线程,所以会丶慢 """ import requests import argparse import re from tld import get_fld jsonps = ["callback", "_callback", "func", "cb", "_cb", "jsonp", "jsonpcallback", "jsonpcb", "json", "jsoncallback", "jbc", "jsonp_cb", "call", "callBack", "jsonCallback", "jsonpCb", "ca", "jsonp_Cb"] headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" } def send(url): rep = requests.get(url, headers=headers) return rep def CorsFuzz(url): # 获取本域名 subdomin = re.findall(r'(http.*://[^/]*)', url, re.DOTALL)[0] protocol = re.findall(r'(http.*://)', url, re.DOTALL)[0] # 获取主域名 domain = get_fld(subdomin) # print(subdomin,domain) # 创建 cors 字典 本身 主域名 任意域名 以其开头 其他子域名 cors = [subdomin, protocol + domain, protocol + "test.com", protocol + domain + ".test.com", protocol + "test." + domain] # print(cors) flag = 0 for cor in cors: headers["Origin"] = cor print("------Origin: " + cor) try: # 获取响应头 # print(url) reph = send(url).headers # print(reph) if "Access-Control-Allow-Origin" in str(reph): print(url + "存在 CORS,其 Origin 头为" + cor + "\n返回值为 Access-Control-Allow-Origin:" + reph["Access-Control-Allow-Origin"]) flag = 1 except: print(url + " 请求错误") if flag == 0: print(url+" 不存在 CORS 漏洞") def JsonpFuzz(url): flag = 0 for jsonp in jsonps: jsonp = jsonp + "=myJsonpFunc" try: if "?" in url: newurl = url + "&" + jsonp print("------" + newurl) rep = send(newurl).content.decode("utf-8") else: newurl = url + "?" + jsonp print("------" + newurl) rep = send(newurl).content.decode("utf-8") if "myJsonpFunc" in rep: flag = 1 print(url + "可能存在 jsonp 劫持,回调函数为:" + jsonp) break except: print(url + " 请求错误") if flag == 0: print(url+" 不存在 jsonp 回调函数") def ImgFuzz(url): # 获取原数据大致大小 repl = len(send(url).content) par = "height=250&width=250&w=250&h=250&size=250&margin=250&font_size&=250length=250" try: if "?" in url: print(url + "&" + par) newl = len(send(url + "&" + par).content) else: print(url + "&" + par) newl = len(send(url + "?" + par).content) except: print(url + " 请求错误") if abs(newl - repl) >= 1000: # 当数据大小相差 1000 时 print(url + "可能存在验证码 Dos\n测试参数为:" + par) def main(url, method): if method=="cors": CorsFuzz(url) elif method=="jsonp": JsonpFuzz(url) else: ImgFuzz(url) if __name__ == '__main__': parser = argparse.ArgumentParser(description='Easy Fuzz') parser.add_argument("-u", "--url", help="指定URL", default="img") parser.add_argument("-m", "--method", help="指定操作") args = parser.parse_args() url = args.url method = args.method # url = "https://baidu.com" # method = "cors" main(url, method)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

J0hnson666

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值