Archief - De topics van lang geleden

Buffer overflow

28-05-2007, 17:36 door Anoniem, 22 reacties
Hoi allemaal!

Ik had een vraagje als dat zou mogen. Met betrekking tot het vinden van de
saved frame pointer. Wanneer je een een segmentation fault programeerd
met bv:

#include (stdio.h)

int main(int arc,char *argv[]){
printf("Test",argv
[1111111111111111111111111111111111111111111111]);
}

starting program /home/shellcode/printf

program recieved signal SIGSEGV, segmentation fault.
in 0x80488365.
(gdb) i r
esp 0xffff348 0xbffff348
eip 0x804836 0x8048365

Kan je dan eigenlijk vanuit gaan dat het adres van 0xffff348 de locatie is die
kan overschrijven met bv het adress waar de shellcode staat ?
Reacties (22)
28-05-2007, 19:19 door Anoniem
Tot nu toe ben ik zo ver gekomen :

1. Vinden locatie van de shellcode zoeken met :

----------------------------
xor ebx,ebx
mov bl,41
push ebx
push ebx
push ebx
pshh ebx
----------------------------

Dit omgezet na shellcode en toen gexecuted in gdb. Toen gaf die

starting program: /home/shellcode/printf1

Program recieved signal SIGSEGV. Semgentation fault.
0x0804945f in shellcode ().
(gdb)x/100 $esp-100
0xbffff340: 0x0804844 0x00000090 0x00000090 0x00000090
0xbffff350: 0x0000009 0x00000090 0x00000090 0x00000090

0xbffff360: 0x0000001

2. Het assembler code geschreven met de pointer na 0xbffff360

jmp 0xbffff360
push esp

char shellcode[] = "xe9dbx72xfbxb7x54";

Toen het complete programma gescreven:

---------------------------
#include (stdio.h)

char shellcode[] = "xexdx72xfbxb7x54";

int mem(){
int *ret;
ret = (int * ) &ret +2;
( * ret ) = (int) shellcode;
};
int main(int arg, char *argv[] ){

if(argc !=2){
printf("Test", argv[11111111111111111111111111111111],mem());
}
}
---------------------------

Dit gexecuted in gdb die nu aangeeft :

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

Starting program recieved signal SIGSEGV, Segmentation fault.
0xc0000758 in ??

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

De esp is nu overgesvreven want eerst gaf die zonder mem() aan
0x0804804873 in main(). Raar alles id dat die met i r aangeeft
dat het esp adress 0xbffff340 terwijl jmp 0xbffff348 had gedeclareerd.
28-05-2007, 20:44 door Anoniem
Wat wil je bewijzen? Dat je slimmer bent dan de rest??
28-05-2007, 21:40 door Anoniem
...................
28-05-2007, 22:40 door Anoniem
Ps. Readactie als je iets wil verranderen kan dat niet dan linkt die
http://www.security.nl/i/143102/. En krijg je een een 404 retour.

#include (stdio.h)

int main(int arc,char *argv[]){

printf("Test",argv
[1111111111111111111111111111111111111111111111]);
}

Had moeten zijn:
------------------------

#include (stdio.h)

char shellcode[] = "xexdx72xfbxb7x54";

int mem(){
int *ret;
ret = (int * ) &ret +2;
( * ret ) = (int) shellcode;
};
int main(int arg, char *argv[] ){

if(argc !=2){
printf("Test", argv[11111111111111111111111111111111],mem());
}
}
29-05-2007, 10:35 door Anoniem
Als je zo goed bent in assembler zoals je doet voorkomen
maak dan snelle assembler geschreven applicaties zodat alles
wat sneller loopt dan via de C code generators. Ga b.v. bij
M$S werken!!!!!
29-05-2007, 10:37 door pikah
Wat probeer je precies te laten zien met deze functie?
Het heeft naar mijn idee niets te maken met het overflowen
van een buffer, wanneer jij vindt dat dat wel is mag jij mij
vertellen welke buffer :D

De reden dat jij een SIGSEGV krijgt is omdat je probeert te lezen uit een stuk geheugen dat niet gealloceerd is door je programma, ofwel je Address Space.

Daarbij moet je erop letten, bij een echte overflow, of er geen beveiligingsfuncties in je kernel zitten zoals, Stack Randomization of het disablen van het uitvoeren van functies op de Stack...

Hetgeen wat jij ziet in dit stukje:

starting program: /home/shellcode/printf1

Program recieved signal SIGSEGV. Semgentation fault.
0x0804945f in shellcode ().
(gdb)x/100 $esp-100
0xbffff340: 0x0804844 0x00000090 0x00000090 0x00000090
0xbffff350: 0x0000009 0x00000090 0x00000090 0x00000090
0xbffff360: 0x0000001

Is dat de functie printf() voordat hij uitgevoerd wordt, de argumenten op de stack plaatst zodat deze later in de functie zelf gebruikt kunnen worden.
29-05-2007, 11:20 door Anoniem
Solid, met alle respect, ga eerst eens leren programmeren in C.
Wat je nu aan het doen bent slaat helemaal nergens op. De
reden van je segmentation fault is het aanroepen van niet
geinitialiseerd geheugen en heeft verder niets met een buffer
overflow te maken. Gewoon een programmeerfout, meer niet...

Anyway, lees 'The C Programming Language' eens en ga je
daarna pas aan het exploiten wagen...
29-05-2007, 17:15 door Anoniem
Is dat de functie printf() voordat hij uitgevoerd wordt, de argumenten
op de stack plaatst zodat deze later in de functie zelf gebruikt kunnen
worden.

0xbffff360is het adress van het begin van de shellcode dacht ik gezien
de /x53 push ebx is. En gezien 7x 53 was gedeclareerd voor herkennings
punt dacht ik dat de volgende lijn 0xbfff30 het begin van de shellcode was.
Maar over het hoofd gezien in nasm geeft die start+ bss aan dus is nog ff
door zoeken doe nog iets fout.

Wat probeer je precies te laten zien met deze functie?

Het was slechts een simpel voorbeeld van als je iets laat crashen
na welk adress je dan moet overschrijven. En de eip waar die
gecrashed is te saven als een esp adress. Dat was opzich de insteek.
grappig is trouwens wel als je uitvoerd :

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

#include (stdio.h)

char shellcode[] = /* 44 Byte shellcode van eSDee */
"x31xc0x31xdbx31xc9xb0x46xcdx80x31"
"xc0x50x68x2fx2fx73x68x68x2fx62x69"
"x6ex89xe3x8dx54x24x08x50x53x8dx0c"
"x24xb0x0bxcdx80x31xc0xb0x01xcdx80";

int mem(){
int *ret;
ret = (int * ) &ret +2;
( * ret ) = (int) shellcode;
};
int main(int arg, char *argv[] ){

if(argc !=2){
printf("Test", argv[11111111111111111111111111111111],mem());
}
}

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

Gdb het resultaat geeft program runned normaly. En het esp adress is
overschreven. In het zelfde programma waardie eerst crashed in main.
29-05-2007, 21:18 door Anoniem
Door Solid
Hoi allemaal!

Ik had een vraagje als dat zou mogen.

Nee. Niet meer.
30-05-2007, 09:31 door Anoniem
Het is een programmeer fout, jij probeert een buffer uit te
lezen die niet geinitialiseerd is, of je het nu wil of niet.


0xbffff360is het adress van het begin van de shellcode dacht
ik gezien
de /x53 push ebx is
Inderdaad het begin van jou shellcode, dit adres is een
adres op de stack, lees maar even een tutorial over waar de
stack begint en hoe groot hij is. Deze shellcode is er
opgezet bij het aanroepen van printf() zoals ik al vertelde.

Voordat een functie wordt aangeroepen zullen alle argumenten
die mee worden gegeven op de stack worden gezet, dit is de
reden dat jij het op de stack ziet, en logisch want het
staat ook op de stack.
30-05-2007, 10:26 door Anoniem
Inderdaad het begin van jou shellcode, dit adres is een
adres op de stack, lees maar even een tutorial over waar de
stack begint en hoe groot hij is.

Thx!, Dat verbaasde me las al verschillende faq's over de stack waar
beschreven stond waar precies het begin van de shellcode stond.
in de meeste stond [[ buffer ] [ ebp ] [ esp] ]. Daarom verbaasde
mij het als je dus dat je direct bij dat adress uit kwam in het geheugen.
Ook gezien de shellcode dacht ik in het cs staat en bij het adress
aangegeven werd waneer ik het zelfde adress aanriep met push 0xbffff360
in objdump. Daar bij stond start + bss. Ik dacht ik alleen bij [ buffer ] was maar wist het niet zeker.
30-05-2007, 11:02 door Anoniem
Je snapt het niet. Als jij een exploit schrijft zal de shellcode
inderdaad in de code sectie staan (als je kiest voor een globale
statische variabele). De bedoeling is juist deze shellcode in het
geheugen van je vulnerable programma injecteren. Meestal
wordt deze in de te overflowen buffer gezet, al zijn er ook
andere nettere mogelijkheden, vandaar dat deze dan op de
stack komt (bij een stack-based buffer overflow). Je moet dus
niet kijken op welk adres de shellcode staat in je exploit, maar
op welk adres deze gepositioneerd wordt in je vulnerable, te
exploiten, programma.
30-05-2007, 11:46 door Anoniem
Je moet dus
niet kijken op welk adres de shellcode staat in je exploit, maar
op welk adres deze gepositioneerd wordt in je vulnerable, te
exploiten, programma.

Ah ok nu weet ik waar ik de fout in ging. Die pationering is toch adress [ [
buffer ] [ ebp ] [ esb] ] ? Buf als de esp en ebp 8 bytes lang is. En de buffer
is 10 bytes is dan de pationering 8 + 10 = 18 bytes de pasionering op de
stack waar de buffer execute wordt?
30-05-2007, 11:52 door Anoniem
Je moet dus
niet kijken op welk adres de shellcode staat in je exploit, maar
op welk adres deze gepositioneerd wordt in je vulnerable, te
exploiten, programma.

Ah ok thx ! Nu begrijp ik waar ik de mist in ga. Dus stel je hebt een buffer
met draarin shellcode en de buffer is 10 bytes lang. Is dan de pasionering
[ [ buffer ] [ ebp ] [ esp ]. Dus 10 + 4 + 4 = 18 bytes ? En dit het de locatie
waar die wordt gexecute?
30-05-2007, 13:41 door Anoniem
Zal het dan nog een keer rustig uit proberen te leggen, maar
raad je (wederom) aan eerst eens wat basiskennis op te doen
van het programmeren in C en de IA-32 architectuur.

Het principe van een buffer overflow is dat je meer data in een
'buffer' stopt dan gereserveerd. Je bent dus in staat belangrijke
systeem data te overschrijven zodat je de executie van een
programma kunt beinvloeden. Als dit op de stack gebeurd, dus
bij een lokaal statisch gedeclareerde buffer, bestaat er een
mogelijkheid om de bewaarde instructiepointer te overschrijven.
Je kunt overigens ook de bewaarde framepointer overschrijven,
maargoed om het een beetje duidelijk proberen te houden zal
ik dit even achterwegen laten.

Dus stel je hebt:

[ buffer ] [ bewaarde framepointer ] [ bewaarde
instructie pointer ]

Als je in staat bent om de bewaarde instructiepointer te
overschrijven kun je dus zelf bepalen op welk geheugenadres
het programma verder gaat met de executie van operation
codes. Zie voor meer informatie de LEAVE en RET instructies in
de Intel Developers Manuals.

Nu heb je alleen 1 probleem, je wilt namelijk zelf gespecificeerde
operation codes uitvoeren. Stel dat je setuid(0); execve(/bin/
sh); exit(0); uit wilt voeren. Het programma dat je wilt exploiten
zal dit zelf hoogstwaarschijnlijk niet in zijn geheugen hebben
staan (het returnen in shared libraries even daar gelaten) en
daar is waar de shellcode in het verhaal komt.

Door middel van het maken van een shellcode (een stukje code
bestaande uit operating code) en deze te 'injecteren' in het
geheugen (bijvoorbeeld het plaatsen op de stack) hebben we
deze code wel in het geheugen van het te exploiteren
programma staan. Vervolgens hoeven we dus alleen nog maar
te weten waar precies deze shellcode staat (als je een
programma lokaal exploit kun je hiervoor mooi het environment
gebruiken aangezien je dan deze plaats met een simpel
sommetje uit kunt rekenen) en met dit adres de bewaarde
instructie pointer te overschrijven.

Nu zijn er tegenwoordig zitten hier tegenwoordig wat haken en
ogen aan door HIPS, dingen waar overigens meestal wel
omheen te werken is, maargoed dit lijkt me nog allemaal een
beetje te hoog gegrepen om verder uit te leggen.

Als je Linux gebruikt kijk dan even of stack randomization aan
staat en zo ja, zet deze dan uit. Als je hier geen zin in hebt, zoek
dan even op google naar 'linux-gate.so.1 jmp esp' oid.
30-05-2007, 13:44 door pikah
Bij een stack-vulnerability wordt het EIP overschreven, dit
is het register dat te vinden is achter de EBP.

In het EIP staat je instruction pointer, ofwel het geheugen
adres wat als volgende wordt uitgevoerd, dit adres moet
wijzen naar jou shellcode, of je moet een van de vele andere
exploit methodes gebruiken net als bv JMP *ESP, dan verwijst het niet naar jou shellcode maar naar een andere instructie.
30-05-2007, 13:52 door Anoniem
@pikah:

EIP en EBP zijn registers, staan niet in het geheugen en zijn dus
niet overschrijfbaar. Je processor zet een kopie van dit register
in het geheugen als er een CALL instructie uit wordt gevoerd om
te weten waar deze mee verder moet als er een RET instructie
wordt uitgevoerd (zie voor EBP de functie proloog en de LEAVE
instructie). Een wel degelijk belangrijk punt om het exploiten
van stack-based buffer overflows te kunnen begrijpen in mijn
ogen...
30-05-2007, 15:10 door Anoniem
Als je Linux gebruikt kijk dan even of stack randomization aan
staat en zo ja, zet deze dan uit. Als je hier geen zin in hebt, zoek
dan even op google naar 'linux-gate.so.1 jmp esp' oid.

Heb er al na gezocht en dank voor de uitleg.
31-05-2007, 11:39 door Anoniem
Door Anoniem
@pikah:

EIP en EBP zijn registers, staan niet in het geheugen en
zijn dus
niet overschrijfbaar. Je processor zet een kopie van dit
register
in het geheugen als er een CALL instructie uit wordt gevoerd om
te weten waar deze mee verder moet als er een RET instructie
wordt uitgevoerd (zie voor EBP de functie proloog en de LEAVE
instructie). Een wel degelijk belangrijk punt om het exploiten
van stack-based buffer overflows te kunnen begrijpen in mijn
ogen...

Ik heb nooit beweerd dat het geheugenadressen zijn, ik leg
het misschien op een verkeerde manier uit, dus misschien
wordt het verkeert geinterpreteerd.
31-05-2007, 11:41 door pikah
Door Anoniem
@pikah:

EIP en EBP zijn registers, staan niet in het geheugen en
zijn dus
niet overschrijfbaar. Je processor zet een kopie van dit
register
in het geheugen als er een CALL instructie uit wordt gevoerd om
te weten waar deze mee verder moet als er een RET instructie
wordt uitgevoerd (zie voor EBP de functie proloog en de LEAVE
instructie). Een wel degelijk belangrijk punt om het exploiten
van stack-based buffer overflows te kunnen begrijpen in mijn
ogen...

Ik beweer nergens dat het geheugenadressen zijn, ik leg het
misschien niet helemaal duidelijk uit wat ik bedoel, dus
misschien wordt het verkeerd geinterpreteerd

Offtopic: Ik blijf steeds uitgelogd, daarom aantal posts
anoniem die door mij zijn gepost. Daardoor ook typos:P
31-05-2007, 20:53 door Anoniem

Bij een stack-vulnerability wordt het EIP overschreven, dit
is het register dat te vinden is achter de EBP.

Ik beweer ook niet dat je zegt dat het geheugenadressen zijn, je zegt
immers hierboven dat het registers zijn. Alleen zeg je ook dat deze bij een
"stack-vulnerability", neem aan dat je hier een stack-based buffer overflow,
overschreven kunnen worden. Dit is niet waar, aangezien dit gewoon
geheugencellen op je processor zijn en niet in het geheugen staan.

Je overschrijft de BEWAARDE instructie of framepointer. Vrij
belangrijk puntje...
01-06-2007, 10:09 door Anoniem

Je overschrijft de BEWAARDE instructie of
framepointer. Vrij
belangrijk puntje...

Klopt, die op het moment van een RET instructie wordt uigevoerd
Reageren

Deze posting is gelocked. Reageren is niet meer mogelijk.