7 de junho de 2016 / delton / 1 Comment
De posse da senha do usuário leviathan6 fazemos o login no servidor leviathan.labs.overthewire.org e procuramos por arquivos:
|
leviathan6@leviathan:~$ ls -al total 28 drwxr-xr-x 2 leviathan6 leviathan6 4096 May 30 12:31 . drwxr-xr-x 10 root root 4096 May 30 12:30 .. -rw-r--r-- 1 leviathan6 leviathan6 220 Apr 9 2014 .bash_logout -rw-r--r-- 1 leviathan6 leviathan6 3637 Apr 9 2014 .bashrc -rw-r--r-- 1 leviathan6 leviathan6 675 Apr 9 2014 .profile -r-sr-x--- 1 leviathan7 leviathan6 7492 May 30 12:31 leviathan6 |
Vamos testar o executável leviathan6:
|
leviathan6@leviathan:~$ ./leviathan6 usage: ./leviathan6 <4 digit code> |
Informando um código de 4 dígitos:
|
leviathan6@leviathan:~$ ./leviathan6 1234 Wrong |
Depurando:
|
leviathan6@leviathan:~$ ltrace ./leviathan6 1234 __libc_start_main(0x804850d, 2, 0xffffd894, 0x8048590 <unfinished ...> atoi(0xffffd9b3, 0xffffd894, 0xffffd8a0, 0xf7e5719d) = 1234 puts("Wrong"Wrong ) = 6 +++ exited (status 6) +++ |
O que será que a função atoi faz? Pesquisando: http://linux.die.net/man/3/atoi
atoi converte uma string em um inteiro.
Como não consegui resolver sozinho o problema, pesquisei e encontrei duas formas de passar esse nível: força bruta ou usar um depurador. Como a ideia é aprender, vamos pelo caminho mais complicado.
Para isso vamos usar o depurador gdb:
|
leviathan6@leviathan:~$ gdb leviathan6 |
Iremos transformar o código em assembler:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
|
(gdb) disas main Dump of assembler code for function main: 0x0804850d <+0>: push %ebp 0x0804850e <+1>: mov %esp,%ebp 0x08048510 <+3>: and $0xfffffff0,%esp 0x08048513 <+6>: sub $0x20,%esp 0x08048516 <+9>: movl $0x1bd3,0x1c(%esp) 0x0804851e <+17>: cmpl $0x2,0x8(%ebp) 0x08048522 <+21>: je 0x8048545 <main+56> 0x08048524 <+23>: mov 0xc(%ebp),%eax 0x08048527 <+26>: mov (%eax),%eax 0x08048529 <+28>: mov %eax,0x4(%esp) 0x0804852d <+32>: movl $0x8048620,(%esp) 0x08048534 <+39>: call 0x8048390 <printf@plt> 0x08048539 <+44>: movl $0xffffffff,(%esp) 0x08048540 <+51>: call 0x80483e0 <exit@plt> 0x08048545 <+56>: mov 0xc(%ebp),%eax 0x08048548 <+59>: add $0x4,%eax 0x0804854b <+62>: mov (%eax),%eax 0x0804854d <+64>: mov %eax,(%esp) 0x08048550 <+67>: call 0x8048400 <atoi@plt> 0x08048555 <+72>: cmp 0x1c(%esp),%eax 0x08048559 <+76>: jne 0x8048575 <main+104> 0x0804855b <+78>: movl $0x3ef,(%esp) ---Type <return> to continue, or q <return> to quit--- 0x08048562 <+85>: call 0x80483a0 <seteuid@plt> 0x08048567 <+90>: movl $0x804863a,(%esp) 0x0804856e <+97>: call 0x80483c0 <system@plt> 0x08048573 <+102>: jmp 0x8048581 <main+116> 0x08048575 <+104>: movl $0x8048642,(%esp) 0x0804857c <+111>: call 0x80483b0 <puts@plt> 0x08048581 <+116>: leave 0x08048582 <+117>: ret End of assembler dump. |
O que nos importa é a seguinte linha:
|
0x08048555 <+72>: cmp 0x1c(%esp),%eax |
Nela o programa faz uma comparação dos registradores esp e eax. Vamos colocar um breakpoint no programa bem na hora da comparação:
|
(gdb) b *main+72 Breakpoint 1 at 0x8048555 |
E então executamos o programa passando como código 0000:
|
(gdb) r 0000 Starting program: /home/leviathan6/leviathan6 0000 Breakpoint 1, 0x08048555 in main () |
Agora vamos ver o que temos no registrado esp:
|
(gdb) x/wu $<span class="hljs-literal">esp</span>+<span class="hljs-number">0x1c</span> |
Pronto, o código que é comparado ao código informado será exibido. Depois é só executar o programa com o código correto.
Referências
http://cplusperks.com/leviathan/#level6
http://www.unknownroad.com/rtfm/gdbtut/gdbtoc.html
3 de junho de 2016 / delton / 0 Comments
De posse da senha do usuário leviathan5 fazemos o login no servidor leviathan.labs.overthewire.org e procuramos por arquivos:
|
leviathan5@leviathan:~$ ls -al total 28 drwxr-xr-x 2 leviathan5 leviathan5 4096 May 30 12:31 . drwxr-xr-x 10 root root 4096 May 30 12:30 .. -rw-r--r-- 1 leviathan5 leviathan5 220 Apr 9 2014 .bash_logout -rw-r--r-- 1 leviathan5 leviathan5 3637 Apr 9 2014 .bashrc -rw-r--r-- 1 leviathan5 leviathan5 675 Apr 9 2014 .profile -r-sr-x--- 1 leviathan6 leviathan5 7642 May 30 12:31 leviathan5 |
Vamos ver o que o arquivo leviathan5 faz:
|
leviathan5@leviathan:~$ ./leviathan5 Cannot find /tmp/file.log |
Parece que ele procura por um arquivo em /tmp/file.log. Neste caso pensei em criar um link simbólico para o arquivo da senha, assim:
|
ln -s /etc/leviathan_pass/leviathan6 /tmp/file.log |
Depois executamos o programa de novo:
|
leviathan5@leviathan:~$ ./leviathan5 |
Pronto, temos a senha do leviathan6!
2 de junho de 2016 / delton / 0 Comments
De posse da senha do usuário leviathan4 fazemos o login no servidor leviathan.labs.overthewire.org e procuramos por arquivos:
|
leviathan4@leviathan:~$ ls -al total 24 drwxr-xr-x 3 leviathan4 leviathan4 4096 May 30 12:31 . drwxr-xr-x 10 root root 4096 May 30 12:30 .. -rw-r--r-- 1 leviathan4 leviathan4 220 Apr 9 2014 .bash_logout -rw-r--r-- 1 leviathan4 leviathan4 3637 Apr 9 2014 .bashrc -rw-r--r-- 1 leviathan4 leviathan4 675 Apr 9 2014 .profile dr-xr-x--- 2 root leviathan4 4096 May 30 12:31 .trash |
Chama atenção o diretório .trash. Vamos ver o que tem nele:
|
leviathan4@leviathan:~$ cd .trash/ leviathan4@leviathan:~/.trash$ ls bin |
Encontramos um arquivo chamado bin. Vamos executá-lo:
|
leviathan4@leviathan:~/.trash$ ./bin 01010100 01101001 01110100 01101000 00110100 01100011 01101111 01101011 01100101 01101001 00001010 |
A saída parece ser um código binário, então procurei um conversor de binário para texto online e pronto, temos a senha!
2 de junho de 2016 / delton / 0 Comments
De posse da senha do usuário leviathan3 fazemos o login no servidor leviathan.labs.overthewire.org e procuramos por arquivos:
|
leviathan3@leviathan:~$ ls -al total 32 drwxr-xr-x 2 leviathan3 leviathan3 4096 May 30 12:31 . drwxr-xr-x 10 root root 4096 May 30 12:30 .. -rw-r--r-- 1 leviathan3 leviathan3 220 Apr 9 2014 .bash_logout -rw-r--r-- 1 leviathan3 leviathan3 3637 Apr 9 2014 .bashrc -rw-r--r-- 1 leviathan3 leviathan3 675 Apr 9 2014 .profile -r-sr-x--- 1 leviathan4 leviathan3 9946 May 30 12:31 level3 |
Encontramos o arquivo level3. Vamos executá-lo:
|
leviathan3@leviathan:~$ ./level3 Enter the password> abc bzzzzzzzzap. WRONG |
O programa espera que seja informada uma senha. Informei abc, mas parece que era a senha errada.
Vamos depurar:
|
leviathan3@leviathan:~$ ltrace ./level3 __libc_start_main(0x80485fe, 1, 0xffffd8b4, 0x80486d0 <unfinished ...> strcmp("h0no33", "kakaka") = -1 printf("Enter the password> ") = 20 fgets(Enter the password> abc "abc\n", 256, 0xf7fcbc20) = 0xffffd6ac strcmp("abc\n", "snlprintf\n") = -1 puts("bzzzzzzzzap. WRONG"bzzzzzzzzap. WRONG ) = 19 +++ exited (status 0) +++ |
Primeiro é feita uma comparação com o comando strcmp, mas parece que ela não serve pra nada, porque mais adiante é feita outra comparação, da senha que digitamos com a string snlprintf. snlprintf é um comando do Linux, mas neste caso está aqui só pra confundir mesmo. Vamos testar:
|
leviathan3@leviathan:~$ ltrace ./level3 __libc_start_main(0x80485fe, 1, 0xffffd8b4, 0x80486d0 <unfinished ...> strcmp("h0no33", "kakaka") = -1 printf("Enter the password> ") = 20 fgets(Enter the password> snlprintf "snlprintf\n", 256, 0xf7fcbc20) = 0xffffd6ac strcmp("snlprintf\n", "snlprintf\n") = 0 puts("[You've got shell]!"[You've got shell]! ) = 20 |
Conseguimos o shell, basta pegar a senha para o nível 4.
2 de junho de 2016 / delton / 0 Comments
De posse da senha do usuário leviathan2 fazemos o login no servidor leviathan.labs.overthewire.org e procuramos por arquivos:
|
leviathan2@melinda:~$ ls -al total 28 drwxr-xr-x 2 root root 4096 Nov 14 2014 . drwxr-xr-x 167 root root 4096 Jul 9 16:27 .. -rw-r--r-- 1 root root 220 Apr 9 2014 .bash_logout -rw-r--r-- 1 root root 3637 Apr 9 2014 .bashrc -rw-r--r-- 1 root root 675 Apr 9 2014 .profile -r-sr-x--- 1 leviathan3 leviathan2 7498 Nov 14 2014 printfile |
Chama a atenção o arquivo printfile. Ao executá-lo ele mostra a saída do arquivo passado como parâmetro.
Vamos tentar:
|
./printfile /etc/leviathan_pass/leviathan3 You cant have that file... |
Como eu não fazia a menor ideia de como continuar, fui pesquisar.
Encontrei uma pessoa que já completou o desafio usando o comando ltrace.
ltrace é uma ferramenta de depuração (debug) usada no Linux.
Primeiro vamos criar um arquivo temporário:
|
<span class="kw"><span class="hljs-built_in">echo</span></span> <span class="st"><span class="hljs-string">"Lorem ipsum dolor amet"</span></span> <span class="kw">></span> /tmp/test ltrace ./printfile /tmp/test __libc_start_main(0x804852d, 2, 0xffffd894, 0x8048600 <unfinished ...> access("/tmp/test", 4) = 0 snprintf("/bin/cat /tmp/test", 511, "/bin/cat %s", "/tmp/test") = 18 system("/bin/cat /tmp/test"Lorem ipsum dolor amet <no return ...> --- SIGCHLD (Child exited) --- <... system resumed> ) = 0 +++ exited (status 0) +++ |
O programa printfile usa o comando cat para carregar o arquivo, então vamos tentar carregar o arquivo com a senha:
|
ltrace ./printfile /etc/leviathan_pass/leviathan3 _libc_start_main(0x804852d, 2, 0xffffd874, 0x8048600 <unfinished ...> access("/etc/leviathan_pass/leviathan3", 4) = -1 puts("You cant have that file..."You cant have that file... ) = 27 +++ exited (status 1) +++ |
A saída é um pouco diferente que o comando anterior. Note a diferença na linha que checa as permissões do arquivo:
|
access("/tmp/test", 4) = 0 </code>access("/etc/leviathan_pass/leviathan3", 4) = -1 |
Segundo a documentação do access (http://linux.about.com/library/cmd/blcmdl2_access.htm)
A verificação é feita com uid e gid reais do processo, em vez de com os uid e gid efetivos como é feito geralmente.
A ideia é usar um arquivo com espaço no nome para que o comando cat seja executado com outros privilégios:
|
<span class="kw"><span class="hljs-built_in">echo</span></span> <span class="st"><span class="hljs-string">"Lorem ipsum dolor amet"</span></span> <span class="kw">></span> "/tmp/one two" ltrace ./printfile "/tmp/one two" __libc_start_main(0x804852d, 2, 0xffffd894, 0x8048600 <unfinished ...> access("/tmp/one two", 4) = 0 snprintf("/bin/cat /tmp/one two", 511, "/bin/cat %s", "/tmp/one two") = 21 system("/bin/cat /tmp/one two"Lorem ipsum dolor amet two /bin/cat: two: No such file or directory <no return ...> --- SIGCHLD (Child exited) --- <... system resumed> ) = 256 +++ exited (status 0) +++ |
Podemos ver que foi executado o comando /bin/cat: two, ou seja, o sistema tentou abrir o arquivo. Por isso vamos criar um link simbólico para o arquivo:
|
<span class="kw">ln</span> <span class="hljs-operator">-s</span> /etc/leviathan_pass/leviathan3 <span class="st"><span class="hljs-string">"/tmp/two"</span></span> |
E depois:
|
cd /tmp leviathan2@leviathan:/tmp$ ~/printfile "one two" Lorem ipsum dolor amet two |
Pronto, temos a senha para o próximo nível!
Referências:
http://blog.moz-code.org/2012/07/leviathan-level-2-walkthrough.html
28 de abril de 2016 / delton / 0 Comments
Depois de conseguir a senha do usuário leviathan1, efetuamos o login no servidor leviathan.labs.overthewire.org
Procurando arquivos:
|
leviathan1@melinda:~$ ls -al total 28 drwxr-xr-x 2 root root 4096 Nov 14 2014 . drwxr-xr-x 167 root root 4096 Jul 9 16:27 .. -rw-r--r-- 1 root root 220 Apr 9 2014 .bash_logout -rw-r--r-- 1 root root 3637 Apr 9 2014 .bashrc -rw-r--r-- 1 root root 675 Apr 9 2014 .profile -r-sr-x--- 1 leviathan2 leviathan1 7493 Nov 14 2014 check |
O arquivo check é um executável. Vamos executá-lo:
|
leviathan1@melinda:~$ ./check password: abc Wrong password, Good Bye ... |
É provável que a senha esteja dentro do executável. Para procurar a senha podemos usar algumas ferramentas. A primeira é o xxd. O comando xxd irá criar um hex dump do executável:
|
leviathan1@melinda:~$ xxd check |
Procurando nas strings encontramos algumas palavras: sex, love, god. O próximo passo é testar essas strings.
Outra forma é usar o comando ltrace. O ltrace é uma ferramenta para debug. Vamos usá-la:
|
leviathan1@melinda:~$ ltrace ./check __libc_start_main(0x804852d, 1, 0xffffd7b4, 0x80485f0 <unfinished ...> printf("password: ") = 10 getchar(0x8048680, 47, 0x804a000, 0x8048642password: abc ) = 97 getchar(0x8048680, 47, 0x804a000, 0x8048642) = 98 getchar(0x8048680, 47, 0x804a000, 0x8048642) = 99 strcmp("abc", "sex") = -1 puts("Wrong password, Good Bye ..."Wrong password, Good Bye ... ) = 29 +++ exited (status 0) +++ |
Na saída do debug podemos ver que o check compara a string informada com uma outra string. Assim temos a senha. Ao executar o check e informar a senha correta obtemos a shell do usuário leviathan2. Agora basta ir ao diretório /etc/leviathan_pass e recuperar a senha.
28 de abril de 2016 / delton / 0 Comments
Resolução do desafio Leviathan
Acessar leviathan.labs.overthewire.org por ssh com o usuário leviathan0 e senha leviathan0.
Depois que o login foi efetuado procurar por arquivos:
|
ls -al total 24 drwxr-xr-x 3 root root 4096 Nov 14 2014 . drwxr-xr-x 167 root root 4096 Jul 9 16:27 .. drwxr-x--- 2 leviathan1 leviathan0 4096 Jul 17 16:44 .backup -rw-r--r-- 1 root root 220 Apr 9 2014 .bash_logout -rw-r--r-- 1 root root 3637 Apr 9 2014 .bashrc -rw-r--r-- 1 root root 675 Apr 9 2014 .profile |
A listagem mostrou um diretório oculto chamado .backup. Ao acessá-lo encontramos o arquivo bookmarks.htm
|
leviathan0@melinda:~$ cd .backup leviathan0@melinda:~/.backup$ ls -al total 140 drwxr-x--- 2 leviathan1 leviathan0 4096 Jul 17 16:44 . drwxr-xr-x 3 root root 4096 Nov 14 2014 .. -rw-r----- 1 leviathan1 leviathan0 133259 Nov 14 2014 bookmarks.htm |
Vamos analisar o arquivo procurando a senha:
|
leviathan0@melinda:~/.backup$ vi bookmarks.html |
Desta forma encontramos a senha do usuário leviathan1.
24 de outubro de 2014 / delton / 0 Comments
Algumas vezes pode ser necessário efetuar uma cópia exata de um HD. Seja para algum tipo de análise ou para migrar um sistema para um disco novo.

O Linux possui um utilitário chamado dd que permite efetuar o clone de partições ou discos inteiros. Podem ser feitos clones de qualquer sistema operacional, não necessariamente do Linux.
Efetuar um clone é muito simples. Neste exemplo vou clonar um HD com Windows 7 para um disco novo. O disco atual é de 320GB e o novo é de 500GB. A única desvantagem é que o disco novo ficará com 320GB de capacidade.
Para isso irei usar o Ubuntu. Não é necessário instalar o sistema, apenas executá-lo. Obviamente é preciso que os dois discos estejam instalados. Depois de efetuar o boot pelo lice CD do Ubuntu, precisamos identificar os discos. Podemos executar o fdisk para isso:
A saída do comando irá listar os discos instalados e mostrará algo semelhante a isso:
|
Disk /dev/sda: 320.1 GB, 320072933376 bytes Disk /dev/sdb: 500.1 GB, 500107862016 bytes |
Desta forma identificamos que o disco instalado em /dev/sda é o disco original de GB e o disco /dev/sdb é o disco que se tornará o clone.
O comando para efetuar o clone é o seguinte:
|
dd if=/dev/sda of=/dev/sdb conv=noerror,sync |
Explicando o comando:
- dd – é o nome do comando;
- if=/dev/hda – é o HD de origem;
- conv= – opções da conversão;
noerror
– instrui o dd a continuar a operação ignorando os erros de leitura. Por padrão o dd vai parar se encontrar um erro;
sync -
preenche os blocos com zero se ocorrerem erros de leitura. Assim fica mantido o sincronismo.
O processo pode ser bastante demorado. Neste exemplo o processo levou 5 horas. O sistema pode parecer travado, então para ver o progresso é preciso abrir outro terminal e executar o seguinte comando para ver o estado da cópia:
|
sudo kill -USR1 $(pgrep ^dd) |
Terminado o processo o HD novo se tornará um clone do disco original. Poderemos então efetuar o boot do e usar o sistema normalmente.
Referências:
http://en.wikipedia.org/wiki/Dd_%28Unix%29
https://wiki.archlinux.org/index.php/disk_cloning#Cloning_an_entire_hard_disk
18 de outubro de 2014 / delton / 0 Comments
Se você perdeu a senha do root e tem acesso a máquina, este artigo vai lhe ajudar a recuperar o acesso ao Linux.
O procedimento foi testado no Debian 7, mas deve funcionar em qualquer distribuição que use o GRUB como gerenciador de boot.
O primeiro passo é efetuar o boot e na tela do GRUB apertar ‘e’ no teclado. A tela a seguir será exibida:

Localize a linha que contém:
Altere para:
Aperte Crtl+X para iniciar o boot. Será exibida a seguinte tela:

Execute os seguintes comandos:
|
mount -o remount, rw / mount -a mount nano /etc/shadow |
Procure pelo root e apague toda a linha, deixando somente os números:


Neste caso deve ficar assim:

Deste modo nós removemos a senha do root. Aperte Ctrl+O e enter para salvar. Depois Ctrl+X para sair.
Execute então os seguintes comandos:
|
sync umount -a mount -o remount, ro / |
Reinicie o sistema pressionando Ctrl+Alt+Del. Após o servidor reiniciar, logue como root. Não será necessário informar a senha. Agora você poderá definir a nova senha com o comando:
Pronto! A senha do root foi atribuída!
Referências:
http://www.vivaolinux.com.br/dica/Recuperando-senha-de-root-no-Debian-Wheezy