Mostrando entradas con la etiqueta shellcode. Mostrar todas las entradas
Mostrando entradas con la etiqueta shellcode. Mostrar todas las entradas

sábado, 11 de diciembre de 2010

Proceso de escritura de un shellcode

Hoy me ha entrado del vicio de escribir un shellcode, aquí queda el proceso para quien se pregunte como se escriben estos extraños seres de la fauna binaria.

Actualización: me había olvidado del BITS 32 en el shellcode para que funcione bien

Un shellcode, llamados así porque generalmente lo que hacían era presentar una shell (aunque se puede hacer cualquier cosa con ellos), son trozos de código ensamblador, normalmente pasados a formato hexadecimal para un "consumo" más cómodo, cuya característica más importante es que se pueden cargar en cualquier posición de memoria.


lunes, 31 de mayo de 2010

Probando shellcodes

Pues hoy vengo con poca cosa, andaba escribiendo algo para pasar el rato... un programilla para probar shellcodes ¿porque no?

Y este es el resultado [ shellcode_tester.c ] o al final coloreado con Pygments

La compilacion es simple, solo hay que hacer
gcc shellcode_tester.c -o shellcode_tester

Las opciones al lanzarlo son:
./shellcode_tester [-nv] [-nw] [-nr] [-f <archivo>]
-nv: No verbose (no se imprimira nada por pantalla)[--no-verbose]
-nw: No write (no se permitira escribir en la memoria del shellcode)[--no-write]
-nr: No read (no se permitira leer la memoria del shellcode)[--no-read]
-f: Introduce el shellcode a traves de un archivo


Mas o menos, usarlo seria algo asi:
kenkeiras@viaxante:~/%%%%%$ ./shellcode_tester
    Shellcode Tester

Introduce el shellcode: \x31\xdb\x8d\x43\x17\xcd\x80\x31\xd2\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x52\x53\x89\xe1\x8d\x42\x0b\xcd\x80\x31\xc0\x40\xcd\x80

Ejecutando Shellcode... [36]
$ echo "Esto es otra shell :D}"
Esto es otra shell :D}
$
kenkeiras@viaxante:~/%%%%%$



/*
*  Shellcode Tester (Yet Another Shellcode Tester)
*  Copyright (c) 2010 Kenkeiras
*
*          DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
*                  Version 2, December 2004

*
* Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
*
* Everyone is permitted to copy and distribute verbatim or modified
* copies of this license document, and changing it is allowed as long
* as the name is changed.

*
*            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
*   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
*
*  0. You just DO WHAT THE FUCK YOU WANT TO.
*

*
*/


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <sys/mman.h>

#define max_size 1024 //Caracteres maximos para el shellcode

// Como (sh en Gnu/Linux de 32 bits)
// \x31\xdb\x8d\x43\x17\xcd\x80\x31\xd2\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x52\x53\x89\xe1\x8d\x42\x0b\xcd\x80\x31\xc0\x40\xcd\x80


char *scs = NULL;

char *sc = NULL;

char a2h(char c){

    char r;
    if (c>'9'){
        if (c>'Z')

            r=c-0x57;
        else
            r=c-0x37;

    }
    else
        r=c-0x30;
    return r;

}

// Formas de leer los shellcode

// \x99\xAA\xaa (\x<numero en hexa>)
int bar_hexa(char *in,char *out){

    char curr;
    int i,r=-1,len=0;

    for (i=0; (i < max_size) && in[i] != '\0'; i++){

        if((r == 2) || ((in[i] == '\\') && (r > 0))){

            r =- 1;
            out[len] = curr;

            len++;

        }
        if(in[i] == '\n'){

            break;
        }
        else if (in[i] == '\r'){

            continue;
        }
        else if (in[i] == 'x'){

            r = 0;
        }
        else if(r >- 1){

            if (r == 0){
                curr = a2h(in[i])*16;

            }
            else{
                curr = a2h(in[i]) + curr;

            }
            r++;
        }
    }
    return len;

}

// Escrito directamente
int raw_bin(char *in,char *out){

    int i,len=strlen(in);
    for (i = 0;i < len;i++){

        out[i] = in[i];
    }
    return len;

}


int main(int argc,char **argv){

    FILE *f = stdin;
    char verbose = 1;

    char stack_write = 1;
    char stack_read = 1;

    int i,len,r;

    sc=malloc(max_size+1);

    if (argc>1){
        for (i=1;i<argc;i++){

            if ((strcmp(argv[i],"-nv") == 0) && (strcmp(argv[i],"--no-verbose") == 0)){

                verbose = 0;
            }
            else if ((strcmp(argv[i],"-f") == 0) && ((i+1)<argc) ){

                f = fopen(argv[i+1],"r");
                i++;

            }
            else if ((strcmp(argv[i],"-nw") == 0) && (strcmp(argv[i],"--no-write") == 0)){

                stack_write = 0;
            }
            else if ((strcmp(argv[i],"-nr") == 0) && (strcmp(argv[i],"--no-read") == 0)){

                stack_read = 0;
            }
            else{
                printf("Uso: ./shellcode_tester [-nv] [-nw] [-nr] [-f <archivo>]\n");

                printf("-nv: No verbose (no se imprimira nada por pantalla)[--no-verbose]\n");
                printf("-nw: No write (no se permitira escribir en la memoria del shellcode)[--no-write]\n");
                printf("-nr: No read (no se permitira leer la memoria del shellcode)[--no-read]\n");

                printf("-f: Introduce el shellcode a traves de un archivo\n");
            }
        }
    }

    int PROT_MODE = PROT_EXEC|PROT_NONE ;
    if (stack_write){

        PROT_MODE |= PROT_WRITE;
    }
    if (stack_read){

        PROT_MODE |= PROT_READ;
    }

    if (verbose){

        printf("\tShellcode Tester\n\n");
        printf("Introduce el shellcode: ");
    }

    char *s = malloc((max_size*4)+1);

       fgets(s,max_size*4,f);
    r=-1;

    len = bar_hexa(s,sc);

    if (len < (strlen(s)/4)){

        len = raw_bin(s,sc);
    }

    free(s);

    scs=mmap(0,len+1,PROT_MODE, MAP_ANONYMOUS | MAP_SHARED, -1, 0);

    for (i=0;i<len;i++){
        scs[i]=sc[i];

    }

    free(sc);

    if (verbose){

        printf("\nEjecutando Shellcode... [%i]\n",len);
    }
    (*(void(*)()) scs)();

    if (verbose){
         printf("Fin del Shellcode\n");
    }

    return 0;
}


Hasta otra