bsd0x Postado Julho 18, 2020 em 21:23 Compartilhar Postado Julho 18, 2020 em 21:23 Olá, pessoal, recentemente adquiri interesse em desenvolvimento de exploits entre outros assuntos relacionados. Ainda sou muito iniciante e estou tendo algumas dificuldades para entender alguma peculiaridades. Fiz um código em C utilizando assembly inline e o mesmo não estava compilando, achei uma solução para isso na internet que seria execução o seguinte trecho de código. int (*ret)() = (int(*)())sc; ret(); Minha dúvida é: qual a diferença entre usar o __asm__("jmp sc") e usar a solução acima? Codigo completo /* 8049000: b8 01 00 00 00 mov eax,0x1 8049005: bb 01 00 00 00 mov ebx,0x1 804900a: cd 80 int 0x80 8049000: b8 01 00 00 00 mov eax,0x1 8049005: bb 00 00 00 00 mov ebx,0x0 804900a: cd 80 int 0x80 */ #include <stdio.h> int main() { unsigned char sc[] = "\xb8\x01\x00\x00\x00" "\xbb\x01\x00\x00\x00" "\xcd\x80"; printf("Shellcode length: %d\n", sizeof(sc)); //__asm__("jmp sc"); int (*ret)() = (int(*)())sc; ret(); } Link para o comentário Compartilhar em outros sites More sharing options...
fredericopissarra Postado Julho 19, 2020 em 00:04 Compartilhar Postado Julho 19, 2020 em 00:04 Isso, provavelmente, não funcionará, ou, pelo menos, não funcionará em qualquer "box" linux... Em primeiro lugar, os "segmentos" de dados, num sistema paginado, pode definir as páginas com o bit NX ligdo (NX de Non eXecutable). Isso costuma ser particularmente verdade, inclusive, para a pilha. Daí, simplesmente definir um ponteiro de função apontando para a sequência de bytes que definem as instruções simplesmente causará um segmentation fault na maioria dos "boxes" com kernels modernos. Em segundo lugar, o uso da "int 0x80", embora também exista em sistemas amd64 (x86-64), geralmente causam problemas (especialmente com uso de ponteiros). A coisa complica se quiser criar um "shellcode" no modo amd64 (x86-64), onde referências à memória costumam ser relativas ao RIP. O que se pode fazer com relação ao primeiro caso é alocar as páginas "executáveis" (com o bit NX desligado) usando as system calls mmap() e mprotect() [ativando o flag PROT_EXEC] - mesmo assim, dependendo da versão do kernel, existem proteções para esse tipo de tentativa... Depois, copia-se o conteúdo do "shellcode" para dentro dessas páginas. Daí salta-se para elas. Link para o comentário Compartilhar em outros sites More sharing options...
fredericopissarra Postado Julho 19, 2020 em 00:10 Compartilhar Postado Julho 19, 2020 em 00:10 Quanto a dúvida: A diferença é que o operador () de C realizará um CALL... No contexto acima, tanto o JMP quanto um CALL deixarão de fazer o housekeeping necessário para destruir objetos e outras coisas necessárias da libc... Desconsiderando isso, TANTO FAZ fazer um JMP ou um CALL, NESTE CASO. Link para o comentário Compartilhar em outros sites More sharing options...
fredericopissarra Postado Julho 19, 2020 em 00:40 Compartilhar Postado Julho 19, 2020 em 00:40 PS: Você deve estar pensando: "Ahhh... mas aqui funciona!"... Eu usei "provavelmente" e "pode" em vários lugares do texto... Em alguns ambientes que seguem a SysV ABI isso ai não funciona (acho que é o caso do FreeBSD e do MacOS, por exemplo). Mas, isso aqui PODE funcionar: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/mman.h> int main( void ) { int x; static unsigned char shcodep[] = "\x31\xc0" // xor eax,eax "\xc3"; // ret int (*f)(void); // FIXME: PODE ser que funcione! // Cria página com NX desligado, privada ao processo com permissão de leitura/escrita. f = mmap( NULL, sizeof shcodep, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0 ); if ( (ssize_t)f == -1 ) { perror( "mmap" ); return EXIT_FAILURE; } // Copia o "código" para a página alocada. memcpy( f, shcodep, sizeof shcodep ); x = f(); // chama... munmap( f, sizeof shcodep ); printf( "%d\n", x ); return EXIT_SUCCESS; } Link para o comentário Compartilhar em outros sites More sharing options...
bsd0x Postado Julho 20, 2020 em 03:53 Autor Compartilhar Postado Julho 20, 2020 em 03:53 Muito obrigado pela aula, Fred hahahaha vou tentar aplicar isso: Quote O que se pode fazer com relação ao primeiro caso é alocar as páginas "executáveis" (com o bit NX desligado) usando as system calls mmap() e mprotect() [ativando o flag PROT_EXEC] - mesmo assim, dependendo da versão do kernel, existem proteções para esse tipo de tentativa... Depois, copia-se o conteúdo do "shellcode" para dentro dessas páginas. Daí salta-se para elas. Abraço! Inclusive, saudades do grupo C/asm do facebook hahahaha Link para o comentário Compartilhar em outros sites More sharing options...
Posts Recomendados
Arquivado
Este tópico foi arquivado e está fechado para novas respostas.