Java执行命令过程即命令拼接问题

admin 2024年11月14日23:39:42评论10 views字数 1862阅读6分12秒阅读模式
Java执行命令过程即命令拼接问题

题记

java代码执行中,通常会调用Runtime.getRuntime().exec(cmd)去执行,在Runtime.exec()方法有很多可以重载的方法。

Java执行命令过程即命令拼接问题

exec()方法最终都是调用如下:

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

此处的cmdarray为字符串数组,即:

"cmd.exe /c calc.exe"["cmd.exe","/c","calc.exe"]

最后都传递给new ProcessBuilder(cmdarray).start()

分别从windowslinux两个平台来跟进。

Java执行命令过程即命令拼接问题
windows

windows环境下,ProcessBuilderstart函数有多个重载,但是最终都是返回ProcessImpl.start(cmdarray,environment,dir,redirects,redirectErrorStream)

Java执行命令过程即命令拼接问题

ProcessImplstart函数有点长,应该就是读取一下环境,定义了下标准输入输出流

Java执行命令过程即命令拼接问题

最终在start函数中重载了ProcessImpl构造函数

Java执行命令过程即命令拼接问题

ProcessImpl的构造函数中,先是获取了从数组中的第一个获取了程序的可执行路径,然后needsEscaping(),判断是否添加引号,createCommandLine(),判断可执行的文件是否是.CMD或者.BAT结尾来添加双引号

Java执行命令过程即命令拼接问题

needsEscaping中,判断了传入是否有空格和t,有则会添加双引号

Java执行命令过程即命令拼接问题

最终create执行,为native方法

Java执行命令过程即命令拼接问题

Runtime.getRuntime().exec("cmd.exe /c calc.exe")

等于

new ProcessBuilder().command("cmd.exe","/c","calc.exe").start()
Java执行命令过程即命令拼接问题
linux

linux环境下ProcessBuilderstart最后仍然是ProcessImpl.start()

Java执行命令过程即命令拼接问题

ProcessImplstart方法中,window最后返回的是重载的ProcessImpl构造函数,linux则为UNIXProcess

Java执行命令过程即命令拼接问题

调用了forkAndExec

Java执行命令过程即命令拼接问题

该方法也为native方法

Java执行命令过程即命令拼接问题

Java执行命令过程即命令拼接问题
命令拼接问题

如下命令执行例子模拟在传递字符串的情况下的拼接

linux下

Runtime.getRuntime().exec("/bin/sh -c ping dns.cn" + "&Calculator");

windows下

Runtime.getRuntime().exec("cmd.exe /c ping dns.cn" + "&calc.exe");

执行的结果为

linux下未弹出计算器

windows成功弹出计算器

在传入ProcessImpl.start()时没区别

Java执行命令过程即命令拼接问题

Java执行命令过程即命令拼接问题

测试原因

linux下,如果想执行成功需要加引号

Java执行命令过程即命令拼接问题

Java执行命令过程即命令拼接问题

windows下,引号不影响执行

Java执行命令过程即命令拼接问题

Java执行命令过程即命令拼接问题

如果是如下形式呢

Runtime.getRuntime().exec("mysql.exe xxxx"+"&cmd.exe /c calc,exe");

均执行不了,从上面代码根据可以看到,调用exec的只有第一个参数

String executablePath = new File(cmd[0]).getPath();
Java执行命令过程即命令拼接问题
最后

通常在代码执行利用的时候Runtimeexec都是传递字符串数组,就不存在上述问题。

System.getProperty("os.name").toLowerCase().contains("window")? new String[]{"cmd.exe""/c", cmd} : new String[]{"/bin/sh""-c", cmd}

exec(“cmd”)在执行时,参数都会被转成字符串数组,在ProcessBuilder中会被转成ArrayList集合。

数组中的只有第一个为程序的可执行路径,后面的均被识别为其参数。

至于用处,可以用来学习下ctf命令注入?或者实战下命令执行Runtime.exechook了的绕过。

监制:船长、铁子   策划:格纸   文案:青柠   美工:青柠

原文始发于微信公众号(千寻安服):Java执行命令过程即命令拼接问题

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年11月14日23:39:42
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   Java执行命令过程即命令拼接问题https://cn-sec.com/archives/1653795.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息