ONNX с секретом
Задача:
Эта «модель» хранит в себе секрет: если в неё подать что-то очень определённое — она ответит строчкой, которую ни с чем не перепутаешь.
Решение
ONNX-модели удобно визуализировать при помощи Netron. Посмотрим в нём на нашу модель:

Во-первых, можно заметить, что у модели 3 входа.
А ещё пройдя через пару cast-ов и relu, эти входы перемножатся и сравнятся с числом 1547.
Если мы провалимся в ветку else (равенство с 1547 не выполняется), то увидим следующее:

Из этой ветки выходит 3 константы, каждая из которых — вектор из ноликов. Вряд ли нас ждёт что-то интересное, если мы будем переходить по этой ветке.
Теперь исследуем then-ветку (выполняется равенство с 1547):

В этой ветке всё схоже с else, но вектора уже не нулевые, а более интересные 🙂
Можем отметить, что из каждого из трёх векторов вычитается свой преобразованный вход. После вычитания все три вектора конкатенируются и отправляются в «ответ» модели:

Теперь разберёмся, как нам попасть в ветку then:

Наши входы проходят через relu, а затем кастуются в int. После этого их произведение сравнивается с числом 1547.
1547 = 7 × 13 × 17
И поскольку наши входы проходили через relu, не стоит подавать во вход, например (-7, -13, 17).
Подадим нашей модели на вход числа 7, 13, 17:
import numpy as np
import onnxruntime as ort
sess = ort.InferenceSession("model.onnx")
inputs = {
"x": np.array(7, dtype=np.int64),
"y": np.array(13, dtype=np.int64),
"z": np.array(17, dtype=np.int64),
}
out = sess.run(None, inputs)[0]
print(out)
# prints
#[112 118 107 113 133 99 89 95 105 97 83 72 89 73 72 72 82 89
# 78 59 77 69 91 63 75 74 67 78 61 80 79 29 29 29 121]
В задании нам обещали строку, а здесь — массив чисел 🤔
Переведём его в строку при помощи chr:
print("".join(chr(c) for c in out))
#pvkq
#cY_iaSHYIHHRYN;ME[?KJCN=POy
Но по условию задания мы должны были получить строку, которую ни с чем не перепутаешь, а здесь мы видим скорее рандом.
Попробуем перебрать порядок, в котором числа 7, 13, 17 будут подаваться в модель:
import itertools
import numpy as np
import onnxruntime as ort
sess = ort.InferenceSession("model.onnx")
inputs = (7, 13, 17)
for x, y, z in itertools.permutations(inputs):
inputs = {
"x": np.array(x, dtype=np.int64),
"y": np.array(y, dtype=np.int64),
"z": np.array(z, dtype=np.int64),
}
out = sess.run(None, inputs)[0]
print("".join(chr(c) for c in out))
# prints:
#pvkq
#cY_iaSHYIHHRYN;ME[?KJCN=POy
#pvkq
#cY_iaSDUEDDNUJ7IA_CONGRATS!!!}
#jpek]SYc[MN_ONNX_TASK[?KJCN=POy
#jpek]SYc[MDUEDDNUJ7IAeIUTMXGZY'''
#flag{YOU_WIN_ONNX_TASK_CONGRATS!!!}
#flag{YOU_WIHYIHHRYN;MEeIUTMXGZY'''
Несложно заметить строчку flag{YOU_WIN_ONNX_TASK_CONGRATS!!!}, которая и является решением.