Ed Schaller höll en intressant presentation om
remote execution på IBM WebSphere (WAS).
WAS frontas typiskt av en webbserver såsom Apache eller IIS. Webbservern används för lastbalasering och felhantering. Den kommunicerar i sin tur med WAS via en
webbserver-plugin över http. Men inte alla request skickas vidare.
Webservern utgår från url-mappnignar i
web.xml och
ibm-web-ext.xmi. Om en match hittas så skickas requestet vidare, annars hanteras det av webbservern själv.
JSP:er och nullWAS och andra applikationsservrar översätter jsp till Java, kompilerar och kör det som en servlet. Det fungerar normalt även runtime och jsp:er komplieras först när de efterfrågas.
Det gör att webbservern alltid skickar jsp-request vidare eftersom appservern måste få en chans att kolla om den finns och kompilera den.
Så hur tolkas null i den här översättningen från jsp till Java till bytekod? Jo, det visar sig att WAS accepterar null men i accessen till det underliggande filsystemet så termineras strängen vid null. På det viset kan man fejka att man vill nå en jsp men i själva verket peka ut en annan fil. Så här:
ctxroot/path_till_filen%00.jspDet kommer läsa upp den fil attackeraren har anget så länge den finns i den exploderade war:en. Det måste dessutom vara en korrekt jsp. Jobbigt? Nja, i princip allt som inte innehåller <% är en korrekt jsp. T ex textfiler, html, xml, de flesta zip-filer och så vidare. Intressant nog visare det sig att om attackeraren anger en katalog istället för en fil så får han/hon en kataloglistning. Så här:
ctxroot/dir/%00.jspctxroot/.%00.jsp (extra punkt för att komma åt kontextroten)
Web Server PluginOK, null gick bra att att skicka till WAS:en men hur går det med den framförliggande webbservern? Pluginen är skriven i C och terminerar därför vid null, dvs
text.txt.jsp blir
text.txt. Tillbaka på ruta
null så att säga.
Men vi kanske kan lura webbservern med teckenkodning? Java lagrar strängar i UTF-16 internt men tolkar inkommande strängar som UTF-8. Men web server-pluginen förstår inte lång UTF-8. Därtill har IBMs jvm haft en allvarlig bugg i hantering av så kallad
overly long UTF-8 som är fixad i de senaste patcharna. På det viset kan man injicera UTF-8 som webbserver-pluginen inte förstår och som jvm:en sen misstolkar som null. Tecknet är
%C0%80 vilket
tolkas som ASCII null.
Med dubbelpunkt kan man dessutom komma åt WEB-INF-katalogen och kodningen för dubbelpunkt i UTF-8 är
%C0%AE. Totalt sett så här:
ctxroot/%C0%AE/WEB-INF/web.xml%C0%80.jsp… för att komma åt web.xml.
Axis och bilagorMen attackeraren vill inte bara läsa filer utan också få till
remote execution. Så han/hon måste få in en jsp-fil i den exploderade war:en. Här vänder vi oss till det populära
Axis-ramverket för web services.
Man kan nämligen ha bilagor (
attachments) i sin SOAP. Om man lägger bilagan före SOAP:en och dessutom refererar den i SOAP:en, t ex med en
href, så kommer Axis ladda bilagan som fil och cache:a den … i war:en!
Men då måste attackeraren kunna kommunicera med en
web service väl? Nej.
Web services tillåter att klienten skickar ett
SOAP Fault det första den gör. Och då kommer Axis hantera det oavsett om det finns någon
web service som det kan ha gått fel i.
SOAP Fault är kodade på samma sätt som vanlig SOAP så tricket med bilagan funkar bra.
Bilagan rensas av cache-hanteraren så det uppstår en så kallad
race condition där attackeraren måste hinna använda den uppladdade jsp:n innan den tas bort.
Allt det här demade Ed på plats. Japp, skal med användaren wasadmin blev det.Fix?Alla moderna versioner av WebSphere (6 och framåt) har så kallade fixpack för det här problemet. Ed har varit noga med att rapportera det på rätt sätt. Coolast var att IBM ordnade en patch på två veckor för alla de 60 varianter som var sårbara. Det är respekt.
Men om man kör en opatchad WebSphere så är man alltså sårbar.
Ed tyckte också man skulle överväga att stänga av runtime-kompilering och omladdning av jsp:er (
disableJspRuntimeCompilation).