Stack Canaries

Ondersteun HackTricks

StackGuard en StackShield

StackGuard voeg 'n spesiale waarde bekend as 'n kanarie in voor die EIP (Extended Instruction Pointer), spesifiek 0x000aff0d (wat nul, nuwe lyn, EOF, karretjieterugkeer verteenwoordig) om teen buffer-oorvloeiing te beskerm. Tog bly funksies soos recv(), memcpy(), read(), en bcopy() kwesbaar, en dit beskerm nie die EBP (Base Pointer) nie.

StackShield neem 'n meer gesofistikeerde benadering as StackGuard deur 'n Globale Terugkeerstapel te handhaaf, wat alle terugkeeradressse (EIPs) stoor. Hierdie opstelling verseker dat enige oorvloeiing geen skade veroorsaak nie, aangesien dit 'n vergelyking tussen gestoorde en werklike terugkeeradressse toelaat om oorvloeiingsgebeurtenisse op te spoor. Daarbenewens kan StackShield die terugkeeradres teen 'n grenswaarde toets om te bepaal of die EIP na buite die verwagte data-ruimte wys. Nietemin 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:

Hierdie meganisme plaas 'n kanarie voor die EBP, en herorganiseer plaaslike veranderlikes om buffers by hoër geheue-adresse te posisioneer, wat voorkom dat hulle ander veranderlikes oorskryf. Dit kopieer ook argumente wat op die stapel bokant plaaslike veranderlikes oorgedra word veilig en gebruik hierdie kopieë as argumente. Dit beskerm egter nie rye met minder as 8 elemente of buffers binne 'n gebruiker se struktuur nie.

Die kanarie is 'n lukrake nommer afgelei van /dev/urandom of 'n verstekwaarde van 0xff0a0000. Dit word in TLS (Thread Local Storage) gestoor, wat gedeelde geheue-ruimtes oor drade toelaat om draadspesifieke globale of statiese veranderlikes te hê. Hierdie veranderlikes word aanvanklik van die ouerproses gekopieer, en kinderprosesse kan hul data verander sonder om die ouer of broers en susters te beïnvloed. Nietemin, as 'n fork() sonder die skep van 'n nuwe kanarie gebruik word, deel alle prosesse (ouer en kinders) dieselfde kanarie, wat dit kwesbaar maak. Op die i386-argitektuur word die kanarie by gs:0x14 gestoor, en op x86_64 by fs:0x28.

Hierdie plaaslike beskerming identifiseer funksies met buffers wat kwesbaar is vir aanvalle en spuit kode in die begin van hierdie funksies in om die kanarie te plaas, en aan die einde om sy integriteit te verifieer.

Wanneer 'n webbediener fork() gebruik, maak dit 'n brute force-aanval moontlik om die kanarie byte vir byte te raai. Tog maak die gebruik van execve() na fork() die geheue-ruimte oorskryf, wat die aanval nietig maak. vfork() laat die kinderproses toe om sonder duplisering uit te voer totdat dit probeer skryf, waarna 'n duplikaat geskep word, wat 'n ander benadering tot proseskeuring en geheuehantering bied.

Lengtes

In x64 binêre lêers is die kanariekoek 'n 0x8 byte qword. Die eerste sewe bytes is lukraak en die laaste byte is 'n nul byte.

In x86 binêre lêers is die kanariekoek 'n 0x4 byte dword. Die eerste drie bytes is lukraak en die laaste byte is 'n nul byte.

Die minst betekenisvolle byte van beide kanaries is 'n nul byte omdat dit die eerste in die stapel vanaf laer adresse is en daarom funksies wat strings lees sal ophou voordat dit dit lees.

Oorwinnings

Die lek van die kanarie en dit dan oorskryf (bv. buffer-oorvloeiing) met sy eie waarde.

  • As die kanarie in kinderprosesse gevork is, kan dit moontlik wees om dit een byte op 'n slag brute force:

BF Forked & Threaded Stack Canaries
  • As daar 'n interessante lek of arbitrêre lees-kwesbaarheid in die binêre lêer is, kan dit moontlik wees om dit te lek:

Print Stack Canary
  • Oorskryf van stapel gestoorde aanwysers

Die stapel wat kwesbaar is vir 'n stapeloorvloeiing kan adresse na strings of funksies wat oorskryf kan word, bevat om die kwesbaarheid te benut sonder om die stapelkanarie te bereik. Kontroleer:

Pointer Redirecting
  • Wysig beide meester- en draadkanarie

'N Buffer oorvloeiing in 'n geskroefde funksie wat met 'n kanarie beskerm word, kan gebruik word om die meesterkanarie van die draad te wysig. As gevolg hiervan is die mitigasie nutteloos omdat die toets met twee kanaries wat dieselfde is (hoewel gewysig) gebruik word.

Verder kan 'n buffer oorvloeiing in 'n geskroefde funksie wat met 'n kanarie beskerm word, gebruik word om die meesterkanarie wat in die TLS gestoor is, te wysig. Dit is omdat dit moontlik kan wees om die geheueposisie waar die TLS gestoor word (en dus die kanarie) te bereik via 'n bof in die stapel van 'n draad. As gevolg hiervan is die mitigasie nutteloos omdat die toets met twee kanaries wat dieselfde is (hoewel gewysig) gebruik word. Hierdie aanval word uitgevoer in die skryfstuk: 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 wat noem dat gewoonlik die TLS deur mmap gestoor word en wanneer 'n stapel van 'n draad geskep word, word dit ook deur mmap gegenereer volgens hierdie, wat die oorvloeiing soos in die vorige skryfstuk mag toelaat.

  • Wysig die GOT-invoer van __stack_chk_fail

As die binêre lêer gedeeltelike RELRO het, kan jy 'n arbitrêre skryf gebruik om die GOT-invoer van __stack_chk_fail te wysig sodat dit 'n dummiefunksie is wat die program nie blokkeer as die kanarie gewysig word nie.

Hierdie aanval word uitgevoer in die skryfstuk: https://7rocky.github.io/en/ctf/other/securinets-ctf/scrambler/

Verwysings

Ondersteun HackTricks

Last updated