Je uitleg over stackoverflows klopt, alleen kunnen overflows op meer segmenten plaats vinden dan alleen de stack.
Stackoverflows zijn wel vaak het makkelijkste om te exploiten.
Maar PaX is veel meer dan alleen een non-exec stack.
Alleen de stack non-exec zetten heeft namelijk weinig zin:
een attacker kan 9 van de 10 gevallen zijn code op .data/heap kwijt, en het is ook mogelijk om functies die al in meegelinkte libraries of in het programma zelf zitten te gebruiken.
Bijv. door in system() van libc returnen en dan een shell spawnen. Het probleem is dat de code van libc altijd executable moet zijn.
PaX zorgt dat het voor een attacker (bijna) onmogelijk is om nieuwe code in het huidige process te introduceren, door processen die zich 'verdacht' gedragen te killen.
- PaX restrict mmap() (een functie om geheugen te mappen, hiermee zou het dus mogelijk zijn nieuwe geheugen te mappen, en PROT_EXEC als flag te geven, waardoor het executable word.)
- mprotect() (een functie om de flags van pages te wijzigen, als je alleen een non-exec stack heb, kan een attacker in deze functie returnen in libc, en zo de stack weer terug executable zetten, (schijnt nog op openbsd te werken
- PaX randomized het base address van alle segmenten.
(Dit maakt het voor een attacker bijzonder kut om zijn shellcode terug te vinden, jumpen naar een verkeerd address zal in een segmentation fault eindigen.)
- PaX randomized het base address van shared libraries
[esdee@flopppp src]$ ldd /bin/ls|grep libc
libc.so.6 => /lib/i686/libc.so.6 (0x2fd01000)
[esdee@flopppp src]$ ldd /bin/ls|grep libc
libc.so.6 => /lib/i686/libc.so.6 (0x280d1000)
PaX is lang niet waterdicht, maar het legt de lat een stuk hoger. Ik heb eigelijk nog nooit in public een PaX-evading exploit gezien. Alhoewel het waarschijnlijk wel mogelijk is. Zoals je ziet is het base-address van glibc nog best te bruteforcen, maar met een info leak (een soort bug waarbij het bijv. mogelijk is om remote geheugen uit te lezen) zal het niet al te moeilijk worden om PaX te verslaan.
Als de daemon ook nog eens fork()-ed heeft de attack onbeperkt aantal pogingen om addressen goed te gokken. fork() moet volgens posix een exact kopie van het process image maken, en dat doet het dus ook, dus childs zijn niet opnieuw random. Ik denk dat het mogelijk is om dmv. bepaalde process informatie kan achter halen, (bijv. link_map, een linked list waarin alle gelinkte libraries + hun base address staan), waardoor je alsnog een klassieke 'return-into-libc' attack te doen.
Ik heb iig nog nooit een publieke betrouwbare exploit gezien die PaX verslaat, dus met PaX zit je al redelijk goed. Het is kleine moeite om deze patch even toe te passen, en het maakt het voor een attacker een stuk moeilijker.
Het beschermt je alleen niet tegen bijv. php bugs of onveilige wachtwoorden
De reden waarom ik het overigens steeds over 'PaX' heb ipv 'grsecurity' is omdat spender niet de auteur is van PaX en gewoon deze patches bij grsecurity heeft toegevoegd. De echt auteur blijft kennelijk liever wat meer op de achtergrond.