Ghost in the Shellcode CTF 2014 (Dogecrypt)

Решения

http://digitaloperatives.blogspot.ru/2014/01/ghost-in-shellcode-2014-crypto-75.html (Dugie)
http://commandlinewani.blogspot.ru/2014/01/ghostintheshellcode-write-up-dogecrypt.html (Nehal J. Wani)
http://ddaa.logdown.com/posts/176606-gits-2014-crypto-dogecrypt (chengtc)
http://insertco.in/2014/01/19/dogecrypt-gits-2014/ (insertCoin)
Назад к списку заданий

Задание (crypto)

Question 4 - Dogecrypt
Points: 75
Wow such crypto Very download so xz

Подробное описание

Качаем бинарный файл. Первые 12 байт содержат сигнатуру "VimCrypt~01!". Погуглив, выясняем, что редактор Vim может выполнять шифрование текста при его записи с ключом "-x". Значение "01" в сигнатуре обозначает вариант шифрования PKZIP (если бы было "02", то использовался бы алгоритм BlowFish). Т.к. пароль нам не известен, то без брутфорса не обойтись.

Сначала посмотрим на алгоритм шифрования в vim74/src/misc2.c. Преобразуем его в код на Питоне:

keys = []
crc_32_tab = []
 
def CRC32(c, b):
    return crc_32_tab[(c ^ b) & 0xff] ^ (c >> 8)
 
def make_crc_tab():
    for i in range(256):
        v = i
        for s in range(8):
            v = (v >> 1) ^ ((v & 1) * 0xEDB88320)
        crc_32_tab.append(v)
 
def UPDATE_KEYS_ZIP(c):
    keys[0] = CRC32(keys[0], c)
    keys[1] += (keys[0] & 0xFF)
    keys[1] = (keys[1] * 134775813L + 1) & 0xFFFFFFFF
    keys[2] = CRC32(keys[2], (keys[1] >> 24) & 0xFF)
 
# Initialize the encryption keys and the random header according to
# the given password.
# If "passwd" is NULL or empty, don't do anything.
def crypt_init_keys(passwd):
    if passwd != "":
        make_crc_tab()
        keys.append(0x12345678)
        keys.append(0x23456789)
        keys.append(0x34567890)
        for i in passwd:
            UPDATE_KEYS_ZIP(ord(i))
 
# Decrypt "ptr[len]" in place.
def crypt_decode(ptr):
    res = ""
    for i in range(len(ptr)):
        temp = 0xFFFF & (keys[2] | 2)
        temp = (((temp * (temp ^ 1)) >> 8) & 0xff)
        res += chr(ord(ptr[i]) ^ temp)
        UPDATE_KEYS_ZIP(ord(ptr[i]) ^ temp)
 
    return res
 
# Initialize the encryption keys
#crypt_init_keys("some password")
 
# Read crypted data
#f = open("dogecrypt", "rb")
#data = f.read()
#f.close()
 
# Decrypt
#if data[:12] == "VimCrypt~01!":
#   data = data[12:]
#    res = crypt_decode(data)
 
# Write decrypted data
#f = open("_dogecrypt", "wb")
#f.write(res)
#f.close()

Теперь надо определится со словарем для перебора ключей. Как раз кстати, подошла подсказка от организаторов соревнования: "Solveable in <5m. Much attack very wamerican-small". Пакет "wamerican-small" представляет собой английский словарь американского диалекта, при загрузке располагающегося по адресу "/usr/share/dict/american-english-small" (стандартный путь при загрузке пакета "wamerican-small" в Linux системах).
Или качаем отсюда: http://trac.chxo.com/browser/widgets/www/wordkey/american-english-small

… Запускаем процесс перебора паролей по словарю. Ожидаем получить после расшифровки текстовой файл …

В результате перебора получили пароль для зашифрованного файла: parliament
В первой строке файла находится искомый ключ.

...
crypt_init_keys("parliament")
 
f = open("dogecrypt", "rb")
data = f.read()
f.close()
 
if data[:12] == "VimCrypt~01!":
    data = data[12:]
    res = crypt_decode(data)
 
f = open("parliament.txt", "wb")
f.write(res)
f.close()

В первой строке файла находится искомый ключ.
The key is: ShibeSuchDictionaryAttacksWow

Пока не указано иное, содержимое этой страницы распространяется по лицензии Creative Commons Attribution-ShareAlike 3.0 License