Java代码审计初探

小子比较菜,初学java审计 记录一下下,大佬勿喷

因酷教育网校平台SQL注入

https://gitee.com/ms_git/demo_inxedu_open
gitee下载
ce6b26b296d35955e4ee963c2ddd7f6f.png
下载之后导入IDEA
配置SDK版本
7961e103a4dd3376244cc2788d8180f4.png
配置maven ,不然很多库加载不出来
91a1bf21f5a50548a077799f8bd38701.png
配置tomcat
5bb2107e8584bd7de23ce77adf0b2bad.png
数据库已经配置导入了
然后启动
a81e84c7e9906697b95e052ed1c6615e.png
这个页面有点点问题但是不影响 。
找sql注入了 一般是搜索一些关键字

${
select
insert
update
delete
order by


java.sql.Connection:表示与数据库的连接。
getConnection():用于建立数据库连接的方法。
Statement:执行 SQL 语句的接口。
execute():执行任何类型的 SQL 语句的方法。
executeQuery():专门用于执行返回 ResultSet 的 SQL 查询(SELECT 语句)的方法。
PreparedStatement:用于执行预编译的 SQL 查询的接口。
jdbcTemplate:Spring 框架中用于简化 JDBC 操作的类。
queryForInt、queryForObject 和 queryForMap:jdbcTemplate 类中用于执行 SQL 查询并返回不同类型结果的方法。

#{ 这样也算是预编译了  和 用PreparedStatement  ? 预编译差不多

总所周知预编译可以防止sql注入
了解一下预编译代码

String sql = "SELECT * FROM users WHERE username = ? AND password = ?";
preparedStatement = connection.prepareStatement(sql);

先来全局搜一下 ${
文件可能是java 和 xml 文件都要看
6cd95f8ecba349b19d99498346454a32.png
这里可以发现使用delete 来删除广告图片 使用的是 IN子句的SQL查询 然后 value是用 ${value}包裹的
跟进去看看

<!-- 删除广告图片 -->
 <delete id="deleteImages" parameterType="java.lang.String">
  DELETE FROM EDU_WEBSITE_IMAGES WHERE IMAGE_ID IN(${value})
 </delete>

继续往上找可控点 搜索deleteImages
51ccdffa8d9b9d5bdc1073f8e138fdb6.png
这里创建了 deleteImages方法 传入了 imageIds

public void deleteImages(String imageIds) {
  websiteImagesDao.deleteImages(imageIds);
  EHCacheUtil.remove(CacheConstans.BANNER_IMAGES);
 }

3f1564fef11f21677317156a748482d6.png
按住Ctrl + 鼠标左键 定位上一个调用的
509281fea07c54e65d7f9ac65ea2033f.png
会来到这里
现在我们找到了接口 传参的可控点
但是这里是一个后台的功能 哈哈
http://127.0.0.1:8080/admin/website/imagesPage
3bfa0dd2d0a1a4125a1146bae8c40dbf.png
我们点击删除抓包
257010ff1460eaf5771b231ec8217186.png
接口 可控点都是正确的 。一开始发包过去看的时候 是302 跳转
在实战中,如果是我的话可能不会想到这里存在sql注入 哈哈比较菜
简单点sqlmap直接跑
cf45329049ff8deee064ab1db0c037f1.png
7f0318c506bdc1b2b320f8d7757b402b.png
e2b78a67dbccd5cbf1e5a7465d1d66c5.png
这里可以证明是存在sql注入的了

第二个点 sql注入的点
88d2b7a8cc83cd7fd63c77f181af304c.png

DELETE FROM EDU_ARTICLE_CONTENT WHERE EDU_ARTICLE_CONTENT.ARTICLE_ID IN (${value})

依旧使用IN字句查询
继续找
785f2496be82486f844c2b847659b421.png
继续往下跟
1faef3e0ddd70dcaae63502715c3b7ec.png
来到了这里
如果传入的articleIds 不为空就会进入循环 赋给 ids
然后会根据传入的articleIds值进行调用deleteArticleByIds(ids) 然后进行删除
继续跟 deleteArticleByIds
9dd9622267a40a711cf8c592a9351781.png
然后就来到了这里
继续跟deleteArticle 方法 这是一个删除的
ee38317e875d6f24399623dda675dad7.png
然后来到了这里

@RequestMapping("/delete")
public ModelAndView delete(HttpServletRequest request) {
ModelAndView model = new ModelAndView();
try {
    model.setViewName(this.getRequestUri(request));
    String[] aridArr = request.getParameterValues("articelId");
    if (aridArr != null && aridArr.length > 0) {
        this.deleteArticle(aridArr);
    }
} catch (Exception e) {
    model.setViewName(this.setExceptionRequest(request, e));
    logger.error("AdminArticleController.delete()--error", e);
}
return model;
}

主要的代码

String[] aridArr = request.getParameterValues("articelId");

传入了articelId 接口 delete 完整接口/admin/article/ delete
4293a058e0215164f8e124d5f04690f3.png
细心会发现 getParameterValues 函数
和前面一个sql注入调用的是一个
7f4f9e8a1cea01b416a46e9303be4115.png
接口 传参 漏洞点知道了 验证一下
b31d4a05b734c6e6e39a7d818afaf83d.png
1f202d1ac84b0d0a19edf31aba462562.png
sqlmap 验证
b8d01432e81ac4712331ff2b1b8eba8a.png
2ad189aa48d20e928f40e52b5ea36d16.png
这个系统还有很多处sql注入
这个系统是 MyBatis 框架的 #{是可以防止sql注入的
f477ed7cc7bb71f79266c8be4e8ffe1a.png
可以发现里面有些地方使用了#{}进行预防 ,但是很多地方还是使用${去使用 ,然而造成了漏洞。

因酷教育网校平台任意文件上传

文件上传常见函数 或者参数

DiskFileItemFactory
@MultipartConfig
MultipartFile
File
upload
InputStream
OutputStream
write
fileName
filePath

先来搜索一下 upload
e043f5b3e4683caab4a4454005849dbf.png
这里出现一个视频上传的接口

@RequestMapping(value="/uploadvideo",method={RequestMethod.POST})
public String gok4(HttpServletRequest request,HttpServletResponse response,@RequestParam(value="uploadfile" ,required=true) MultipartFile uploadfile,
                   @RequestParam(value="param",required=false) String param,
                   @RequestParam(value="fileType",required=true) String fileType){

这是他的一个接口 参数
主路径在开头
5d2dec5a469eceb8937dbe33442bacc1.png

POST /video/uploadvideo?param=&fileType

在后台找半天没有找到上传视频这个点
接口参数有了 我们直接上传一个文件获取数据包
855927c3bf07e0528a29d0131397d884.png
把这个数据包的 请求替换为自己找的这个
d7b412ca57429a016fca6cb5fc36b88f.png
原本是长这样 替换接口
fd914b9abceb2fdb5dc971e758edfff4.png
他这里的fileType 类型可控,原本是只有那几种图片类型。
由于这里可控filetype 造成任意文件上传
分析一下 代码
a5de67ca2307eb570411264ba15ff299.png
这段代码由于filetype是可以用户自己设定,造成文件上传漏洞,这里可以写一个白名单

List<String> allowedFileTypes = Arrays.asList("jpg", "jpeg", "png", "gif", "mp4", "avi");

只运行上传这几个类型后缀

第二个漏洞点,他这里做了一个简单的校验
就是一开始找图片上传的地方
3e7570b17641cc7977b6de30c41707a8.png
数据包

POST /image/gok4?&param=online&fileType=jpg,gif,png,jpeg&pressText=undefined HTTP/1.1
Host: 127.0.0.1:8080
Content-Length: 8740
Cache-Control: max-age=0
sec-ch-ua: 
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: ""
Upgrade-Insecure-Requests: 1
Origin: http://127.0.0.1:8080
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary8u8KcA4F9WoK4tkH
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.5845.111 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: iframe
Referer: http://127.0.0.1:8080/admin/websiteProfile/online?tabPageId=jerichotabiframe_8
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cookie: remember-me=YWRtaW46MTcxODk3MDQ3MDU0NzowZWFlOWEwZmQzY2QzYWVlM2MwZjNjMWVkOWVjNDk3MA; inxedulogin_sys_user_=inxedulogin_sys_user_1; JSESSIONID=4DB22884B104B1636BD64E45638ECB69
Connection: close

------WebKitFormBoundary8u8KcA4F9WoK4tkH
Content-Disposition: form-data; name="uploadfile"; filename="downloadApp.png"
Content-Type: image/png

接口
/image/gok4
他这个接口是自己重写的,在lib目录下
1af149ecb09e0b93b55b506a2807899f.png
可以发现这里存在这么一段代码

f (fileType.contains(ext) && !"jsp".equals(ext)) {
                    String filePath = this.getPath(request, ext, param);
                    File file = new File(this.getProjectRootDirPath(request) + filePath);
                    if (!file.getParentFile().exists()) {
                        file.getParentFile().mkdirs();
                    }

这里做了一个防止上传jsp的操作 ,如果上传类型为jsp就上传失败
6e815b3548bb109554ae053bd0f9d9fb.png
但是我们知道可以使用几种方式绕过
既然不能写jsp 这里可以写jspx
a16baee994c06f16e9d509bc526d1ccd.png
也可以使用
.jsp::$DATA: 绕过
上传一个木马尝试
4ccf46cac37fde3ba67f1ec2ef4294ec.png
这样就成功上传了 链接一下
b28a9a1192980c4f22d2772fe66be517.png
b56f35813ee5270223150ef7cb9a1f1f.png
成功上传
这两个漏洞都是比较简单,而且都是未授权上传 不需要cookie ,只是功能点在后台
ec3da0b34b000c10c18de90f21c779ce.png
删除cookie 依旧可以成功上传。

JFinalCMS 任意文件读取/下载

网上存在这个漏洞
d7314736859e9514756dfc37f61d7b79.png

可以发现接口是 /common/down/file
来分析一下
c5815986214491758aa1d2e4f0ee4f03.png
搜索/down/file 可以看出是一个下载的功能
点击第一个
462692017cf545faf95de5a18582dd5a.png
这里的file 也是一个路径
file 定义了一个处理文件下载请求的方法。
参数是fileKey

renderFile(new File(PathKit.getWebRootPath() + fileKey))

使用PathKit.getWebRootPath()获取web根目录路径,并拼接fileKey参数值生成文件路径,然后调用renderFile方法返回该文件。
比如路径是 xx.cn/common/down/file?fileKey=xx.html
可以通过../../../去获取路径下的文件 来调试一下
44fb9afd68d065fa80010fb68c0e8af1.png

看idea
5be0a8c9752e306f6b2b8a3fedf93a4d.png
看步入之后会显示路径
a7f1b287653eb15f251403fcc18fc51a.png
这是他的路径 我 前面输入的xx.html是有问题可以看见 他直接连在跟目录上了
b6e13384ca7d1f4180b4e1753cd11860.png
就会报错
7aa34c28e7715f452af5e121171f1d75.png
我们重新来
我们读取上一级目录下的test文件
89bfa5e0520084744f30d81673fcf060.png
d29e8ecb042a138a0686cf9a6f3f4e76.png步入
52f9fc2bb824de8272cc28c05ac24c1b.png
这样就会跳转到webapps下的test.txt文件了
burp更加清晰
638a0a8058f8a6960bf00f14550fac15.png
可以成功的读取到 。
这里就是直接用PathKit.getWebRootPath()获取web根目录路径 然后就直接拼接了fileKey的参数导致的文件读取/目录遍历。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值