使用运行时 API 的命令注入 bash

Command Injection bash using Runtime API

提问人:mido med 提问时间:11/9/2023 最后编辑:BalusCmido med 更新时间:11/10/2023 访问量:43

问:

我正在尝试测试命令注入漏洞。

我使用执行命令的 servlet ,然后我尝试在 url 中传递另一个命令以利用命令注入漏洞,但是当我传递新命令时,没有任何反应。这是我的 servlet 代码和我用来传递新命令的 url:ls

@WebServlet("/command")
public class CommandInjectionServlet extends HttpServlet {

    

    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        try {
            String comm = "/bin/bash -c ls " + request.getParameter("parameter");
            Process process = Runtime.getRuntime().exec(comm);
            BufferedReader stdInput = new BufferedReader(
                    new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8));

            String s = null;
            while ((s = stdInput.readLine()) != null) {
                response.getWriter().println(s);
            }
        } catch (IOException e) {
            e.printStackTrace(); 
            System.out.println("Error executing command");
        }
    }
    
}

以及我使用的网址http://localhost:8080/myproject/command?parameter=;ifconfig

Java 安全 代码 命令注入

评论

0赞 Maurice Perry 11/10/2023
试试这个:http://localhost:8080/myproject/command?parameter=%3Bifconfig
0赞 user85421 11/10/2023
顺便说一句,文档:“已弃用。 此方法容易出错,不应使用,应改用相应的方法 exec(String[])ProcessBuilder。命令字符串仅使用空格字符分解为标记。对于带有嵌入空格的参数(如文件名),这可能会导致问题,因为令牌不包含完整的文件名。exec(String)"

答:

6赞 John Bollinger 11/9/2023 #1

您正在尝试通过将分号()注入构造的命令字符串来运行两个命令来代替一个命令。分离命令的意义是 shell 的一个特性,因此,如果命令通过 shell 运行,这可能有效,类似于 C 的 system() 函数。;;

但是 Runtime.exec() 不是这样工作的。尽管从其他一些重载中可以更清楚地看出,但这一系列方法的模式类似于 execve() 函数及其各种包装函数。分号对他们来说没有特别的意义。一元使用 .然后,将第一个元素作为命令的名称,其余所有元素作为命令行参数。这不容易受到您尝试执行的命令注入模式的影响。Runtime.exec()StringTokenizer

评论

0赞 mido med 11/9/2023
那么我该如何解决这个问题
1赞 John Bollinger 11/9/2023
@midomed,你说的“解决问题”是什么意思?“不容易受到您尝试执行的命令注入模式的影响”是否有不清楚的地方?您是否在问如何修改 servlet 以使其易受攻击?servlet 代码具有一些奇怪的特征,并且可能一开始就没有按预期工作,但是试图闯入系统的人通常不会从对他们试图破解的系统进行任何控制开始。