Нужно найти флаг из 10 чисел.
Solution
Закину бинарь в бинжу, чтобы начался его анализ, а сам в это время посмотрю строки в файле с помощью strings:
UWVS
t$,U
^L[^_]
Correct!
Wrong!
;*2$"$
GCC: (GNU) 6.1.1 20160802
GCC: (GNU) 6.3.1 20170109
Чего-то очень интересного нет. Но Correct! и Wrong! стоит проверить) Они находятся прямо в функции main. Не всегда все так очевидно.
int32_t main(int32_t argc, char** argv, char** envp)
void* const __return_addr_1 = __return_addr
int32_t* var_10 = &argc
void s
__builtin_memset(&s, c: 0, n: 0x28)
mapM_(int_read, 0xa, &s)
mapM_(int_print, 0xa, &s)
putchar(c: 0xa)
if (int_foldl1(xor, 0xa, &s) != 0 || int_foldl(and, 1, 0xa, &s) == 0)
puts(str: "Wrong!")
else
puts(str: "Correct!")
return 0
Выглядит не очень понятно. Поэтому попробую запустить его:
root@af1dc1924b47:/rev# ./crackme1
12
22
33
11
11
11
11
11
11
11
12 22 33 11 11 11 11 11 11 11
Wrong!
Значит бинарь считывает 10 чисел с клавиатуры, а далее проверяет их корректность в int_fold1.
int_foldl1:
int32_t int_foldl1(int32_t* func, int32_t count, int32_t* key)
return int_foldl(func, pos: 0, len: count, key)
int_foldl:
int32_t int_foldl(int32_t* func, int32_t pos, int32_t len, int32_t* key)
if (len == 0)
return pos
return int_foldl(func, pos: func(pos, *key), len: len - 1, key: &key[1])
Давайте разберем. Функция int_foldl1 является вызывающей для int_foldl, которая задает pos в 0. Условие проверки мы видели.
В качестве проверки у нас используются логические функции xor и and.
xor:
int32_t xor(int32_t arg1, int32_t arg2) __pure
{
return (arg1 ^ arg2);
}
and:
int32_t and(int32_t arg1, int32_t arg2) __pure
{
if ((arg1 != 0 && arg2 != 0))
return 1;
return 0;
}
В отладчике я сидеть не хочу, поэтому накидаю код на python:
def xor_test(nums: int):
key = 0
for n in nums:
key ^= n
print(key)
return key
def and_test(nums: int):
key = 1
for n in nums:
if key != 0 and n != 0:
key = 1
else:
key = 0
return key
nums = []
if xor_test(nums) != 0 or and_test(nums) == 0:
print('Wrong')
else:
print('Correct')
Теперь нужно подобрать правильный список из 10 чисел, чтобы у нас выполнилось условие проверки. В целом, это не должно быть сложно. Так как чисел у нас 10, то мы легко может пройти проверку xor - нужно передавать пары одинаковых чисел. Для прохождения проверки AND нам нужно, чтобы у нас не было 0. Это тоже легко. Сильно голову ломать не буду, подставлю 10 единиц:
cu63:crackme1/ $ python test.py
1
0
Correct
Проверю на оригинальном бинаре:

Это строка и является флагом.