java执行命令
参考
[本地命令执行 · 攻击Java Web应用-Java Web安全] (javasec.org)
java 执行命令的函数调用链
通过观察整个调用链我们可以清楚的看到exec方法并不是命令执行的最终点,执行逻辑大致是:
Runtime.exec(xxx)java.lang.ProcessBuilder.start()new java.lang.UNIXProcess(xxx)UNIXProcess构造方法中调用了forkAndExec(xxx)native方法。forkAndExec调用操作系统级别fork->exec(*nix)/CreateProcess(Windows)执行命令并返回fork/CreateProcess的PID。
有了以上的调用链分析我们就可以深刻的理解到Java本地命令执行的深入逻辑了,切记Runtime和ProcessBuilder并不是程序的最终执行点!
runtime 直接加载
1 | |
通过反射加载getruntime
1 | |
调用UseProcessBuilder
1 | |
反射UNIXProcess/ProcessImpl执行本地命令
1 | |
使用
1 | |
forkAndExec命令执行-Unsafe+反射+Native方法调用
如果RASP把UNIXProcess/ProcessImpl类的构造方法给拦截了我们是不是就无法执行本地命令了?其实我们可以利用Java的几个特性就可以绕过RASP执行本地命令了,具体步骤如下:
- 使用
sun.misc.Unsafe.allocateInstance(Class)特性可以无需new或者newInstance创建UNIXProcess/ProcessImpl类对象。 - 反射
UNIXProcess/ProcessImpl类的forkAndExec方法。 - 构造
forkAndExec需要的参数并调用。 - 反射
UNIXProcess/ProcessImpl类的initStreams方法初始化输入输出结果流对象。 - 反射
UNIXProcess/ProcessImpl类的getInputStream方法获取本地命令执行结果(如果要输出流、异常流反射对应方法即可)。
1 | |
JNI命令执行
java 通过JNI 调用动态链接库,只需要在动态链接库中写一个本地命令就OK 了
但是这个方法对攻击服务器的作用并不是很大
首先你不像前面的Java 原生代码 ,可以直接使用工具编写成一个字节
在这个场景下需要,提前给系统添加一个动态链接库才行。
如果将动态链接库编写成base64 编码之后的字符串的话,对http 数据包的大小有更强的依赖。
java本地命令 执行
Java本地命令执行是一个非常高危的漏洞,一旦被攻击者利用后果不堪设想。这个漏洞原理一样是非常简单且容易被发现。开发阶段我们应该尽可能的避免调用本地命令接口,如果不得不调用那么请仔细检查命令执行参数,严格检查(防止命令注入)或严禁用户直接传入命令!代码审计阶段我们应该多搜索下Runtime.exec/ProcessBuilder/ProcessImpl等关键词,这样可以快速找出命令执行点。
java执行命令
https://tsy244.github.io/2025/05/17/java安全/java执行命令/