Abra-me
Prepare-se para se divertir com hackers! Nesta postagem do blog, mostraremos como invadir um arquivo executável C simples protegido por senha usando o Ubuntu 20.04 LTS. Esteja você apenas começando ou um profissional experiente, este tutorial tem algo para todos. Hora de flexionar essas habilidades cibernéticas!
Todos os arquivos usados neste tutorial podem ser encontrados no GitHub aqui . Você pode clonar o repositório em seu ambiente local para acessar os arquivos criptografados.
Para começar, podemos executar o crackmearquivo para observar seu comportamento navegando até o diretório crackme e digitando o seguinte comando:
$ ./crackme
Access Denied
O filecomando é usado para identificar o tipo de um arquivo. Ele faz isso executando uma série de testes em uma ordem específica: testes de sistema de arquivos, testes de números mágicos e testes de linguagem .
Esses testes são projetados para determinar o tipo de arquivo com base em seu conteúdo e quaisquer metadados associados a ele. Se você deseja usar o filecomando para identificar o tipo de um arquivo específico, pode fazê-lo executando file [filename]em seu terminal. Por exemplo:
$ file crackme
crackme: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.24, BuildID[sha1]=e06e0b0229279a69506925702a7f79e36bdc3eb2, not stripped
- Um arquivo executável projetado para ser executado em um sistema operacional Linux de 64 bits
- Compilado para a arquitetura x86–64 e vinculado dinamicamente, o que significa que depende de bibliotecas compartilhadas para funcionar
- Interpretado pelo interpretador /lib64/ld-linux-x86–64.so.2
- Construído para GNU/Linux 2.6.24 e possui um identificador exclusivo chamado “BuildID”
- Não foi removido, portanto ainda contém informações de depuração e símbolos que podem ser usados para análise.
Também vale a pena notar que ltracepode ser usado em conjunto com outras ferramentas como gdb( GNU Debugger ) para analisar melhor o comportamento do programa e potencialmente fazer engenharia reversa que não usaremos para este tutorial.
Podemos executar ltraceo arquivo crack me digitando o seguinte comando:
$ ltrace ./crackme
__libc_start_main(0x40087d, 1, 0x7ffeef764458, 0x400a70 <unfinished ...>
strncmp("SHELL=/bin/bash", "Passw0rd=", 9) = 3
strncmp("PWD=/home/vagrant/crackme_tutori"..., "Passw0rd=", 9) = -10
strncmp("LOGNAME=vagrant", "Passw0rd=", 9) = -4
strncmp("XDG_SESSION_TYPE=tty", "Passw0rd=", 9) = 8
strncmp("MOTD_SHOWN=pam", "Passw0rd=", 9) = -3
strncmp("HOME=/home/vagrant", "Passw0rd=", 9) = -8
strncmp("LANG=C.UTF-8", "Passw0rd=", 9) = -4
strncmp("LS_COLORS=rs=0:di=01;34:ln=01;36"..., "Passw0rd=", 9) = -4
strncmp("SSH_CONNECTION=10.0.2.2 61015 10"..., "Passw0rd=", 9) = 3
strncmp("LESSCLOSE=/usr/bin/lesspipe %s %"..., "Passw0rd=", 9) = -4
strncmp("XDG_SESSION_CLASS=user", "Passw0rd=", 9) = 8
strncmp("TERM=xterm-256color", "Passw0rd=", 9) = 4
strncmp("LESSOPEN=| /usr/bin/lesspipe %s", "Passw0rd=", 9) = -4
strncmp("USER=vagrant", "Passw0rd=", 9) = 5
strncmp("SHLVL=1", "Passw0rd=", 9) = 3
strncmp("XDG_SESSION_ID=22", "Passw0rd=", 9) = 8
strncmp("XDG_RUNTIME_DIR=/run/user/1000", "Passw0rd=", 9) = 8
strncmp("SSH_CLIENT=10.0.2.2 61015 22", "Passw0rd=", 9) = 3
strncmp("XDG_DATA_DIRS=/usr/local/share:/"..., "Passw0rd=", 9) = 8
strncmp("PATH=/usr/local/sbin:/usr/local/"..., "Passw0rd=", 9) = -32
strncmp("DBUS_SESSION_BUS_ADDRESS=unix:pa"..., "Passw0rd=", 9) = -12
strncmp("SSH_TTY=/dev/pts/0", "Passw0rd=", 9) = 3
strncmp("OLDPWD=/home/vagrant/crackme_tut"..., "Passw0rd=", 9) = -1
strncmp("_=/usr/bin/ltrace", "Passw0rd=", 9) = 15
puts("Access Denied"Access Denied
) = 14
+++ exited (status 1) +++
PC: ALX
__libc_start_mainé uma função que configura o ambiente de um programa e chama sua função principal. Ele aceita vários argumentos e é fornecido pela biblioteca padrão C ( libc ). Ele é chamado pela função de ponto de entrada principal do programa.- As linhas que começam com
strncmpmostram que o programa está chamando astrncmpfunção, que é uma função que compara um determinado número de caracteres (neste caso, 9 caracteres) de duas strings. As strings comparadas parecem ser várias variáveis de ambiente (por exemplo, "SHELL", "PWD", "LOGNAME" etc.) e a string"Passw0rd=". Parece que o programa está verificando se alguma das variáveis de ambiente começa com a string"Passw0rd=". - A
putsfunção é chamada ao final com a string " Acesso negado ", o que pode indicar que o programa está imprimindo esta mensagem se nenhuma das variáveis de ambiente começar com"Passw0rd=".
Para definir uma variável de ambiente no Linux, podemos usar o exportcomando no terminal. Por exemplo, para definir uma variável de ambiente Passw0rdcom o valor test, podemos executar:
export Passw0rd=test
$ ltrace ./crackme
__libc_start_main(0x40087d, 1, 0x7fff085f1d38, 0x400a70 <unfinished ...>
strncmp("SHELL=/bin/bash", "Passw0rd=", 9) = 3
strncmp("PWD=/home/vagrant/crackme_tutori"..., "Passw0rd=", 9) = -10
strncmp("LOGNAME=vagrant", "Passw0rd=", 9) = -4
strncmp("XDG_SESSION_TYPE=tty", "Passw0rd=", 9) = 8
strncmp("MOTD_SHOWN=pam", "Passw0rd=", 9) = -3
strncmp("HOME=/home/vagrant", "Passw0rd=", 9) = -8
strncmp("LANG=C.UTF-8", "Passw0rd=", 9) = -4
strncmp("LS_COLORS=rs=0:di=01;34:ln=01;36"..., "Passw0rd=", 9) = -4
strncmp("SSH_CONNECTION=10.0.2.2 61015 10"..., "Passw0rd=", 9) = 3
strncmp("LESSCLOSE=/usr/bin/lesspipe %s %"..., "Passw0rd=", 9) = -4
strncmp("XDG_SESSION_CLASS=user", "Passw0rd=", 9) = 8
strncmp("TERM=xterm-256color", "Passw0rd=", 9) = 4
strncmp("LESSOPEN=| /usr/bin/lesspipe %s", "Passw0rd=", 9) = -4
strncmp("USER=vagrant", "Passw0rd=", 9) = 5
strncmp("SHLVL=1", "Passw0rd=", 9) = 3
strncmp("XDG_SESSION_ID=22", "Passw0rd=", 9) = 8
strncmp("XDG_RUNTIME_DIR=/run/user/1000", "Passw0rd=", 9) = 8
strncmp("SSH_CLIENT=10.0.2.2 61015 22", "Passw0rd=", 9) = 3
strncmp("XDG_DATA_DIRS=/usr/local/share:/"..., "Passw0rd=", 9) = 8
strncmp("PATH=/usr/local/sbin:/usr/local/"..., "Passw0rd=", 9) = -32
strncmp("Passw0rd=test", "Passw0rd=", 9) = 0
MD5_Init(0x7fff085f1b90, 0x400b06, 9, 6) = 1
strlen("test") = 4
MD5_Update(0x7fff085f1b90, 0x7fff085f2f68, 4, 0x7fff085f2f68) = 1
MD5_Final(0x7fff085f1bf0, 0x7fff085f1b90, 0x7fff085f1b90, 0) = 1
sprintf("09", "%02x", 0x9) = 2
sprintf("8f", "%02x", 0x8f) = 2
sprintf("6b", "%02x", 0x6b) = 2
sprintf("cd", "%02x", 0xcd) = 2
sprintf("46", "%02x", 0x46) = 2
sprintf("21", "%02x", 0x21) = 2
sprintf("d3", "%02x", 0xd3) = 2
sprintf("73", "%02x", 0x73) = 2
sprintf("ca", "%02x", 0xca) = 2
sprintf("de", "%02x", 0xde) = 2
sprintf("4e", "%02x", 0x4e) = 2
sprintf("83", "%02x", 0x83) = 2
sprintf("26", "%02x", 0x26) = 2
sprintf("27", "%02x", 0x27) = 2
sprintf("b4", "%02x", 0xb4) = 2
sprintf("f6", "%02x", 0xf6) = 2
strcmp("c4032d9e95a93d91b9b595dcfcca640b"..., "098f6bcd4621d373cade4e832627b4f6"...) = 51
puts("Access Denied"Access Denied
) = 14
+++ exited (status 1) +++
PC: Here
- Já sabemos que a primeira linha mostra que a
__libc_start_mainfunção foi chamada com quatro argumentos: o endereço da função principal, o número de argumentos do programa, um ponteiro para uma matriz de argumentos do programa e um ponteiro para uma função a ser chamada quando a função principal retorna. - As linhas a seguir mostram uma série de chamadas para a
strncmpfunção, que compara duas strings e retorna um inteiro indicando sua ordenação lexicográfica. Parece que o programa está tentando comparar cada uma das variáveis de ambiente no sistema com a string"Passw0rd=". - Depois disso, há chamadas para as funções
MD5_Init,MD5_UpdateeMD5_Final, que fazem parte da função hash criptográfica MD5 . Parece que o programa está calculando o hash MD5 do valor da variável de ambiente Passw0rd. - Em seguida, há chamadas para a
sprintffunção, que formata uma string e a armazena em um buffer. Parece que o programa está formatando os bytes do hash MD5 como valores hexadecimais e os armazenando em strings. - A saída inclui uma chamada para a
strcmpfunção com duas strings como argumentos: "c4032d9e95a93d91b9b595dcfcca640b" e "098f6bcd4621d373cade4e832627b4f6". Isso indica que o programa está comparando o hash MD5 da senha com o hash da variável de ambiente Passw0rd que foi exportada. - A
putsfunção é chamada ao final com a string "Acesso Negado", indicando que a Senha está incorreta. No entanto, isso provavelmente será resolvido em breve.
Podemos usar este site para reverter as strings com hash para seus valores.
Agora que determinamos que a senha com hash é LionelMessi , podemos definir a Passw0rdvariável de ambiente para esse valor e executar novamente o ltracecomando para ver se ele produz um resultado diferente. Vamos tentar!
$ export Passw0rd=LionelMessi
$ ./crackme
Access Granted
É sempre importante lembrar de usar senhas fortes e exclusivas e nunca reutilizar senhas em contas diferentes.
Fique de olho em nosso próximo lançamento no GitHub de um programa C que compara hashes MD5 com um dicionário e os reverte para sua forma de string original. Fique atento!
Esperamos que você tenha gostado deste tutorial sobre como quebrar um arquivo simples. Se você tiver quaisquer comentários ou perguntas, não hesite em deixá-los na seção de comentários abaixo. Feliz hacking!





































![O que é uma lista vinculada, afinal? [Parte 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)