Единороги заняли на этом соревновании пятое место среди тридцати команд
reverse, 100 баллов > Wrong!!!
I think there's something wrong with this program. @dyisshysvsys
Перед нами .Net. Открываем в DNSpy, любуемся функцией:
Ставим брейкпоинт на 15 строке, запускаемся
На скрине я уже сменил false
на true
.
reverse, 200 баллов > Try now
Flag is passphrase. GO! @dyisshysvsys
Нам предоставляют два файла: Rev200.exe и task.png
Снова .Net. Состоит из двух классов – Program
и CRYPTED
Класс Program
Нас просят ввести пароль, который вместе с солью и ключом передаются в экземпляр класса CRYPTED. Затем идет сравнение с b64 строкой.
Посмотрим на второй файл задания: это скрин с представлением успешной работы программы. Там закрашена вводимая строка, но видны дата и время запуска – 09.10.2019 10:23. Время не обязательно будет ровно таким же, какое использовалось для ключа и соли, это стоит учесть. Ключ и соль имеют одинаковое значение (шанс того, что в генерация произойдет на 59-ю секунду так, что в соль упадет новая минута, достаточно мал) в виде b64 будут выглядеть так: MTAuMjMuMDkuMTAuMjAxOQ
(10.23.09.10.2019
)
Второй класс является оберткой над RijndaelManaged (имплементация AES в .Net) с длиной ключа 128 бит, режимом CBC. Помимо конструктора, доступны следующие методы:
EncryptToByte
EncryptToBase64String
, обертка надEncryptoToByte
GetKey
GetIV
ToString
Код EncryptToByte:
public byte[] EncryptToByte(string plain)
{
ICryptoTransform cryptoTransform = CRYPTED.rijndael.CreateEncryptor();
byte[] bytes = CRYPTED.unicodeEncoding.GetBytes(plain);
return cryptoTransform.TransformFinalBlock(bytes, 0, bytes.Length);
}
Код конструктора (доступны три перегруженных конструктора, взял один из них):
public CRYPTED(string base64key, string base64iv)
{
this.InitializeRijndael();
CRYPTED.rijndael.Key = Convert.FromBase64String(base64key);
CRYPTED.rijndael.IV = Convert.FromBase64String(base64iv);
}
У нас есть шифротекст, вектор инициализации и ключ, а также знания об используемом шифровании. Вот самые простые варианты по расшифровке, что приходят в голову:
- Онлайн сервис (cyberchef)
- Написать программу на шарпах
- Изменить через DNSpy исходники, чтобы не открывать среду разработки.
Решим через cyberchef:
Строки wide-формата, можно воспользоваться Find / Replace для устранения недостатка
reverse, 300 баллов > Bot
We have created the best calculator. Probably.....
@calculator_kubanctf_bot
Дан телеграм-бот Моя выдержка из общения с ним:
Я, [15.10.19 11:52]
/start
Сalculator_KubanCTF, [15.10.19 11:52]
try now
Я, [15.10.19 11:52]
123
Сalculator_KubanCTF, [15.10.19 11:52]
123
Я, [15.10.19 11:52]
1+2
Сalculator_KubanCTF, [15.10.19 11:52]
3
Я, [15.10.19 11:52]
-23
Сalculator_KubanCTF, [15.10.19 11:52]
-23
Я, [15.10.19 11:52]
a + 3
Сalculator_KubanCTF, [15.10.19 11:52]
try now
Я, [15.10.19 11:52]
a = 4
Сalculator_KubanCTF, [15.10.19 11:52]
try now
Я, [15.10.19 11:52]
//
Сalculator_KubanCTF, [15.10.19 11:52]
try now
Я, [15.10.19 11:52]
exit()
Я, [15.10.19 11:52]
/start
Сalculator_KubanCTF, [15.10.19 11:52]
try now
Я, [15.10.19 11:52]
import os
Сalculator_KubanCTF, [15.10.19 11:52]
123
Я, [15.10.19 11:52]
import os
Сalculator_KubanCTF, [15.10.19 11:52]
don't hack pls
Я, [15.10.19 11:52]
globals()[::]
Сalculator_KubanCTF, [15.10.19 11:52]
__name__
Я, [15.10.19 11:53]
(1,2,3)[2]
Сalculator_KubanCTF, [15.10.19 11:53]
try now
Я, [15.10.19 11:53]
(1,2,3)[2]
Сalculator_KubanCTF, [15.10.19 11:53]
3
Я, [15.10.19 11:53]
import
Сalculator_KubanCTF, [15.10.19 11:53]
try now
Я, [15.10.19 11:53]
eval("import os") and 1
Сalculator_KubanCTF, [15.10.19 11:53]
don't hack pls
Я, [15.10.19 11:54]
eval("import os") and 1
Сalculator_KubanCTF, [15.10.19 11:54]
don't hack pls
Я, [15.10.19 11:54]
str(globals())
Сalculator_KubanCTF, [15.10.19 11:54]
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x7f6f37b84d68>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': '/home/ubuntu/reverse/v1.py', '__cached__': None, 'telebot': <module 'telebot' from '/home/ubuntu/python-virtual-environments/env/lib/python3.6/site-packages/telebot/__init__.py'>, 'os': <module 'os' from '/usr/lib/python3.6/os.py'>, 'apihelper': <module 'telebot.apihelper' from '/home/ubuntu/python-virtual-environments/env/lib/python3.6/site-packages/telebot/apihelper.py'>, 'acos': <built-in function acos>, 'acosh': <built-in function acosh>, 'asin': <built-in function asin>, 'asinh': <built-in function asinh>, 'atan': <built-in function atan>, 'atan2': <built-in function atan2>, 'atanh': <built-in function atanh>, 'ceil': <built-in function ceil>, 'copysign': <built-in function copysign>, 'cos': <built-in function cos>, 'cosh': <built-in function cosh>, 'degrees': <built-in function degrees>, 'erf': <built-in function erf>, 'erfc': <built-in function erfc>, 'exp': <built-in function exp>, 'expm1': <built-in function expm1>, 'fabs': <built-in function fabs>, 'factorial': <built-in function factorial>, 'floor': <built-in function floor>, 'fmod': <built-in function fmod>, 'frexp': <built-in function frexp>, 'fsum': <built-in function fsum>, 'gamma': <built-in function gamma>, 'gcd': <built-in function gcd>, 'hypot': <built-in function hypot>, 'isclose': <built-in function isclose>, 'isfinite': <built-in function isfinite>, 'isinf': <built-in function isinf>, 'isnan': <built-in function isnan>, 'ldexp': <built-in function ldexp>, 'lgamma': <built-in function lgamma>, 'log': <built-in function log>, 'log1p': <built-in function log1p>, 'log10': <built-in function log10>, 'log2': <built-in function log2>, 'modf': <built-in function modf>, 'pow': <built-in function pow>, 'radians': <built-in function radians>, 'sin': <built-in function sin>, 'sinh': <built-in function sinh>, 'sqrt': <built-in function sqrt>, 'tan': <built-in function tan>, 'tanh': <built-in function tanh>, 'trunc': <built-in function trunc>, 'pi': 3.141592653589793, 'e': 2.718281828459045, 'tau': 6.283185307179586, 'inf': inf, 'nan': nan, 'bot': <telebot.TeleBot object at 0x7f6f37ae2cc0>, 'get_text_messages': <function get_text_messages at 0x7f6f37ad92f0>, '__warningregistry__': {'version': 6, ("unclosed file <_io.TextIOWrapper name='flaghere/flag.txt' mode='r' encoding='UTF-8'>", <class 'ResourceWarning'>, 1): True}}
Я, [15.10.19 11:57]
str(open("flaghere/flag.txt", "r").read())
Сalculator_KubanCTF, [15.10.19 11:57]
flag{c@lculator_was_h@cked}
reverse, 500 баллов > neural_hack
neural_hack :)
Дан архив. Нам предоставляют обученную нейронку, которая делает для картинки 75x1010 суждение о том, насколько она похожа на исходную картинку. В определенный момент орги, заметив, что таск никто не решил, выложили хинт, но это никому не помогло.
Моё решение, занявшее ~22 часа работы ноутбука, заключается в расставлении черных и белых точек, вычислении дельты и сохранении текущего результата, если он признан более хорошим.
Если открыть эти картинки в image viewer’е и поперемещаться между ними, можно прочитать текст.
Флаг: kubanctf{best_network_hack}
Главная часть кода:
import time
l1_stored = tf.reduce_sum(tf.square(image_array - flag_array))
x = 1010
y = 75
display(imafile)
###
#imafile = Image.open('flag.png')
#imafile = old_image.copy()
###
current_image = imafile.copy()
last = 1322713.5
while 1:
draw = ImageDraw.Draw(imafile)
for i in range(4):
ranx = randint(0, x)
rany = randint(0, y)
color = choice(["white", "black"])
draw.rectangle(((ranx, rany), (ranx, rany)), fill=color)
image = np.array(imafile)[np.newaxis, :, :, :3] / 255
image_array = model(image)
l1_error = tf.reduce_sum(tf.square(image_array - flag_array))
#print("l1:", l1_error)
#display(imafile)
if l1_error< l1_stored:
l1_stored = l1_error
current_image = imafile.copy()
clear_output()
display(imafile)
print("l1:", l1_error)
print("div:", l1_error/1322713.5)
else:
imafile = current_image.copy()
Тетрадь Юпитера с решением можно посмотреть здесь
author: Rakovsky Stanislav, Unicorn CTF
editor: Anna Mazurkevich, MPEI CTF