Wednesday, May 3, 2017

CNY Hackathon Spring 2017 Review - Part 3

This is the final installation for the CTF challenge discussion from the CNY Hackathon Spring 2017 Event.

For part 1, go here: Part 1
For part 2, go here: Part 2

This will cover the Programming and Exploit Challenges:
  1. programming-1
  2. exploit-2
  3. exploit-3
  4. exploit-4
Exploit-1 is not being covered here since I think there was a problem with the design or execution of the problem. No teams were able to solve this, so I am going to try and fix this and re-use it next semester.

Programming-1

Challenge:

Can you beat my bot? Only other non-human players accepted!
172.18.20.1:9898

First off, I messed this one up a bit. The actual IP address was 172.18.20.51, not 172.18.20.1 but the port number was correct. I didn't realize this during the competition and the mistake was only pointed out to me after the fact. That being said a number of teams were able to discover the correct IP and solved this. Here's how the challenge worked:

When connecting to the service, a message is received which read:

Rock, Paper, Scissors!
You have to beat me 100 times to receive the flag. However, if I win 75 times, it's game over!
Choose wisely!
If we tie, we have to shoot again until there is a winner. Can you figure out my strategy?
Make your selection: (1) Rock, (2) Paper, (3) Scissors:

However, the socket had a super short timeout, so the players had to respond within 1 second or the socket was closed and the game was over. This required that the player be fast at their selection, ideally scripting their logic to play the game. The player was also at a disadvantage since they had to win 100 times before the computer won 75 times. So while possible to win via random chance, the scales were tipped to the computer side a bit to push the player to find a way to predict the computer's moves in order to gain an advantage. The computer logic was broken down as follows:

If the last result was not a tie, choose randomly* from (Rock, Paper, Scissors). Over time, this would result in the computer winning roughly 1/3 of the matches via random chance and the player winning 1/3 of the matches as well. However, there was a 1/3 chance of both players selecting the same option, and this is where the flaw could be discovered. On the computer side, there was a special bit of logic on how to handle a tie. In the case of a tie, the computer was programmed to always choose their next option to be the result that would beat the tie, meaning:

If both players chose rock, the computer would always choose paper next, if both chose paper, the computer would choose scissors, and if both chose scissors, the computer would choose rock. By evaluating the results of the selections made after a tie, the player should have identified this flaw which essentially resulted in them being able to win 2/3 of all matches. It's also possible that by random chance the player could win but just choosing randomly every time. After winning 100 matches, the program will spit out the flag:

flag{1_H0pe_yOu_wr0t3_4_sCr1pt_F0r_Th4t!}

Exploit-2

Challenge:

One host, three progressively harder flags to obtain.
172.18.20.50

This was a late addition to the CTF as I wanted to add a multi-stage challenge into the mix where the players built off the initial phases to work toward progressively harder flags. This also built off testing out enumeration skills, exploitation, and privilege escalation. This challenge was also built off of vulnerabilities I discovered during some of the tests I've performed.

First off, the player needs to determine what services are available on the identified host. Here, Nmap is helpful:


Available services are: ssh, rpcbind, and nfs. Pretty straightforward. Next is enumeration of the services. NFS should be the first target since these typically may contain useful information. For this step 'showmount' can be used to determine whether there are shares that are available to view.


The results show that there are two shares available to all hosts (indicated by the *): shared and backups. These can be mounted with the mount command:


Once mounted doing a file listing should result in one file of interest:


The backup file can be copied locally and extracted to view the contents:


So there's a flag file, and a few of the sensitive files from the /etc directory. The flag file gives the player the first of the three available flags:

flag{Th15_iS_0nlY_P4rt_1}

Next the player should cat the 'shadow' file which contains system user account password hashes. The file contains a number of hashes but conveniently leaves out the root hash.


Any of the user account passwords should be easily cracked with john or hashcat and the rockyou.txt word list. Players only needed to crack one of the accounts since all users ended up with the same permissions. In retrospect I probably should have configured the system to use a less CPU intensive hashing algorithm due to the limitations on the player provided systems, but it only took a few minutes to get a valid hit. The easiest password to crack was for user 'steve' who's password was just 'steve'.

Once cracking some credentials, the player needed to use them to SSH into the system. The second flag is waiting in the shared home directory.


flag{p4rt_2_0f_3_C0mp13tE}

The final part of this challenge requires escalating to root to read the third flag file (located in /root). The key to this part required use of the second NFS share.  The configuration for the NFS shares is listed in /etc/exports, and by viewing this configuration one thing in particular should stick out:


Specifically, the "shared" folder has two specific options set: "rw" and "no_root_squash". The "rw" option indicates that the folder is writable by anyone that has access to it. But what about "no_root_squash"? Well Google gives us a few hints:


Essentially, "no_root_squash" maintains the permissions of files being uploaded to the  shared folder. If a user has root on any box, they can create a file or executable with root permissions, upload it to the share, and maintain those privileges on the system they uploaded the file to. This can be leveraged in a few ways, the first is to create an executable as root, and set the sticky bit so that it executes as root, and then upload and run the executable on the system as an unprivileged user. As a result, the executable will execute as root and can be used to read the final flag. 

In order to exploit this, the share needs to be mounted so that files can be written to it. Then you need a binary that can be used to provide the escalation. A simple setuid exec /bin/sh C program can do the trick.


Once it's compiled and set with the root sticky bit, it can be executed from the remote system as an unprivileged user which results in full root access to the system.


Thanks for reading this three part series! Looking forward to coming up with new challenges next semester.

Thursday, April 27, 2017

CNY Hackathon Spring 2017 Review - Part 2

This is a continuation of the CTF challenge discussion from the CNY Hackathon Spring 2017 Event.

For part 1, go here: Part 1

This will cover the Miscellaneous Challenges:
  1. misc-1
  2. misc-2
  3. misc-3

Misc-1

Challenge:

When attempting to access the link for the misc-1 challenge, the browser prompts to download a file: misc-1.wav


Attempting to listen to the file doesn't result in much, as it sounds just like random beeping-type noises. Attempting to run 'strings' on the file doesn't yield anything either. So where's the flag hidden? The answer is in the spectrogram. Hiding text or images in audio spectrogram isn't new, it's been done multiple times in the past by artists like Aphex Twin and Nine Inch Nails.

Similarly, the flag text for this challenge has been embedded into the wav spectrogram. By changing the view mode in Audacity to Spectrogram, the flag text can be read.



flag{c4n_Y0u_H3ar_Me_N0w}

Misc-2

Challenge:

Similar to misc-1, when accessing the misc-2 challenge the user is again prompted to download a file. This time it's a tarball named misc-2.tar.gz

The tarball unpacks to a misc2 folder with a single file called flag.txt However the contents of the file are not encouraging:


It's not going to be THAT easy.. However, ls -la provides a little more info...


The .git folder should give away that it's a git repository but there's only the one file it it doesn't contain anything useful. However, with git, you can track files in different branches as well to keep workspaces separated and then merge them if needed. The command 'git branch' provides the next clue:


The repository shows 17 branches being tracked, these can be checked out with 'git checkout <branchname>'. 


Once checked out, you can see new files available:


Each piece of the flag is contained in the flag-XX.txt file, which is spread across the branches. At this point you can either enumerate all of the branches and flag files and piece it together or return to the master branch and merge all of the branches together. If you choose the latter, all pieces end up in the main directory and you can re-build the flag. In total there are 42 flag pieces that yield the final flag:

flag{th15_t00k_4_l0t_10ng3R_Th4n_3XpeCt3d}

Misc-3

Challenge: 

Can you beat my whitelist and capture the flag? 
172.18.20.51:7070

When connecting to the listed service, the following text is returned:


So you're challenged to cat out /etc/flag, but there's a restriction on the available characters. Simply trying to enter 'cat /etc/flag' won't work since the slash characters aren't in the allowed list.


The goal here is to use some bash-fu to try and string together some of the commands you *can* use to run the command "cat /etc/flag" (head /etc/flag, tail /etc/flag would also work here). The special characters that are allowed are the key. The pipe command can be used to chain commands together, the tick (`) can be used to execute a command, but what about the colon (:)?

Step 1, is to figure out how to get bash to return a slash (/) character or a file path that can be manipulated to yield the correct location of the flag. One possibility here is the 'which' command. 'Which' returns the location of a command on the system. Something like 'which bash' would return the location of the bash executable.


The result of 'which bash' is actually pretty useful here, it provides a file path similar to the format needed for the flag, but how can you manipulate /bin/bash to become /etc/flag? Well, one option is  'sed'. Sed is a command that can be used to filter and transform text. Consider having the following string: "There is a cat." and you want to change the word "cat" to "dog", you could do that pretty easily.


It's pretty typical that you see the slash character used when making a change like the one shown above, but in reality sed is pretty lenient on the separator. As long as it's consistent and not a special character that provides another function, sed will happily perform the modification. Replacing the slash above with that colon character yields the same result.


 Knowing this, it's possible to solve this challenge. First use the results from which, and then pipe that to sed to get the first transformation (changing bin to etc). This is shown below.


As you can see, bin has now been swapped with etc. We can chain this again to convert /etc/bash to /etc/flag with another pipe:


So /bin/bash has now become /etc/flag. The final step is to get the shell to execute cat /etc/flag. Here the single tick operator (`) is key. You need to wrap all of the commands used to transform /bin/bash to /etc/flag using the tick operator as an argument to cat. One successful command to solve this is shown below.

cat `which bash | sed s:bin:etc: | sed  s:bash:flag:`

Monday, April 24, 2017

CNY Hackathon Spring 2017 Review - Part 1

This past weekend marked the latest iteration of the Central New York Hackathon. For those unfamiliar, the CNY Hackathon is a computer security competition where students compete in a variety of events held every semester either at Mohawk Valley Community College or Utica college. The even attracts a number of students from both Utica College and MVCC as well as students from surrounding schools such as Syracuse, LeMoyne, Morrisville and SUNY Poly. The CNY Hackathon is made up of a CCDC-style event where teams must defend an unknown network against a red team, a CTF event where teams are given a number of challenges to solve, and other miscellaneous events. These have included wireless hacking, security-based games, and black-box challenges where students have to interact with systems that behave unexpectedly. Students can score points if their critical services are online and accessible, or when any of the available challenges are solved. For more information about the event, check out their website: http://www.cnyhackathon.org/

My role in the event for the past few years has been the CTF event, where I lead the design and implementation of the challenges. These include challenges I've designed or borrowed from other CTF events, as well as challenges designed by other volunteers that work with me or are interested in making the CNY Hackathon a success.

Overall, this year's event went pretty well, but due to a packed schedule for me, I was unable to be on-site during the competition. As a result, I couldn't monitor the CTF challenges as closely as I would have liked and a few problems arose. Still, I think the event went well and almost all of the challenges were solved by at least one team. What will follow is a walkthrough of each of the challenges, methods for solving it, and related information. One challenge did not work as I had intended so I will not be covering it here. I plan on fixing it and trying it again next semester.

I'm going to split this into a few separate posts. Today is part 1 which will cover the crypto challenges. These were:

  1. crypto-1
  2. crypto-2
  3. crypto-3



Crypto-1

Challenge:

I think my cat fell asleep on the keyboard while I was making breakfast. Or maybe it's a message? When you figure it out, submit as flag{<plaintext>}. Gotta run, I think something is burning...

AAAABAAAAAAAABAABBABABBAAABABBAAAAAABAABAABAABAAABBAABAAABBBAABAABABAAABBABBAAAAABABAAAABBAABBAABBABBAAAAABBABBAABBABBAAAAABB

Also, hidden in the HTML source was a hint:

<!-- <img src="crypto-1.png" alt="Hint"> -->

Which returned the following image:


Between the challenge text referencing breakfast and the image above, the idea was for students to figure out what type of cipher was in use, then decode the message to get the flag. Searching for something like "ABAB cipher" reveals the type of encryption used in the challenge:


Bacon's cipher!

The first link includes a decoder where the ciphertext can be input and 'decrypted'. I increased the difficulty here a bit by only using a 24-character alphabet instead of the full 26-character one. The rumkin tool shown above can decode the message to provide the key:


Once decoded, the flag should be submitted as flag{BACONMAKESTHEWORLDGOROUND}



Crypto-2

Challenge:

We intercepted a communication, but our mathematicians at Bletchley can't figure it out. If you manage to break the code, submit as flag{<plaintext>}!

WEHRMACHT 3 rotors
I, II, III
UMKERWALZE B
GRUNDSTELLUNG C, N, Y
RINGSTELLUNG C, T, F
STECKERVERBINDUNGEN H-A, C-K

RBIFLMWJSASJAZGSQVZVKRSCKLKNIPYYUFTKBOXBFEBYTWHVSQGHEYJIKBG

This one was slightly harder but the challenge provides some hints to get started. First the references to "intercepting a communication" and "mathematicians at Bletchley", combined with the references to rotors should be enough to identify that this was related to the WW2 Enigma machine. Alternatively, searching for some of the German words such as RINGSTELLUNG and GRUNDSTELLUNG would provide information that this was related to Enigma. Similar to crypto-1, I made use of online encryption and decryption tools so that students wouldn't have to try and write their own enigma decryptor.

Here, students would have to find a decryptor that takes all the information provided to decrypt the ciphertext. One that definitely works is http://www.dcode.fr/enigma-machine-cipher


By filling in all of the provided information into the decryptor, including the rotor positions and plug board configurations, the plaintext message can be decrypted properly. This yields the following plaintext message which can be submitted for points: 

flag{IFAMACHINEISEXPECTEDTOBEINFALLIBLEITCANNOTALSOBEINTELLIGENT}



Crypto-3

Challenge:

Let me tell you, below, you'll find 10 incredible ciphertexts. Truly incredible, believe me. One of these contains a great flag, possibly the greatest flag. It's a very, very good flag worth many, many points. You've never seen a flag like this one, everyone tells me this. All 10 ciphertexts were encrypted using the same stream cipher key. Super secure stuff folks, totally secure. All plaintext bytes fall in normal ASCII range (0x20-0x7e), which means that all messages will be readable when decrypted correctly. Totally readable, let me tell you. These messages only use the best characters. Really good, nobody has selected better characters. The ciphertext below is shown in hexadecimal format, which is the best format. The very best format. Bigly. 


Message 1:

e1e937368654db6d003b7fc4b8d5a93d2e1dc5d12d43177ab08938c15ccf12c854fd3836fdd8500c64ea85eef610fb583a4579c5de57d44bb25dbb366bc4e19e9402a353ef113ba17e505433094766faaba51ed26d42b58bab51a876d236f6251c6d9ab20f4a2d9bd19aab8010c43b41ca44f65b791466b4c0eeadd216a4619bea1cb6296226382219436c4663cdf8b5ebd63e1e388af606abbf928b69584d1dad9144a52a42eb919eb5aa5c9237ded330b3afba21d43ae45675f38eb9187f655f45448f6de443121f42c3477a1669d71f74109bb04cb3ae85268f46bcc57f453e6bffa8585bc48c4086a9a28264d6ef8d694569c9e4e0a61e4be3ee8f589c3ae2f58fb4a219d406997e2dda4aefe4b4fb8408ada5da25c15bece6cc9ebd

Message 2:

fce92d7f866d9e611f227680fccbac3a7d49849d3d4d1328c28d2e851ee351ca4efb3172b5d51f0163be9fe9fc5cf610380a7a84d35795059708b87f568cb6939f0da616ff1772a27c505433094766f4b5a554dc1a6eb590ab4ea97a8637b96b497d99a30f56248894cdbe835c9f7572ca16ed4e6e1f22e0dba6bfd25ea7619eb80ebe3526603e251d0d7b0736ebf9baf8d12450778ac60ce4b3d38964115715a1c25ea52e42fad493a4a219c639c5d23abde587378769b44b65f297b21c2b6955114ac36eb15e44195f965d6601308e505119dff84cabaf8501c012bdc8744f3e74f2ea591e8397418db7a5846ed6ee90264c289ecbaea34d22ace38b15833dabfd94a3e65ec90dd87e699f0deae0b9e38a5b89a8cc60dc4eb9fc899bf6ab56467d9fbdd2a1ae99ddc59a269b5e855c1826f429ef4c75506d54e3d8b618d50525a59deac969e53109531afa7d4697

Message 3:

e6ee3f2a8640d16c57233a8cbdcaa8737d01809d3641153296cc25904bc301c444e0293ab5dc1e0927ea98eaf30ea21d2c5f6495d25ed551f514bf7f70c0a5dcd12ae743ee077fee71040e7b254765f4b5a21f986d6af797bf4cec338676b948483490b14a5035cdc7ceb09f1e911140df5ae05b7d1e2cb4fdf2ebd511b3248aa61ead2362286c03040d7c072dbee4f4fd946d5a3cdafd0cb0bed6df675e515aedde44ad7042c5df99f4a11ac62bdfd877efea93379c27b70459a793fc087f6155014c8d66e444010855c35a7c003dc511625c90f60db2becd0add12a4c97e5e7266bae6585783855b89a0e99a72daa8ab695567d2e1a5a34d0aeeef9f0cd32ba7ba92a7f41b8617972a699b5bf8a1b4afd70fbaa9c6279557f7e3c099f2ab564834a5a89dbbbb8ed691c069f943900a096ee629bd547a5b2118f5c6fa119b0025a48aafd17fab2b46461ee07c0f

Message 4:

e5e3363f8a04ca6a15777681bdd7be73681b809d364d1336cccc198e4b8d03cc01fa3573b5d21e0827ea98eeee5cf50a325e68c5de59d450a15db8377ac1e1939f07e744f81274bc6c15447b180f74f8f7e933dc206ef496ea4ca43fd234fc685767d5a65d476c9fd1dbb3c110e83a508f5deb406f5a75fcd5f2ecd259b238dab91ab02228261525050d780934b9f9a0bf90235a79def90ce4b7d79e6a42031bf3d40aab3c11e5dd89a0ab109f7fc5d836f1a1d2109b2ce44a75f78dfc1278205d044e8621a649071b459056320026801d731f97b042bbead107ca12bac9665d3e6ae9af4d1ac88607

Message 5:

fb64dacacb04ca671c3b738abb9cb43c7c45c5f4645d013f86cc348e1edf02cc01fa3573b5ca1f1f63be99e1f913ef08385e688bcb159b6bba0aec163fc6b4818543a457f10e3bba70154d7b1f1364e5b0ad54dc042be29da44cec2e9d78f8671c5d83be0f6e298cd3cfbacf43d23d4ac05aab0f5198820dd9a6bac343ae6192a31cb12a7f26292e054e6a1c26fdbef4d6d1265036ddb11eaba9d68c2d116a5ae9d05caf7e16e2d4dcb6ab0f927fc0d225f9fcdc6add2bb15030f496b9096e205216058d6ee44e010e448641320426d214260897f143fdb9d11adf5bb082317c7764f2fb14

Message 6:

e5e37d21c304d96d19397dc4a8d3ed3f681c8bde2c081334c2852e975bd905c046ef297ffad3501968be96e6f418a217285e23c5fe55df05a115a9313fd8a997d10da24ee9426fa775150076414770fbbde933dc3a62f994ea4bad23d22cf1604f38d5a849023885dbc9bacf46de2140dc16e64e6b0e2eb4dae9a2c311b827dabe13bc2b26652327150d7f0763f4f5f8bf9f22503c8afe0fe4afda9a6c114015ecd40abe3142e7d4d2f49a14832697ca38e8e396649225a80472e5deba1479204f0d40c36eb044010810905a761667803e69129ab042bbead107ca5ff4cf7e437b23eee00b16c6cd09aabbf6d67c9eed8c695869cbaaaca80200ace19e588734a7ba8aa3ed0eca06d87e699b59bde0a7ea8409ada1c133c15feceacdc1b3bd4a0770deedd4bfb69dd4d0d82af94a9f184c3ae232ef48605d7511e79dfa1d9b4639b984af9c79a42c03545eb37e40c069aa272c475435f5c11b191ad37c18cf19ac715dc1d8d80601063ea18d01b0b60bb38a0d8a96916015f1f1d2

Message 7:

fce97673ef04da6b1439f86445c8ed206810c5c92c49067a8398608052c65f8968ae3979fb9a044d73f699e1f15cfb17280a788bdb5ec956a112a33b3fdba9938543b057ee4268af71140e7b380f78e6f9be1b8f6d67fa9ba15dbe7a8037f6641c6094ab440c6ca494dbb2cf5ede2105df44ea5a7c5a6df294efb888119e619bba14b529616f362f505964482ee0b0b2fe9c24522086b120e4bac2906d5e4413fbd44eea2a0daac594b1ee3d8b3ac5d434fce1d2349626b44875aede9f1e79745a0c4b8f78e80c2d5a518e137c1c3d800074138af40db2ac8506db1cf4ee645a3e77f2e6585bca900984a1e19d6e84a890264e6b9efea1ab0645ac

Message 8:

e6ee3f3ad404d663133c7f96af9cac216c4988c8274052298f8d32955bd851dd49ef3336fac8024d6fff93e4ff0ef1547d4b63819f4cde05b61ca2786b8cb2878217a65ff34274bb6a0345371a0262b5aea00e946d7ffd99be16ec13867fea29507d9ea20f0f6c99d5d1bacf44d93005e153f20f5d1465f8d5e8a88661b63588a314ad352667222e5079640563dbe2b5fb886d5f37ceb101a5add7df75594617a1c146ab2742f3de89a6ee148f38df9d24fee79d2b9f69a24b7ff49cbd1767204f00448e2fe4780c1b44c440320721c550621599f648afafcb0cca12b6c965597b66f4af6813ca8d48cfbda29e6a95e3873b5226dfe4a4e7021efea082199037a7e889e8a218ca029f71759244eedebcfcfb1a97b0cd32cc65e8eadb94ccbe5d03758692dbbfbb9fce

Message 9:

fba62d3aca489e6e1f3871c4bdc8ed3a7d4984c9645c1a3fc298298c5b8451e0c30ec47bb5d31f1927f29fe0f115ec1f7d4b79c5de55c251bd14a2383fc2ae85dd438e11f10e3ba2771f4b7b0d1331fcade91b886d7ffd9dea4ca5379776b95e547581e766053a8894c9ba8a5e9d7552c757f10f5198820dc2e3ecd554b22fd6ea12aa6675696c281149254805f0e2a7ebd1225879cbfd05e8fbc69764114e1fe5d84bea3711aac293f4aa159537d8d332eefbd2259d2de4577fa09db30979754b1105826fa00c101255c3437b1f2c801f685c96e30daea5850ec253aec57f493023cee74e5bed865ec897ed8460d6dc8b2444759eeba3b3180ae0ec9358842eadee9fe6e31086028a7e689941f8a1b4edcb0ebce6c134991afcfaddcde7b14a1f3496a2d3f4aed8d6c7d168f948900e0960

Message 10:

f0f32e73df4bcb22073e7688fcdea8736e0c91c92d46157a83cc348e4acb1d8952fa3c64bb9d503468eb120f030ee7583a45648bd81bcf4af51fa97f78c9b586980da016fc426fa16c114c7b0b027cbbf9e93299af8b0c8bea59ec3d9735b7291c3cb4b75f4e2d98c7dff1c610910c4adad405b6741622e7d1e3e286118e2e8f28fb402a6a263f2f15032b4802f7f4f4f290234779c5f749bdb4c7df6a5f4c0da1d943a77e03e4c88bb5b752c67ff5c823bdf69d3111c95d5675a099b31265671b114ac372a1494a5a10a25d765328c7116f12d3b05ab8eacd0ed957f4df7e437b23fdfd4e1ad7c3598da1f29a6ed6ef8d204f619ee3aee94d4bcef59e588734abe9daa9ec1b860a8b2a729540f8f5bde6ca1ce8eb8560dc49bee8c684fdbe0f127bd2afd8f3ac9dc1c89475a94e92150d22b97dad5e775d7407f191ae1c9c156abf9aead374a073464e14b35a01d16aab272c40063ef18c0d4d0fcf7c4b8c5688605dc0d4de0c53137fa39659b0b60cfa95429292c4651fa5fd99d7ffeb036d849f8759103413d1f706ea80a5df01c4e934f75053906ec149f63328b110db56f503c6c79039dc435c3bcfca0ac8ea4c7a71e68617c5a61cbc1bb0f3ff192020075371d8c8fd00cb165427b4

This was based off of a challenge I had seen in the past that was covered in Dan Boneh's online crypto class as well as in at least one other CTF. The premise is this: A stream cipher or one-time-pad is generated and used to encrypt multiple messages. This completely negates the security that would otherwise be provided, since the encrypted messages can be used to negate the original key.

To demonstrate this, consider the following:

Assume you have two strings s1 and s2 and a key (k) such that: 
s1=AAAAAAAA (0x4141414141414141)
s2=BBBBBBBB (0x4242424242424242)
k= 0x0469d7d45d389ecb

If you encrypt (XOR) s1 with k you get:

 0x4141414141414141
0x0469d7d45d389ecb
-------------------
0x452896951c79df8a

Similarly, s2 XOR k results in:

 0x4242424242424242
0x0469d7d45d389ecb
-------------------
0x462b95961f7adc89

As a result we have two ciphertexts, c1 and c2:
c1 = 0x452896951c79df8a
c2 = 0x462b95961f7adc89

Now if we calculate the XOR of the two ciphertext and the XOR of the two plaintexts, what is the result?

 0x4141414141414141
0x4242424242424242
-------------------
0x3030303030303030

 0x452896951c79df8a
0x462b95961f7adc89
-------------------
0x3030303030303030

Whatever security was obtained by the one time pad or stream key is negated when that same key is used on two messages.

Given this, crypto-3 can be solved by XORing two of the messages together and then extracting the plaintext through a method called crib-dragging. The following post does a much better job of explaining this process: http://jarmoc.com/blog/2013/08/12/otp/

A useful tool here is cribdrag, available from SpiderLabs: https://github.com/SpiderLabs/cribdrag

To use cribdrag, we first have to XOR two of the messages together. cribdrag provides a method for accomplishing this with the xorstrings.py script. Simply call the xorstrings.py and provide the hex from two of the messages. To give the maximum text to work with, I selected the longest messages to start: message10 and message6. xorstrings will return the hex of the combined messages (shown in bold).

$ python xorstrings.py f0f32e73df4bcb22073e7688fcdea8736e0c91c92d46157a83cc348e4acb1d8952fa3c64bb9d503468eb120f030ee7583a45648bd81bcf4af51fa97f78c9b586980da016fc426fa16c114c7b0b027cbbf9e93299af8b0c8bea59ec3d9735b7291c3cb4b75f4e2d98c7dff1c610910c4adad405b6741622e7d1e3e286118e2e8f28fb402a6a263f2f15032b4802f7f4f4f290234779c5f749bdb4c7df6a5f4c0da1d943a77e03e4c88bb5b752c67ff5c823bdf69d3111c95d5675a099b31265671b114ac372a1494a5a10a25d765328c7116f12d3b05ab8eacd0ed957f4df7e437b23fdfd4e1ad7c3598da1f29a6ed6ef8d204f619ee3aee94d4bcef59e588734abe9daa9ec1b860a8b2a729540f8f5bde6ca1ce8eb8560dc49bee8c684fdbe0f127bd2afd8f3ac9dc1c89475a94e92150d22b97dad5e775d7407f191ae1c9c156abf9aead374a073464e14b35a01d16aab272c40063ef18c0d4d0fcf7c4b8c5688605dc0d4de0c53137fa39659b0b60cfa95429292c4651fa5fd99d7ffeb036d849f8759103413d1f706ea80a5df01c4e934f75053906ec149f63328b110db56f503c6c79039dc435c3bcfca0ac8ea4c7a71e68617c5a61cbc1bb0f3ff192020075371d8c8fd00cb165427b4 e5e37d21c304d96d19397dc4a8d3ed3f681c8bde2c081334c2852e975bd905c046ef297ffad3501968be96e6f418a217285e23c5fe55df05a115a9313fd8a997d10da24ee9426fa775150076414770fbbde933dc3a62f994ea4bad23d22cf1604f38d5a849023885dbc9bacf46de2140dc16e64e6b0e2eb4dae9a2c311b827dabe13bc2b26652327150d7f0763f4f5f8bf9f22503c8afe0fe4afda9a6c114015ecd40abe3142e7d4d2f49a14832697ca38e8e396649225a80472e5deba1479204f0d40c36eb044010810905a761667803e69129ab042bbead107ca5ff4cf7e437b23eee00b16c6cd09aabbf6d67c9eed8c695869cbaaaca80200ace19e588734a7ba8aa3ed0eca06d87e699b59bde0a7ea8409ada1c133c15feceacdc1b3bd4a0770deedd4bfb69dd4d0d82af94a9f184c3ae232ef48605d7511e79dfa1d9b4639b984af9c79a42c03545eb37e40c069aa272c475435f5c11b191ad37c18cf19ac715dc1d8d80601063ea18d01b0b60bb38a0d8a96916015f1f1d2
151053521c4f124f1e070b4c540d454c06101a17014e064e41491a19111218491415151b414e002d005584e9f716454f121b474e264e104f540a004e47111c11490002581500000619044c0d4a450c404400014595e9f51f0012411e451946495304611f164c151d1c164b09564f2d0a06c2e3f81f180c530b0a40450036095596e8fc014c431c08000e544f6103010c4d0f0117454f0946591b1d45064e0c184d0d49194f41031c59412d46455962021b55150b5583ecf55207454709061c47541c0a001c110d4b5200320700454f472f060049001803001c091308001000000000131d450c110e50271a044c12480201491708554902414f4b6214000000000c53500a01154c0c53541b0e1945151a0c4e15454a44531d1652020b454e0345150b0c420c4c1a0015184c5f50040d0d41185b4f421617000116160c5401075353061e454f0d045f451a4a002441110301000007520b044d1654151c0053434f241100010c060a521541021b58000007491f4f180455050a540c4b

Now, use the cribdrag.py script to try and separate the plaintext. cribdrag takes the combined XOR hex as input and creates an interactive script that you can continue to work with. 

$ python cribdrag.py 151053521c4f124f1e070b4c540d454c06101a17014e064e41491a19111218491415151b414e002d005584e9f716454f121b474e264e104f540a004e47111c11490002581500000619044c0d4a450c404400014595e9f51f0012411e451946495304611f164c151d1c164b09564f2d0a06c2e3f81f180c530b0a40450036095596e8fc014c431c08000e544f6103010c4d0f0117454f0946591b1d45064e0c184d0d49194f41031c59412d46455962021b55150b5583ecf55207454709061c47541c0a001c110d4b5200320700454f472f060049001803001c091308001000000000131d450c110e50271a044c12480201491708554902414f4b6214000000000c53500a01154c0c53541b0e1945151a0c4e15454a44531d1652020b454e0345150b0c420c4c1a0015184c5f50040d0d41185b4f421617000116160c5401075353061e454f0d045f451a4a002441110301000007520b044d1654151c0053434f241100010c060a521541021b58000007491f4f180455050a540c4b
Your message is currently:
0 ________________________________________
40 ________________________________________
80 ________________________________________
120 ________________________________________
160 ________________________________________
200 ________________________________________
240 ________________________________________
280 ________________________________________
320 ________________________________________
360 ___________________
Your key is currently:
0 ________________________________________
40 ________________________________________
80 ________________________________________
120 ________________________________________
160 ________________________________________
200 ________________________________________
240 ________________________________________
280 ________________________________________
320 ________________________________________
360 ___________________

The question here is what to start with, the text provided in the challenge provides some clues. The wording of the challenge should be vaguely familiar... Let's try using the word " great " (note the spaces).

Please enter your crib:  great 

The script will attempt to run the provided text against the whole combined message. What we're looking for is any other readable text that appears in the results.

If you scroll through the output, cribdrag highlights lines that might be of interest. Take a look at line 225, the results show the characters " to me."

*** 218: "3oruat "
219: "(gbeat "
*** 220: " wreat3"
221: "0greag="
*** 222: " grerie"
223: " grv|1,"
224: " gax$x1"
*** 225: " to me."
*** 226: "3z7ipzp"
227: "="~to$"
*** 228: "ekck1S:"
229: ",v|5Fn$"
230: "1i"B{pl"

So what does this mean? Basically, at that offset (225) the characters (space)great(space) are XORed with the characters (space)to(space)me, meaning that some of the plaintext has been recovered. For cribdrag, enter the offset where this occurs (225) and that we provided part of the key, and cribdrag will fill in the plaintext from the two messages.

Enter the correct position, 'none' for no match, or 'end' to quit: 225
Is this crib part of the message or key? Please enter 'message' or 'key': key
Your message is currently:
0 ________________________________________
40 ________________________________________
80 ________________________________________
120 ________________________________________
160 ________________________________________
200 _________________________ to me.________
240 ________________________________________
280 ________________________________________
320 ________________________________________
360 ___________________
Your key is currently:
0 ________________________________________
40 ________________________________________
80 ________________________________________
120 ________________________________________
160 ________________________________________
200 _________________________ great ________
240 ________________________________________
280 ________________________________________
320 ________________________________________
360 ___________________

Let's choose another word that this specific person likes to say pretty often: "many". As before we'll enter the word with the spaces and see if anything comes back. Specifically, around offset 143, there's some text to work with.

139: "o
       boum"
140: "An`b4/"
141: "#lm#v!"
*** 142: "!a,ax7"
*** 143: ", none"
144: "mb`y<o"
145: "/lv+6)"
146: "!z$!pf"

As before, enter the offset and that it's part of the key to fill in the results.

Enter the correct position, 'none' for no match, or 'end' to quit: 143
Is this crib part of the message or key? Please enter 'message' or 'key': key
Your message is currently:
0 ________________________________________
40 ________________________________________
80 ________________________________________
120 _______________________, none___________
160 ________________________________________
200 _________________________ to me.________
240 ________________________________________
280 ________________________________________
320 ________________________________________
360 ___________________
Your key is currently:
0 ________________________________________
40 ________________________________________
80 ________________________________________
120 _______________________ many ___________
160 ________________________________________
200 _________________________ great ________
240 ________________________________________
280 ________________________________________
320 ________________________________________
360 ___________________

This provides a good starting point and now we can use some of the recovered words to expand on some of the plaintext. Consider the word "none" above. We can have cribdrag use that as a word and that might provide us with some information on what the next word of the other message might be. So let's have cribdrag search for ", none " (note the space after none). We should see some results around the same offset as before (143).
 
141: "/!b"ad7"
142: "-,#`ore"
*** 143: " many o"
144: "a/ox+*)"
145: "#!y*!lf"

Since we searched part of the "message" we need to have cribdrag fill this in properly, so enter offset 143 and instead of "key" enter "message".

Enter the correct position, 'none' for no match, or 'end' to quit: 143
Is this crib part of the message or key? Please enter 'message' or 'key': message
Your message is currently:
0 ________________________________________
40 ________________________________________
80 ________________________________________
120 _______________________, none __________
160 ________________________________________
200 _________________________ to me.________
240 ________________________________________
280 ________________________________________
320 ________________________________________
360 ___________________
Your key is currently:
0 ________________________________________
40 ________________________________________
80 ________________________________________
120 _______________________ many o__________
160 ________________________________________
200 _________________________ great ________
240 ________________________________________
280 ________________________________________
320 ________________________________________
360 ___________________

Maybe it's " many of "? 

141: "#lm#v!x#o"
142: "!a,ax7*))"
*** 143: ", none of"
144: "mb`y<of y"
145: "/lv+6))?;"

Yeah, that's looking good. Let's save that.

Enter the correct position, 'none' for no match, or 'end' to quit: 143
Is this crib part of the message or key? Please enter 'message' or 'key': key
Your message is currently:
0 ________________________________________
40 ________________________________________
80 ________________________________________
120 _______________________, none of________
160 ________________________________________
200 _________________________ to me.________
240 ________________________________________
280 ________________________________________
320 ________________________________________
360 ___________________
Your key is currently:
0 ________________________________________
40 ________________________________________
80 ________________________________________
120 _______________________ many of ________
160 ________________________________________
200 _________________________ great ________
240 ________________________________________
280 ________________________________________
320 ________________________________________
360 ___________________

That gives us ", none of" which we can expand out again to account for the space.

This process can continue to slowly build out the plaintext of both messages. If you get stuck, you can try common words or phrases to try and extract some of the text at other points of the messages. Eventually, you'll be able to extract the contents of both messages:

Your message is currently:
0 We're going to launch an investigation t
40 o find out. And then the next time -- an
80 d I will say this, of those votes cast, 
120 none of them come to me, none of them co
160 me to me. They would all be for the othe
200 r side. None of them come to me. But whe
240 n you look at the people that are regist
280 ered, dead, illegal, and two states, in 
320 some cases, maybe three states. We have 
360 a lot to look into.

Your key is currently:
0 But you will be getting a total star.  Y
40 ou’re going to be getting a total gem.
80  He’s a gem.  (Applause.)  You’ll s
120 ee.  You’ll see.  And many of you know
160 him anyway.  But you’re going to see.
200  And again, we have some great people g
240 oing in.  But this one is something -- i
280 s going to be very special, because this
320 is one, if I had to name the most impor
360 tant, this would ce

Once you have the plaintext, you can use it against the other messages to find which one has the key in it (Spoiler Alert, it's message 8). Since we have the contents of message10 and message 6 now, we can xor one of those with message8 to get them combined then run cribdrag on them providing the entirety of the message we've already decoded to extract all of message8. Below I've combined message10 and message8

$ python xorstrings.py e6ee3f3ad404d663133c7f96af9cac216c4988c8274052298f8d32955bd851dd49ef3336fac8024d6fff93e4ff0ef1547d4b63819f4cde05b61ca2786b8cb2878217a65ff34274bb6a0345371a0262b5aea00e946d7ffd99be16ec13867fea29507d9ea20f0f6c99d5d1bacf44d93005e153f20f5d1465f8d5e8a88661b63588a314ad352667222e5079640563dbe2b5fb886d5f37ceb101a5add7df75594617a1c146ab2742f3de89a6ee148f38df9d24fee79d2b9f69a24b7ff49cbd1767204f00448e2fe4780c1b44c440320721c550621599f648afafcb0cca12b6c965597b66f4af6813ca8d48cfbda29e6a95e3873b5226dfe4a4e7021efea082199037a7e889e8a218ca029f71759244eedebcfcfb1a97b0cd32cc65e8eadb94ccbe5d03758692dbbfbb9fce f0f32e73df4bcb22073e7688fcdea8736e0c91c92d46157a83cc348e4acb1d8952fa3c64bb9d503468eb120f030ee7583a45648bd81bcf4af51fa97f78c9b586980da016fc426fa16c114c7b0b027cbbf9e93299af8b0c8bea59ec3d9735b7291c3cb4b75f4e2d98c7dff1c610910c4adad405b6741622e7d1e3e286118e2e8f28fb402a6a263f2f15032b4802f7f4f4f290234779c5f749bdb4c7df6a5f4c0da1d943a77e03e4c88bb5b752c67ff5c823bdf69d3111c95d5675a099b31265671b114ac372a1494a5a10a25d765328c7116f12d3b05ab8eacd0ed957f4df7e437b23fdfd4e1ad7c3598da1f29a6ed6ef8d204f619ee3aee94d4bcef59e588734abe9daa9ec1b860a8b2a729540f8f5bde6ca1ce8eb8560dc49bee8c684fdbe0f127bd2afd8f3ac9dc1c89475a94e92150d22b97dad5e775d7407f191ae1c9c156abf9aead374a073464e14b35a01d16aab272c40063ef18c0d4d0fcf7c4b8c5688605dc0d4de0c53137fa39659b0b60cfa95429292c4651fa5fd99d7ffeb036d849f8759103413d1f706ea80a5df01c4e934f75053906ec149f63328b110db56f503c6c79039dc435c3bcfca0ac8ea4c7a71e68617c5a61cbc1bb0f3ff192020075371d8c8fd00cb165427b4
161d11490b4f1d411402091e53420452024519010a0647530c41061b11134c541b150f5241555279071481ebfc00160c470e070a4757114f43030b07134507011a1a06490f001b1a0612094c11001e0e57493c0dc2f4f112544f002e114a5d004c412a1550414101120e4b0954483c4f3b87f7b92902471f040b4a0070381b078befed1f4c411d01457a4f4d612c164109184e184e0b4648181910001f060a1a0018050c594117160213594649472a55074311001a8ea0ff1d0a54050e05024754110e4d5d4531464154661d44540902410d074a461217450602134542161b1a0045095226091d4e11421c500404430c0a1b1d4741070a0e4f5530551c4117030c0153414e034c08145b070704162b011a31067f5b4852102c56021d10310052110e543d034c17020f

Then cribdrag on the combination and entering the contents of the decoded message 10 (only up to the length of message 8:

Please enter your crib: But you will be getting a total star.  You’re going to be getting a total gem.  He’s a gem.  (Applause.)  You’ll see.  You’ll see.  And many of you know him anyway.  But you’re going to see.  And again, we have some great people going in.  But this one is something -- is going to be ver
0: "Their hackers are much smarter than our hackers, and we can't sustain ourselves with that. It's like - take the New England Patriots and Tom Brady and have them play your high school football team. That's the difference between China's hackers and our hackers. flag{this_is_a_very_very_great_flag}"
Enter the correct position, 'none' for no match, or 'end' to quit: 0
Is this crib part of the message or key? Please enter 'message' or 'key': key
Your message is currently:
0 Their hackers are much smarter than our 
40 hackers, and we can't sustain ourselves 
80 with that. It's like - take the New Engl
120 and Patriots and Tom Brady and have them
160 play your high school football team. Th
200 at's the difference between China's hack
240 ers and our hackers. flag{this_is_a_very
280 _very_great_flag}
Your key is currently:
0 But you will be getting a total star.  Y
40 ou’re going to be getting a total gem.
80  He’s a gem.  (Applause.)  You’ll s
120 ee.  You’ll see.  And many of you know
160 him anyway.  But you’re going to see.
200  And again, we have some great people g
240 oing in.  But this one is something -- i
280 s going to be ver

That's it! It's super time-consuming and I probably did a horrible job of explaining it, but that's why it was worth so many points :)