DefCon42 Posted August 16, 2019 Posted August 16, 2019 People who patch this instead of trying to find the key are boring :^) Language : C++ Platform : Windows x64 OS Version : Windows 10 Packer / Protector : None Description : This is a simple crackme i made over the course of the last 30 minutes. Hopefully you get a little fun out of it. Screenshot : crackme.exe
VirtualPuppet Posted August 16, 2019 Posted August 16, 2019 (edited) There are many working keys. One of them is "$^CQE!#(Mrfe%&&$": The key was brute forced using a quickly written C++ executable: The code for the C++ executable is as follows: Spoiler #include <iostream> #include <stdint.h> #include <array> #include <functional> bool isallowed(char c) { return (c != '"' && c != ' '); } bool check_keys(double additive_key, char k0, char k1, char k2, char k3) { double product = additive_key + (static_cast<double>(k3) * 0.2254315957569856) + (static_cast<double>(k2) * -0.06225786672735933) + (static_cast<double>(k1) * 0.06576137583312501) + (static_cast<double>(k0) * -0.2174719016579794) + 0.0; return (product > 0.00001 || product < -0.00001); } bool bruteforce(std::array<char, 16>& key, std::array<int, 4> indices, double additive_key) { for (int a = 0; a < 256; a++) { for (int b = 0; b < 256; b++) { for (int c = 0; c < 256; c++) { for (int d = 0; d < 256; d++) { if (isallowed(a) && isallowed(b) && isallowed(c) && isallowed(d)) { if (!check_keys(additive_key, a, b, c, d) && isprint(a) && isprint(b) && isprint(c) && isprint(d)) { std::cout << "Found partial key match!" << std::endl << "a = " << a << "('" << static_cast<char>(a) << "')" << std::endl << "b = " << b << "('" << static_cast<char>(b) << "')" << std::endl << "c = " << c << "('" << static_cast<char>(c) << "')" << std::endl << "d = " << d << "('" << static_cast<char>(d) << "')" << std::endl << std::endl; key[indices[0]] = a; key[indices[1]] = b; key[indices[2]] = c; key[indices[3]] = d; return true; } } } } } } std::cout << "Could not bruteforce the selected keypart!" << std::endl; return false; } void printkey(std::array<char, 16> const& key) { std::cout << "Current key:" << std::endl; for (char const& ch : key) { if (ch == 0) std::cout << "_"; else std::cout << ch; } std::cout << std::endl; std::cout << std::endl; } int main(int argc, char* argv[]) { std::array<char, 16> key = { 0 }; printkey(key); if (bruteforce(key, std::array<int, 4> {{ 0, 4, 8, 12 }}, -0.255666)) printkey(key); if (bruteforce(key, std::array<int, 4> {{ 1, 5, 9, 13 }}, 16.80323)) printkey(key); if (bruteforce(key, std::array<int, 4> {{ 2, 6, 10, 14 }}, 10.05288)) printkey(key); if (bruteforce(key, std::array<int, 4> {{ 3, 7, 11, 15 }}, 13.157277)) printkey(key); std::cout << "Finished bruteforce!" << std::endl; std::cin.ignore(); std::cin.get(); return 0; } Edited August 16, 2019 by VirtualPuppet 1
DefCon42 Posted August 16, 2019 Author Posted August 16, 2019 4 hours ago, VirtualPuppet said: There are many working keys. One of them is "$^CQE!#(Mrfe%&&$": The key was brute forced using a quickly written C++ executable: The code for the C++ executable is as follows: Hide contents #include <iostream> #include <stdint.h> #include <array> #include <functional> bool isallowed(char c) { return (c != '"' && c != ' '); } bool check_keys(double additive_key, char k0, char k1, char k2, char k3) { double product = additive_key + (static_cast<double>(k3) * 0.2254315957569856) + (static_cast<double>(k2) * -0.06225786672735933) + (static_cast<double>(k1) * 0.06576137583312501) + (static_cast<double>(k0) * -0.2174719016579794) + 0.0; return (product > 0.00001 || product < -0.00001); } bool bruteforce(std::array<char, 16>& key, std::array<int, 4> indices, double additive_key) { for (int a = 0; a < 256; a++) { for (int b = 0; b < 256; b++) { for (int c = 0; c < 256; c++) { for (int d = 0; d < 256; d++) { if (isallowed(a) && isallowed(b) && isallowed(c) && isallowed(d)) { if (!check_keys(additive_key, a, b, c, d) && isprint(a) && isprint(b) && isprint(c) && isprint(d)) { std::cout << "Found partial key match!" << std::endl << "a = " << a << "('" << static_cast<char>(a) << "')" << std::endl << "b = " << b << "('" << static_cast<char>(b) << "')" << std::endl << "c = " << c << "('" << static_cast<char>(c) << "')" << std::endl << "d = " << d << "('" << static_cast<char>(d) << "')" << std::endl << std::endl; key[indices[0]] = a; key[indices[1]] = b; key[indices[2]] = c; key[indices[3]] = d; return true; } } } } } } std::cout << "Could not bruteforce the selected keypart!" << std::endl; return false; } void printkey(std::array<char, 16> const& key) { std::cout << "Current key:" << std::endl; for (char const& ch : key) { if (ch == 0) std::cout << "_"; else std::cout << ch; } std::cout << std::endl; std::cout << std::endl; } int main(int argc, char* argv[]) { std::array<char, 16> key = { 0 }; printkey(key); if (bruteforce(key, std::array<int, 4> {{ 0, 4, 8, 12 }}, -0.255666)) printkey(key); if (bruteforce(key, std::array<int, 4> {{ 1, 5, 9, 13 }}, 16.80323)) printkey(key); if (bruteforce(key, std::array<int, 4> {{ 2, 6, 10, 14 }}, 10.05288)) printkey(key); if (bruteforce(key, std::array<int, 4> {{ 3, 7, 11, 15 }}, 13.157277)) printkey(key); std::cout << "Finished bruteforce!" << std::endl; std::cin.ignore(); std::cin.get(); return 0; } can't complain about a bruteforce, though i could probably have made it impractical with a longer key length
VirtualPuppet Posted August 17, 2019 Posted August 17, 2019 9 hours ago, DefCon42 said: can't complain about a bruteforce, though i could probably have made it impractical with a longer key length Well, mathematically, it’s just a question of finding 4 variables that, when multiplied with their factor and summed together yields a value within the allowed limit. one could either brute force it or calculate it by hand. Even if you increase keylength, the key will be easy to recover as long as you calculate the key parts separately.
DefCon42 Posted August 18, 2019 Author Posted August 18, 2019 1 hour ago, VirtualPuppet said: Well, mathematically, it’s just a question of finding 4 variables that, when multiplied with their factor and summed together yields a value within the allowed limit. one could either brute force it or calculate it by hand. Even if you increase keylength, the key will be easy to recover as long as you calculate the key parts separately. that's true if you only have 4 variables to work with, but that might not always be the case (even four wasn't instant on my machine); it's relatively easy to make it large enough that a bruteforce becomes ineffective
HooK Posted August 28, 2019 Posted August 28, 2019 DefCon42, can you remake the Crackme with more than 4 variables so we can put it to the test? Thanks, -HooK
DefCon42 Posted August 30, 2019 Author Posted August 30, 2019 (edited) On 8/28/2019 at 6:39 PM, Hookahice said: DefCon42, can you remake the Crackme with more than 4 variables so we can put it to the test? Thanks, -HooK Sure! See attached. crackme2.exe Edited August 30, 2019 by DefCon42 clarification 1
DrayNeur Posted November 3, 2020 Posted November 3, 2020 Hi i just look to it and than decompile it so it give me all the source code so i could recompile it myself and decrypt the control flow :D. Great share m8! Info: I use IDA Pro last version to get the Pseudo code that i retranslated in Windows c++ main.cpp
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now