thegoodfellas/blogset-br huggingface dataset:
mensagem.-- messagebox.asm -- ; GABBA GABBA HEY! include '\fasmw16727 (windows)\INCLUDE\WIN32AX.INC' ; Inclui no processo de compilacao o ; arquivo que contem os parametros ; necessarios para a obtencao do .exe.code ; Marca o inicio da secao 'codigo' do programa. start: ; Entry-Point (O programa comeca a ser executado daqui) invoke MessageBox, HWND_DESKTOP, "6_Bl4ck9_f0x6 says: GABBA GABBA HEY!","Titulo",MB_OK invoke ExitProcess,0.end start ; Marca o fim do codigo do programa-- cut here -- Bem, como voce pode notar inserimos comentario em assembly usando o ponto e virgula (;). Nao comentei as duas funcoes pro code nao ficar feio, mas o que acontece eh que quando o prog chega nessa linha de codigo ele invoca (chama) a funcao MessageBox(), que no caso recebe os parametros necessarios para a exibicao da mensagem, que sao, a mensagem em si, o titulo da messagebox (caixa mensagem) e o botaozinho, que no ca-so vai ser soh um OK, MB_OK (MessageButton_OK). Mas voce poderia colocar um MB_YESNO ou alguma outra coisa nesse parametro soh pra ficar zuando, e dizer pras minas que voce desenvolve programas pra computador e vende eles para empresas como a Ivia que criou o internet banking de um monte de banco como Barclays Bank, BNB, BASA, Bradesco ou a Lanlink, lah de Fortaleza, seu black hat ;) Depois ele chama a funcao exit() e sai com o status '0'... :) Entao, lah no editor tu vai lah em 'Run' e depois vai em Compile, ou Digita Ctrl+F9. Depois da compilacao do codigo fonte tu vai ter uma .executavelzinho nomeado como messagebox.exe, rode ele pra ver a mensagem:Ta bom, pra que eu quero essa merda? Voce diz. Entao eu digo, vamo carregar esse exe pra dentro do Immunity.Bem, na segunda coluna da esquerda para->a->direita voce pode ver os opcodes, eh isso daih que eh o shellcode :) Tan dam! Lembra que te dei os toques de que uma ins-trucao em assembly (terceira coluna) eh convertida em opcode (segunda coluna) pelo processador? Pois eh, na verdade o processador soh executa instrucoes em hexa, ou seja, o que estah na segunda coluna. Se voce nao reparou o endereco de retorno nao passa de opcodes (e.g. "\xb0\xd9\xed\xb7" 4 bytes em hardware de 32 bits :). Se voce agrupar alguns desses opcodes (Correspondendo a alguma funcao) e executa-los, voce executarah a funcao... Sacow? Ao inves de jogar o executavel pra maquina remota, o que voce faz e jogar apenas os opcodes (que executam uma determinada funcao) para dentro da memoria do PC remoto usando o stack frame montado na memoria da vitima que nao controla dados que serao enviados para faze-los serem executados, ou seja, os opcodes enviados executam as tais determinadas funcoes que citei. Como voce pode ver acima esses opcodes estao muito confusos, a compilador organizou as instrucoes em ordem a facilitar a execucao do software e consequentemente tornando dificil a extracao dos opcodes por conta de instrucao que fazem chamadas a determinados enderecos e que ainda saltam para determinados locais e que jogam parametros para a pilha e blah, blah, blah. Soh eh foda que o fasm nao
executar a funcao que ta dentro do binario. Armamos o trabuco e o sistema senta o dedo pra nois. "Por que assembly?" pergunta o orangutango alih no kanto hahah Struck sem vergonha hahah. Se voce usar a linguagem 'C' quando voce for pegaros opcodes voce vai ter um pouco de dor de cabeca porque o compilador embaralha demais as intrucoes e assim "consequentemente" tornando os opcodes confusos, por essa rasao devemos usar assembly e pegar os opcodes diretamente do que nos escrevemos. Entao, devemos usar as instrucoes "push" seguida do parametro para jogar o argumento de uma funcao qualquer (por exemplo: exit) sobre a stack, depois que o argumento dela ta na pilha nos chamamos o endereco que ela ta armazenada na dll usando a instrucal call (chamar) e ela "como toda boa funcao" vai obter seus parametros da pilha em ordem inversa, se essa funcao for exit(), na sua execucao o programa vai encerrar com o status que tu jogou na pilha. Exemplo pratico..:Como todos sabemos a funca Sleep() dorme, como o proprio nome jah entrega. Essa funcao recebe como parametro um numero inteiro que vai dizer o tempo que ela vai deixar o programa "dormindo" em "run-time", 1000 ms de segundo equivalem a 1 segundo. Veja um exemplo em C.1) 1rst example coded in C language-- Sleep.c -- #include #include // <-- Header que guarda a nossa funcao Sleep();int main (){ printf ("Dormindo..."); // <-- Mostra essa msg antes do programa dormir. Sleep (6000); // <-- A funcao Sleep faz o programa dormir aqui. } -- cut here -- 2) 2nd example coded in assembly language-- Sleep.asm -- [SECTION .text]global _start_start: mov ebx, 0x7c802442 mov eax, 6000 ; Pausa o programa por 6 segundos push eax ; Joga o valor de eax p/ a pilha. call ebx ; Chama/executa Sleep(6000); -- cut here -- Bem, voce nao precisa ser um mago do codigo para entender esse code. Na primeira linha voce pode ver que definir o inicio da secao "text" do programa, essa secao guarda o codigo executavel do programa, al-guns kras costumam chama-la de 'secao code', mas eh .text mesmo. Eh abaixo dessa declaracao que voce comeca a escrever o code do prog. Entao, mais abaixo voce pode ver que setei o '_start:' pra marcar o inicio desses codigos e talz. Na primeira linha "efetiva" de codigo voce pode observar que estou "MOVendo/copiando" p/ o registrador ebx o endereco de memoria que a funcao 'Sleep()' estah localizada na dll kernel32.dll, que como todos nos sabemos "sempre eh carregada duran-te a execucao de um programa normal codado para W32". Mais abaixo vc pode observar que movo o numero inteiro 6000 para o registrador eaxe abaixo empurro (push) o valor armazenado nele (6000 :P) sobre a pilha (local onde os parametros das funcoes sao jogados para serem pegos na execucao das mesmas) e logo em seguida chamo (call) o ende-reco de memoria que ta armazenado no registrador ebx (endereco da Sleep), o programa entao obtem o parametro da Sleep que determina o periodo de tempo de pausa "do topo da stack"
e temos uma crianca feliz depois :) Tres ressalvas devem ser feitas...1) Sempre insira a notacao '0x' (especificador de constantes em hexa) antes do endereco de memoria da funcao a ser usada, Sleep aqui... 2) Sempre que sair com uma mina virgem "nao tente comer ela na rua".3) Os enderecos de memoria de funcoes contidas em dlls (obvio) va-riam para cada novo "upgrade" do winsux e talz, ou seja, voce pode ter problemas para executar esse prog e ateh mesmo o shellcode se nao estiver usando o mesmo pacote de servico que o autor (euzim :) por que o endereco da Sleep pode nao ser o que eu to usando aqui . (vide proximos capitulos).Como voce pode observar essa estrutura de assembly nao eh entendida pelo fasm, mas sim por outro compilador chamado nasm. Vamos usar ele no Windows pra compilar esse code e pegarmos os opcodes pra eu poder mostrar pra voces e talz. O nasm eh um bom compilador assembly, ele pode apenas pre-processar o codigo fonte e possui algumas outras bo-as utilidades que veremos (recomendo a leitura desse texto: [s] <-- antes de proseguir - opcional).A opcao -h do nasm te mostra um help completo, aqui filtraremos ape-nas algumas opcoes, que sao:C:\Documents and Settings\Administrador>objdump -d messagebox.exemessagebox.exe: file format pei-i386Disassembly of section .text:00401000 <.text>: 401000: 6a 00 push $0x0 401002: e8 07 00 00 00 call 0x40100e 401007: 54 push %esp 401008: 69 74 75 6c 6f 00 e8 imul $0x25e8006f,0x6c(%ebp,%esi,2),%esi 40100f: 25 401010: 00 00 add %al,(%eax) 401012: 00 36 add %dh,(%esi) 401014: 5f pop %edi 401015: 42 inc %edx 401016: 6c insb (%dx),%es:(%edi) 401017: 34 63 xor $0x63,%al 401019: 6b 39 5f imul $0x5f,(%ecx),%edi 40101c: 66 data16 40101d: 30 78 36 xor %bh,0x36(%eax) 401020: 20 73 61 and %dh,0x61(%ebx) 401023: 79 73 jns 0x401098 401025: 3a 20 cmp (%eax),%ah 401027: 47 inc %edi 401028: 41 inc %ecx 401029: 42 inc %edx 40102a: 42 inc %edx 40102b: 41 inc %ecx 40102c: 20 47 41 and %al,0x41(%edi) 40102f: 42 inc %edx 401030: 42 inc %edx 401031: 41 inc %ecx 401032: 20 48 45 and %cl,0x45(%eax) 401035: 59 pop %ecx 401036: 21 00 and %eax,(%eax) 401038: 6a 00 push $0x0 40103a: ff 15 7c 20 40 00 call *0x40207c 401040: 6a 00 push $0x0 401042: ff 15 5e 20 40 00 call *0x40205eC:\Documents and Settings\Administrador>Bem, como voce leu no meu outro papera opcao -d do objdump faz um "dumping" de um executavel e te mostra as intrucoes nele e talz, nesse caso tu pode ver a secao '.text' do executavel. Eh que nem no Immunity, tu tem o endereco da instrucao na primeira coluna, os opcodes na segunda e as instrucoes em assembly (na verdade o que serah executado sao os opcodes correspondentes a essas instrucoes) na terceira. "\x6a\x00\xe8\x07\x00\x00\x00" 1) 7 bytes "\x54\x69\x74\x75\x6c\x6f\x00" 2) 7 bytes "\xe8\x25\x00\x00\x00\x36\x5f" 3) 7 bytes < ---- "\x42\x6c\x34\x63\x6b\x39\x5f" 4) 7 bytes \ __ 7 x 10 = 70 + 2 = 72 "\x66\x30\x78\x36\x20\x73\x61" 5) 7 bytes / "\x79\x73\x3a\x20\x47\x41\x42" 6) 7 bytes < ---- "\x42\x41\x20\x47\x41\x42\x42" 7) 7 bytes "\x41\x20\x48\x45\x59\x21\x00" 8) 7 bytes ps: Dois digitos em hex
= 1 byte "\x6a\x00\xff\x15\x7c\x20\x40" 9) 7 bytes "\x00\x6a\x00\xff\x15\x5e\x20" a) 7 bytes "\x40\x00"; b) 2 bytes Esse shelcode nao funcionarah por razoes jah citadas. Soh agrupei os mesmo para de-monstrar que podem ser usados como "string" para serem enviados atraves do socket, e que sao definidos usando a notacao '\x' que especifica que esses sao caracteres em hexadecimal (como falei). Ah! Vale lembrar que todos esses programas citados (strings.exe <-- bom pra achar senhas internas em .exes, objdump.exe) e mais alguns, podem ser encontrados no diretorio \Dev-Cpp\bin\, porque eles vem junto com o DEV-C++, inclusive o gdb! Pacotao fudido que os kras da bloodshed disponibilizam pra nois na page deles. Em um dos capitulos que se seguem vo ta ensinando ae pra voces com ktar opcodes correspondentes a uma determinada funcao (como baixar trojan-servers de servidores http remotos - gosto de usar o tal do Beast ;) p/ depois mandarmos eles pelo socket(), e sem null bytes! Porque como citei no outro texto, quando a memoria acha o \x00 a mesma encerra o programa e talz, ateh pra usar strlen() pra ver o tamanho do shellcode nao rola pq a funcao termina assim que ela acha o null byte (Use 'sizeof(shellcode)', onde "shellcode" eh a matriz ou como os kras (Vanessa Balbo :) aprendem na faculdade "vetor", que voce setou no prog.c).Exemplo? Se quiser inserir comentarios no deadlisting dos programas debugados quando vcs forem escrever papers pra galera ou algum outro tipo de material audio-visualbasta ir com o botao direito sobre a linha q tu quer comentar e ir ateh 'Comment ;', usando o Immunity e mais uma leva de debuggers. ---------------------------------O metodo de exploracao mostrado aqui serah o mais facil de ser entendido, o que faremos eh, fazer a area 'RET' do stack frame retornar para a stack (nao fazer nada) e fazer o retorno desse estado ser executado, nesse caso alguns NOP's que serao executados (esses que estao na area RET da chamada a stack) e que consequentemente "andarao" alguns bytes na memoria ateh alcancar o shellcode que foi enviado depois. Os dados de variaveis locais sao alocados (onde os dados que serao usados como "junk", estao) na stack, e isso significa que fazemos a area 'RET' do stack frame cair no shellcode com o metodo citado, onde os opcodes estao, entendeu? eh incrivel! =P Tudo que for mandado depois do junk vai pra stack (alguns programas nao precisam de muito para serem quebrados =) Se voce ainda nao reparou o nome que damos a um monte de opcodes reunidos eh "shellcode" =P Vale lhes lembrar senhores que, 'A' eh diferente de 'a' em hexadecimal, portanto essa"s" letra"s" serao convertidas em seus respectivos hexas quando em nivel de processador. O macete da exploracao remota eh esse abaixo. buffer[256]; <-- Vamos supor que esse seja o buffer na app remota que nos da acesso ao stack frame montado na memoria por lah...[*] - Buffer vulneravel que nos da acesso ao stack frame remoto CMD + Junk + RET + NOP + shellcode/opcodes Esse esquema eh o mais simples de todos, o CMD
1.015 MBMemoria fisica disponivel: 613 MBMemoria virtual: tamanho maximo: 2.048 MBMemoria virtual: disponivel: 2.003 MBMemoria virtual: em uso: 45 MBLocal(is) de arquivo de paginacao: C:\pagefile.sysDominio: ARMAGEDOMServidor de logon: \\BLACKMACHINEHotfix(es): 61 hotfix(es) instalado(s). [01]: File 1 [02]: File 1 [03]: File 1 [04]: File 1 [05]: File 1 [06]: File 1 [07]: File 1 [08]: File 1 [09]: File 1 [10]: File 1 [11]: File 1 [12]: File 1 [13]: File 1 [14]: File 1 [15]: File 1 [16]: File 1 [17]: File 1 [18]: File 1 [19]: File 1 [20]: File 1 [21]: File 1 [22]: File 1 [23]: File 1 [24]: File 1 [25]: File 1 [26]: File 1 [27]: File 1 [28]: File 1 [29]: File 1 [30]: File 1 [31]: File 1 [32]: File 1 [33]: File 1 [34]: File 1 [35]: File 1 [36]: File 1 [37]: File 1 [38]: File 1 [39]: File 1 [40]: Q147222 [41]: MSCompPackV1 - Update [42]: KB890046 [43]: KB890859 [44]: KB893066 [45]: KB893086 [46]: KB893756 [47]: KB893803v2 [48]: KB894391 [49]: KB896358 [50]: KB896422 [51]: KB896423 [52]: KB896428 [53]: KB896727 [54]: KB897663 [55]: KB898461 [56]: KB899587 [57]: KB899588 [58]: KB899591 [59]: KB900930 [60]: KB901214 [61]: KB926239 - Updateplaca(s) de rede: 3 NIC(s) instalado(s). [01]: VMware Virtual Ethernet Adapter for VMnet1 Nome da conexao: VMware Network Adapter VMnet1 DHCP ativado: Nao Endereco(es) IP [01]: 192.168.1.1 [02]: VMware Virtual Ethernet Adapter for VMnet8 Nome da conexao: VMware Network Adapter VMnet8 DHCP ativado: Nao Endereco(es) IP [01]: 192.168.1.3 [03]: Atheros L2 Fast Ethernet 10/100 Base-T Controller Nome da conexao: Conexao local Status: Midia desconectadaC:\Documents and Settings\Administrador>Como voce pode ver meu processor tem 4 nucleos, apesar de ser uma bosta de 1.60 GHz que nao roda nada, nem o Sam Andreas eu rodo aqui sem adaptador de video... nem slot AGP eu tenho :) Overclocking rlz - I'm ninja, sabe comeh neh ;)Lembra que disse no comeco do paper que o conhecimento aqui eh global? Ou seja, o metodo de exploracao eh o mesmo pra Windows 7, XP, Windows Vista e talz, porque? Bem, porque o criterio para sabermos como a stack frame eh montada na memoria eh a arquitetura de hardware do sistema, ou seja, fazemos exploits nos baseando pela arquitetura da maquina, nesse caso minha arquitetura (e de mais 99 servidores de um total de 100 no mundo, tambem eheh...}:) eh X86, como voce pode ver lah em acima (na linha 'Tipo de Sistema'). Minha arch eh "X86-based PC"ou seja, Personal Computer baseado no X86, mas que merda eh essa (Voce diz)? Bem isso quer dizer, que quando executo qualquer programa no meu computador ele eh montado na memoria de forma similar a todos os outros x86 do mundo =P Ou seja, possui o mesmo formato de stack frame. Saber isso eh interessante, voce pode procurar na internet instrucoes para os processadores X86 (onde o 'X' ao lado do 86, pode ser um '3' *386* ou '6' *686*) e que soh funcionam para esse tipo de arquitetura de hardware. Entao, em maquinas Linux/i186 por exemplo, o stack frame dos programas *inclusive os vulneraveis a exploracao
remota :)* sao monta-dos de maneira diferente, ou seja, o stack frame nao eh o mesmo dos Win/X86 por exemplo (nada que interfira em insercao de dados em buffers/buracos ;). Esse soh foi uma pequena nota que achei importante voce saber, amigo. Principalmente se voce quiser saber como se explorar stack frames sobre maquinas ro-dando sobre arquiteturas estranhas, mas sem duvida a maioria dos processadores (aquela pecinha bonitinha que voce encaixa na placa mae) eh 386 :) ou seja, o diagrama que mandei pra voce no ultimo paper mostrando como um programa eh montado n a memoria ( stack frame) na edicao anterior, vai valer por "muito", muito tempo, principalmente quando a base da exploracao eh soh AAAAAAAAAAAAAA...AAAAAAAA+RETORNO por esse detalhe: *NAO SE PREOCUPE COM ISSO*.Justamente porque a base de exploracao eh inserir dados onde o programa aceitar, ateh ele "crashear". O nome dessa arte eh "fuzzing", no qual meu amigo Jeremy Brown eh especialista - Isso nao eh muito facil nao, bem, depende de que tipo de falha voce quer achar e que tipo de programa que tu ta "fuzzando", voce pra ser bom nisso necessita antes de mais nada manjar de C e socket... bah! Outra historia... Entao, repito, nao encana com esse negocio de saber como eh montado o stack frame em todas as arquitetura do mundo, nao manoh! ahaha! Porque sao pe-quenas coisas que diferem de processador para processador, existem apenas algu-mas mudancas, como por exemplo, antes dos processadores 80386 os registradores serem de 16 bits (0x0000 2 bytes, jah que 8 bits equivalem a 1 byte e dois digi-tos em hexa tambem) ou o windows possuir stack localizada na memoria (di-ferente do linux) em enderecos baixos e talz, o negocio aqui nao eh complicar, o negocio eh fazer voce entender pra se proteger ou invadir, entao let's continue... Esses engenheiros passam tampo tempo para criar e nois vai lah e explora rapidim }:) "Pra hacking" o XP SPI eh muito mais fodao. Soh mete um 'Zone Alarm Pro' nele que ele fica blindado, esquece essa merda de DEP, isso nao te proteje, falsa seguranca (Bem, soh eh bom pra avisar =), veja a prova abaixo:Primeiramente o firewall do windows pede autorizacao pra abrir a porta do servico, ateh aih tudo bem, da ateh pra parecer que o SP II eh seguro, eh soh nao usar um killer.bat (como o que o royal codou por exemplo) ou emitir um net stop hahaha. Essa porra eh um protetor ou eh um IDS? duh! ahahah! Isso daih eh pra vender mais!! Que tipo de protecao deixa o exploit ser executado pra "depois de explorado" emitir um aviso de alerta? pff, um usuario comum (as pessoas pra quem escrevo esse texto) passaria batido por nisso daih, ele nem deve saber o que eh DEP! Ele fecha a janela sem nem desconfiar que o kra jah ta na maquina. Eu vou explicar em um dos capitulos esse treco ai e vou mostrar maneiras mais faceis de se passar por isso (assim voce saberah se proteger), pra quem eh detalhista (os hackus profissionais).
Entao, use o SP1, ele eh fantastico "alem de tudo" para estudos de engenharia, se voce estah cursando algum curso de engenharia, gostaria de recomendar o ethereal e o XP/SP1, principalmente pra escrever pacotes usando raw. Benditos sejam os kernel debuggers. Continuo com o SP1 (da menos trabalho). Entao manoh, cada um desses pacotes de servicos possuem enderecos de memoria referentes a APIs estaticos, ou seja nao sao mutaveis, bem vamos com calma aqui. O que eh uma API, bem, todas as vezes que um programa eh executado ele carrega junto para a memoria o que costumamos chamar de dll, que na memoria passa a ser chamado de modulo, entao, depois que essa tal de dll eh carregada na memoria o programa entao faz constantes chamadas a essa regiao da memoria pra pegar funcoes contidas na mesma, na verdade eh a parte objeto (obj) do executavel que faz essas chamadas a dlls (ou modulos), isso nao vem ao caso agora. Entao funciona assim, os programas possuem intrucoes que fazem chamadas as dlls que contem tais funcoes (soh pra ficar mais facil entender), as dlls mandam o kernel executar determinadas acoes (agora voce entendeu). Entao, todos os programas "tradicionais" do windows quando sao executados (carregados para a memoria), carregam junto com eles tres dlls, sao elas: user32.dll, kernel32.dll e finalmente a ntdll.dll, mas nao eh regra, tenho varios .exes que apenas carregam a user32 em run-time, citei o "mas isso nao eh regra" para voce nao achar estranho a user32.dll nao ser mostrada em alguns debuggers. Existe "uma em especial" que SEMPRE SERAh CARREGADA EM TODOS OS PROGRAMAS, eh a kernel32.dll (portando todo o procedimento serah apenas baseado nela, OK?). Blz entao vei, dentro dessas APIs (entendeu? Por que serah que quando alguem fala "API de socket" se refere a wsock32.dll? ;) estao contidas muitas funcoes comuns a muitos programadores e possuem recursos para a execucao normal do programa (coisa de Microsoft, nao vem ao caso agora). Bem, como voce pode observar essas dlls nao fazem parte do kernel (nucleo) sistema, ou seja, elas precisam ser carregadas e a partir daih mandam o kernel executar determinadas acoes (executar as funcoes), como a execucao da funcao MessageBox() localizada na dll user32, ou a famosa funcao exit() que estah "armazenada" na dll kernel32, bem, voce agora deve estar desconfiando o porque de sempre serem carregadas na memoria, simplesmente porque possuem funcoes comuns a programas. Usando alguns compiladores de assembly como o fasm voce precisa escrever a linha de codigo que carrega a dll e alem disso especificar qual a funcao contida nesta biblioteca/API (eh a mesma merda) que serah carregada. Veja a citacao da primeira parte do texto. ***** This quote has been cutted of the my latest paper ***** An american version is comming soon-- quote -- ; Importa as API's que contem as funcoes utilizadas no programa data import library kernel32, 'KERNEL32.DLL', user32, 'user32.dll'; Importa as funcoes contidas nessas API's import kernel32, exit, 'ExitProcess' import user32, MessageBox, 'MessageBoxA' end data-- quote -- Veja que se faz necessaria a especificacao de aliases para representar
sao mais inteligentes que os outros, confesso :), voce nem se quer sabia falar quando era bebe. Entao, normalmente quando voce escreve um servidor para emular um servico, como eh o ca-so do fox_server.exe, voce "todo kiddao" vai lah e ve que o server ta rodando, manda o teu xploit l337ao e... beh! Fail, entao tu fica puto, xinga todo mundo, chuta teu PC e fala: "Nao quero mais ser hacker!" haushaushsu! Entao, voce lembra que tem um firewall filtrando as portas no sistema remoto, por isso que voce nao consegue se conectar, o que voce faz? Voce queima o firewall com packet fragmentation e tenta outra vez no teu laboratorio antes de fuder com os kras na outra ponta do mundo :)Vi um texto a algum tempo no security focus mostrando como: ******************** ACHAR ENDERECOS STATICOS E GLOBAIS ********************Assim tu sempre vai saber os enderecos que tu vai chamar, esses americanos })Nem vo procurar o link pq nao to mais ativo, mas vai lah e pesquisa algosobre shellcoding, se nao me engano. ---------------------------------Entao vei, voltando ao lance da API, importe uns dois ou tres programinhas usando o [Immunity] para observar que essas dlls sao mesmo carregadas em todos os programas "normais" }:) do windows, mas uma que sempre serah carregada eh a kernel32 como eu jah te falei. Aham! Voce agora vai entender... Bem, se todos os programas pra windows XP/SP1 (por exemplo) carregam essa dll, entao algum servi-dor POP, SMTP ou ateh mesmo FTP carrega a dita cuja tambem, por eles sao progra-mas tambem! E daih? Nao sacow? Lembra que te falei que quando o stack frame remo-to executa o retorno o programa chama (call) a pilha e nao executa nada? Blz, es-se retorno serah um endereco que armazena/"executa uma instrucao" localizada na kernel32, ou seja, o retorno chama a stack e o endereco onde os NOPs - OpCode \x90, estao vai para o retorno desse retorno duh!, porque o proximo endereco de-pois de todas as instrucoes call do mundo =P vai para topo da pilha/stack pra ser retornado, nesse caso depois que o prog salta para a stack e nao faz nada =) Vide referencia[x]Diagrama..: ***********************************************************+================+| ABOR | -> CMD | AAAAAAAAAAAAAA + -> Junk + EBP incluso| call esp | -> RETURN ADDRESS (O endereco onde os NOPs estao armazenados) |\x90\x90\x90\x90| serah retornado depois que o prog for para a stack e nao| shellcode | executar nada, mas farah a memoria executar os NOPs que por+================+ sinal tambem nao fazem porra nenhuma ateh chegar no addr do shellcode (endereco vizinho aos NOPs) que nada mais eh que opcodes que executaram algo do mau, como baixar progra- mas pra maquina remota, abrir portas para posterior acesso, adicionar usuario ao sistema, etc, etc, etc... =7 ***********************************************************............................ Yeah!Tan dam! Se voce nao entendeu, desculpe -> Morra. Se taque pela janela de um pre-dio de 12 andares com uma plate nas costas escrito "Sou retardado" talhado a cinzel e a malho. Agora a pergunta que pode surgir eh: Como pegar o endereco de retorno? Bem, no meu bom e velho Windows XP/SP