Olá, espero que estejam todos ok…
Depois de muito bate cabeça e controversias frequentando a lista exploits-brasil um grupo com ideias em comum resolveu criar uma nova lista de discussões…
A lista criada foi chamada de 0ops-br, uma breve tradução da wiki seria:
Um “oops” é um *desvio* do comportamento correto do kernel do linux, o qual produz algum tipo de erro/log.
Tá, pode não ser o melhor nome do mundo mas se você já sabe o significado é bem provável que trará discussões interessantes pra lista ;).
Algumas considerações:
— A lista é moderada
— Os moderadores são bastardos (fdpsemcostume!)
— Os interesses estão entre, mas não somente, OS Internals, Programação baixo nível (C, assembly), Exploração de Softwares, Engenharia Reversa, Malware Analysis e Hacking/Phreaking em geral (exemplo: Lock Picking, DIY projects…)
— …
O endereço da lista é: http://groups.google.com/group/oops-br
Apenas as postagens são moderadas (pra evitar sujeira na lista).
Se você se interessa pelos assuntos acima e sabe como se portar em uma maillist, será bem vindo :).
Sobre o numero de mensagens/dia, só vai passar o que os moderadores julgarem interessantes, então pode ser produtiva ou nenhuma mensagem mas dificilmente será “suja/poluida”…
—
waKKu
Post Info:
# Author: Flavio do Carmo Junior aka waKKu
# URL: Author’s Webpage
# Date: April 06, 2011
# Category: Exploiting, Programming, Security
Bom, já viram que eu meio que abandonei isso aqui né…
Resolvi que escrever em inglês seria mais vantajoso pra mim (estou indo embora do BR em breve e seria uma forma de expor minhas habilidades/curriculo).
De qualquer forma, hoje o meu camaradinha tuxtrack lá do #dclabs na FreeNode me pediu um help sobre stack overflow…
Como eu sei alguma coisa sobre o conhecimento dele, eu preferi explicar o EIP Overwrite (stack overflow) de uma forma diferente, talvez seja util pra mais alguém então aí está:
Explicando melhor as dúvidas que surgiram:
– Porque estamos vendo instruções como:
0x08048383 : mov %eax,0x4(%esp)
0x0804838a : mov %eax,(%esp)
– Ao invés dos clássicos:
push %eax
(calcula um novo eax aqui)
push %eax
???????
Resposta: Porque a cada push, na verdade, o ciclo de instruções executa um:
movl %eax, (%esp)
sub $-4, %esp
Então podemos ver claramente que isso ai é MAIS lento do que eu fazer um único movl usando um endereçamento de referencia, como acontece aqui:
0x08048383 : mov %eax,0x4(%esp)
Isso são otimizações do gcc, tem opções específicas do compilador que produzem o codigo com push’s normal…
Hoje em dia a realidade já é otimização, então é importante trabalhar com elas.
Outra pergunta:
– Porque você falou que a call empurra o valor EIP+5 (eip == propria call)??
Resposta:
– EIP no momento da execução da instrução call, obviamente, aponta para o proprio endereço de memória da instrução call. A instrução call tem 5 bytes (quando desviando para um endereço de memória (label), sendo 1 opcode + 4 bytes do endereço sendo chamado), então o endereço da proxima instrução depois da CALL é exatamente o “Endereço da CALL” + 5.
Mais sobre isso no final do post…
UPDATE: <shinku> Nem toda call tem 5 bytes ;P (Conversa no IRC)
— É verdade, quando uma call usa um registrador, ela tem outro tamanho, exemplo:
0: ff d0 call *%eax
Num caso desse, obviamente, o endereço “empurrado” vai ser EIP_ATUAL+Tamanho_da_Instr_CALL…
Mais info sobre CALL: http://home.comcast.net/~fbui/intel_c.html#call
Agora sim, segue o que construi para minha explicação pro tuxtrack:
Leia o resto deste post »
Post Info:
# Author: Flavio do Carmo Junior aka waKKu
# URL: Author’s Webpage
# Date: March 17, 2011
# Category: Assembly, Exploiting, Programming, Security, Shellcoding
Dae povo…
Se você não leu nossos outros posts da saga Linux x86 ShellCodes – 10X, LEIA ANTES DESSE, HÁ MUITA COISA LÁ QUE NÃO SERÁ REPETIDA AQUI.
1. Introdução
Conforme prometido no post anterior, dei a ideia de abordarmos um exemplo da técnica “CALL + POP”…
Vamos lá… Dessa vez o assembly vai ser um pouco mais “completo”.
Objetivo do nosso ShellCode de hoje: Criar um usuário com uma senha predefinida por nós e com uid = 0.
Considerações:
– O Linux armazena os usuários e senhas no arquivo /etc/passwd *
– A senha será gerada usando o crypt(3) e um MD5-based
– Teremos que inserir uma linha no arquivo utilizando só assembly
* O Linux só consulta o /etc/shadow se o valor do campo password no /etc/passwd for “x”, caso a senha já conste no arquivo ele autentica diretamente.
Do man 5 passwd
The encrypted password field may be blank, in which case no password is required to authenticate as the specified login name. However, some applications which read the /etc/passwd file may decide
not to permit any access at all if the password field is blank. If the password field is a lower-case “x”, then the encrypted password is actually stored in the shadow(5) file instead; there must
be a corresponding line in the /etc/shadow file, or else the user account is invalid. If the password field is any other string, then it will be treated as an encrypted password, as specified by
crypt(3).
OK, já vimos que esse shellcode vai ser bem diferente…
a. A nossa syscall(): write(2) – Número: 4
Leia o resto deste post »
Post Info:
# Author: Flavio do Carmo Junior aka waKKu
# URL: Author’s Webpage
# Date: March 10, 2011
# Category: Assembly, Exploiting, Programming, Security
Olá povo…
Como prometido, vamos evoluir nossos shellcodes (pelo menos tornar isso útil né).
Se você não leu nossos outros posts da saga Linux x86 ShellCodes – 10X, LEIA ANTES DESSE, HÁ MUITA COISA LÁ QUE NÃO SERÁ REPETIDA AQUI.
Objetivo do nosso shellcode: Executar a syscall:
execve(‘/bin/bash’, [ ‘/bin/bash’, 0x00 ], [ 0x00 ])
1. Origanizando as ideias
Vamos considerar como Bad Chars os bytes 0x00 - 0x0d - 0x0a.
a. Especificação da nossa syscall:
man 2 execve
SYNOPSIS
#include
int execve(const char *filename, char *const argv[],
char *const envp[]);
DESCRIPTION
execve() executes the program pointed to by filename. filename must be either a binary executable, or a script starting with a line of the form “#! interpreter [arg]”. In the latter case, the interpreter must be a valid pathname for an executable which is not itself a script, which will be invoked as interpreter [arg] filename.
argv is an array of argument strings passed to the new program. envp is an array of strings, conventionally of the form key=value, which are passed as environment to the new program. Both argv and envp must be terminated by a null pointer. The argument vector and environment can be accessed by the called programâs main function, when it is defined as int main(int argc, char *argv[], char *envp[]).
…
Então, temos:
1o. Argumento: Ponteiro para uma string contendo o filename
2o. Argumento: Ponteiro para um array de argumentos, terminando com 0x00*
3o. Argumento: Ponteiro para um array de ambiente (environment), terminando com 0x00
*: O primeiro valor do array de argumentos deve ser o caminho do programa sendo executado.
b. Número da nossa syscall: 11 (ou 0x0b em hexa)
waKKu@blog$ grep __NR_execve /usr/include/asm-i486/unistd.h
#define __NR_execve 11
2. Escrevendo na stack
Leia o resto deste post »
Post Info:
# Author: Flavio do Carmo Junior aka waKKu
# URL: Author’s Webpage
# Date: March 03, 2011
# Category: Assembly, Exploiting, Programming, Security, Shellcoding
Dae povo…
<HERESIA> Querem contribuir com os posts no blog? Deem uma olhada no Sobre isso aqui…</HERESIA>
Esses dias atrás conversando no canal #dclabs com a galera sobre os posts e tal e pediram pra gente falar um pouco sobre shellcodes…
Bom, não sou nenhum especialista no assunto mas vou tentar passar um pouco das minhas experiências. Apesar de hoje em dia todo mundo acabar usando o MetaSploit Framework pra gerar seus shellcodes e encoda-los ainda, mas eu gosto de saber como as coisas funcionam “de verdade”…
Heads-up: Eu me reservo o direito de errar, mas prometo que tudo que ta aqui foi/será testado. Tudo que to escrevendo aqui vem da minha cabeça e, dentro dela, faz mto sentido ;).
1. Introdução
Shellcode é aquele pedaço mágico de código dentro do nosso payload que enviamos em Opcodes e que será injetado diretamente na memória do programa vulnerável e, se tudo der certo, será executado ao final da nossa exploração.
A origem do nome shellcode é porque inicialmente o que todos desejavam era que após a execução de um exploit nós tivessemos acesso a shell do sistema, e assim poderiamos fazer o que quiser, hoje em dia isso nem sempre é verdade, as vezes o que queremos é adicionar um usuário no sistema ou baixar as proteções de um firewall.
E por que continuamos a chama-lo de shellcode?
— Sei lá… Talvez porque é mais fácil do que chamar de “Pedaço mágico de código inserido na memória de um programa vulnerável a fim de executar <INSIRA AQUI O OBJETIVO DO SEU SHELLCODE>”… Mas de qualquer forma, algumas aplicações já estão abolindo a separação “payload” e “shellcode” – chama tudo de payload pra simplificar.
2. Bad Chars
Leia o resto deste post »
# Author: Raphael Prudencio aka raph0x88
# URL:
Author’s Webpage
# Date: February 28, 2011
# Category: Exploiting, Programming, Security
Sup guys…
Depois de tanto tempo dando desculpas eu consegui sentar pra terminar o post. Alguns meses atrás jogaram um challenge lá no #dclabs e como sou bastante curioso, fui ver do que se tratava, era um challenge de stack overflow da uCon 2009 porém com frescuras requintes interessantes e um detalhe curioso, vamos ao que interessa;
int main (int argc , char *argv[]) {
if (argc != 2) {
__print_sw_title(argv[0]);
return ERRO;
}
if (__lets_play(argv[1])) {
__create_tag(argv[0]);
printf("\n +-+ Bang ! +-+ \n");
} else {
printf("\n Shut your fucking face, uncle fucka! \n");
}
return OK;
}
...
int __lets_play (char *param) {
int i = 0;
char buffer[2];
for(i = 0; i < strlen(param); i++) {
if (i % 2)
buffer[i] = param[rand() % strlen(param)];
else
buffer[i] = '\0';
}
if ((int) buffer < 0)
return 0;
return 1;
}
Antes de entrar nos requintes desse challenge que deveria ser o rand(), vamos ao pequeno detalhe.
Leia o resto deste post »
Post Info:
# Author: Flavio do Carmo Junior aka waKKu
# URL: Author’s Webpage
# Date: February 16, 2011
# Category: Exploiting, Programming, Security
Post na correria, foi quase um copy & paste da análise que tinha feito pro grupo, mas só pra não passar em branco…
1. Introdução
O YOPS é um Web Server extremamente simples que o grupo DcLabs lançou um advisory de Remote Command Execution no ano passado.
2. Encontrando o bug
O ipax usou um fuzzer no software e descobriu que enviando um buffer grande com o comando “HEAD” o software abortava com “Segmentation Fault” (quando um programa tenta acessar memória fora do seu segmento o kernel mata ele com esse sinal
(man 7 signal)).
Utilizando uma versão compilada com debug symbols do programa, um debugger (gdb) e utilizando nosso fuzzer podemos identificar onde a falha ocorre e qual o caminho até ela:
# --- gdb output ---
MANAGER: 1 jobs in ACCEPTOR->PARSER queue
errorer #1 has job (status = 400) (.errors/400.html)
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 1208023360 (LWP 14222)]
logger_th (arg=Cannot access memory at address 0xa30300c
) at main.c:383
383 printf("logger #%d: '%s' LOGGED [%d]\n", id, job->hdr.request_line, job->status);
# --- gdb output ---
A falha aconteceu na função logger_th(), alguma coisa sobrescreveu o endereço de seus argumentos (logger_th (arg=Cannot access memory at address 0xa30300c)).
3. Bug ou Vulnerabilidade
Leia o resto deste post »
Post Info:
# Author: Flavio do Carmo Junior aka waKKu
# URL: Author’s Webpage
# Date: February 10, 2011
# Category: Exploiting, Programming, Security
Olá pepessoal… 😉
De volta hoje com um post um pouco diferente…
1. Introdução
Acho que muitos ai lembram do post “A verdade sobre o apagão” que rolou naquela época do apagão elétrico lá…
Eu, curioso que sou, acabei lendo mais coisas no blog do nosso amigo (ainda naquela mesma época)…
Ontém no canal do #dclabs, não sei porque diabos, entramos (eu e raph0x88) num assunto sobre a possibilidade de Information Leakage (Vazamento de Informações) quando o programador “esquece” um ExitCode pro seu programa (uma função em API/biblioteca também poderia ser explorada). O problema que além de curioso eu sou teimoso pra kct. Uma das coisas que eu tinha lido (e nunca testado) no blog do nosso amigo era um post sobre esse assunto usando a função strcmp(), onde ele diz:
Como todos sabem (se não souberem man strcmp), a função strcmp() é responsável por comparar duas strings e retornar um numero de ordem lexicográfica entre elas. Isto significa que se ao ir comparando caractere-a-caractere, em um dado momento se um caractere do primeiro parâmetro for diferente do segundo, a função irá retornar a diferença entre eles. Caso os parâmetros sejam iguais a função retorna 0 (zero).
De volta a sala de justiça e com toda minha teimosia (pensando: Há! O raph0x88 não conhece essa manha do strcmp() e eu vou me dar bem!), eis 10% do log:
<waKKu> raph0x88 eu to dizendo q eu levo menos de 10 tentativas pra identificar CADA caracter da senha
<waKKu> raph0x88 valendo 1 semana de MESTRE waKKu ?
<raph0x88> DUVIDOOOO
<raph0x88> menos de 10 tentativas?
<raph0x88> valendo..
<raph0x88> 1 semana de mestre wakku
<raph0x88> ou uma semana de mestre raph
<raph0x88> tu tem q me mostrar um codigo que advinhe uma senha q eu colocar de 10 characteres
<raph0x88> em menos de 100 tentativas
<raph0x88> senão é 1 semana me chamando de mestre
<waKKu> aceito
<raph0x88> e se tu conseguir, eu te chamo de mestre
Na verdade eu acreditava que eu ia levar somente 1 tentativa por caracter… Mas meu inconsciente pedia 10
Leia o resto deste post »
Post Info:
# Author: Flavio do Carmo Junior aka waKKu
# URL: Author’s Webpage
# Date: February 06, 2011
# Category: Exploiting, Programming, Security
Dae povo…
Durante o H2HC de 2009 rolou o curso de Linux Exploitation da COSEINC, o instrutor foi o BSDaemon (Rodrigo Rubira). Na conclusão do curso foi lançado um “desafio” que valeria um certificado diferenciado para o mesmo (aliás, nunca vi nem a cor…).
[UPDATE: Recebi o certificado ;)…]
Era novembro/2009 e a vulnerabilidade do mes era um clássico stack overflow no campo netmask do dhclient.
Vou tentar expor os detalhes pra chegar até a falha, a falha em si e por fim: o meu Exploit 😉
Antes de cuspir um monte de código do dhclient aqui, muita gente não deve saber o funcionamento do protocolo DHCP, entao vou tentar esclarecer algumas coisas.
Quando o processo de DHCP é iniciado no cliente:
1– O cliente (no nosso caso o processo dhclient) envia um pacote broadcast de DHCPDISCOVER
2– O servidor DHCP responde com um DHCPOFFER oferecendo um IP, netmask, lease-time e demais configs
3– O cliente então envia um DHCPREQUEST desse IP, dizendo que ele aceita a config
4– O servidor DHCP então envia um DHCPACK, dizendo que ele registrou a config do cliente
A– O cliente agora faz um cálculo baseado no lease-time fornecido pelo servidor e se programa pra enviar um novo DHCPREQUEST antes que o lease-time expire, pra notificar que ele ainda usa esse IP e evitar que o DHCP server entregue-o pra outro cliente.
B– Novamente o servidor DHCP envia um DHCPACK confirmando.
Caso haja alguma alteração nas configurações do servidor DHCP (novo domínio, netmask, router, dns…) o servidor anexa as alterações no DHCPACK.
Se analisarmos esse processo, existe um “gap” ai que temos que levar em consideração: até o passo 4, o cliente NÃO tem um IP! Ou seja, temos 2 linhas de exploração 1) agir nos 4 passos e utilizar um shellcode que não dependa/utilize rede 2) agir no momento A-B e depender do calculo de lease-time.
Eu como estava criando um exploit acadêmico e tinha controle das configurações do servidor, usei a segunda opção e reduzi o lease-time no servidor.
Com TUDO isso em mente, ainda antes de entendermos a falha, vamos dar uma olhada na estrutura interna do DHCP.
Leia o resto deste post »
Post Info:
# Author: Flavio do Carmo Junior aka waKKu
# URL: Author’s Webpage
# Date: February 04, 2011
# Category: Food for Thoughts, Programming
Vocês já devem estar enjoados de blogs com nomes l33t fazendo referência ao assembly, mas… Esse é, (in)felizmente, mais um deles:
http://fnstenv.blogspot.com – Nbrito
http://x9090.blogspot.com – x9090
http://xorl.wordpress.com – xorl
Para os menos avisados, aqui vai uma (não tão) breve explicação do nome do nosso blog.
“Show me the code!” – vale mais que 1000 palavras…
Vamos começar com um simples shellcode…
Objetivo: executar a syscall exit() com o parametro “123”.
waKKu@0xcd80: blog$ cat 0xcd80.s
.text
.globl _start
_start:
movl $1, %eax
movl $123, %ebx
int $0x80
Vamos “monta-lo” (assembler), estou usando uma maquina 64bits, então vou especificar o --32 para que seja gerado o código 32bits (nesse código simples não faria nenhuma diferença):
waKKu@0xcd80: blog$ as --32 -o 0xcd80.o 0xcd80.s
Após o código ser montado, geramos o arquivo 0xcd80.o
Vamos analisar os “opcodes” gerados pelo nosso shellcode:
waKKu@0xcd80: blog$ objdump -d 0xcd80.o
0xcd80.o: file format elf32-i386
Disassembly of section .text:
00000000 <_start>:
0: b8 01 00 00 00 mov $0x1,%eax
5: bb 39 05 00 00 mov $0x7b,%ebx
a: cd 80 int $0x80
Os mais antenados já acharam o nosso blog ali né ;).
Praqueles que ainda não encontraram, introduzo-os a uma das minhas tools que mantenho sempre na minha toolbox.
Ai vai o makesc.sh
waKKu@0xcd80: blog$ ./makesc.sh 0xcd80.o
***** NULL BYTE FOUND (5) *****
Using 16 opcodes/line
// ShellCode -> [ 'File:0xcd80.o', 'Size:12 bytes', 'NULLs: 5' ]
"\xb8\x01\x00\x00\x00\xbb\x39\x05\x00\x00\xcd\x80"
waKKu@0xcd80: blog$
E voilá, ali está nosso “\xcd\x80“…
Tudo isso pra dizer: 0xcd80 ou “\xcd\x80” são os opcodes responsáveis pela instrução assembly: int $0x80 em Linux x86
O que faz essa instrução? Bom, isso fica pra outro post…
Já que viemos até aqui vamos executar nosso shellcode.
Antes de executa-lo precisamos linka-lo, vou usar as bibliotecas de 32bits:
waKKu@0xcd80: blog$ ld -m elf_i386 -o 0xcd80 0xcd80.o
waKKu@0xcd80: blog$ file 0xcd80
0xcd80: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, not stripped
waKKu@0xcd80: blog$ objdump -d 0xcd80
0xcd80: file format elf32-i386
Disassembly of section .text:
08048074 <_start>:
8048074: b8 01 00 00 00 mov $0x1,%eax
8048079: bb 7b 00 00 00 mov $0x7b,%ebx
804807e: cd 80 int $0x80
waKKu@0xcd80: blog$
Só pra levantar mais curiosidades, um dump do binário também depois de linkado, veja os endereços das instruções.
Enfim, executamos:
waKKu@0xcd80: blog$ ./0xcd80
waKKu@0xcd80: blog$ echo $?
123
Aí está, como prometido, um exit(123)… Espetacular, não? :X
That’s all folks!
PS: Notou/curioso sobre o aviso “NULL BYTE FOUND”?… Falaremos sobre isso também em outro post.. 😉
—
See you in another lif… oops, post!
waKKu