java审计1:ModelAttribute
前言
本章节是按照 文章 进行 @ModelAttribute 功能点的漏洞审计,以及实际debug中各种执行。
程序 shop1.war可以在原博客主中下载。
配置debug环境
tomcat + idea 远程调试代码
1.安装tomcat
• Tomcat 9.x:支持 Java 8、Java 11、Java 17(及更高版本)。
• Tomcat 10.x:要求 Java 11 或更高版本,主要用于支持 Servlet 4.0 规范及其相关特性。
主机里只有1.8,因此我们用的tomcat 9
https://tomcat.apache.org/download-90.cgi
点击如下zip进行下载
1 | $ unzip apache-tomcat-9.0.95.zip |
2.war包存放路径
$TC/webapps/shop-1.0.0.war
3.tomcat开启远程调试端口
修改文件 catalina.sh,在注释后第一行添加如下
CATALINA_OPTS="-Xdebug -Xrunjdwp:transport=dt_socket,address=8000,suspend=n,server=y"
apache开启与关闭
1 | $TC/bin/catalina.sh start |
检测调试端口是否开启成功
netstat -tuln | grep 8000
如果你想url的根路径就是你的war包的话,可以修改/opt/apache-tomcat-9.0.17/conf/server.xml
默认web服务开放端口8080
开启apache后,通过浏览器访问即可
4.idea2024配置
由于我们是war包,因此得反编译相同结构的java文件内容才行。
如果是当前项目打包好的war放到tomcat中直接debug应该是没啥问题的,但如果是war包反编译弄成java代码后进行debug的话,可能会有行数不一致的情况
在classes文件夹隔壁,新创建一个java文件夹
打开如下设置
选择刚才新创建的java文件夹,然后按照如下进行设置
然后吧classes中所有文件复制过去,把.class文件换成反编译后的.java文件
当然,弄过去后会一堆报错,但实际没关系,关闭语法报错提示正常调试
java文件滑动条这里右键出来
接下来配置调试器
关联到之前apache开放的调试端口
开始调试
在 Java Web 开发中,框架默认是否开启参数自动绑定取决于所使用的框架。Spring MVC 框架默认开启自动绑定,会根据请求中的参数自动将其绑定到控制器方法中的对象或参数。
对象绑定:当请求中的参数名与对象的属性名一致时,Spring MVC 会自动将请求参数的值绑定到对象的对应属性上。例如:
如果请求中有 balance=100 这样的参数,Spring 会将其自动赋值给 user 对象中的 balance 属性。
1.buy路径
路由中我们看到buy路径有 @ModelAttribute 修饰的对象 user
这意味着我们能够修改user中的任意属性
我们查看他有哪些属性
我们能看到代码中有一段使用了setBalance将修改当前的user对象内容。(自动绑定我理解为只是在当前函数中,使用到该参数时,才替换成我们绑定的值,但对象实际的值并不会修改)
那么我们修改user对象中balance的值,就能够修改当前user.getBalance()的内容了。
当然,源代码中也有对该参数进行禁止绑定的配置,但是能够通过大小写进行绕过。
2.profile路径
除了/buy以外,/profile也使用了 @ModelAttribute 修饰user
并且注意到cart.add中利用user的内容进行添加。
那么我们把productId为4的flag添加到我们购物车中即可
还是先debug查看需要什么
那么我们修改这个id即可,注意User中对cart的赋值使用的是 setCartItems,因此传参的时候,传的是 cartItems(大小写应该无所谓)
cartItems[0].id=4
因为是get请求,因此需要全部url编码
(我应该设置的[0],不过不知道为什么所有item都变了)
当然,我们也能用post请求
别直接GET改POST,burp中有修改post功能,帮你添加上post需要的字段
注意
正如之前所说,自动绑定修改的是当前函数修饰的对象所用到的值,对象本身并没改变,因此刷新当前页面就恢复了
修复
使用 DTO 模式,在对象中放入能修改的字段,在后续进行更新
这样,就不能直接自动绑定到user的balance等字段了。
@InitBinder:通过 WebDataBinder 的 setDisallowedFields() 方法指定哪些字段不被绑定。
如源程序中定义了如下
但是由于大小写原因,使用Balance也能进行绑定。。
虽然也有办法检测传输来的参数然后进行手动验证,但感觉还是dto方式好点,直接禁了