首页 > 编程语言 >Java代码审计-命令执行

Java代码审计-命令执行

时间:2024-08-04 19:26:10浏览次数:14  
标签:审计 Java String ProcessBuilder exec 代码 cmd 命令 执行

Java代码审计-命令执行

前言

今天来学一下java代码审计中的命令执行漏洞相关知识,浅浅记录一下。

一、漏洞简介

命令执行漏洞是指应用有时需要调用一些执行系统命令的函数,如果系统命令代码未对用户可控参数做过滤,则当用户能控制这些函数中的参数时,就可以将恶意系统命令拼接到正常命令中,从而造成命令执行攻击。
命令执行攻击主要存在以下几个危害:继承 Web 服务程序的权限去执行系统命令或读/写文件,反弹 shell,控制整个网站甚至控制服务器,进一步实现内网渗透。
在 PHP 开发语言中有 system()、exec()、shell_exec()、eval()、passthru()等函数可以执行系统命令。在 Java 开发语言中可以执行系统命令的函数有 Runtime.getRuntime.execProcessBuilder.start

二、命令连接符

Windows与Linux均支持:

  • cmd1 | cmd2 只执行cmd2

  • cmd1 || cmd2 只有当cmd1执行失败后,cmd2才被执行

  • cmd1 & cmd2 先执行cmd1,不管是否成功,都会执行cmd2

  • cmd1 && cmd2 先执行cmd1,cmd1执行成功后才执行cmd2,否则不执行cmd2

Linux单独支持:

  • cmd1;cmd2 依次顺序执行命令

三、ProcessBuilder命令执行

1.ProcessBuilder简介

ProcessBuilder类是java.lang包下的基础类,在使用时无需导入,可以直接使用。它主要用于创建和运行各类外部程序。其start() 方法利用这些属性创建一个新的 Process 实例,可以利用 ProcessBuilder 执行命令。

如下示例,ping本地

public static void main(String[] args) throws IOException {
        try {
            // 创建 ProcessBuilder 实例
            ProcessBuilder processBuilder = new ProcessBuilder("cmd","/c","ping", "127.0.0.1");
            System.out.println(processBuilder.command());//要执行的指令打印
            // 启动进程
            Process process = processBuilder.start();
            // 获取进程的输入流
            InputStream inputStream = process.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));

            String line;
            // 读取进程的输出
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
            // 等待进程结束
            process.waitFor();
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }

输出如图所示。

输出结果

2.漏洞利用

如上述代码,如果直接输入的命令为127.0.0.1|dir,则执行效果如下。

输出结果

四、Runtime exec 命令执行

1.Runtime exec简介

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

//在单独的进程中执行指定的字符串命令
public Process exec(String command) 
//在单独的进程中执行指定的命令和参数
public Process exec(String[] cmdarray) 
//在具有指定环境的单独进程中执行指定的命令和参数
public Process exec(String[] cmdarray, String[] envp) 
//在具有指定环境和工作目录的单独进程中执行指定的命令和参数
public Process exec(String[] cmdarray, String[] envp, File dir) 
//在具有指定环境的单独进程中执行指定的字符串命令
public Process exec(String command, String[] envp) 
//在具有指定环境和工作目录的单独进程中执行指定的字符串命令
public Process exec(String command, String[] envp, File dir)

比如直接拼接字符串,然后exec()方法执行命令,结果如下

public static void main(String[] args) throws IOException {
        // 从用户输入获取要 ping 的目标 IP 地址
        System.out.print("请输入要 ping 的 IP 地址或域名: ");
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        String userInput = reader.readLine();

        // 不安全的命令执行
        String command = "cmd /c"+ "ping " + userInput;  // 直接使用用户输入构建命令
        Process process = Runtime.getRuntime().exec(command);

        // 打印结果
        BufferedReader processInput = new BufferedReader(new InputStreamReader(process.getInputStream()));
        String line;
        while ((line = processInput.readLine()) != null) {
            System.out.println(line);
        }
    }

输入如下图所示。

输出结果

2.漏洞利用

和第二部分一样,输入的参数未经过过滤,随意拼接造成漏洞执行。

输出结果

五、探索

1.代码底层原理

探索一下,Runtime.getRuntime().exec(command)执行命令的底层原理。

String command = "cmd /c"+ "ping " + userInput;  // 直接使用用户输入构建命令
Process process = Runtime.getRuntime().exec(command);

进入exec方法

输出结果

发现调用了exec(String command, String[] envp, File dir)方法,默认envp和dir为空。

输出结果

发现这个函数 是借助StringTokenizer工具 对字符串进行分割,存入数组,再执行。

接下来,调试具体看下情况。

输出结果

然后,再次调用了exec(cmdarry,encp,dir),

输出结果

原来,在这里最终调用的还是ProcessBuilder()方法 。

2.疑问

还是有个小疑问,在写代码进行测试的时候,命令语句,拼接了cmd /c 。如果没有这个,也能执行ping命令,但是加入|dir注入并没有成功。那么,为什么会没有cmd /c 注入不会成功呢?另外为什么要加cmd /c 呢?

个人之见解如下:

  • 首先对于没有使用cmd /c 的方式,不会造成命令注入,上述看代码原理已经探索过,分割字符串时按照空格分割,所以会造成"ping" “127.0.0.1|dir” 两个字符串。"127.0.0.1|dir"被看成一个整体字符串,而命令不被解析,导致注入失败。

  • 对于使用 cmd /c的方式,更加灵活,可以使用管道、重定向等命令,所以对"127.0.0.1|dir"进行了解析,但是也造成了命令注入的风险。

3.小结

  • 使用 cmd /c:

    • 适合执行包含多个命令、管道、重定向等复杂命令的情况。

    • 所有在命令行中可用的功能和语法都可以使用。

    • 需要防范命令注入,需对输入参数进行过滤

  • 不使用 cmd /c:

    • 只适合执行简单的原生命令。

    • 不能利用命令解释器的特性,如管道和其他命令的结合。

    • 经个人简单测试,命令注入失败。

六、总结

本文浅显探索了Java中命令执行漏洞的相应代码和产生原理,另发现,看底层代码的具体实现逻辑还是挺有意思的!

参考

  • 网络安全:Java代码审计实战
  • Java代码审计(入门篇)

标签:审计,Java,String,ProcessBuilder,exec,代码,cmd,命令,执行
From: https://blog.csdn.net/qq_44780157/article/details/140826196

相关文章

  • 【全网首发】2024华数杯数学建模ABC题选题分析+解题思路代码+成品论文更新
    建议选哪道题?A题特点:数理分析题目此题难度较大与国赛难度较为贴近B题特点B题以运筹学/网络科学,图论、优化问题为主,涉及到的概念多,对基础要求较高,不建议优先选择。常用MATLAB函数例如toposort(有向无环图的拓扑顺序)、isomorphism(计算两个图之间的同构)、centrality(衡量节点......
  • 2--Web前端开发-JavaScript
    引入方式1、内部脚本:将JS代码定义在HTML页面中JavaScript代码必须位于<script></script>标签之间在HTML文档中,可以在任意地方,放置任意数量的<script>一般会把脚本置于<body>元素的底部,可以改善显示速度<script>alert("hellojavascript");</script>可放在代码中任意位......
  • 【仓颉】入门文档代码圆周率估算代码更正
    项目实现前实现后代码组织方式模块/包二级结构包/子包树形结构没有父包的包称为root包,root包及其子包(包括子包的子包)构成的整棵树称为module编译单元包包(每个子包单独编译)访问修饰符public:可修饰顶层和非顶层成员,包内外可见default(不写):仅本包内可见pro......
  • Java流程控制语句结构--分支结构
    目录if语句switch语句三元运算符(条件运算符)总结Java中的分支结构是程序设计中用于根据条件选择不同执行路径的重要机制。它允许程序在运行时根据特定条件来决定执行哪一部分代码。Java中的分支结构主要包括以下几种:if语句基本形式:if(条件表达式){语句块;}如果条件表达式......
  • Java流程控制语句结构--循环结构
    目录while循环do…while循环for循环三种循环的死循环形式while循环while是最基本的循环,它的结构为:while(布尔表达式(判断条件)){//循环内容}只要布尔表达式为true,循环就会一直执行下去。do…while循环对于while语句而言,如果不满足条件,则不能进入循环。但有时候我......
  • Java流程控制04:循环结构
    顺序结构的程序语句只能被执行一次。如果您想要同样的操作执行多次,就需要使用循环结构。Java中有三种主要的循环结构:while循环do…while循环for循环1.while循环while是最基本的循环,它的结构为:while(布尔表达式){//循环内容}只要布尔表达式为true,循环就会一......
  • Java流程控制05:break & continue
    1.break关键字break主要用在循环语句或者switch语句中,用来跳出整个语句块。break跳出最里层的循环,并且继续执行该循环下面的语句。【演示:跳出循环】publicstaticvoidmain(String[]args){ inti=0; while(i<100){ i++; System.out.println(i); if(i==......
  • JavaScript之ECMAScript(二)
    三、ECMAScript基础(一)函数1.函数的定义函数指能实现特定功能的代码块,通常使用function(){}进行函数的定义2.函数的三种定义形式2.1使用function关键字定义使用function函数名(){函数体}进行定义,使用“函数名()”进行调用。2.1使用var关键字定义使用va......
  • Java基于微信小程序的高校大学生新生迎新管理系统 uniapp
    文末获取资源,收藏关注不迷路文章目录项目介绍技术介绍项目界面关键代码目录项目介绍随着信息技术的飞速发展,信息化已经深入到社会生活的各个领域。高校作为科研的前沿阵地,一直走在科技发展的前列,特别是在信息化方面。如今,大部分高校都建立了数字化、信息化的校园平......
  • 基于Java的少儿托管系统的设计与实现/毕业项目/课程设计/MySQL
     基于Java的少儿托管系统的设计与实现摘  要随着互联网技术的快速发展,无论是人们的生活还是工作,互联网技术都带来了很多的方便,人们通过互联网技术不仅能够提高工作效率还能够降低出错的几率。随着人们工作的忙碌,越来越多的家长选择放学后对孩子进行托管,但托管机构的......