Archief - De topics van lang geleden

syntax of compile error

22-01-2007, 10:59 door Anoniem, 16 reacties
Hallo allemaal!,
Ik had een vraagje als dat zou mogen.Momenteel ben ik bezig te verdiepen
tussen de relatie van c/shellcode en de gcc compiler.En vroeg me eigenlijk
af bij een paar puntjes die misschien security related zijn en kwetsbaar
voor buffer overflows.Het gaat namelijk om het volgende.

Waneer je onder c de functie exit() neemt zegt gcc als je alleen de exit();
aanroept "exit.c:7: error too few arguments to function 'exit'.Dus waneer dan
er een 0 aan toevoeg en er exit(0); van maak en het met gcc compileer is
er niets aan de hand.Teminste dit is onder c.

Wanneer het dan ga testen onder onder assembly syntax op een linux 86x
intel computer en de functie zou schrijven als:

mov eax,1
mov ebx,0
int 0x80

Tot me verbazing kan je het ook zo schrijven en kan de 0 helemaal
omzeilen.Door gewoon het te schrijven als:

mov al,1
int 0x80

Nu geeft die wel een fout melding met gcc met "program exited with code
07".Door dit probleem te overbruggen en de functie xor toe te voegen als bv

xor eax,eax
xor ebx,ebx
mov al,1
int 0x80

Nu geeft die met gdb aan "Program exited normaly".En erna het getest als
shellcode en werkte die gewoon prima

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

int main(){

char shellcode[] = "x31xc0x31xdbxb0x01xcdx80";

int (*shell)();
shell = (int(*)()) shellcode;
(int)(*shell)();
}

Maar nu vraag ik me alleen af of dit nou ligt aan de copmiler of c syntax ligt.En of functies als exit(0); op deze manier niet gevoelig zijn voor buffer
overflows als bv inline assembly zou worden toegevoegd gezien de
compiler alleen nul verwacht of iets dergelijks verwacht.
Reacties (16)
22-01-2007, 11:31 door SirDice
De int 0x80 call gebruikt de waarde van het register ebx als exit code. In je assembly zou dit register best eens al een waarde kunnen hebben. In C moet je een parameter opgeven simpelweg omdat de functie zo is gedefinieerd. In het geval van exit moet je een integer opgeven (hoeft niet perse 0 te zijn).

De exit code van een programma kun je weer gebruiken in shell scripts. Zie bijv. man bash, EXIT STATUS.
22-01-2007, 11:39 door Anoniem
Eerst een post over TNT-post, nu assembly? Wat is de relatie met
security.nl?
22-01-2007, 11:56 door SirDice
Door Anoniem
Wat is de relatie met security.nl?
Shell-code, reverse engineering ;)
22-01-2007, 17:42 door Anoniem
sirdice,
Maar is deze dan niet gevoelig voor buffer overflows.Want juist omdat het
een integer verwacht als bv 1 of 0 maar wat nou als je een functie zou schrijven als bv

jmp label_two

label_one:
pop ebx

mov al,1
int 0x80

label_two:
call label_one
mov ebx,0
mov ebx,1
mov ebx,0

Dan crashed exit toch?

In je assembly zou dit register best eens al een waarde kunnen hebben

Maar als deze een waarde zou hebben en xor ebx,ebx gebruikt zou deze toch
geen waarde meer hebben?
22-01-2007, 21:49 door Anoniem
"Maar als deze een waarde zou hebben en xor ebx,ebx gebruikt zou deze
toch
geen waarde meer hebben?"

na :
xor ebx,ebx
heeft ebx wel een waarde : 0

ieder bit je van het ebx register heeft altijd een waarde ; de waarde 1 of de
waarde 0. In de huidige computers word nog geen gebuikgemaakt
van "staatloos"

Greetingz,
Jacco
22-01-2007, 23:32 door Anoniem
ieder bit je van het ebx register heeft altijd een waarde ; de waarde 1
of de waarde 0. In de huidige computers word nog geen gebuikgemaakt
van "staatloos"

Dan zou die toch eigenlijk geen code 07 mogen geven bij mov al,1 int 0x80.Want als ebx op 0 zou staan dan weet int 0x80 dat de integer waarde van ebx 0 is toch?Of komt dit als de waarde 1 zou zijn dat die dan deze procedure uitvoerd terwijl er geen functies beschikbaar zijn.

man exit
1. Call the functions registered with the atexit(3) function, in
the reverse order of their registration.
23-01-2007, 03:15 door SirDice
Door Koekie
jmp label_two

label_one:
pop ebx

mov al,1
int 0x80

label_two:
call label_one
mov ebx,0
mov ebx,1
mov ebx,0

Dan crashed exit toch?
Nope.. Code exit "netjes" met als errorcode het adres net na de call label_one.

1. Call the functions registered with the atexit(3) function, in the reverse order of their registration.
Lees man 3 atexit ;)
23-01-2007, 08:52 door Anoniem
Nope.. Code exit "netjes" met als errorcode het adres net na de call
label_one.

Maar zou het ebx register hier niet gevoelig voor zijn met een andere vorm
waarmee het ebx register overflushed zou worden met 0 waardes?

Ps.Zou er vandaag mee beginnen met lezen van atexit.Het is echt
verslavend gewoon steeds moeilijkere routines in c te programeren
en die weer te programeren in assembly.Steeds het weer verder pushen
van kennis :D
23-01-2007, 12:14 door SirDice
Een register kan alleen een waarde bevatten.. Die kun je echt niet overflowen[1]. De rest van de code doet iets met die waarde, dat zou je wel kunnen misbruiken, als de code bijv. een bepaalde waarde niet verwacht. In het geval van exit is die mogelijkheid er niet. Het programma eindigt met de errorcode die is opgeslagen in het ebx register.

[1] Je kunt een register wel overflowen maar niet op de buffer manier. Een register is een plek voor de processor om waardes in op te slaan. Als je bijv. een 8 bit register hebt kan deze de waardes 0-255 bevatten. Als het register de waarde 255 heeft en je telt er 1 bij op dan wordt de waarde 0 en wordt het overflow of carry bit in het status register gezet. D.m.v. tests of conditionele branches kun je weer iets aan de hand van die status bits doen. Bijvoorbeeld 1 optellen bij een ander register zodat je een 16 bit waarde kan optellen in 2 8 bit registers.
23-01-2007, 13:17 door Anoniem
Een register kan alleen een waarde bevatten.. Die kun je echt niet
overflowen[1]. De rest van de code doet iets met die waarde, dat zou je wel
kunnen misbruiken, als de code bijv. een bepaalde waarde niet verwacht.
In het geval van exit is die mogelijkheid er niet.

Ok thanks ! Dan is het weer verder speuren dacht misschien was het
iets.

Offtopic: Sirdice weet jij trouwens hoe je een nieuwe regel van een string
kan aangeven zoals bij c n? Ik dacht eerst dat iets was als txt db 'test',0 of
txt db ',0x12 maar hij blijft maar testlinux# aan geven en zocht eigenlijk een
oplossing voor:

test
linux#
23-01-2007, 14:57 door SirDice
0x00 is meestal (niet altijd) het einde van een string. 0x12 is een linefeed, volgens mij moet je 0x15 hebben; Carriage Return. Op sommige OS'en (dos/windows bijv.) moet je zelfs beiden gebruiken; CR/LF. Beetje afhankelijk van de functie de je gebruikt vermoed ik. De C n wordt meestal automatisch "vertaald" naar de juiste combinatie.

Als je serieus iets met assembly en machinecode wil doen kan ik je aanraden om eerst een beetje te spelen met een 8 bit cpu. Registers, programcounter etc. zijn dan wat simpeler. De nieuwe 64 bit cpu's wken niet zo gek veel af van datzelfde principe. Ik was al een beetje op zoek naar een leuke emulator (6502, 6809, Z80, 8051 ofzo) maar kon zo snel niets vinden.

Off-topic: ASCII zit wel geinig in elkaar. Wel eens afgevraagd waarom del 0x7f is? Dat stamt uit de ponskaart tijd. Gaatjes in een kaart kun je niet meer dichtmaken namelijk, lastig als je een foutje maakt. 0x7f heeft alle 7 bits gezet (open, een gaatje). Zo ook carriage return en linefeed. Denk maar aan een ouderwetse typemachine. Met de hendel kun je een regel naar beneden. Met diezelfde hendel trek je ook de carriage ('t ding waar je papier in zit) terug.
23-01-2007, 16:27 door Anoniem
Beetje afhankelijk van de functie de je gebruikt vermoed ik

De write versie in /usr/include/unistd.h.Maar ook 0x00 of 0x15 of 0x12 of
0x12,0x15 werkte niet.Eigenlijk nog best wel raar dat die niet op die ascii
codes reageerd met txt db 'test',10 werkt die wel had die opgezocht in in de ascii tabel bleek het DLE "data link escape" te zijn.

Om nog ff op je advies terug te komen dankje ik zou er us na kijken was al
aan het zoeken van die microcontrolers die op die displaytjes kon
aansluiten en zo kleine programmatjes kan schrijven.Nog mooier zou zijn
misschien nog een keer een oude comodore/atari te ritselen.Das ook wel
handig voor op de tv en op bed :D

off-topic: Toch nog geniaal bedacht voor die tijd :D
23-01-2007, 19:35 door Anoniem
0x0D is CR (carriage return)
0x0A is LF (line feed)
23-01-2007, 23:58 door Bitwiper
Door SirDice
0x12 is een linefeed, volgens mij moet je 0x15 hebben; Carriage Return.
Carriage Return is 0xD (decimaal 13) en LineFeed is 0xA (decimaal 10). Onder Linux/Unix etc. moet je alleen linefeeds gebruiken (de heren Kernighan en Richie hebben dat zo gewild; de heer Jobs lag toen al dwars en koos juist voor CR terwijl de heer Gates voor the best of both worlds koos - en het rijkst werd).

Doe maar eens:
od -t x1 /etc/hosts
en bewonder de laatste byte(s)

PS echte geeks editten shadow in een hexeditor :)
24-01-2007, 11:54 door SirDice
Door Erik van Straten
Door SirDice
0x12 is een linefeed, volgens mij moet je 0x15 hebben;
Carriage Return.
Carriage Return is 0xD (decimaal 13) en LineFeed is 0xA
(decimaal 10).
Ah.. Je hebt gelijk.. I heb scheel in de tabel gekeken en de
octale waardes opgegeven. Doh.. Nu is het mijn beurt om rood
te worden ;)
24-01-2007, 12:01 door Anoniem
Eigenlijk ook raar dat die dan niet octets herkent van bv 0x12 of 0x012 en
wel decimaal en heximaal acepteerd.Decimaal en heximaal zou ik eerder verwacht hebben met 32bit registers.

Maar bij een declaratie van als mov al,1 is het eigenlijk best raar dat die dan niet een octet acepteerd.
Reageren

Deze posting is gelocked. Reageren is niet meer mogelijk.