Showing posts with label cryptanalysis. Show all posts
Showing posts with label cryptanalysis. Show all posts

Tuesday, February 7, 2017

AlexCTF 2017 - Crypto


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}

Sunday, February 5, 2017

BITSCTF 2017 - Crypto [Banana Princess (20), Enigma (30), Beginner's Luck (40), Sherlock (60)]


This CTF was a lot of fun!  There were a lot of easier challenges, and had some inventive challenges!

For the Crypto challenges, they were mostly encoding based or very simple XOR ciphers.

Banana Princess


This first crypto challenge included a pdf file (MinionQuest.pdf) and description:

The princess has been kidnapped! It is up to you to rescue her now, with the help of the minions. They have provided you with a letter (which may or may not have touched the kidnappers hands on its way to you).

Authors - Speeeddy, Blaze


Initially checking the exifdata seemed like a good idea:

ExifTool Version Number         : 10.08
File Name                       : MinionQuest.pdf
Directory                       : .
File Size                       : 420 kB
File Modification Date/Time     : 2017:02:04 22:29:08-08:00
File Access Date/Time           : 2017:02:05 02:24:27-08:00
File Inode Change Date/Time     : 2017:02:04 22:29:11-08:00
File Permissions                : rw-r--r--
Error                           : File format error

Looks like the pdf is corrupted, maybe the bytes or xor'd or something. Looking at a normally formed pdf elsewhere we can find similar strings to the corrupted ones:

<</Yvarnevmrq 1/Y 430190/B 6/R 404343/A 1/G 429991/U [ 576 155]>>

This could possibly be a simple rotation, so going here (http://planetcalc.com/1434/) we can see it shows up at the ROT13 point:

<</Linearized 1/L 430190/O 6/E 404343/N 1/T 429991/H [ 576 155]>>

So now we just have to ROT13 the whole file!
At this point I just used python to do the rest:

# rot13 code from http://stackoverflow.com/questions/3269686/short-rot13-function
import string
rot13 = string.maketrans( 
        "NOPQRSTUVWXYZnopqrstuvwxyzABCDEFGHIJKLMabcdefghijklm",
        "ABCDEFGHIJKLMabcdefghijklmNOPQRSTUVWXYZnopqrstuvwxyz" 
        )

# print string.translate("Hello World!", rot13)

x = open('./MinionQuest.pdf', 'rb').read()
y = open('./out.pdf', 'w')

y.write(string.translate(x, rot13))
print 'done.'



This drops a pdf called 'out.pdf' which contains some better data to check out, looks like a part of it is redacted!



At this point I tried a few things, including looking for PDF layers, importing into Gimp and checking for PSD layers (as the exifdata did mention Adobe Photoshop CC 2015 & Microsoft Word), then after those checks failed, the next was to try file carving.

For file carving I ended up using one of my favorite tools, hachoir & hachoir-subfile! - https://bitbucket.org/haypo/hachoir/wiki/hachoir-subfile

$ hachoir-subfile out.pdf files
[+] Start search on 430190 bytes (420.1 KB)

[+] File at 1738 size=34851 (34.0 KB): JPEG picture => files/file-0001.jpg
[+] File at 36872 size=3448 (3448 bytes): JPEG picture => files/file-0002.jpg

[+] End of search -- offset=430190 (420.1 KB)
Total time: 108 ms -- global rate: 3.8 MB/sec

Looks like it worked! Output two files in our output directory of 'files'. This also dropped the full image without the redacted bar layer:



Flag: BITSCTF{save_the_kid}


Enigma


This challenge ended up being solved faster than expected, but was nice to do, here's the description:

Its World War II and Germans have been using Enigma to encrypt their messages. Our analysts have figured that they might be using XOR-encryption. XOR-encrption is vulnerable to a known-plaintext attack. Sadly all we have got are the encrypted intercepted messages. Your task is to break the Enigma and get the flag.

The included encrypted.tar.zx file dropped six files which were scrambled a little, here's an example of one:

$ xxd 2e
00000000: 3630 3c35 362a 2642 6775 2651 6372 7263  60<56*&Bgu&Qcrrc
00000010: 7426 6f75 7226 6e63 7372 6326 6d6a 6774  t&our&ncsrc&mjgt
00000020: 2826 5463 6163 6826 676b 2647 6463 6862  (&Tcach&gk&Gdchb

Ended up using this tool for the majority of the challenges - https://wiremask.eu/tools/xor-cracker/ (Could probably do exactly the same using xortool, etc.)
On there we find the highest probability of the first file's XOR key has a length of 1, weighing in around 14.5% probability.
It also drops the most likely key as 0x06.

Wrote another small python program (which may have been overkill in hindsight):

from pwn import *

data = []
files = ['1e','2e','3e','4e','5e','6e']
key = '\x06'

for f in files:
  x = open(f, 'rb').read()
  data.append(x)

for x in data:
  print xor(data, key)


This printed out the conversions:

Britische Passagier-Konvoi beschmutzt bei 60 Grad Norden und 15 Grad Westen. Nehmen Sie es sofort06:30, Das Wetter ist heute klar. Regen am AbendAdvance Ihre Einheit 1 Grad Norden und 2 Grad OstenDer Code für den Tag ist BITCTF{Focke-Wulf Fw 200}Berichte der britischen Marineüberwachung in Ihrer Region. Gehen Sie undercoverWir verfehlen Torpedos. Nur 2 übrig. Senden Sie die Lieferungen sofort
Britische Passagier-Konvoi beschmutzt bei 60 Grad Norden und 15 Grad Westen. Nehmen Sie es sofort06:30, Das Wetter ist heute klar. Regen am AbendAdvance Ihre Einheit 1 Grad Norden und 2 Grad OstenDer Code für den Tag ist BITCTF{Focke-Wulf Fw 200}Berichte der britischen Marineüberwachung in Ihrer Region. Gehen Sie undercoverWir verfehlen Torpedos. Nur 2 übrig. Senden Sie die Lieferungen sofort
Britische Passagier-Konvoi beschmutzt bei 60 Grad Norden und 15 Grad Westen. Nehmen Sie es sofort06:30, Das Wetter ist heute klar. Regen am AbendAdvance Ihre Einheit 1 Grad Norden und 2 Grad OstenDer Code für den Tag ist BITCTF{Focke-Wulf Fw 200}Berichte der britischen Marineüberwachung in Ihrer Region. Gehen Sie undercoverWir verfehlen Torpedos. Nur 2 übrig. Senden Sie die Lieferungen sofort
Britische Passagier-Konvoi beschmutzt bei 60 Grad Norden und 15 Grad Westen. Nehmen Sie es sofort06:30, Das Wetter ist heute klar. Regen am AbendAdvance Ihre Einheit 1 Grad Norden und 2 Grad OstenDer Code für den Tag ist BITCTF{Focke-Wulf Fw 200}Berichte der britischen Marineüberwachung in Ihrer Region. Gehen Sie undercoverWir verfehlen Torpedos. Nur 2 übrig. Senden Sie die Lieferungen sofort
Britische Passagier-Konvoi beschmutzt bei 60 Grad Norden und 15 Grad Westen. Nehmen Sie es sofort06:30, Das Wetter ist heute klar. Regen am AbendAdvance Ihre Einheit 1 Grad Norden und 2 Grad OstenDer Code für den Tag ist BITCTF{Focke-Wulf Fw 200}Berichte der britischen Marineüberwachung in Ihrer Region. Gehen Sie undercoverWir verfehlen Torpedos. Nur 2 übrig. Senden Sie die Lieferungen sofort
Britische Passagier-Konvoi beschmutzt bei 60 Grad Norden und 15 Grad Westen. Nehmen Sie es sofort06:30, Das Wetter ist heute klar. Regen am AbendAdvance Ihre Einheit 1 Grad Norden und 2 Grad OstenDer Code für den Tag ist BITCTF{Focke-Wulf Fw 200}Berichte der britischen Marineüberwachung in Ihrer Region. Gehen Sie undercoverWir verfehlen Torpedos. Nur 2 übrig. Senden Sie die Lieferungen sofort

In this we find the flag:

BITCTF{Focke-Wulf Fw 200}


Beginner's Luck


This one had an interesting premise, one that is well known and holds a good message to carry on:

Derp just had his first class of cryptography, and he feels really confident about his skills in this field. Can you break his algorithm and get the flag?


The challenge included BITSCTFfullhd.png and enc27.py. Looking at enc27.py we see this:

#!/usr/bin/env python

def supa_encryption(s1, s2):
    res = [chr(0)]*24
    for i in range(len(res)):
        q = ord(s1[i])
        d = ord(s2[i])
        k = q ^ d
        res[i] = chr(k)
    res = ''.join(res)
    return res

def add_pad(msg):
    L = 24 - len(msg)%24
    msg += chr(L)*L
    return msg

with open('fullhd.png','rb') as f:
    data = f.read()

data = add_pad(data)


with open('key.txt') as f:
    key = f.read()
    
enc_data = ''
for i in range(0, len(data), 24):
    enc = supa_encryption(data[i:i+24], key)
    enc_data += enc

with open('BITSCTFfullhd.png', 'wb') as f:
    f.write(enc_data)



Looks like it takes a base image, 'full.png', adds some bytes to the end of the file, does a simple XOR with 'key.txt' and then writes it back out to 'BITSCTFfullhd.png'. So again, similar to the previous challenges, all this is doing is a XOR.

Again on this one, just used the XOR-Cracker online mentioned in the comments:
from pwn import *

# Used https://wiremask.eu/tools/xor-cracker/
key='726b68255150346730263367343640342a256628554e235c'.decode('hex')

srcImg = open('BITSCTFfullhd.png', 'rb').read()
out = open('out.png', 'w')
result = xor(srcImg, key)
print key

out.write(result)


This dropped the png:



BITSCTF{p_en_gee}


Sherlock


This one was the highest points, but ended up being the simplest to solve, this was just a one-liner:

cat final.txt | grep -Eo '[A-Z]' | tr -d '\n' | sed 's/ZERO/0/g;s/ONE/1/g' | perl -lpe '$_=pack"B*",$_'

To explain this a little, the final.txt contained a lot of very normal text, but certain characters were capitalized in a sea of lowercase chars. I forget the name of this exactly, book cipher? This was very quick to recognize, and could be extracted with some grep, tr, sed & perl. The capital letters spelled out binary using words 'ZERO' & 'ONE', which was converted and printed using perl.

BITSCTF{h1d3_1n_pl41n_5173}

Tuesday, September 22, 2015

CSAW 2015 - Crypto [50, 50, 50, 100]

























This was a great CTF!  Ended up solving 15 (CSAW '15) challenges in total, and most of them were in the first hour, but they were also very fun!

The Crypto challenges were interesting, and the first few had a little twist of recent popular media in them.

First, let's go through the 50 pt challenges.  Each one had a filename relating to an episode of Mr. Robot.


eps1.1_ones-and-zer0es.mpeg  (50)

This was the first challenge.  Looking like a forensics challenge almost, the first thing I intuitively did was strings the mpeg, it's a crypto challenge right?
(By the way, I had noticed a few of the challenges last year were solved just by using strings, so I tried that on almost everything I got....  Seemed to work for a couple this year as well!)

$ strings eps1.1_ones-and-zer0es.mpeg
01100110011011000110000101110100011110110101000001100101011011110111000001101100011001010010000001100001011011000111011101100001011110010111001100100000011011010110000101101011011001010010000001110100011010000110010100100000011000100110010101110011011101000010000001100101011110000111000001101100011011110110100101110100011100110010111001111101001000000100100100100111011101100110010100100000011011100110010101110110011001010111001000100000011001100110111101110101011011100110010000100000011010010111010000100000011010000110000101110010011001000010000001110100011011110010000001101000011000010110001101101011001000000110110101101111011100110111010000100000011100000110010101101111011100000110110001100101001011100010000001001001011001100010000001111001011011110111010100100000011011000110100101110011011101000110010101101110001000000111010001101111001000000111010001101000011001010110110100101100001000000111011101100001011101000110001101101000001000000111010001101000011001010110110100101100001000000111010001101000011001010110100101110010001000000111011001110101011011000110111001100101011100100110000101100010011010010110110001101001011101000110100101100101011100110010000001100001011100100110010100100000011011000110100101101011011001010010000001100001001000000110111001100101011011110110111000100000011100110110100101100111011011100010000001110011011000110111001001100101011101110110010101100100001000000110100101101110011101000110111100100000011101000110100001100101011010010111001000100000011010000110010101100001011001000111001100101110

So, just guessing, this is probably a string encoded in binary.  Let's see what it looks like, if it's not, we'll output it to a file.

Found a very simple line to use to convert the binary to string in python: http://stackoverflow.com/questions/7290943/write-a-string-of-1s-and-0s-to-a-binary-file

>>> b = '011001....0101110'  # Abbreviated version of the dump above 
>>> print bytearray(int(b[x:x+8], 2) for x in range(0, len(b), 8))

flat{People always make the best exploits.} I've never found it hard to hack most people. If you listen to them, watch them, their vulnerabilities are like a neon sign screwed into their heads.




eps1.7_wh1ter0se.m4v  (50)

Same idea on this Challenge.  Let's strings the m4v file.

$ strings eps1.7_wh1ter0se.m4v


EOY XF, AY VMU M UKFNY TOY YF UFWHYKAXZ EAZZHN. UFWHYKAXZ ZNMXPHN. UFWHYKAXZ EHMOYACOI. VH'JH EHHX CFTOUHP FX VKMY'U AX CNFXY FC OU. EOY VH KMJHX'Y EHHX IFFQAXZ MY VKMY'U MEFJH OU.

Looks like this one could be a simple caesar or substitution cipher. Tried my usual one-liner in python to find any glaring possible shifts it could be (Similar to this - http://fadec0d3.blogspot.com/2014/04/):
$ python
>>> s = "EOY XF, AY VMU M UKFNY TOY YF UFWHYKAXZ EAZZHN. UFWHYKAXZ ZNMXPHN. UFWHYKAXZ EHMOYACOI. VH'JH EHHX CFTOUHP FX VKMY'U AX CNFXY FC OU. EOY VH KMJHX'Y EHHX IFFQAXZ MY VKMY'U MEFJH OU."
>>> [''.join([chr(ord(x) + n) for x in s]) for n in range(-10, 20)]

Nothing is immediately obvious.
The next part I didn't do in python, just used a service that helps crack substitution ciphers.

http://quipqiup.com/index.php

Rank 1 (looks like it uses a GA to solve it) was the solution:
BUT NO, IT WAS A SHORT CUT TO SOMETHING BIGGER. SOMETHING GRANDER. SOMETHING BEAUTIFUL. WE'VE BEEN FOCUSED ON WHAT'S IN FRONT OF US. BUT WE HAVEN'T BEEN LOOKING AT WHAT'S ABOVE US.



eps1.9_zer0-day.avi  (50)

Again, let's strings the file, see what we get.

$ file eps1.9_zer0-day.avi
eps1.9_zer0-day.avi: ASCII text, with very long lines

$ cat eps1.9_zer0-day.avi

Oh! Base64! Cool.  Looks like it also has newlines in it....

$ python

>>> b = 'RXZpbCBDb3JwLCB3ZSBoYXZlIGRlbGl2ZXJlZCBvbiBvdXIgcHJvbWlzZSBhcyBleHBlY3RlZC4g\nVGhlIHBlb3BsZSBvZiB0aGUgd29ybGQgd2hvIGhhdmUgYmVlbiBlbnNsYXZlZCBieSB5b3UgaGF2\nZSBiZWVuIGZyZWVkLiBZb3VyIGZpbmFuY2lhbCBkYXRhIGhhcyBiZWVuIGRlc3Ryb3llZC4gQW55\nIGF0dGVtcHRzIHRvIHNhbHZhZ2UgaXQgd2lsbCBiZSB1dHRlcmx5IGZ1dGlsZS4gRmFjZSBpdDog\neW91IGhhdmUgYmVlbiBvd25lZC4gV2UgYXQgZnNvY2lldHkgd2lsbCBzbWlsZSBhcyB3ZSB3YXRj\naCB5b3UgYW5kIHlvdXIgZGFyayBzb3VscyBkaWUuIFRoYXQgbWVhbnMgYW55IG1vbmV5IHlvdSBv\nd2UgdGhlc2UgcGlncyBoYXMgYmVlbiBmb3JnaXZlbiBieSB1cywgeW91ciBmcmllbmRzIGF0IGZz\nb2NpZXR5LiBUaGUgbWFya2V0J3Mgb3BlbmluZyBiZWxsIHRoaXMgbW9ybmluZyB3aWxsIGJlIHRo\nZSBmaW5hbCBkZWF0aCBrbmVsbCBvZiBFdmlsIENvcnAuIFdlIGhvcGUgYXMgYSBuZXcgc29jaWV0\neSByaXNlcyBmcm9tIHRoZSBhc2hlcyB0aGF0IHlvdSB3aWxsIGZvcmdlIGEgYmV0dGVyIHdvcmxk\nLiBBIHdvcmxkIHRoYXQgdmFsdWVzIHRoZSBmcmVlIHBlb3BsZSwgYSB3b3JsZCB3aGVyZSBncmVl\nZCBpcyBub3QgZW5jb3VyYWdlZCwgYSB3b3JsZCB0aGF0IGJlbG9uZ3MgdG8gdXMgYWdhaW4sIGEg\nd29ybGQgY2hhbmdlZCBmb3JldmVyLiBBbmQgd2hpbGUgeW91IGRvIHRoYXQsIHJlbWVtYmVyIHRv\nIHJlcGVhdCB0aGVzZSB3b3JkczogImZsYWd7V2UgYXJlIGZzb2NpZXR5LCB3ZSBhcmUgZmluYWxs\neSBmcmVlLCB3ZSBhcmUgZmluYWxseSBhd2FrZSF9Ig=='

b = b.split()  # Split by those newlines

print ''.join([x.decode('base64') for x in b])

Evil Corp, we have delivered on our promise as expected. The people of the world who have been enslaved by you have been freed. Your financial data has been destroyed. Any attempts to salvage it will be utterly futile. Face it: you have been owned. We at fsociety will smile as we watch you and your dark souls die. That means any money you owe these pigs has been forgiven by us, your friends at fsociety. The market's opening bell this morning will be the final death knell of Evil Corp. We hope as a new society rises from the ashes that you will forge a better world. A world that values the free people, a world where greed is not encouraged, a world that belongs to us again, a world changed forever. And while you do that, remember to repeat these words: "flag{We are fsociety, we are finally free, we are finally awake!}"


Flag:
flag{We are fsociety, we are finally free, we are finally awake!}




Notesy  (100)

This was one of those challenges most people were stumped on.  I was stumped on it for a while, and in IRC you could see this as a common subject.

I tried Goatse, Notesy, Alphabetic analysis, and various other ideas.  Even tried a few web / exploitation ideas out in case it was a mix of Crypto + Web.

Finally I got a hint which went along the lines: "It's not too difficult, try one of the first things you input"

Sure enough, that worked!

On any of these interactive Crypto challenges, the first thing I try is the alphabet, also repeating characters and symbols to see what the mapping is between input and output.



This was the Flag:
UNHMAQWZIDYPRCJKBGVSLOETXF