CR1: Ultracoded (50)
Starting out with a very simple one, here's the description:
Fady didn't understand well the difference between encryption and encoding, so instead of encrypting some secret message to pass to his friend, he encoded it! Hint: Fady's encoding doens't handly any special character
Initially we're given a file (named zero_one) with a bunch of spelled-out bits:
...ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ONE ONE ZERO ONE ZERO ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ZERO ZERO ONE ONE ZERO ZERO ONE ONE ONE ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ONE ONE ZERO ONE ZERO ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ZERO ZERO ONE ONE ONE ZERO ONE ZERO ONE ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ONE ONE ZERO ONE ZERO ZERO ONE ZERO ONE ZERO ZERO ZERO ZERO ZERO ONE ZERO ONE ONE ONE ZERO ONE ZERO ONE ZERO ONE ZERO ZERO ONE ZERO ZERO ONE ZERO ONE ZERO ZERO ZERO ZERO ONE ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ZERO ZERO ONE ONE ONE ZERO ONE ZERO ONE ZERO ONE ZERO ZERO ONE ONE ZERO ZERO ZERO ONE ONE ZERO ONE ZERO ZERO ONE ZERO ZERO...
First thing to do in this situation is to use a bit of sed to convert them all to their original form:
$ cat zero_one | sed 's/ //g;s/ZERO/0/g;s/ONE/1/g;' 0100110001101001001100000110011101001100011010010011000001110101010011000110100101000001011101010100100101000011001100000111010101001100011010010011000001100111010011000101001100110100011101000100110001101001010000010111010001001001010000110011010001110101010011000101001100110100011001110100110001010011010000010111010101001100011010010011010001110101010010010100001100110100011101000100110001010011001100000111010001001001010000110011010001110101010011000110100100110100011101010100100101000011001100000111010001001100010100110100000101110101010011000101001100110000011101000100110001010011010000010111010101001100011010010011010001100111010011000101001100110000011101000100100101000011001101000111010101001100011010010011010001110101010010010100001100110100011101010100110001010011010000010111010101001100010100110011000001110101010010010100001100110100011101010100110001101001001100000111010001001001010000110011010001110100010011000110100101000001011101000100110001010011001100000110011101001100011010010011010001110101010011000110100100110100011001110100110001101001010000010111010001001100011010010011000001110101010010010100001100110100011101000100110001101001010000010111010101001100011010010011010001110100010011000101001101000001011101000100100101000011001100000111010001001100010100110100000101110100010010010100001100110000011101010100110001101001001100000110011101001100010100010011110100111101
Next we can find what this turns into with some perl:
$ cat zero_one | sed 's/ //g;s/ZERO/0/g;s/ONE/1/g;' | perl -lpe '$_=pack"B*",$_' Li0gLi0uLiAuIC0uLi0gLS4tLiAtIC4uLS4gLSAuLi4uIC4tLS0tIC4uLi4uIC0tLSAuLS0tLSAuLi4gLS0tIC4uLi4uIC4uLSAuLS0uIC4uLi0tIC4tLiAtLS0gLi4uLi4gLiAtLi0uIC4tLiAuLi4tLSAtIC0tLSAtIC0uLi0gLQ==
Now we have some Base64 we can decode:
$ cat zero_one | sed 's/ //g;s/ZERO/0/g;s/ONE/1/g;' | perl -lpe '$_=pack"B*",$_' | base64 -D .- .-.. . -..- -.-. - ..-. - .... .---- ..... --- .---- ... --- ..... ..- .--. ...-- .-. --- ..... . -.-. .-. ...-- - --- - -..- -
Aaaand now we have some Morse code, which ended up being decoded using - http://morsecode.scphillips.com/translator.html
If anyone knows a good command-line tool for this, please leave a comment below! Would love to add that to the one-liner!
Using the online tool, we get this result:
ALEXCTFTH15O1SO5UP3RO5ECR3TOTXT
It wasn't over yet, this wasn't the flag based on their flag format, but it wasn't too difficult to spot the encoding, all O characters were really underscores:
ALEXCTF{TH15_1S_5UP3R_5ECR3T_TXT}
CR2: Many time secrets (100)
Description:
This time Fady learned from his old mistake and decided to use onetime pad as his encryption technique, but he never knew why people call it one time pad!
Not sure who this Fady person is, sounds familiar... Sounds like we need to crack a poorly encrypted message with OTP issues.
Downloading the file they provide, called msg, we see it's a few lines of hex:
0529242a631234122d2b36697f13272c207f2021283a6b0c7908 2f28202a302029142c653f3c7f2a2636273e3f2d653e25217908 322921780c3a235b3c2c3f207f372e21733a3a2b37263b313012 2f6c363b2b312b1e64651b6537222e37377f2020242b6b2c2d5d 283f652c2b31661426292b653a292c372a2f20212a316b283c09 29232178373c270f682c216532263b2d3632353c2c3c2a293504 613c37373531285b3c2a72273a67212a277f373a243c20203d5d 243a202a633d205b3c2d3765342236653a2c7423202f3f652a18 2239373d6f740a1e3c651f207f2c212a247f3d2e65262430791c 263e203d63232f0f20653f207f332065262c3168313722367918 2f2f372133202f142665212637222220733e383f2426386b
Looking up common techniques for cracking OTP we can find the Many Time Pad Attack / the Crib Dragging technique - http://crypto.stackexchange.com/questions/59/taking-advantage-of-one-time-pad-key-reuse
There's a very nice python library for crib dragging here - https://github.com/SpiderLabs/cribdrag
This allows us to easily read in msg file and start the process of discovery. First we need the messages on one line:
$ cat msg | tr -d '\n'; echo 0529242a631234122d2b36697f13272c207f2021283a6b0c79082f28202a302029142c653f3c7f2a2636273e3f2d653e25217908322921780c3a235b3c2c3f207f372e21733a3a2b37263b3130122f6c363b2b312b1e64651b6537222e37377f2020242b6b2c2d5d283f652c2b31661426292b653a292c372a2f20212a316b283c0929232178373c270f682c216532263b2d3632353c2c3c2a293504613c37373531285b3c2a72273a67212a277f373a243c20203d5d243a202a633d205b3c2d3765342236653a2c7423202f3f652a182239373d6f740a1e3c651f207f2c212a247f3d2e65262430791c263e203d63232f0f20653f207f332065262c31683137223679182f2f372133202f142665212637222220733e383f2426386b
Then we pass this in as the first argument to the cribdrag.py tool, initially we have a blank canvas:
./cribdrag/cribdrag.py 0529242a631234122d2b36697f13272c207f2021283a6b0c79082f28202a302029142c653f3c7f2a2636273e3f2d653e25217908322921780c3a235b3c2c3f207f372e21733a3a2b37263b3130122f6c363b2b312b1e64651b6537222e37377f2020242b6b2c2d5d283f652c2b31661426292b653a292c372a2f20212a316b283c0929232178373c270f682c216532263b2d3632353c2c3c2a293504613c37373531285b3c2a72273a67212a277f373a243c20203d5d243a202a633d205b3c2d3765342236653a2c7423202f3f652a182239373d6f740a1e3c651f207f2c212a247f3d2e65262430791c263e203d63232f0f20653f207f332065262c31683137223679182f2f372133202f142665212637222220733e383f2426386b Your message is currently: 0 ________________________________________ 40 ________________________________________ 80 ________________________________________ 120 ________________________________________ 160 ________________________________________ 200 ________________________________________ 240 ________________________________________ 280 ____ Your key is currently: 0 ________________________________________ 40 ________________________________________ 80 ________________________________________ 120 ________________________________________ 160 ________________________________________ 200 ________________________________________ 240 ________________________________________ 280 ____ Please enter your crib:
Now we know that the flag will be in the format ALEXCTF{...}, so we can start with that:
Please enter your crib: ALEXCTF{ *** 0: "Dear Fri" 1: "hho;Q`TV" 2: "ef&JwFkP" 3: "k/WlQymM" 4: ""^qJnp" 5: "SxWuhb/" 6: "u^hsu=9h" 7: "Sann*+U\" ...
Many examples were dropped (276), and a few of them were intelligible. The first one looked like a good candidate, starting with 0, we identify it as a 'message'.
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': message Your message is currently: 0 ALEXCTF{________________________________ 40 ________________________________________ 80 ________________________________________ 120 ________________________________________ 160 ________________________________________ 200 ________________________________________ 240 ________________________________________ 280 ____ Your key is currently: 0 Dear Fri________________________________ 40 ________________________________________ 80 ________________________________________ 120 ________________________________________ 160 ________________________________________ 200 ________________________________________ 240 ________________________________________ 280 ____ Please enter your crib:
"Dear Friend," makes the most sense in the clue we have, so going with that we can find more information:
Please enter your crib: Dear Friend, 0: "ALEXCTF{HERE"
This time 0 is the key, next we can guess underscore is after 'HERE' in the flag from the normal flag format. Continuing this process onwards will fill in the full flag:
Please enter your crib: ALEXCTF{HERE_ *** 260: "ncryption sch" Enter the correct position, 'none' for no match, or 'end' to quit: 260 Is this crib part of the message or key? Please enter 'message' or 'key': message Please enter your crib: encryption scheme 259: "}ALEXCTF{HERE_GOE" Enter the correct position, 'none' for no match, or 'end' to quit: 259 Is this crib part of the message or key? Please enter 'message' or 'key': key Please enter your crib: }ALEXCTF{HERE_GOES_ *** 207: "ecure, Let Me know " Enter the correct position, 'none' for no match, or 'end' to quit: 207 Is this crib part of the message or key? Please enter 'message' or 'key': message Please enter your crib: }ALEXCTF{HERE_GOES_ *** 233: "agree with me to us" Enter the correct position, 'none' for no match, or 'end' to quit: 233 Is this crib part of the message or key? Please enter 'message' or 'key': message Please enter your crib: agree with me to use this encryption scheme 233: "}ALEXCTF{HERE_GOES_THE_KEY}ALEXCTF{HERE_GOE" Enter the correct position, 'none' for no match, or 'end' to quit: 233 Is this crib part of the message or key? Please enter 'message' or 'key': key Your message is currently: 0 ALEXCTF{HERE____________________________ 40 ________________________________________ 80 ________________________________________ 120 ________________________________________ 160 ________________________________________ 200 _______}ALEXCTF{HERE_GOES________}ALEXCT 240 F{HERE_GOES_THE_KEY}ALEXCTF{HERE_GOE____ 280 ____ Your key is currently: 0 Dear Friend,____________________________ 40 ________________________________________ 80 ________________________________________ 120 ________________________________________ 160 ________________________________________ 200 _______ecure, Let Me know _______agree w 240 ith me to use this encryption scheme____ 280 ____ Please enter your crib: ... Enter the correct position, 'none' for no match, or 'end' to quit: none No changes made. Your message is currently: 0 ALEXCTF{HERE_GOES_THE_KEY}ALEXCTF{HERE_G 40 OES_THE_KEY}ALEXCTF{HERE_GOES_THE_KEY}AL 80 EXCTF{HERE_GOES_THE_KEY}ALEXCTF{HERE_GOE 120 S_THE_KEY}ALEXCTF{HERE_GOES_THE_KEY}ALEX 160 CTF{HERE_GOES_THE_KEY}ALEXCTF{HERE_GOES_ 200 THE_KEY}ALEXCTF{HERE_GOES_THE_KEY}ALEXCT 240 F{HERE_GOES_THE_KEY}ALEXCTF{HERE_GOES_TH 280 E_KEY Your key is currently: 0 Dear Friend, This time I understood my m 40 istake and used One time pad encryption 80 scheme, I heard that it is the only encr 120 yption method that is mathematically pro 160 ven to be not cracked ever if the key is 200 kept secure, Let Me know if you agree w 240 ith me to use this encryption scheme alw 280 ays
Flag:
ALEXCTF{HERE_GOES_THE_KEY}
CR4: Poor RSA (200)
Description:
This time Fady decided to go for modern cryptography implementations, He is fascinated with choosing his own prime numbers, so he picked up RSA once more. Yet he was unlucky again! poor_rsa.tar.gz
This was a challenge where a little crypto education would've helped. Started this one off by looking up previous write-ups for RSA based challenges on a CTF. This one turned out to be great! - https://0x90r00t.com/2015/09/20/ekoparty-pre-ctf-2015-cry100-rsa-2070-write-up/
Extracting the tar.gz gave us two files, a encrypted flag and a public key:
-rw-r--r--@ 1 user staff 69B Dec 11 01:08 flag.b64 -rw-r--r--@ 1 user staff 162B Dec 11 00:59 key.pub
Walking through that writeup made this process very simple, starting off by identifying how many bits are used on the public key:
Modulus (399 bit): 52:a9:9e:24:9e:e7:cf:3c:0c:bf:96:3a:00:96:61: 77:2b:c9:cd:f6:e1:e3:fb:fc:6e:44:a0:7a:5e:0f: 89:44:57:a9:f8:1c:3a:e1:32:ac:56:83:d3:5b:28: ba:5c:32:42:43 Exponent: 65537 (0x10001)
Looks like we also got an odd amount of bits (no pun intended).
Now we need to format the hex values to get the integer product:
openssl rsa -noout -text -inform PEM -in key.pub -pubin | grep -Evi 'mod|exp' | tr -d ':\n '
Then to get the int value, pass it into python:
$ openssl rsa -noout -text -inform PEM -in key.pub -pubin | grep -Evi 'mod|exp' | tr -d ':\n ' | xargs python -c 'import sys; print int(sys.argv[1], 16)' 833810193564967701912362955539789451139872863794534923259743419423089229206473091408403560311191545764221310666338878019
Now we can query factordb for this value: http://www.factordb.com/index.php?query=833810193564967701912362955539789451139872863794534923259743419423089229206473091408403560311191545764221310666338878019
We end up seeing there is a match!
This turns out to be:
863653476616376575308866344984576466644942572246900013156919 * 965445304326998194798282228842484732438457170595999523426901
Now that we have p & q, we can generate the private key using RSATool - https://github.com/ius/rsatool
$ python ./rsatool/rsatool.py -p 863653476616376575308866344984576466644942572246900013156919 -q 965445304326998194798282228842484732438457170595999523426901 -o ./priv.key
Finally we just need to decrypt the flag using openssl:
$ openssl rsautl -decrypt -in flag.raw -inkey priv.key
This drops the Flag:
ALEXCTF{SMALL_PRIMES_ARE_BAD}