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进行下载

image-20241010202936176
1
2
3
4
5
$ unzip apache-tomcat-9.0.95.zip

$ cd apache-tomcat-9.0.95/

$ TC=$(pwd)

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"

image-20241010203111195

apache开启与关闭

1
2
3
$TC/bin/catalina.sh start

$TC/bin/catalina.sh stop

检测调试端口是否开启成功

netstat -tuln | grep 8000

image-20241010203208761

如果你想url的根路径就是你的war包的话,可以修改/opt/apache-tomcat-9.0.17/conf/server.xml

image-20241010203315018

默认web服务开放端口8080

image-20241010203330170

开启apache后,通过浏览器访问即可

image-20241010203442840

4.idea2024配置

由于我们是war包,因此得反编译相同结构的java文件内容才行。

如果是当前项目打包好的war放到tomcat中直接debug应该是没啥问题的,但如果是war包反编译弄成java代码后进行debug的话,可能会有行数不一致的情况

在classes文件夹隔壁,新创建一个java文件夹

打开如下设置

image-20241011145226148

选择刚才新创建的java文件夹,然后按照如下进行设置

image-20241011145243568
image-20241011145256100

然后吧classes中所有文件复制过去,把.class文件换成反编译后的.java文件

当然,弄过去后会一堆报错,但实际没关系,关闭语法报错提示正常调试

image-20241011145327715

java文件滑动条这里右键出来

file://C:/Users/admin/AppData/Local/Temp/.MWY8U2/1.png

接下来配置调试器

image-20241011145449711
image-20241011145454446

关联到之前apache开放的调试端口

image-20241011145507746

开始调试

在 Java Web 开发中,框架默认是否开启参数自动绑定取决于所使用的框架。Spring MVC 框架默认开启自动绑定,会根据请求中的参数自动将其绑定到控制器方法中的对象或参数。

对象绑定:当请求中的参数名与对象的属性名一致时,Spring MVC 会自动将请求参数的值绑定到对象的对应属性上。例如:

如果请求中有 balance=100 这样的参数,Spring 会将其自动赋值给 user 对象中的 balance 属性。

image-20241010202743976

1.buy路径

路由中我们看到buy路径有 @ModelAttribute 修饰的对象 user

image-20241011145557343

这意味着我们能够修改user中的任意属性

我们查看他有哪些属性

image-20241011145608992

我们能看到代码中有一段使用了setBalance将修改当前的user对象内容。(自动绑定我理解为只是在当前函数中,使用到该参数时,才替换成我们绑定的值,但对象实际的值并不会修改)

image-20241011145640382

那么我们修改user对象中balance的值,就能够修改当前user.getBalance()的内容了。

当然,源代码中也有对该参数进行禁止绑定的配置,但是能够通过大小写进行绕过。

image-20241011145652303
image-20241011145658795
image-20241011145704590

2.profile路径

除了/buy以外,/profile也使用了 @ModelAttribute 修饰user

并且注意到cart.add中利用user的内容进行添加。

image-20241011145757832

那么我们把productId为4的flag添加到我们购物车中即可

image-20241011145807571

还是先debug查看需要什么

image-20241011145818220

那么我们修改这个id即可,注意User中对cart的赋值使用的是 setCartItems,因此传参的时候,传的是 cartItems(大小写应该无所谓)

image-20241011145829136

cartItems[0].id=4

因为是get请求,因此需要全部url编码

image-20241011145841144

(我应该设置的[0],不过不知道为什么所有item都变了)

image-20241011145857520

当然,我们也能用post请求

别直接GET改POST,burp中有修改post功能,帮你添加上post需要的字段

image-20241011145909441
image-20241011145913975
image-20241011145923473

注意

正如之前所说,自动绑定修改的是当前函数修饰的对象所用到的值,对象本身并没改变,因此刷新当前页面就恢复了

image-20241011145949334

修复

使用 DTO 模式,在对象中放入能修改的字段,在后续进行更新

image-20241011150017124

这样,就不能直接自动绑定到user的balance等字段了。

@InitBinder:通过 WebDataBinder 的 setDisallowedFields() 方法指定哪些字段不被绑定。

如源程序中定义了如下

image-20241011150046952

但是由于大小写原因,使用Balance也能进行绑定。。

虽然也有办法检测传输来的参数然后进行手动验证,但感觉还是dto方式好点,直接禁了