Прежде всего, хочу подчеркнуть два ключевых момента:
1. Если вы не математик, для успешного выполнения задания вам потребуется уверенное владение языком программирования Python. Надеюсь, это понятно.
2. В процессе выполнения задания крайне важно не разрывать соединение с сервером, иначе придется начинать работу заново.
Подключаемся к серверу:
После подключения мы получим значения N, e_1 и e_2. Скопируйте их куда-нибудь — они понадобятся позже.
В большинстве случаев, когда речь идет о RSA, мы сталкиваемся с реализацией этого алгоритма, имеющей определенные уязвимости. В данном случае уязвимость заключается в использовании двух экспонент e_1 и e_2 вместо одной e. Это "нововведение" сразу же наводит на мысль о возможности Common Modulus Attack. Я не буду углубляться в детали атаки, большинству читателей это вряд ли интересно — они пришли сюда за разбором задачи, с которой возникли трудности.
Внимательно изучив скрипт, предоставленный автором таска, мы сможем понять логику работы сервера: одно и то же сообщение шифруется сначала с использованием экспоненты e_1 и модуля N, а затем с использованием экспоненты e_2 и того же модуля N. В результате мы получаем два различных шифртекста c1 и c2. Это серьезная уязвимость, и в рамках CTF мы еще не раз столкнемся с подобными задачами.
Возвращаемся к серверу. Действия [1] и [2] можно игнорировать, так как они не понадобятся для решения задачи. Выбираем действие [4]. Сервер предоставит нам два шифртекста, каждый из которых представляет собой сообщение, зашифрованное с использованием одного и того же модуля, но разных экспонент. Думаю, вы уже догадались, что эти шифртексты подвержены Common Modulus Attack. Давайте обозначим первый шифртекст как c1, а второй — как c2. Однако шифртексты представлены в шестнадцатеричном формате. Поэтому прежде чем мы сможем с ними работать, необходимо преобразовать их из шестнадцатеричного формата в десятичный. Сделаем это с помощью Python:
Теперь воспользуемся скриптом, который поможет нам расшифровать ключ:
Если на вашем компьютере не установлена библиотека libnum, вам необходимо сначала ее установить с помощью следующей команды:
После выполнения скрипта вы получите расшифрованный ключ. Разумеется, ключ я вам не покажу, чтобы вы могли самостоятельно выполнить задачу и, таким образом, получить новые знания.
Теперь вернемся к серверу и выберем действие [3]. Введите расшифрованный ключ, и сервер предоставит вам флаг.
1. Если вы не математик, для успешного выполнения задания вам потребуется уверенное владение языком программирования Python. Надеюсь, это понятно.
2. В процессе выполнения задания крайне важно не разрывать соединение с сервером, иначе придется начинать работу заново.
Подключаемся к серверу:
Bash:
nc 62.173.140.174 11002
После подключения мы получим значения N, e_1 и e_2. Скопируйте их куда-нибудь — они понадобятся позже.
В большинстве случаев, когда речь идет о RSA, мы сталкиваемся с реализацией этого алгоритма, имеющей определенные уязвимости. В данном случае уязвимость заключается в использовании двух экспонент e_1 и e_2 вместо одной e. Это "нововведение" сразу же наводит на мысль о возможности Common Modulus Attack. Я не буду углубляться в детали атаки, большинству читателей это вряд ли интересно — они пришли сюда за разбором задачи, с которой возникли трудности.
Внимательно изучив скрипт, предоставленный автором таска, мы сможем понять логику работы сервера: одно и то же сообщение шифруется сначала с использованием экспоненты e_1 и модуля N, а затем с использованием экспоненты e_2 и того же модуля N. В результате мы получаем два различных шифртекста c1 и c2. Это серьезная уязвимость, и в рамках CTF мы еще не раз столкнемся с подобными задачами.
Возвращаемся к серверу. Действия [1] и [2] можно игнорировать, так как они не понадобятся для решения задачи. Выбираем действие [4]. Сервер предоставит нам два шифртекста, каждый из которых представляет собой сообщение, зашифрованное с использованием одного и того же модуля, но разных экспонент. Думаю, вы уже догадались, что эти шифртексты подвержены Common Modulus Attack. Давайте обозначим первый шифртекст как c1, а второй — как c2. Однако шифртексты представлены в шестнадцатеричном формате. Поэтому прежде чем мы сможем с ними работать, необходимо преобразовать их из шестнадцатеричного формата в десятичный. Сделаем это с помощью Python:
Python:
c1_hex = '43e2b4c84aff770b7388499cc2af2535655de75aa333b5e97fbe1f45b626c9d5b09901a5863ff2da652018058a9e87110b721c40593ac4d36ccdf1b3933d5dd2'
c1 = int(c1_hex, 16)
c2_hex = '55e70b7b592aa36ec9a7d61e4bd7930d590447cc1a243f2aeba2ff132e42bd8dcc1a4fdfef8659ed5f9aa96724290f2cdc80a6e353849b3d51c1524b071cea34'
c2 = int(c2_hex, 16)
Теперь воспользуемся скриптом, который поможет нам расшифровать ключ:
Python:
from libnum import *
def common_modulus(e1, e2, c1, c2, N):
a, b, d = xgcd(e1, e2)
if b < 0:
c2 = invmod(c2, N)
b = -b
if a < 0:
c1 = invmod(c1, N)
a = -a
m = (pow(c1, a, N) * pow(c2, b, N)) % N
return [m, a, b, d]
def pad(m, d, i, N):
if -d * 4 * i < 0:
f = pow(invmod(2, N), d * 4 * i, N)
else:
f = pow(2, -d * 4 * i, N)
return m * f % N
N = # здесь укажите значение N
e_1 = # здесь укажите значение e_1
c1 = # здесь укажите значение c1
e_2 = # здесь укажите значение e_2
c2 = # здесь укажите значение c2
m, _, _, _ = common_modulus(e_1, e_2, c1, c2, N)
plaintext = n2s(m)
print(plaintext.decode())
Если на вашем компьютере не установлена библиотека libnum, вам необходимо сначала ее установить с помощью следующей команды:
Bash:
pip install libnum
После выполнения скрипта вы получите расшифрованный ключ. Разумеется, ключ я вам не покажу, чтобы вы могли самостоятельно выполнить задачу и, таким образом, получить новые знания.
Теперь вернемся к серверу и выберем действие [3]. Введите расшифрованный ключ, и сервер предоставит вам флаг.