本文为博主原创,未经许可严禁转载。
本文链接:https://blog.csdn.net/zyooooxie/article/details/109691608
前面说到 Fiddler 的QuickExec、Filters ,本篇分享 说的是用AutoResponder 来模拟HTTP Basic、Digest认证。
个人博客:https://blog.csdn.net/zyooooxie
AutoResponder
这功能启用后,可以将某一请求的响应结果替换成指定的资源,可以是本地文件,也可以是Fidder内置的各种HTTP响应。
模拟Basic认证
HTTP Basic Authentication 认证过程:
1.客户端向服务器请求数据;
2.服务器认为没有通过认证,向客户端发送401 (WWW-Authenticate: Basic realm=“XXXXXX”);
3.客户端将自动弹出一个登录窗口,要求用户输入用户名和密码;
4.用户输入用户名和密码后,客户端将用户名及密码以BASE64编码加密,发请求(Authorization: Basic xxxxxxxxx);
5.服务器收到上述请求信息后,将Authorization字段后的用户信息取出、解密,将解密后的用户名及密码与用户数据库进行比较验证;
第一步:test_url替换为401_AuthDigest.dat
第二步:浏览器访问test_url,看到弹窗
第三步:手动输入“zyooooxie” 、“csdn” 【用户名:‘zyooooxie’,密码:‘csdn’】
第四步:抓包,查看实际请求
先将用户名及密码以BASE64编码,看看结果:
再看下 Fiddler抓包 结果:
如何来请求呢?
A. 用Postman来看下:
抓包:
回头再看下:
B. 用requests来看下:
1 2 3 4 5 6 7 8 9 10 | res = requests.get('https://www.youxi369.com/gonglue/7814.html', verify=False, auth=('zyooooxie', 'csdn')) # print(res.request.headers) print(res.request.headers['Authorization']) print(res.headers) print() res = requests.get('https://www.youxi369.com/gonglue/7814.html', verify=False, auth=HTTPBasicAuth('zyooooxie', 'csdn')) print(res.request.headers['Authorization']) print(res.headers) |
抓包:
模拟Digest认证
HTTP Digest Authentication 认证过程:
1.客户端先发送请求;
2.服务器端返回401,提示未认证【服务器产生一个随机数nonce,将这个随机数放在WWW-Authenticate响应头,与服务器支持的认证算法列表,认证的域realm一起发送给客户端】;
3.客户端发现是401响应,弹出认证窗口,让用户输入用户名和密码;
4.客户端以用户名,密码,nonce,HTTP方法,请求的URI等信息为基础,产生response进行反馈;
5.服务器重新计算,对客户端反馈的response进行校验,验证是否匹配;
第一步:
第二步:
手动输入’csdn’, ‘zyooooxie’【用户名:csdn;密码:zyooooxie】
第三步:
抓包,查看实际请求
A. 服务器返回401 “Unauthorized” 响应代码,并提供认证域(realm),以及一个随机生成的、只使用一次的数值(密码随机数)nonce。
B. 客户端收到服务器的401(Unauthorized)回复后,使用nonce值,加上username,password, http method, http uri利用MD5(或者服务器指定的其他算法)计算出request-digest,作为repsonse的值。
【客户端发送 响应摘要response=MD5(HA1:nonce:HA2),其中HA1=MD5(username:realm:password), HA2=MD5(method:digestURI)】
细致些:
对用户名、认证域(realm)以及密码的合并值计算 MD5 哈希值,结果称为 HA1。
对HTTP方法以及URI的摘要的合并值计算 MD5 哈希值,例如,“GET” 和 “/dir/index.html”,结果称为 HA2。
对 HA1、服务器密码随机数(nonce)、请求计数(nc)、客户端密码随机数(cnonce)、保护质量(qop)以及 HA2 的合并值计算 MD5 哈希值。结果即为客户端提供的 response 值
如何来请求呢?
C. 用Postman来看下:
抓包:
回头再看下:
D. 用requests来看下:
1 2 3 | res = requests.get('https://www.youxi369.com/gonglue/7814.html', verify=False, auth=HTTPDigestAuth('csdn', 'zyooooxie')) pprint(res.request.headers['Authorization']) pprint(res.headers) |
仔细一看,response这个值 和之前的不同呀!!!
抓包:
cnonce 值 不同。
【cnonce:客户端产生的随机数,用于客户端对服务器的认证。由于“中间人”与“恶意服务器”等攻击方式的存在,导致一个特意选择而非随机唯一的nonce值传给客户端用于摘要的计算成为可能,使得“选择性明文攻击”可能奏效,最后用户密码泄露。因此与nonce一样,cnonce可用于增加摘要生成的复杂性,从而增加破解密码的难度,也就保证了对服务端的认证】
那 python MD5 能不能算出来这个response?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | import hashlib realm = "[email protected]" nonce = "dcd98b7102dd2f0e8b11d0f600bfb0c093" opaque = "5ccc069c403ebaf9f0171e9517f40e41" qop = 'auth' name = 'csdn' pwd = 'zyooooxie' nc = '00000001' cnonce = "0fdb256a7022a4a8" uri = '/gonglue/7814.html' # HA1部分 # 当algorithm值为"MD5"或未指定时 m = hashlib.md5() new = f'{name}:{realm}:{pwd}' print('_MD5加密前为 :' + new) m.update(new.encode(encoding='utf-8')) H_new = m.hexdigest() print('_MD5加密后为 :' + H_new) m2 = hashlib.md5() # HA2部分 # 当qop值为"auth"或未指定时,HA2计算方法如下 new = f'GET:{uri}' print('___MD5加密前为 :' + new) m2.update(new.encode(encoding='utf-8')) H2_new = m2.hexdigest() print('___MD5加密后为 :' + H2_new) # response部分 # 当qop值为"auth"或"auth-int"时,response计算方法如下 response = hashlib.md5('{}:{}:{}:{}:{}:{}'.format(H_new, nonce, nc, cnonce, qop, H2_new).encode()).hexdigest() print('response值:', response) |
cnonce=“98501cd980670b7f”,再算下response值: 61cca301298db8ff321c87d5b1ee479f
和 之前的 Digest username=“csdn”, realm=“[email protected]”, nonce=“dcd98b7102dd2f0e8b11d0f600bfb0c093”, uri="/gonglue/7814.html", response=“61cca301298db8ff321c87d5b1ee479f”, opaque=“5ccc069c403ebaf9f0171e9517f40e41”, qop=“auth”, nc=00000001, cnonce=“98501cd980670b7f” 结果一致;
交流技术 欢迎+QQ 153132336 zy
个人博客 https://blog.csdn.net/zyooooxie