栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

命令注入漏洞

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

命令注入漏洞

命令注入漏洞
    • 原理
    • 示例代码
    • 命令注入的局限
    • 无法进行命令注入的原因

原理

命令注入是指在某种开发需求中,需要引入对系统本地命令的支持来完成某些特定的功能。当未对可控输入的参数进行严格的过滤时,则有可能发生命令注入。攻击者可以使用命令注入来执行系统终端命令,直接接管服务器的控制权限。

在开发过程中,开发人员可能需要对系统文件进行移动、删除或者执行一些系统命令。Java的Runtime类可以提供调用系统命令的功能。如下代码可根据用户输入的指令执行系统命令。由于cmd参数可控,用户可以在服务器上执行任意系统命令,相当于获得了服务器权限。

示例代码
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.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.lang.reflect.Proxy;


@WebServlet(name="Command",urlPatterns = "/Command")
public class Command extends HttpServlet {

    @Override
    public void init() throws ServletException{

    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        String cmd = req.getParameter("cmd");
        Process process = Runtime.getRuntime().exec(cmd);
        InputStream in = process.getInputStream();
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        byte[] b = new byte[1024];
        int i = -1;
        while ((i = in.read(b))!=-1){
            byteArrayOutputStream.write(b,0,i);
        }
        PrintWriter out = resp.getWriter();
        out.print(byteArrayOutputStream.toString());
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }

    @Override
    public void destroy() {
        super.destroy();
    }
}

命令注入的执行结果如图

命令注入的局限

系统命令支持使用连接符来执行多条语句,常见的连接符有|、||、&、&&,其含义为

符号含义
|前面命令输出结果作为后面命令的输入内容
||前面命令执行失败时才执行后面的命令
&前面命令执行后继续执行后面的命令
&&前面命令执行成功后才执行后面的命令

例如命令ping www.baidu.com&ipconfig的执行效果如图所示,先执行完ping命令,后执行ipconfig命令

对于Java环境中的命令注入,连接符的使用存在一些局限。例如如下代码,利用ping命令来诊断网络。其中url参数为用户可控,当恶意用户输入www.baidu.com&ipconfig时,系统可以成功执行,但是Java运行环境中就不行,因为www.baidu.com&ipconfig被当作一个完整的字符串而非两条命令,因此如下代码不存在命令执行漏洞。

protected ByteArrayOutputStream ping(String url) throws IOException{
	Process process = Runtime.getRuntime().exec("ping " + url);
	InputStream in = process.getInputStream();
	ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
	byte[] b = new byte[1024];
	int i = -1;
	while((i = in.read(b)) != -1){
		byteArrayOutputStream.write(b,0,i);
	}
	return byteArrayOutputStream;
}
无法进行命令注入的原因

Runtime类中exec方法存在如下几种实现,显而易见,要执行的命令可以通过字符串和数组的方式传入。

public Process exec(String command) throws IOException {
        return exec(command, null, null);
    }
public Process exec(String command, String[] envp) throws IOException {
        return exec(command, envp, null);
    }
public Process exec(String cmdarray[]) throws IOException {
        return exec(cmdarray, null, null);
    }
public Process exec(String[] cmdarray, String[] envp, File dir)
        throws IOException {
        return new ProcessBuilder(cmdarray)
            .environment(envp)
            .directory(dir)
            .start();
    }

当传入的参数类型为字符串时,会先经过StringTokenizer的处理,主要是针对空格以及换行符等空白字符进行处理,后续会分割出一个cmdarray数组保存分割后的命令参数,其中cmdarray的第一个元素为所要执行的命令。经过处理后的参数www.baidu.com&ipconfig成为ping命令的参数,因此此时的连接符&并不生效,从而无法注入系统命令。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/298623.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号