java web常见lou洞

1、使用IDEA和PhpStudy搭建hello-java-sec 靶场并成功运行

下载解压hello-java-sec靶场后,启动phpstudy的mysql,用idea打开hello-java-sec靶场

配置数据库

保证jdk版本1.8,保证各项依赖正常导入,即可成功



2、分析常见的java sql注入漏dong代码样例,包含jdbc、mybatis注入并结合靶场进行漏dong复现

JDBC有两种方法执行SQL语句,分别为PrepareStatement和Statement。两个方法的区别在于PrepareStatement会对SQL语句进行预编译,而Statement方法在每次执行时都需要编译,会增大系统开销。

Statement方法啊,其实就是直接对用户输入进行了拼接,非常明显的sql注入lou洞。靶场复现如下图

PrepareStatement方法支持使用'?'对变量位进行占位,在预编译阶段填入相应的值构造出完整的SQL语句,此时可以避免SQL注入的产生。但开发者有时为了便利,会直接采取拼接的方式构造SQL语句,此时再进行预编译则无法阻止SQL注入的产生。如以下代码所示,PrepareStatement虽然进行了预编译,但在以拼接方式构造SQL语句的情况下仍然会产生SQL注入。

靶场复现如下图,已经拼接了,再编译有什么用

靶场还有JDBCTemplate示例,JDBCTemplate是Spring对JDBC的封装,如果使用拼接语句便会产生注入。代码如下,截图不全,但是看重点,拼接语句执行查询,还是有lou洞

如果我们输入参数2 or 1=1,理论结果是返回所有user,但是出现了报错,看到下图

那么我们仔细回顾一下代码JdbcTemplate.queryForMap() ← 期望只返回1条记录

但实际返回了3条记录

于是抛出了异常,那么我们修改参数添加limit 1如下图,成功拿到id为1的完整数据

JDBC方式是将SQL语句写在代码块中,不利于后续维护。如今的Java项目或多或少会使用对JDBC进行更抽象封装的持久化框架,如MyBatis和Hibernate。通常,框架底层已经实现了对SQL注入的防御,但在研发人员未能恰当使用框架的情况下,仍然可能存在SQL注入的风险。

MyBatis 是一个流行的Java持久性框架,通过预处理和参数绑定的方式,有效地防止SQL注入攻ji

但如果 MyBatis 框架的使用不当或未正确配置,仍然可能存在SQL注入的风险。比如拼接符 ${} ,从而造成了SQL注入lou洞

靶场order by注入代码如下:

/**


*/

@GetMapping("/vul/order")

public List orderBy(String field, String sort) {

return userMapper.orderBy(field, sort);

}

// 不安全的注解写法

public interface UserMapper {

@Select("select * from users order by {field} {sort}")

List orderBy(@Param("field") String field, @Param("sort") String sort);

}

// 不安全的XML映射写法

select * from users order by {field} {sort}

/**


*/

💥 lou洞原理与攻ji场景{field}和 {sort}会直接将传入的参数值替换到SQL语句中。MyBatis不会对其进行任何处理,就如同字符串拼接。这导致用户输入可以被用来改变SQL语句的原始结构。

攻ji者可以通过操纵 field或 sort参数,注入恶意的SQL片段。比如,攻ji者可以传入这样的参数:

field参数为:id; DROP TABLE users; --

sort参数为:ASC(此时它是什么已经不重要了)

最终生成的SQL语句会变成:

select * from users order by id; DROP TABLE users; -- ASC

这条语句执行时,会先正常查询,然后直接删除 users表,导致灾难性后果。--是SQL注释符,它后面的 ASC会被忽略。

除了这种极端情况,攻ji者还可以利用漏dong:

窃取敏感数据:通过联合查询(UNION SELECT)获取数据库中的密码、个人信息等

探测数据库结构:获取其他表名和字段名,为进一步攻ji做准备

篡改数据或提权:进行非法的UPDATE、INSERT操作

靶场复现如下

URL里的参数:

?field=id&sort=desc,abs(111111)

如果后端代码像之前讨论的那样不安全(使用了${sort}拼接),那么最终生成的SQL语句是:

select * from users order by id desc, abs(111111)

这段SQL的意思是:

select * from users:查询所有用户(所以你看到了数据)。

order by id desc:首先,按 id字段降序排列。

, abs(111111):然后,用 abs(111111)这个固定值作为第二排序条件。因为对于每一行数据,abs(111111)的值都是111111,所以它不会改变第一步排序的结果,是个无效排序。

为什么要传abs(111111)?

这不是为了攻ji,而是为了"探测"和"验证"!​ 这是在试探:

试探一:传一个SQL函数abs(),如果页面正常返回(就像你的截图),立刻证明后台存在SQL注入漏dong!因为程序没有过滤,直接执行了这个函数。

试探二:证明攻ji者可以控制ORDER BY子句的一部分,从而能够插入更多、更危险的SQL代码。

  1. 从"无害探测"到"真正攻ji"

一旦攻ji者通过abs(111111)确认漏dong存在,他下一步就会尝试真正的攻ji,比如你的例子中工具条上写的"SQLI"。他可以构造一个真正的恶意参数,例如:

攻ji参数(示例):

?field=id&sort=desc UNION SELECT 1, username, password FROM admin--

这样,他就能把admin表的管理员账号密码也联合查询出来一起返回

靶场搜索注入代码如下:

@GetMapping("/vul/search")

public List searchVul(@RequestParam("user") String user) {

return userMapper.searchVul(user);

}

// 不安全的注解

@Select("select * from users where user like '%${q}%'")

List search(String q);

但是'%${q}%'会被直接替换成 '%用户输入的内容%',没有任何安全处理。

攻ji示例:用户输入如何"变身"?

万能密码绕过认证

用户输入:' or '1'='1

最终SQL:select * from users where user like '%' or '1'='1%'

这个查询的意思是:

like '%'→ 匹配空字符串(通常为真)

or→ 或者

'1'='1'→ 这个条件永远成立(1等于1)

结果:查询返回所有用户,而不是特定的用户

如下图

靶场原参数,运行结果如下图,其实差不多,都是or 1=1条件为真,返回所有user

3、分析常见的命令注入漏dong代码样例,并说明什么情况下才可以利用以及原理。

编程语言如C/C++,Java, PHP, Python, Go, Rust等,都支持执行系统命

令,所以都有可能存在命令注入漏dong。注入的命令以应用程序的当前权限被执行,如果应用程序是使用root权限执行,那么注入的命令也是以root执行。

如果参数完全可控,则可以执行任意命令

若没有手动创建 shell 执行命令,没有存在参数注入,则无法实现命令注入

手动创建 shell 执行命令,可执行-c 的参数值的命令,但注入的命令内不能有空格、\t\n\r\f 分隔符,否则会被分割

下图示例,执行了命令,弹出来计算器

4、分析代码执行漏dong、表达式注入漏dong、SSTI模板注入漏dong样例并理解原理
代码执行 :java是编译型语言,该漏dong主要是指脚本引擎代码注入。Java的javax.script.ScriptEngineManager类的eval函数可以被控制用于执行代码,幸运的是,在Java 8之后ScriptEngineManager的eval函数就没有

了。如果使用低版本的Java还是可能遭受脚本引擎代码注入攻击的。

// 通过加载远程js文件来执行代码,如果加载了恶意js则会造成任意命令执行

// 远程恶意js: var a = mainOutput(); function mainOutput() { var x=java.lang.Runtime.getRuntime().exec("open -a Calculator");}

// ⚠️ 在Java 8之后移除了ScriptEngineManager的eval

靶场漏dong示例代码如下

public void jsEngine(String url) throws Exception {

ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");

Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);

String payload = String.format("load('%s')", url);

engine.eval(payload, bindings);

}

运行如下

表达式注入

漏dong概述

表达式注入漏dong类似远程代码执行漏洞(原理上),但远程代码执行漏洞是直接注入代码原生语句,而表达式注入漏洞是基于代码之上构建的执行逻辑。

一定意义上,表达式是代码的浓缩,同时也具备像代码一样可被执行的属性。

Java语言方面的表达式EL(Expression Language),主要包括一下内容:

SpEL表达式(Spring)

OGNL表达式(Struts2、Confluence)

Groovy表达式

SpEL(Spring Expression Language)是Spring Framework中的一种表达式语言,它允许在运行时对对象图进行查询和操作。在应用程序中,如果使用不当,攻击者可以通过构造恶意输入来注入SpEL表达式,从而在表达式被解析时执行任意的命令,导致安全漏dong。

靶场漏dong示例代码如下

public String vul(String ex) {

ExpressionParser parser = new SpelExpressionParser();

复制代码
EvaluationContext evaluationContext = new StandardEvaluationContext();

Expression exp = parser.parseExpression(ex);
String result = exp.getValue(evaluationContext).toString();
return result;

}

运行结果


5、理解常见的信息泄露漏dong,如actuator、swagger等

靶场示例


漏洞利用

https://github.com/LandGrey/SpringBootVulExploit

https://github.com/0x727/SpringBootExploit

相关推荐
阳无2 小时前
宝塔部署的前后端项目从IP访问改成自定义域名访问
java·前端·部署
Pluchon2 小时前
硅基计划4.0 算法 动态规划进阶
java·数据结构·算法·动态规划
会游泳的石头2 小时前
Java 异步事务完成后的监听器:原理、实现与应用场景
java·开发语言·数据库
数智工坊2 小时前
【操作系统-IO调度】
java·服务器·数据库
Galloping-Vijay2 小时前
解决 WSL2 + Windows Hosts + 开启 VPN 后无法访问本地 Web 服务的问题
前端·windows
黎雁·泠崖2 小时前
Java字符串进阶:StringBuilder+StringJoiner
java·开发语言
豆奶dudu2 小时前
安卓应用签名生成+微信开放平台安卓应用签名
android·微信开放平台
糖猫猫cc2 小时前
Kite:Kotlin/Java 通用的全自动 ORM 框架
java·kotlin·springboot·orm
u0104058362 小时前
Java微服务架构:设计模式与实践
java·微服务·架构