Попался на глаза интересный челлендж http://www.flare-on.com/
Хоть он и закончился. Решил пройти.
Первое задание.
Дано
файл: i_am_happy_you_are_to_playing_the_flareon_challenge.exe
размер: 1546 байт
Не упакован.
При запуске просит ввести пароль.
Let's start out easy
Enter the password>
На неправильный пароль выдает: You are failure
Посмотрим что внутри:
Введенные данные сохраняются в переменную byte_402158
push ebp
mov ebp, esp
sub esp, 10h
mov [ebp+var_10], eax
push 0FFFFFFF6h ; nStdHandle
call GetStdHandle
mov [ebp+var_C], eax
push 0FFFFFFF5h ; nStdHandle
call GetStdHandle
mov [ebp+hFile], eax
push 0 ; lpOverlapped
lea eax, [ebp+NumberOfBytesWritten]
push eax ; lpNumberOfBytesWritten
push 2Ah ; nNumberOfBytesToWrite
push offset aLetSStartOutEa ; "Let's start out easy\r\nEnter the passw"...
push [ebp+hFile] ; hFile
call WriteFile
push 0 ; lpOverlapped
lea eax, [ebp+NumberOfBytesWritten]
push eax ; lpNumberOfBytesRead
push 32h ; nNumberOfBytesToRead
push offset byte_402158 ; lpBuffer
push [ebp+var_C] ; hFile
call ReadFile
xor ecx, ecx
И вот собственно весь алгоритм валидации:
loc_40104D:
mov al, byte_402158[ecx]
xor al, 7Dh
cmp al, byte_402140[ecx]
jnz short loc_40107B
inc ecx
cmp ecx, 18h
jl short loc_40104D
Цикл xor-ит введенные данные, числом 0x7D, и сравнивает со статическим буфером.
Посмотрим, что там в буфере:
0x1F, 0x08, 0x13, 0x13, 0x04, 0x22, 0x0E, 0x11,
0x4D, 0x0D, 0x18, 0x3D, 0x1B, 0x11, 0x1C, 0x0F,
0x18, 0x50, 0x12, 0x13, 0x53, 0x1E, 0x12, 0x10
На С++ это задание можно представить так:
#include <iostream>
#include <string>
#include <vector>
int main()
{
std::vector<char> secret = {
0x1F, 0x08, 0x13, 0x13, 0x04, 0x22, 0x0E, 0x11,
0x4D, 0x0D, 0x18, 0x3D, 0x1B, 0x11, 0x1C, 0x0F,
0x18, 0x50, 0x12, 0x13, 0x53, 0x1E, 0x12, 0x10
};
std::string success{ "You are success" };
std::string failure{ "You are failure" };
std::cout << "Let's start out easy" << std::endl;
std::cout << " Enter the password>";
std::string pass;
std::cin >> pass;
for (int i = 0; i < 24; ++i)
{
if (secret[i] != (pass[i] ^ 0x7D))
{
std::cout << failure << std::endl;
return 0;
}
}
std::cout << success << std::endl;
return 0;
}
Решение:
Пропустим исходный буфер через xor:
buf = [ 0x1F, 0x08, 0x13, 0x13, 0x04, 0x22, 0x0E, 0x11,
0x4D, 0x0D, 0x18, 0x3D, 0x1B, 0x11, 0x1C, 0x0F,
0x18, 0x50, 0x12, 0x13, 0x53, 0x1E, 0x12, 0x10]
for ch in buf:
print(chr(ch^0x7D), end='')
print()
bunny_sl0pe@flare-on.com
Вероятно, нужно было отправить сюда e-main, и в ответ пришло бы 2-е задание, но так как челлендж уже закончился, все задания скачиваются одним архивом.
Первое задание было оооочень простым, посмотрим что со втором (я уже глянул, там тоже все просто, но немного посложнее), продолжение следует...
Код на GitHub
Код на GitHub