3

Я работаю над игрой в ctf:

Зашифровано с помощью AES в режиме ECB. Все значения base64 закодированы

ciphertext = 8LBUVZfDfI6wnggG1uUYuQsRoGd08pGwHCN++R5rabMW9PJmWHWcSrjy5Tfffj6L
key = 3q1FxGhuZ5fQYbjzDxgQ35==

Я попытался расшифровать его в своем терминале, оставив зашифрованный текст в base64 и используя флаг -base64 , но безуспешно . Затем я пошел на http://extranet.cryptomathic.com/aescalc , где после преобразования значений в шестнадцатеричные я смог расшифровать:

key: DEAD45C4686E6797D061B8F30F1810DF 
text: F0B0545597C37C8EB09E0806D6E518B90B11A06774F291B01C237EF91E6B69B316F4F26658759C4AB8F2E537DF7E3E8B
out: 7B796F755F73686F756C645F6E6F745F706F73745F7468655F61637475616C5F6374665F76616C75657D5F5F5F5F5F5F

Затем я вернулся в свой терминал, пытаясь:

echo -n F0B0545597C37C8EB09E0806D6E518B90B11A06774F291B01C237EF91E6B69B316F4F26658759C4AB8F2E537DF7E3E8B | openssl enc -d -K DEAD45C4686E6797D061B8F30F1810DF -aes-128-ecb -nosalt

но я получил ту же ошибку:

bad decrypt
140735124906848:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:evp_enc.c:531:

Я пробовал это на Ubuntu 17.04, а теперь на моем MacOSX с использованием OpenSSL 1.0.2l. Почему я не могу расшифровать в моем собственном терминале?

3 ответа3

5

Поскольку openssl по умолчанию использует заполнение PKCS # 7, а ваш открытый текст не содержит заполнение PKCS # 7. Если ваш открытый текст был дополнен, то он был дополнен байтами значения 5F . Вместо этого используйте опцию -nopad , заполнение со значением 5F не является какой-либо схемой заполнения, известной мне; если это необходимо удалить, вам нужно будет удалить его самостоятельно.

В настоящее время вы показываете ввод в шестнадцатеричном формате. Шестнадцатеричное - это представление байтов, а не сами значения байтов. Вам нужно либо напрямую ввести исходный материал из файла, используя < для вашего файла, либо путем шестнадцатеричного декодирования ввода.

Выход также будет двоичным; это не будет представлять любой читаемый открытый текст. Поэтому вам может потребоваться преобразовать вывод в шестнадцатеричные числа, прежде чем сравнивать его со значениями в вашем вопросе.

3

Ну, вы можете рассмотреть возможность использования Python или любого другого языка сценариев / программирования для таких вещей.

Преимущества выполнения этого программно:

  • Всякий раз, когда вам нужно будет повторить что-то подобное, ваш код будет готов.
  • Вы можете написать комментарии, чтобы объяснить, что происходит, поэтому, если вам когда-нибудь понадобится понять, что вы делали ранее, надеюсь, код и комментарии позволят вам это сделать.
  • Многие вещи, такие как кодирование, обработка байтов и т.д., Проще, чем в консоли
  • Большинство языков являются кроссплатформенными, поэтому они легко будут работать в Windows, Linux, Android, если вы когда-нибудь переключите свое устройство.

Что касается вашей проблемы, она может быть решена с помощью Python, чтобы сделать все:

# we import the function we need from common librairies
from base64 import b64decode
from Crypto.Cipher import AES
from binascii import hexlify, unhexlify


# First we decode the message and the key from base64 into bytes:
msg = b64decode("8LBUVZfDfI6wnggG1uUYuQsRoGd08pGwHCN++R5rabMW9PJmWHWcSrjy5Tfffj6L")
key = b64decode("3q1FxGhuZ5fQYbjzDxgQ35==")

# We then instantiate a cipher_suite using AES with the provided key, in ECB mode
cipher_suite = AES.new(key, AES.MODE_ECB)

# We can decrypt the message using our cipher_suite:
recovered = cipher_suite.decrypt(msg)

# We can print it:
print ("plaintext: ", recovered)

# There is some garbage at the end, but if we display it in hexadecimal form:
print ("in hex:", hexlify(recovered))
# We can see it's just padding using '5f', so let's create a function to remove such padding:
def unpad(padded):
  # we declare the value of our padding:
  paddingByte = unhexlify('5f')
  # we do a loop, while the last byte is padding
  while padded[-1:]==paddingByte:
    # we remove the last byte
    padded = padded[:-1]
  # once it's done, we return
  return padded

# We can now use our function to remove padding:
print ("unpadded: ", unpad(recovered))

Теперь, если вы не хотите изучать Python или любой другой язык и / или если вы действительно хотите делать все это в своем терминале, это также возможно: тогда вы можете делать все напрямую, используя каналы для передачи данных из одного команду другому, команду подстановки для подачи правого ключа в openssl и команды base64 для обработки base64 плюс xxd для преобразования двоичных данных в шестнадцатеричные (для ключа в openssl) и, наконец, для удаления отступа sed используйте 5f :

echo "8LBUVZfDfI6wnggG1uUYuQsRoGd08pGwHCN++R5rabMW9PJmWHWcSrjy5Tfffj6L" | base64 --decode | openssl enc -d -K $(echo "3q1FxGhuZ5fQYbjzDxgQ35==" | base64 --decode | xxd  -c 16 -ps) -aes-128-ecb -nosalt -nopad | sed 's/_*$//g'

Я не знаю почему, но лично я считаю, что подход к Python чище.


Вы также упомянули, что получили мусор, как указал вам Мартен Бодьюс, это связано с тем, что вы подаете шестнадцатеричные значения в OpenSSL, в то время как вы должны предоставить двоичные данные (а не шестнадцатеричное значение) для сообщения, пока вы должен предоставить ключ в шестнадцатеричном виде:

echo -n f0b0545597c37c8eb09e0806d6e518b90b11a06774f291b01c237ef91e6b69b316f4f26658759c4ab8f2e537df7e3e8b | xxd -r -p | openssl ...

PS: вам, вероятно, следует избегать публикации фактических значений, с которыми вы сталкиваетесь в CTF, так как это может испортить игру людям, чей первый рефлекс - поиск значений в Google.

2

декодировать base64

echo 8LBUVZfDfI6wnggG1uUYuQsRoGd08pGwHCN++R5rabMW9PJmWHWcSrjy5Tfffj6L | base64 -D > aesdata.dat

(-D - это особенность Mac OS. Linux обычно использует -d или --decode ).

Так же:

echo 3q1FxGhuZ5fQYbjzDxgQ35== | base64 -D > aeskey.dat

но openssl ожидает шестнадцатеричные значения в параметрах (но двоичные в зашифрованных файлах):

xxd -p < aeskey.dat выдает dead45c4686e6797d061b8f30f1810df . Или по каналу из предыдущей команды, если вы хотите избежать беспорядка.

В заключение:

openssl enc -d -nopad -aes-128-ecb -K dead45c4686e6797d061b8f30f1810df -in aesdata.dat -out plain

расшифрую это. -Nopad позволяет избежать ошибки дешифрования, так как используется нестандартное заполнение.

Теперь hd plain чтобы проверить результат, который действительно то, что вы искали.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .