Java安全—SPEL表达式XXESSTI模板注入JDBCMyBatis注入

embedded/2025/1/17 2:37:19/

前言

之前我们讲过SpringBoot中的MyBatis注入和模板注入的原理,那么今天我们就讲一下利用以及发现。

这里推荐两个专门研究java漏洞的靶场,本次也是根据这两个靶场来分析代码,两个靶场都是差不多的。

https://github.com/bewhale/JavaSec

https://github.com/j3ers3/Hello-Java-Sec

JDBC注入

JDBC和MyBatis差不多,也是数据库驱动的一种,之前只讲了MyBatis的注入,今天顺便讲一下JDBC注入。直接看漏洞代码好吧,可以看到这种是采用Statement方法拼接SQL语句,没有使用预编译,不用多说这样子包早成sql注入的。

利用一个报错语句即可实现注入。

id=1"' and updatexml(1,concat(0x7e,(SELECT database()),0x7e),1)-- +

接着看使用PrepareStatement方法对SQL语句进行预编译的,它这里的代码还是直接拼接构造sql,那么它的预编译是无效的。

正常查询id = 1。

拼接一下or语句,id = 1 or 1 =1。

还有一种就是采用了JdbcTemplate方法去封装,但如果是拼接构造的SQL语句,那么依旧会产生注入。

安全写法:SQL语句占位符(?)+PrepareStatement预编译。

MyBatis注入

like注入

之前我们说过MyBatis在使用模糊查询like的时候,如果开发者使用#号那么就是预编译,如果使用$号那么就是语句拼接。

可以回顾一下文章

安全mybatis中#{}和${}导致sql注入问题及解决办法_${}sql注入-CSDN博客

Mybatis模糊查询: Select * from users where username like '%#{username}%'

在这种情况下使用 # 程序会报错,开发者为了图个方便直接把#{username}改为${username},从而造成注入。

sql注入语句。

正确写:Select * from users where username like concat('%',#{username}, '%')

Order by注入

这个是由于使用 #{} 会将对象转成字符串,形成 order by  "user"  desc 造成错误,因此很多研发会采用${}来解决,从而造成SQL注入。

看一下代码,${field}表示拼接语句。

sql注入语句。

In注入

in之后多个id查询时使用 # 同样会报错,入。因此很多研发会采用${}来解决,从而造成SQL注入。

例如以下语句${ids}表示拼接,可以构造sql语句。

注入语句:1,2,3) and (updatexml(1,concat(0x7e,(select user())),0))-- -

cms代码审计

我们来对一个cms进行简单的代码审计,找一下注入点。

由于我们这里是白盒测试,所以我们可以看一下它的pom文件,看它引入了什么。可以看到引入了MyBatis数据库驱动,那么就有可能存在我们上面说过的注入问题。

我们直接进行全局搜索好吧,直接搜 %${ 发现没有这种写法。

还有一种写法是 (${,直接搜发现有挺多的。

直接找个具有sql语句的文件打开,可以到存在我们前面说过的In注入。可以看到当id = "deleteArticleByIds"时就会调用这个sql语句进行文章删除,那么我们直接搜索一下这个deleteArticleByIds,看看是啥玩意。

直接搜索可以看到deleteArticleByIds这是一个执行删除文章的方法。

往上滑一下,发现有路由,当我们访问/delete时就是执行删除页面。

但是我们直接访问/delete是不行的,说明上面还有一层路由。

继续往上看,在最上面可以看到一个一级路由,根据注释我们就可以知道应该先访问admin/article进入后台才能访问/delete。

访问后台进行登录,账号密码为admin/111111。

成功登录。

在文章管理的地方我们找到删除操作。

我们进行删除操作,然后抓个包,这里可看到请求的路径是和我们上面说的路由时对应上的,在一级路由/admin/article后面加二级路由/delete才能进行删除操作。

把抓到的数据包丢到sqlmap上一把梭哈,可以看到确实存在sql注入,我们上面分析的没错。

XXE

这个靶场也提供了五种XXE漏洞的实例。

里面还回告诉你在白盒测试中以下函数有可能会造成XXE漏洞,黑盒测试的话就只能看看哪里有处理XXE数据的地方,直接搞个payload去测就行。

模板注入

之前我们交过这个模板注入,就是你引用模板的时候会解析里面的代码,那么我把模板换成java的恶意代码是否可以造成rce呢?来到靶场这里看到有这个thymeleaf模板注入,这个是我们之前讲过的。

提交payload,本地弹出计算机。

来到源码,可以看到模板下面存在en.html,zh.html。

而且SSTI.java类里面模板参数可控,这就会造成模板注入。

这篇文章总结了不同语言下的模板注入,有兴趣的可以看一下。

https://www.cnblogs.com/bmjoker/p/13508538.html

SPEL表达式

这个玩意可以理解为SpringBoot框架中的一种语言,用于在运行时查询和操作对象图,由于未对参数做过滤可造成任意命令执行。可以看一下代码,简单来说就是ex参数可控,传进来的参数通过SPEL表达式进行解析。

参数为100-1时页面显示99。

参数为100-2时页面显示98,这就说明了SPEL表达式会去解析我们ex参数。

这时候我们把参数换成恶意代码,即可造成rce。

还给出了审计函数。

黑名单过滤,可以看到过滤了exec,Runtime,那么上面payload就不能用了,可以看一下下面的文章是如何绕过的。

https://www.freebuf.com/vuls/197008.html

总结

最后,以上仅为个人的拙见,如何有不对的地方,欢迎各位师傅指正与补充,有兴趣的师傅可以一起交流学习。


http://www.ppmy.cn/embedded/154537.html

相关文章

STM32 FreeRTOS 基础知识

多任务处理 内核是操作系统的核心组件。诸如 Linux 这样的操作系统采用的内核, 看似允许用户同时访问计算机。很明显,多个用户可以同时执行多个程序。 每个执行程序都是受操作系统控制的任务(或线程)。如果一个操作系统能够以这…

青少年编程与数学 02-006 前端开发框架VUE 21课题、路由控制

青少年编程与数学 02-006 前端开发框架VUE 21课题、路由控制 一、路由二、路由控制三、应用示例1. 安装Vue Router2. 设置路由3. 在主项目中引入路由4. 创建视图和组件5. 运行项目 课题摘要:本文介绍了Vue项目中的路由控制,包括安装Vue Router、定义路由组件、配置路…

IIS安全配置基线

IIS安全配置基线 1. 限制目录的执行权限2. 开启日志记录功能3. 自定义错误页面4. 关闭目录浏览功能5. 停用或删除默认站点6. 删除不必要的脚本映射7. 专职低权限用户运行网站8. 在独立的应用程序池中运行网站 IIS(Internet Information Services)安全部署…

vue中 子组件在父组件中因为异步问题导致的的underfind报错问题

问题描述 在首页中展示介个相同样式的卡片组件 其中子组件数据为父组件发送数据请求后获取 使用props进行传值处理 这时候我发现控制台出现了underfind报错 原因 当父组件通过 props 向子组件传递数据时,如果数据在父组件中是异步获取的(例如通过 AP…

APISQL在线一键安装教程

本文档将指导您在 Linux 服务器上使用 Docker 安装 APISQL 软件。提供了两种安装方式:在线安装和离线安装,您可以根据实际环境选择合适的安装方式。 1. 准备工作 1.1 硬件要求 Linux (x86_64) 服务器 1.2 软件要求 Docker Engine 推荐版本&#xff…

【算法与数据结构】—— 回文问题

回文问题 目录 1、简介2、经典的回文问题(1) 判断一个字符串是否为回文(2) 给定字符集求构建的最长回文长度(3) 求最长回文子串方法一:中心拓展方法二:Manacher 算法 (4) 求回文子串的数目方法一:中心拓展方法二:Manacher 算法 1、…

Flutter中Get.snackbar避免重复显示的实现

在pubspec.yaml中引入依赖框架。 #GetX依赖注解get: ^4.6.5创建一个SnackBarManager管理类去管理每个提示框。 import package:get/get.dart; import package:flutter/material.dart;class SnackBarManager {factory SnackBarManager() > instance;static final SnackBarMa…

《零基础Go语言算法实战》【题目 2-11】属性的权限

《零基础Go语言算法实战》 【题目 2-11】属性的权限 下面代码的输出是什么? type Programmer struct { name string json:"name" } func main() { js : { "name":"18" } var p Programmer err : json.Unmarshal([]byte(js), &am…