Shellcode en el programa C

4 minutos de lectura

avatar de usuario
usuario720694

En Desmitificando el Execve Shellcode se explica una forma de escribir un shellcode ejecutivo:

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

unsigned char code[] = 
"\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80";

main()
{

    printf("Shellcode Length: %d\n", strlen(code));

    int (*ret)() = (int(*)())code;

    ret();
}

que dice la linea int (*ret)() = (int(*)())code; ¿hacer?

  • cdecl dice: convierte el código en el puntero para que la función devuelva int

    –David Ranieri

    18 mayo 2013 a las 17:23

  • no entiendo el () después ret e int()() antes del código.

    – usuario720694

    18 mayo 2013 a las 17:33

  • Para poder analizar tales construcciones en la cabeza, siga la regla de las agujas del reloj/espiral: c-faq.com/decl/spiral.anderson.html

    – jwaliszko

    18 mayo 2013 a las 17:50

  • Por cierto: este enfoque está deshabilitado de forma predeterminada en los sistemas operativos W^X. Corriendo nop (0x90) en un OS X de 64 bits en un procesador moderno, EXC_BAD_ACCESS porque el kernel no ejecutará ningún código desde .bss, .text o el montón porque estas áreas se refieren a entradas de tabla de página de modo largo/PAE con el bit 63 establecido (NX). Podría funcionar en un sistema operativo que no sea PAE/no de modo largo sin algo como PAX/ExecShield en algo antiguo, como DOS. Escribir en áreas de código tampoco funcionará (automutación sobre un montón de asm en línea C nops). Es mejor hacer un programa que escupa un ejecutable mínimo para la(s) plataforma(s) dada(s) y ejecutarlo.

    usuario246672

    26 sep 2015 a las 0:30


  int (*ret)() = (int(*)())code;
  ~~~~~~~~~~~~   ~~~~~~~~~~~~~~
        1              2

  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
               3
  1. Se define ret como un puntero a una función que no tiene parámetro () y regresa int. Entonces, esos () indica la definición de los parámetros de una función.

  2. es para fundicion code a un puntero a una función que no tiene parámetro () y regresa int.

  3. moldes code como una función y la asigna a ret. Después de eso puedes llamar ret();.

unsigned char code[] =  "\x31\xc0\x50\x68\x6e\x2f\...

Es una secuencia de instrucciones de máquina representada por valores hexadecimales. Se inyectará en el código como una función.

  • Entonces, cuando se llama a ret(), ¿cómo se “ejecuta” realmente el código, ya que veo que no se ve la llamada C que “carga” el shellcode y lo ejecuta?

    – usuario720694

    18 mayo 2013 a las 17:45

  • @ user85030, sí, se llama “cargar” ret()google para “puntero a la función”

    –David Ranieri

    18 mayo 2013 a las 17:47


  • los Enlace que ha proporcionado lo está explicando en 11 pasos. Esa secuencia de instrucciones de la máquina está haciendo todo lo mismo que necesita un proceso de llamada.

    – masud

    18 mayo 2013 a las 17:49


  • Bueno. Así que leí sobre punteros de función y entendí la parte 1). ¿Se puede escribir la parte 2) como (int* ())código en lugar de (int

    ())¿código? Para reformular mi pregunta, ¿cómo se convierte una variable en una función? (Dado que tenemos un puntero de función a la izquierda asignado a la función de la derecha.

    – usuario720694


  • 18 mayo 2013 a las 18:56 (int* ()) No puede utilizar code porque no es la forma de declarar el puntero a la función. Piense en las direcciones, en C todos los objetos tienen direcciones, solo arroja la dirección de

    como la dirección de una función.

    – masud

    (*(void(*)())shellcode)()

18 mayo 2013 a las 19:09

    p = (void(*)()) shellcode;
    (*p)();

==[] La línea int declara la función ret(), apuntando al código[] formación; en otras palabras, la función se asigna al código

instrucciones binarias.

  • La construcción \x es una forma segura de incrustar caracteres hexadecimales en una cadena. Por ejemplo, podría reemplazar “\x31” por “1” ya que el código de carácter de “1” es 49, o hexadecimal 31. no entiendo el () despuésret e int(

    )() antes del código.

    – usuario720694

  • ret 18 mayo 2013 a las 17:17es un puntero de función (en.wikipedia.org/wiki/Function_pointer()) a una función con un número indefinido de argumentos ( int) que devuelve un (int(*) () ) . code está echando ret dirección de función para hacer de acuerdo con la dirección del puntero de función que toma un número indefinido de argumentos, así es como

    se declara.

    – Jack

  • 18 mayo 2013 a las 17:35

    ¿Se puede volver a escribir esta parte del puntero de función en una forma más simple?

    – usuario720694

18 mayo 2013 a las 19:03

¿Se puede volver a escribir esta parte del puntero de función en una forma más simple?

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

unsigned char code[] = 
"\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80";

typedef int(*shellcode_t)();

int main(int argc, char ** argv) {
    printf("Shellcode Length: %ld\n", strlen(code));

    shellcode_t ret = (shellcode_t)code;

    ret();
}

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad