小迪安全v2023学习笔记(六十六讲)—— Java安全SQL注入SSTISPELXXE

文章目录

  • 前记
  • WEB攻防——第六十六天
    • Java安全&SPEL表达式&SSTI模板注入&XXE&JDBC&MyBatis注入
      • 环境搭建
        • Hello-Java-Sec
        • JavaSec
      • Java安全 - SQL注入-JDBC&MyBatis
        • JDBC注入
          • 原理
          • 语句拼接
          • 预编译的错误使用
          • JdbcTemplate
          • 正则过滤
        • MyBatis注入
          • 原理
          • Like注入
          • Order By注入
          • In注入
        • 白盒案例演示
        • 总结
      • Java安全 - XXE注入-Reader&Builder
        • 原理
        • 靶场演示
      • Java安全 - SSTI模板-Thymeleaf&URL
        • 原理
        • 靶场案例
      • Java安全 - SPEL表达式-SpringBoot框架
        • 原理
        • 靶场案例

前记

  • 今天是学习小迪安全的六十六天,本节课正式进入Java安全的第一讲,主要内容是SQL注入、SSTI注入、SPEL注入以及XXE注入
  • 主要是以理解为主,也有实战案例
  • 需要用到的资源已放至下方链接,需要自取:
    • https://pan.baidu.com/s/1TzXyNGLKNz2wycxJm9X6GQ
    • 提取码:ling

WEB攻防——第六十六天

Java安全&SPEL表达式&SSTI模板注入&XXE&JDBC&MyBatis注入

环境搭建

Hello-Java-Sec

在这里插入图片描述

  • 这个直接在github上下载即可,然后支持两种安装模式:docker和手动安装

  • 这里就手动安装了,环境要求为jdk1.8,然后如果要测试SQL注入的话,需要先导入数据库,数据库版本为MySQL5.7MySQL8+有语法错误!

  • application-dev.properties文件中修改为本地的数据库:
    在这里插入图片描述

  • 并且将db.sql文件改为如下内容:

CREATE DATABASE IF NOT EXISTS java_secDEFAULT CHARACTER SET utf8COLLATE utf8_general_ci;USE java_sec;-- 用户表(5.7 兼容版)
CREATE TABLE `users`
(`id`   int(11) unsigned NOT NULL AUTO_INCREMENT,`uuid` CHAR(36) NOT NULL,`user` varchar(50)  NOT NULL,`pass` varchar(128) NOT NULL,PRIMARY KEY (`id`),UNIQUE KEY `uuid_unique` (`uuid`)
);-- 触发器:插入时自动生成 UUID
DELIMITER $$
CREATE TRIGGER `users_before_insert`
BEFORE INSERT ON `users`
FOR EACH ROW
BEGINIF NEW.uuid IS NULL OR NEW.uuid = '' THENSET NEW.uuid = UUID();END IF;
END$$
DELIMITER ;-- 预置数据(手动给 uuid)
INSERT INTO `users` (`id`, `uuid`, `user`, `pass`) VALUES(1, UUID(), 'zhangwei', '123456'),(2, UUID(), 'Admin',    'password'),(3, UUID(), 'wangwei',  '123123');-- 登录日志表
CREATE TABLE `auth`
(`id`   int(6) unsigned NOT NULL AUTO_INCREMENT,`user` varchar(50) NOT NULL,`ip`   varchar(50) NOT NULL,`date` varchar(60) NOT NULL,PRIMARY KEY (`id`)
);-- 存储型 XSS 表
CREATE TABLE `xss`
(`id`      int(6) unsigned NOT NULL AUTO_INCREMENT,`user`    varchar(50) NOT NULL,`content` TEXT        NOT NULL,`date`    varchar(60) NOT NULL,PRIMARY KEY (`id`)
);
  • 然后连接到数据库,添加这里填写的数据库名,导入db.sql文件进去:
    在这里插入图片描述
    在这里插入图片描述

  • 之后在根目录下maven打包,然后运行jar包即可:
    在这里插入图片描述
    在这里插入图片描述

  • 默认端口是8888,这里我改成了8890,然后直接打开就行,默认账号密码为admin/admin
    在这里插入图片描述

JavaSec
  • 这个的下载地址是:bewhale/JavaSec: Java安全 学习记录,环境要求Jdk1.8

  • 然后下载源码之后,改动src/main/resources/application.yml文件中的数据库配置为你自己的数据库配置

  • 接着创建数据库javasec数据库版本为MySQL5.7),我这里改成了javaseclab,导入javasec.sql文件:
    在这里插入图片描述
    在这里插入图片描述

  • 然后回到根目录用maven打包,运行jar包即可:
    在这里插入图片描述
    在这里插入图片描述

  • 这里默认端口是8000,我改成了8891,然后也是直接打开即可,默认账号密码为admin/admin
    在这里插入图片描述

Java安全 - SQL注入-JDBC&MyBatis

JDBC注入
原理
  • JDBC是 Java 平台最核心的数据库访问标准,用来完成「Java 程序 ↔ 任何关系型数据库」之间的通信。
  • 但是它比较复杂和难以管理,所以在企业开发中用得不多
  • 这里主要是看它使用不当的SQL语法导致的SQL注入,主要有四种
语句拼接
  • 第一种就是直接拼接语句,这个很简单漏洞语句一般是这样:
String sql = "select * from users where id = '" + id + "'";
  • 直接尝试注入就OK了:
    在这里插入图片描述

  • 如果坚持使用这种方式,就需要严格的黑名单过滤才行

预编译的错误使用
  • 在使用预编译时,也不能用拼接的方式去执行SQL语句:
String sql = "select * from users where id = " + id;
PreparedStatement st = conn.prepareStatement(sql);
  • 这个跟没使用预编译是一样的结果,正确的方式是通过?占位符来实现预编译:
String sql = "select * from users where id = ?";
PreparedStatement st = conn.prepareStatement(sql);
st.setString(1, id);
JdbcTemplate
  • JDBCTemplateSpringJDBC的封装,如果使用拼接语句便会造成SQL注入
JdbcTemplate jdbctemplate = new JdbcTemplate(dataSource);
String sql = "select * from users where id = " + id;
return jdbctemplate.queryForMap(sql);
  • 如果一定要用,可以使用ESAPI框架:
String sql = "select * from users where id = '" + ESAPI.encoder().encodeForSQL(oracleCodec, id) + "'";
ResultSet rs = stmt.executeQuery(sql);
正则过滤
  • 正则表达式只允许a-z0-9出现,然后继续使用拼接语句,虽然感觉过滤了其他的字符,但是也可能存在绕过的风险
  • 正确的做法限制传入数据的数据类型,比如限定为整型、boolean、浮点型等
MyBatis注入
原理
  • MyBatis 是一个流行的Java持久性框架,通过预处理和参数绑定的方式,有效地防止SQL注入攻击,但如果 MyBatis 框架的使用不当或未正确配置,仍然可能存在SQL注入的风险。
  • MyBatis中,#{}语法表示使用预编译${}语法表示使用拼接
Like注入
  • 在使用like语句进行模糊查询时,语法如下:
Select * from users where username like '%${username}%'
  • 在这种情况下,直接使用#程序会报错,大部分程序员解决错误的方式是将#改为$,由此便产生SQL注入
  • POC为:
xxx%' union select database(),user(),@@version,4,5 -- -
  • 正确的写法为:
Select * from users where username like concat('%',#{username}, '%')
Order By注入
  • 在使用Order By注入进行排序的时候,语法如下:
select * from users order by ${field}
  • 同样在这种情况下,直接使用#程序会报错,大部分程序员解决错误的方式是将#改为$,由此便产生SQL注入
  • POC为:
 id and (updatexml(1,concat(0x7e,(select user())),0))-- -
  • 正确的写法为:
<mapper namespace="com.best.hello.mapper.UserMapper"><select id="orderBySafe" resultType="com.best.hello.entity.User">select * from users<choose><!-- 根据字段选择排序方式,避免 SQL 注入 --><when test="field == 'id'">order by id desc</when><when test="field == 'user'">order by user desc</when><otherwise><!-- 默认排序方式,防止不合法输入 -->order by id asc limit 1</otherwise></choose></select>
</mapper>
  • 固定排序方式,或者根据字段选择排序方式,避免让用户自己写入
In注入
  • 在使用in语句进行条件查询的时候,语法如下:
Select * from users where id in (${ids})
  • 直接使用#仍然会报错,大部分程序员解决错误的方式是将#改为$,由此便产生SQL注入
  • POC为:
1,2,3) and (updatexml(1,concat(0x7e,(select user())),0))-- -
  • 正确的写法如下:
"<script>" + "SELECT * FROM users WHERE id IN " + "<foreach item='item' index='index' collection='ids' open='(' separator=',' close=')'>" + "#{item}" + "</foreach>" + "</script>"
  • 使用foreach语句进行循环遍历
白盒案例演示
  • 这里演示的案例是inxedu,首先我们在IDEA中打开,找到src/main/resources/project.properties文件,修改为自己的配置:
    在这里插入图片描述

  • 然后和搭建教程那里一样,导入根目录下的demo_inxedu_v2_0_open.sql(数据库版本为MySQL5.5):
    在这里插入图片描述

  • 之后在IDEA中,点击右边的Maven按钮,clean之后再package得到war工件:
    在这里插入图片描述

  • 点击当前文件,然后编辑配置,点击+号配置Tomcat服务器:
    在这里插入图片描述

  • 这里我选择的是Tomcat9,注意这里的端口要与配置中的一致

  • 然后点击“部署”,选择+号添加工件,然后将下面的根路径改成/
    在这里插入图片描述

  • 配置完成后直接启动Tomcat即可,如果这里一直显示工件配置出错,记得看看数据库账号密码是否正确

  • 配置完成之后页面:
    在这里插入图片描述

  • 这里既然是白盒测试,我们首先要看他是用的JDBC还是MyBatis去管理数据库吧,这里怎么看呢?

  • 直接在pom.xml中搜有没有用到MyBatis就行了:
    在这里插入图片描述

  • 用到了呀,既然用到了,那针对MyBatis出现SQL注入的情况就那三种,全局搜索一下有没有关键字就行了

  • 比如用到like有没有%${,用到Order By有没有${,用到in有没有(${
    在这里插入图片描述

  • 这里不就是吗?点进去可以看到是删除文章的一个功能,这里用的是delete标签,然后ID值为deleteArticleByIds,通过ID去删除文章

  • 我们可以直接搜一下这个id值看看哪个java文件调用了它:
    在这里插入图片描述

  • 有这么多,其实你慢慢看可以找到AdminArticleController.java这个文件是真正的功能点,点进去找它的触发路径为/admin/article
    在这里插入图片描述

  • 请求路径为delete
    在这里插入图片描述

  • 现在我们在源码中找到了它可能存在漏洞的点,那么我们就在网站中去找到这个功能点

  • 这个是个后台功能点,需要登入后台,账号密码为admin/111111
    在这里插入图片描述

  • 直接访问admin/article显示404,那这里就找哪里有文章删除的功能,在文章资讯管理下的文章列表这里就有删除的按钮:
    在这里插入图片描述

  • 随便删除一篇文章,然后f12抓一下数据包看是不是我们在java中看到的链接:
    在这里插入图片描述

  • 这里确实是admin/article/delete,所以我们找到了删除的功能点,接下来就是找它的注入点了,那这里看负载也是找到了它使用的POST提交articelId,这里也是对应上了:
    在这里插入图片描述

  • 接下来就直接BP抓包,然后用Sqlmap跑一下:
    在这里插入图片描述
    在这里插入图片描述

  • 这里接下来的步骤就不演示了,之前的课讲过

总结
  • 不管是JDBC还是MyBatis,只要是使用拼接语法,都可能造成SQL注入
  • 在代码审计的时候,也可以抓住这一点去快速判断是否存在注入

Java安全 - XXE注入-Reader&Builder

原理
  • XXE (XML External Entity Injection), XML 外部实体注入,当开发人员配置其 XML 解析功能允许外部实体引用时,攻击者可利用这一可引发安全问题的配置方式,实施任意文件读取、内网端口探测、命令执行、拒绝服务等攻击。
  • Java中相关的类/方法:
    1. XMLReader
    2. SAXReader
    3. SAXBuilder
    4. Unmarshaller
    5. DocumentBuilder
  • 代码审计中,除了上述的类/方法以外,还可以审计下列类/方法:
    1. XMLStreamReader
    2. SAXParser
    3. SAXSource
    4. TransformerFactory
    5. SAXTransformerFactory
    6. SchemaFactory
    7. XPathExpression
靶场演示
  • 这个在白盒中就是看有没有上面这些函数,有没有过滤,然后去进行测试
  • 如果是在黑盒中,其实和PHP没什么不同,都是看有没有这种XML传入参数的地方,然后payload一个个测试就行了
  • 无非就是使用的函数不一样,其他的测试方法都是一样的,所以这里就不演示了

Java安全 - SSTI模板-Thymeleaf&URL

原理
  • SSTIServer Side Template Injection)服务器模板注入,服务端接收了用户的输入,将其作为Web应用模板内容的一部分,在进行目标编译渲染的过程中,执行了用户插入的恶意内容
  • 这个东西前期也是讲过,当时就是介绍了一下,用的Thymeleaf,然后简单的看了它的历史漏洞
  • Java中主要的SSTI出现的位置:
    1. Thymeleaf
    2. URL作为视图
    3. Freemarker
    4. Velocity
  • 关于其他语言模板注入的文章可以参考一下:1. SSTI(模板注入)漏洞(入门篇) - bmjoker - 博客园
靶场案例
  • 这里的话就还是以thymeleaf作为演示吧,我们看一看源码:
    在这里插入图片描述

  • 主要出现的原因就是这个return "lang/" + lang;语句,后面的lang参数是可控的

  • 所以我们传入payload就可以造成RCE等这些漏洞:
    在这里插入图片描述

  • 执行就会弹出计算器

  • 其他的模板基本也是一样的,在黑盒测试中,主要就是看有没有这种模板切换的地方,比如切换语言、切换皮肤、切换主题等等,有没有可控的参数,就测测看

  • 但一般没有提示是基本测不出来的

Java安全 - SPEL表达式-SpringBoot框架

原理
  • SPELSpring Expression Language)表达式注入,是一种功能强大的表达式语句,用于在运行时查询和操作对象图,由于未对参数做过过滤可造成RCE
  • 参考文章:Spring-SpEL表达式超级详细使用全解-CSDN博客
  • 可以将其类似于PHP中的eval函数,将字符串解析为命令之类的函数
靶场案例
  • 这里首先需要判断有没有这个漏洞,可以尝试输入一些字符串让他解析,看他能不能解析

  • 比如输入100-1这种运算字符串看它会不会执行计算:
    在这里插入图片描述

  • 这里返回99,说明它会解析字符串,那么我们就可以尝试这个SpEL注入

  • 主要产生漏洞的代码为:

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;
}            
  • 然后我们注入的POC为:
T(java.lang.Runtime).getRuntime().exec("calc.exe")
  • T(...)SpEL专用的“取类对象”的操作符,这里就是取到Runtime这个类,然后调用该类的静态方法调用exec方法调用计算器
  • 如果存在黑名单过滤的话就可以结合Java反射进行绕过,比如过滤Rumtime字符串,POC就可以这样写:
T(String).getClass().forName("java.l" + "ang.Ru" + "ntime").getMethod("ex" + "ec", T(String[])).invoke(T(String).getClass().forName("java.l" + "ang.Ru" + "ntime").getMethod("getRu" + "ntime").invoke(T(String).getClass().forName("java.l" + "ang.Ru" + "ntime")),new String[]{"calc"})
  • 就是利用它Java的反射机制,让他利用forName去加载类,利用字符串拼接的方式绕过直接写入Runtime字符串
  • 这个也是能够成功调出计算器的:
    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/96102.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/96102.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

把 AI 变成「图书馆管理员」——基于检索增强的离线图书语音导航小盒子

标签&#xff1a;检索增强、语音导航、离线 LLM、RAG、ESP32-S3、低功耗、TTS、BLE ---- 1. 背景&#xff1a;读者找不到书的痛苦 高校图书馆每天 5000 人次&#xff0c;高频问题&#xff1a; • “《深度学习》在哪个书架&#xff1f;” • “有没有类似《三体》的科幻&…

架构思维:在AI时代为产品“减负”的终极武器——用结构化智慧破解数字化复杂困局

摘要 数字化产品的复杂度飙升已成为企业发展的核心瓶颈。本文基于架构思维的本质&#xff08;元素、连接、演进&#xff09;&#xff0c;结合5A架构体系&#xff08;业务/信息/应用/技术/治理架构&#xff09;&#xff0c;系统阐述如何通过分而治之、共性沉淀、AI赋能三大策略降…

黎阳之光:以数字之力,筑牢流域防洪“智慧防线”

当洪水来袭&#xff0c;每一分精准的预报、每一次及时的预警、每一轮科学的预演、每一套完善的预案&#xff0c;都可能关系到江河安澜与万家平安。在水利现代化建设的浪潮中&#xff0c;黎阳之光凭借数字孪生、视频孪生等核心技术&#xff0c;打造流域防洪“四预”管理平台&…

transformer模型初理解

模型介绍 在 Transformer 之前&#xff0c;主流的序列模型是 **RNN&#xff08;循环神经网络&#xff09;** 工作方式类似「逐字阅读」&#xff1a;处理序列时&#xff0c;必须从第一个词开始&#xff0c;一个接一个往后算&#xff08;比如翻译时&#xff0c;先看 “我”&#…

驱动开发系列66 - glCompileShader实现 - GLSL中添加内置函数

一&#xff1a;概述 本文介绍如何为 GLSL 语言中增加一个内置函数&#xff0c;以https://registry.khronos.org/OpenGL/extensions/ARB/ARB_shader_texture_image_samples.txt扩展为例&#xff0c;介绍下添加textureSamples内置函数的过程。

指针的应用学习日记

Git常见的命令&#xff1a;%h 简化哈希 %an 作者名字 %ar 修订日期(距今) %ad修订日期 %s提交说明指针简介指针(Pointer)是C语言的一个重要知识点&#xff0c;其使用灵活、功能强大&#xff0c;是C语言的灵魂。 指针与底层硬件联系紧密&#xff0c;使用指针可操作数据的地址&am…

KMM跨平台叛逃实录:SwiftUI与Compose Multiplatform共享ViewModel的混合开发框架(代码复用率85%)

KMM跨平台叛逃实录&#xff1a;SwiftUI与Compose Multiplatform共享ViewModel的混合开发框架&#xff08;代码复用率85%&#xff09;一、架构革命&#xff1a;跨平台统一状态管理1.1 核心架构设计1.2 技术矩阵对比二、KMM共享ViewModel实现2.1 基础状态管理2.2 ViewModel核心架…

关于Android webview协议混淆

背景&#xff1a;android中引入的html页面是http请求(web服务仅开放了80端口)&#xff0c;但html页面引用的后端接口是https请求&#xff0c;则发生android中html页面请求接口异常<请求无法发送到后端服务(status0)>。浏览器出于安全考虑&#xff0c;要求&#xff1a; 同…

Android Jetpack | Lifecycle

一.前言 本篇主线包含三点&#xff0c;Lifecycle的作用、简单使用、核心原理&#xff08;包含核心类与源码主线分析&#xff09;&#xff1b; 二.作用 官方文档生命周期感知型组件可执行操作来响应另一个组件&#xff08;如 Activity 和 Fragment&#xff09;的生命周期状态…

单片机编程架构

没有最好的程序架构。 只要在项目中实现产品功能并稳定工作&#xff0c;且能在团队内统一应用管理就是最优的程序架构。 一、单片机运行模型&#xff1a; 1.能分配时间的裸机代码 2.FreeRTOS操作系统 代码分层框架&#xff1a; 1.与板关联的底层 2.《驱动底层的驱动层》《中间层…

114. 二叉树展开为链表

题目&#xff1a;给你二叉树的根结点 root &#xff0c;请你将它展开为一个单链表&#xff1a; 展开后的单链表应该同样使用 TreeNode &#xff0c;其中 right 子指针指向链表中下一个结点&#xff0c;而左子指针始终为 null 。展开后的单链表应该与二叉树 先序遍历 顺序相同。…

【Langchain系列三】GraphGPT——LangChain+NebulaGraph+llm构建智能图数据库问答系统

Langchain二次开发专栏 【Langchain系列一】常用大模型的key获取与连接方式 【Langchain系列二】LangChain+Prompt +LLM智能问答入门 【Langchain系列三】GraphGPT——LangChain+NebulaGraph+llm构建智能图数据库问答系统 【Langchain系列四】RAG——基于非结构化数据库的智能问…

【GNSS定位原理及算法杂记6】​​​​​​PPP(精密单点定位)原理,RTK/PPK/PPP区别讨论

PPP 技术详解&#xff1a;原理、流程与 RTK/PPK 对比 在高精度 GNSS 定位技术体系中&#xff0c;除了 RTK 和 PPK 以外&#xff0c;还有一类无需基站即可实现分米到厘米级定位的方法 —— PPP&#xff08;Precise Point Positioning&#xff0c;精密单点定位&#xff09;。它以…

LeetCode 837.新 21 点:动态规划+滑动窗口

【LetMeFly】837.新 21 点&#xff1a;动态规划滑动窗口 力扣题目链接&#xff1a;https://leetcode.cn/problems/new-21-game/ 爱丽丝参与一个大致基于纸牌游戏 “21点” 规则的游戏&#xff0c;描述如下&#xff1a; 爱丽丝以 0 分开始&#xff0c;并在她的得分少于 k 分时…

Codeforces 盒装苹果

题目来源&#xff1a;问题 - 2107B - Codeforces 这道题其实只需要判断两个要点&#xff0c;首先判断一下最大值-1后与最小值的差值是否>k&#xff0c;这里有个小细节&#xff0c;当有多个最大值时&#xff0c;可以先将一个最大值-1后再排序&#xff0c;判断新数组最大值与最…

数据结构--------堆

目录 二叉树 树的概念与结构 非树形结构&#xff1a; 注意&#xff1a; 树的相关术语 树的表示 孩子兄弟表示法 树形结构实际运用场景&#xff08;拓展&#xff09; 1. 文件系统管理 2. 数据库与索引 3. 编程语言与数据结构 信息组织与展示 1. 思维导图 2. 目录与…

VSCode Cursor 大模型 插件扩展 Kilo Code 配置

1.1 概述 Kilo Code 是一个 VSCode Cursor 插件扩展&#xff0c;提供了对多种 AI 模型的支持&#xff0c;包括 Claude Code 和 Qwen3。通过正确配置 Kilo Code&#xff0c;可以在开发过程中获得更好的 AI 辅助编程体验。 Kilo使用文档&#xff1a;https://kilocode.ai/docs/zh-…

深入解析:Unity、Unreal Engine与Godot引擎中的Uniform变量管理

在现代游戏开发中&#xff0c;Uniform变量是实现高质量图形渲染的关键元素。不同游戏引擎对Uniform变量的管理方式有所不同&#xff0c;了解这些差异可以帮助开发者在选择引擎时做出更明智的决策。本文将深入探讨Unity、Unreal Engine和Godot引擎中Uniform变量的管理方式&#…

遨游旅游天地,开启探索未知的梦幻之旅

你是否也怀揣着一颗对世界充满好奇的心&#xff0c;渴望踏上探索旅游世界的奇妙旅程&#xff1f;旅游&#xff0c;是一场与未知的邂逅&#xff0c;是心灵的一次自由翱翔。想象一下&#xff0c;你置身于神秘莫测的撒哈拉沙漠。当夕阳的余晖洒在连绵起伏的沙丘上&#xff0c;那金…

SConscript 脚本入门教程

第一章&#xff1a;什么是 SCons 和 SConscript&#xff1f;核心概念SCons 是一个现代化的构建工具&#xff0c;用于自动化软件构建过程&#xff0c;类似于 Make 但功能更强大、语法更简洁。SConstruct&#xff1a;是 SCons 的主配置文件&#xff0c;通常在项目根目录&#xff…