01
—
起因
最近补习班机构开设了一套机考系统,需要集赞才能够领取使用。
我硬是在小号一个一个加了18个人才凑够了数量成功领取(无奈大号添加的人实在太多)
闲来无事的我便是测试一下是不是有漏洞呢?
想来它肯定是搭建在了公网上了,才能做到让学生在线答题排名。
(因为之前想过对另一个系统开展测试,但遗憾的是系统是搭建在内网上的,学生只能在线下机房才能参与考试,无奈只能放弃。)
02
—
展开思路
拿到站点之后
拿到目录探测工具里扫一下
可以看到有不少东西,在后台登录口进行了弱口令、js未授权均无果。
不过没关系,这次报告的重点不在这里哈哈
还是回到重点,学生端的使用入口
|首先第一个小瑕疵
这里的登录验证码并不会随着登录而刷新,可以重复使用,一般的OCR就可以对其识别,给了攻击者暴力破解密码以及用户枚举的机会。
03
—
正式开始漏洞挖掘之旅
登录账号
对页面的功能点展开思考
1.用户的个人信息界面
站点会和服务器进行数据请求和交换----看看有没有控制用户参数,可能出现越权漏洞
可以看到有头像的存在,说明可以进行文件上传---可以测试xss和getshell
2、3.我的笔迹与习题收藏
站点会和服务器交互显示用户储存的题目等信息-----可以测试sql注入、注入写马
4.套卷练习
本系统需要vip兑换码成为会员身份才可以进行套卷练习--可测SQL注入、未授权vip身份
5.退出点
结合头像上传处可以考虑退出链接替换头像url造成csrf漏洞,效果就是看到头像的用户就会自动退出账号,再次发散思想,可以尝试注销账号、修改密码等csrf如果造成看到头像的用户就自动注销自己的账号绝对就是高危漏洞。
04
—
漏洞一xss
这个漏洞也是有点奇怪
报错信息是从用户端发包给服务端然后再显示的,而不是输入了错误的兑换码然后服务端返回报错信息,这就导致用户输入的字段会回显在页面上(xss可测)
报错信息
%E6%BF%80%E6%B4%BB%E6%8F%90%E7%A4%BA&msg=%E5%8D%A1%E5%8F%B7%E6%88%96%E5%AF%86%E7%A0%81%E9%94%99%E8%AF%AF%EF%BC%8C%E8%AF%B7%E7%A1%AE%E8%AE%A4%EF%BC%8C%E8%B0%A2%E8%B0%A2%EF%BC%81
解码后
激活提示&msg=卡号或密码错误,请确认,谢谢!
我们尝试替换为<script>alert(安心落意)</script>
成功弹窗,xss漏洞一枚
05
—
进入下一界面,展开思考
进入下一界面,展开思考
1.最重要的漏洞,想要达到没有会员兑换码也可以享受会员身份的效果
尝试:翻看js代码进行审计,看看兑换成功or失败是否存在返回包的明显不同,尝试进行修改看看能不能绕过判定逻辑。
2.用户填写兑换码---数据库校验是否存在--返回结果 测试SQL注入
首先输入错误的兑换码看看数据包
在源码中输入passwordError搜索,可以看到逻辑
var msg = "";
var flag = false;
if (result.entity == 'passwordError') {
msg = "卡号或密码错误,请确认,谢谢!";
} else if (result.entity == 'userError') {
msg = "该会员卡已被使用!";
} else if (result.entity == 'usedError') {
msg = "该会员卡已被使用!";
} else if (result.entity == 'overdueError') {
msg = "该会员卡已过期!";
} else if (result.entity == 'destroyError') {
msg = "该卡已作废,不能进行激活,请确认!谢谢";
} else if (result.entity == 'typeError') {
msg = "卡号或密码错误,请确认,谢谢!";
} else if (result.entity == 'succeed') {
dialog('激活提示', "您的会员卡已兑换成功!", 0);
flag = true;
setTimeout(function () {
window.location.reload();
}, 2000);
}
if (!flag) {
$('.dialog-shadow').remove();
dialog('激活提示', msg, 1);
}
} else {
dialog('激活提示', result.message, 1);
setTimeout(function () {
window.location.reload();
}, 2000);
}
06
—
未授权漏洞,享受VIP身份
再次输入错误兑换码,并且拦截,修改数据包
可见前端已经显示兑换成功,但是先别着急,有可能显示还是没有会员权限的
成功,以前做不了的卷子都可以做喽 由于这是系统核心功能点 高危逻辑+1
07
—
逻辑漏洞,任意账户接管()
继续挖掘
接下来,也是整个渗透过程的最亮点(),可以修改全站用户的账号,并且查看密码等敏感个人信息,接管用户账号期间被害者全程无感。
(注意是修改用户的账号而不是密码,由于注册时填写的手机or邮箱就是账号,用户是无法通过发送验证码找回的,永久接管)
思路:尝试修改userid尝试越权;这里还有一个出乎我意料的点,就是居然有mobile这个字段,修改手机号本应该是需要验证码等手段经过授权才能够修改的,但是这里就直接出现了,这个思考也是直接引起了后面的漏洞。
信息字段汇总
user.userId=
user.sex=1
user.showName
user.subject
mobile=
user.email
user.picImg=/imag/xxxxx/089871.jpg
登录AB不同账号,拿到不同的userid
尝试修改userid,虽然数据包仍然返回成功,但是没有修改另一账号的信息。然后尝试部分删除cookie后直接显示302,这里心想应该就是没有洞了,很显然鉴权参数融入了cookie。Userid无用。
但是随后的测试又让我改变了这一想法,因为,csrf居然测试成功???
心想不应该啊,csrf居然能成功说明鉴权信息出现了缺陷,回头去看数据包
这是csrf发出的包
这是原来的数据包
没错,cookie中缺少了JSESSIONID,这时候我拿缺少JSESSIONID的包去修改userid居然发现成功了。Cookie变成了万能cookie,可以用于任意用户的信息修改。
userid为32281 手机号为15511xxxxx
修改userid为32070,返回手机号被占用,此时再修改一下任意手机号的数字即可绑定成功!
任意用户账号修改成功!
假如黑客遍历userid,把手机号改成13888888976这样的号码,可以说是很难自己找回了
导致全站用户丢失学习记录,做题进度,危害极大。
密码是MD5,解密即可登录。
|关于JSESSIONID
JSESSIONID 是Java Servlet技术中用于维持Web应用用户会话的一个标识符。当用户访问基于Java Servlet容器(如Apache Tomcat、Jetty等)构建的Web应用程序时,服务器会为每个新的、未携带会话标识的HTTP请求分配一个新的会话对象,并生成一个唯一的JSESSIONID作为该会话的标识符。
具体工作流程如下:
会话创建:
当用户首次访问Web应用时,如果应用内有创建会话的动作(比如调用了 HttpServletRequest.getSession() 方法),服务器会为该用户创建一个会话,并生成JSESSIONID。
会话标识传输:
JSESSIONID通常以两种方式传递给客户端:
作为Cookie发送到用户的浏览器,浏览器在后续对同一服务器的请求中自动携带此Cookie。
如果用户禁用了Cookie,服务器还可以通过URL重写的方式,即将JSESSIONID附加在每个动态资源URL的查询字符串或路径部分,以便在每次请求时都能传递会话标识。
会话管理:
服务器端通过JSESSIONID来识别不同的用户会话,从而能够维持用户的状态信息,如登录状态、购物车内容或其他临时数据。
JSESSIONID的生命周期取决于服务器端的会话管理策略,包括会话超时设定、手动失效(通过HttpSession.invalidate()方法)或者浏览器关闭(若仅依赖Cookie且不启用持久化会话)等情况。
总之,JSESSIONID是Java Web应用程序中用于跟踪用户会话的关键标识,确保了在无状态的HTTP协议基础上实现有状态的用户交互过程。
在此系统中删除了JSESSIONID,创造了一个万能用户的标识。