DISCLAIMER. It is impossible to go through other people's passwords, you cannot read texts addressed to you, it is impossible to create and distribute malicious software with the purpose of illegal access to computer information. Punishable under the Criminal Code. Dixi.
SGFzaGVkU2FsdCg4Ynl0ZXNJblVURjE2TEUpQ291bnRlckNpcGhlcnRleHRB
RVMyNTZFQ0J8MWE0MDhhYTVhZjkzMDkxOGRkYjkyNzQ3NDBhMDJjMmJkM2Vl
N2NkNjU3MDQwMDAwMDQxN2E2Nzc4Yzc3YzYwZjcxMGJlNTNiNmViODQ0ZDg0
MmUwZWEwZGYwNDA2NTU4NWEzMzIzYTUwZjc2OGY1N3xQb3NzaWJsZVBhc3N3
b3JkUGF0dGVybnN8RERMTExMTEx8RExMTExMTER8TExMRERMTEx8TExMTExM
REQ=
HashedSalt(8bytesInUTF16LE)CounterCiphertextAES256ECB|1a408a
a5af930918ddb9274740a02c2bd3ee7cd6570400000417a6778c77c60f71
0be53b6eb844d842e0ea0df04065585a3323a50f768f57|PossiblePassw
ordPatterns|DDLLLLLL|DLLLLLLD|LLLDDLLL|LLLLLLDD
1A408AA5AF930918DDB9274740A02C2BD3EE7CD6
- salt hash (20 bytes);0x00000457 = 1111
- iteration counter PBKDF2;0417a6778c77c60f710be53b6eb844d8
- the first ciphertext block (16 bytes);42e0ea0df04065585a3323a50f768f57
- the second ciphertext block (16 bytes). #!/usr/bin/env python3 # -*- coding: utf-8 -*- # Usage: python3 crack_salt_hash.py from hashlib import sha1 from itertools import product ALPH = 'abcdefghijklmnopqrstuvwxyz' SIZE = 4 TOTAL = len(ALPH)**SIZE def crack_hash(func, output, enc): progress = 0 for salt in product( *([ALPH]*SIZE) ): if func(''.join(salt).encode(encoding=enc)).hexdigest() == output: print(progress+1, 'of', TOTAL) return ''.join(salt) progress += 1 if progress % 10000 == 0: print(progress, 'of', TOTAL) return None if __name__ == '__main__': print(crack_hash(sha1, '1a408aa5af930918ddb9274740a02c2bd3ee7cd6', 'UTF-16LE'))
$ gcc fastpbkdf2.c -fPIC -std=c99 -O3 -c -g -Wall -Werror -o fastpbkdf2.o $ gcc -shared -lcrypto -o libfastpbkdf2.so fastpbkdf2.o
$ g++ bruter.cxx -o bruter -L"/path/to/libfastpbkdf2.so" -Wl,-rpath="/path/to/libfastpbkdf2.so" -lfastpbkdf2
bool checkPassword( uint8_t* password, const uint8_t* ciphertext, uint8_t* decrypted, int& decryptedLength ) { uint8_t key[KEY_LENGTH]; fastpbkdf2_hmac_sha1( password, PASSWORD_LENGTH, salt, SALT_LENGTH, iterations, key, KEY_LENGTH ); decryptedLength = CryptoPP_Decrypt_AES_256_ECB( ciphertext, (uint8_t*) key, decrypted ); if (isPrintable(decrypted, decryptedLength)) return true; return false; }
CryptoPP_Decrypt_AES_256_ECB
is a decryption function not written yet. The return value is true / false , depending on the outcome of the test of the criterion. The criterion of the correct decrypt is the printability of all the characters of the plaintext, the evaluation of the criterion lies on the isPrintable
function (see full listing in the Conclusion). int CryptoPP_Decrypt_AES_256_ECB( const uint8_t* ciphertext, uint8_t* key, uint8_t* plaintext ) { ECB_Mode<AES>::Decryption decryptor; decryptor.SetKey(key, AES::MAX_KEYLENGTH); ArraySink ps(&plaintext[0], PLAINTEXT_LENGTH); ArraySource( ciphertext, CIPHERTEXT_LENGTH, true, new StreamTransformationFilter( decryptor, new Redirector(ps), StreamTransformationFilter::NO_PADDING ) ); return ps.TotalPutLength(); }
void Parallel_TotalBruteForce( uint8_t* goodPassword, uint8_t* goodDecrypted, int& goodDecryptedLength ) { uint8_t alp[27] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '\0' }; uint8_t num[11] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '\0' }; #ifdef WITH_OPENMP omp_set_num_threads(myOMP_THREADS); #endif uint64_t progress = 0; bool notFinished = true; #pragma omp parallel for shared(progress, notFinished) collapse(8) for (int a = 0; a < 2; a++) for (int b = 2; b < 8; b++) for (int c = 0; c < 26; c++) for (int d = 0; d < 26; d++) for (int e = 0; e < 26; e++) for (int f = 0; f < 26; f++) for (int g = 0; g < 26; g++) for (int h = 0; h < 10; h++) { if (notFinished) { uint8_t password[9]; password[PASSWORD_LENGTH] = '\0'; uint8_t indeces[6] = { 2,3,4,5,6,7 }; memmove(indeces+b, indeces+b+1, 5-b); uint8_t decrypted[100]; int decryptedLength; password[ a] = '!'; // 0-1 password[ !a] = num[h]; // 0-1 password[ b] = 'Q'; // 2-7 password[indeces[0]] = alp[c]; // 2-7 password[indeces[1]] = alp[d]; // 2-7 password[indeces[2]] = alp[e]; // 2-7 password[indeces[3]] = alp[f]; // 2-7 password[indeces[4]] = alp[g]; // 2-7 if ( // DDLLLLLL checkPassword( password, ciphertext, decrypted, decryptedLength ) || // DLLLLLLD checkPassword( rotateLeft(password, 1), ciphertext, decrypted, decryptedLength ) || // LLLLLLDD checkPassword( rotateLeft(password, 1), ciphertext, decrypted, decryptedLength ) || // LLLDDLLL checkPassword( rotateLeft(password, 3), ciphertext, decrypted, decryptedLength ) ) { #pragma omp critical { memcpy( goodPassword, password, 9 ); memcpy( goodDecrypted, decrypted, decryptedLength ); goodDecryptedLength = decryptedLength; notFinished = false; } } if (progress % PROGRESS_SEP == 0) cout << progress << " of " << TOTAL << endl; progress += STEP; } } }
notFinished
flag notFinished
used to exit for . This approach is more peculiar to working with pthread directly, OpenMP has #pragma omp cancel
for this, but the compiler bombarded me with warnings, the nature of which is not completely clear to me, so it was decided to use the flag.ldQ9!nwd
".2E2B2A602A2B2C20594F552044495341524D4544204D4521202C2B2A602A2B2E
. /** * @file bruter.cxx * @author Sam Freeside <snovvcrash@protonmail[.]ch> * @date 2018-01 * * @brief Brute forcing 4 password patterns: "DDLLLLLL", "DLLLLLLD", "LLLLLLDD", "LLLDDLLL" */ /** * LEGAL DISCLAIMER * * bruter.cxx was written for use in educational purposes only. * Using this tool without prior mutual consistency can be considered * as an illegal activity. It is the final user's responsibility * to obey all applicable local, state and federal laws. * * The author assume no liability and is not responsible for any misuse or * damage caused by this tool. */ #include <iostream> #include <algorithm> #include <cstring> #include <cstdlib> #include <ctime> #include <ctype.h> #include <omp.h> #include "cryptopp/filters.h" #include "cryptopp/files.h" #include "cryptopp/modes.h" #include "cryptopp/hex.h" #include "cryptopp/aes.h" #include "lib/fastpbkdf2.h" #define myOMP_THREADS 4 // == CPU(s) = [Thread(s) per core] * [Core(s) per socket] * [Socket(s)] #define myOMP_SCHEDULE_CHUNKS 4 #define TOTAL 5703060480 // == 26*26*26*26*26*10 * 2*6 * 4 #define STEP 4 #define PROGRESS_SEP 1000000 using namespace std; using namespace CryptoPP; const uint8_t ciphertext[100] = { 0x04, 0x17, 0xA6, 0x77, 0x8C, 0x77, 0xC6, 0x0F, 0x71, 0x0B, 0xE5, 0x3B, 0x6E, 0xB8, 0x44, 0xD8, 0x42, 0xE0, 0xEA, 0x0D, 0xF0, 0x40, 0x65, 0x58, 0x5A, 0x33, 0x23, 0xA5, 0x0F, 0x76, 0x8F, 0x57 }; const int PLAINTEXT_LENGTH = 32; const int CIPHERTEXT_LENGTH = 32; const int SALT_LENGTH = 8; const int PASSWORD_LENGTH = 8; const int KEY_LENGTH = 32; const uint8_t salt[SALT_LENGTH] = { 'd', 0x00, 'u', 0x00, 'k', 0x00, 'g' }; const uint32_t iterations = 0x00000457; // == 1111 void Parallel_TotalBruteForce( uint8_t* goodPassword, uint8_t* goodDecrypted, int& goodDecryptedLength ); int CryptoPP_Decrypt_AES_256_ECB( const uint8_t* ciphertext, uint8_t* key, uint8_t* plaintext ); bool checkPassword( uint8_t* password, const uint8_t* ciphertext, uint8_t* decrypted, int& decryptedLength ); uint8_t* rotateLeft( uint8_t* password, int n ); bool isPrintable( uint8_t* text, int textLength ); int main() { uint8_t goodPassword[9] = { '*','*','*','*','*','*','*','*', '\0' }; uint8_t goodDecrypted[100]; int goodDecryptedLength = 0; HexEncoder encoder(new FileSink(cout)); cout << "[*] Ciphertext:" << endl; encoder.Put(ciphertext, CIPHERTEXT_LENGTH); encoder.MessageEnd(); cout << endl << endl; Parallel_TotalBruteForce(goodPassword, goodDecrypted, goodDecryptedLength); cout << endl << "[+] Decrypted block:" << endl; encoder.Put(goodDecrypted, goodDecryptedLength); encoder.MessageEnd(); cout << endl; goodDecrypted[goodDecryptedLength++] = '\0'; cout << "[+] Decrypted string:" << endl; cout << '\"' << goodDecrypted << '\"' << endl; cout << "[+] Password:" << endl; cout << '\"' << goodPassword << '\"' << endl << endl; return 0; } void Parallel_TotalBruteForce( uint8_t* goodPassword, uint8_t* goodDecrypted, int& goodDecryptedLength ) { uint8_t alp[27] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '\0' }; uint8_t num[11] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '\0' }; #ifdef WITH_OPENMP omp_set_num_threads(myOMP_THREADS); #endif uint64_t progress = 0; bool notFinished = true; #pragma omp parallel for shared(progress, notFinished) collapse(8) for (int a = 0; a < 2; a++) for (int b = 2; b < 8; b++) for (int c = 0; c < 26; c++) for (int d = 0; d < 26; d++) for (int e = 0; e < 26; e++) for (int f = 0; f < 26; f++) for (int g = 0; g < 26; g++) for (int h = 0; h < 10; h++) { if (notFinished) { uint8_t password[9]; password[PASSWORD_LENGTH] = '\0'; uint8_t indeces[6] = { 2,3,4,5,6,7 }; memmove(indeces+b, indeces+b+1, 5-b); uint8_t decrypted[100]; int decryptedLength; password[ a] = '!'; // 0-1 password[ !a] = num[h]; // 0-1 password[ b] = 'Q'; // 2-7 password[indeces[0]] = alp[c]; // 2-7 password[indeces[1]] = alp[d]; // 2-7 password[indeces[2]] = alp[e]; // 2-7 password[indeces[3]] = alp[f]; // 2-7 password[indeces[4]] = alp[g]; // 2-7 if ( // DDLLLLLL checkPassword( password, ciphertext, decrypted, decryptedLength ) || // DLLLLLLD checkPassword( rotateLeft(password, 1), ciphertext, decrypted, decryptedLength ) || // LLLLLLDD checkPassword( rotateLeft(password, 1), ciphertext, decrypted, decryptedLength ) || // LLLDDLLL checkPassword( rotateLeft(password, 3), ciphertext, decrypted, decryptedLength ) ) { #pragma omp critical { memcpy( goodPassword, password, 9 ); memcpy( goodDecrypted, decrypted, decryptedLength ); goodDecryptedLength = decryptedLength; notFinished = false; } } if (progress % PROGRESS_SEP == 0) cout << progress << " of " << TOTAL << endl; progress += STEP; } } } uint8_t* rotateLeft( uint8_t* password, int n ) { rotate(&password[0], &password[n], &password[PASSWORD_LENGTH]); return password; } bool checkPassword( uint8_t* password, const uint8_t* ciphertext, uint8_t* decrypted, int& decryptedLength ) { uint8_t key[KEY_LENGTH]; fastpbkdf2_hmac_sha1( password, PASSWORD_LENGTH, salt, SALT_LENGTH, iterations, key, KEY_LENGTH ); decryptedLength = CryptoPP_Decrypt_AES_256_ECB( ciphertext, (uint8_t*) key, decrypted ); if (isPrintable(decrypted, decryptedLength)) return true; return false; } int CryptoPP_Decrypt_AES_256_ECB( const uint8_t* ciphertext, uint8_t* key, uint8_t* plaintext ) { ECB_Mode<AES>::Decryption decryptor; decryptor.SetKey(key, AES::MAX_KEYLENGTH); ArraySink ps(&plaintext[0], PLAINTEXT_LENGTH); ArraySource( ciphertext, CIPHERTEXT_LENGTH, true, new StreamTransformationFilter( decryptor, new Redirector(ps), StreamTransformationFilter::NO_PADDING ) ); return ps.TotalPutLength(); } bool isPrintable( uint8_t* text, int textLength ) { // OuKSJJRlqS7Tqzn+r9GZ4g== for (int i = 0; i < textLength; i++) if (!isprint(text[i])) return false; return true; }
CXXTARGET = bruter CXXSOURCES = $(wildcard *.cxx) CXXOBJECTS = $(patsubst %.cxx, %.o, $(CXXSOURCES)) CSOURCES = $(wildcard */*.c) CHEADERS = $(wildcard */*.h) COBJECTS = $(patsubst %.c, %.o, $(CSOURCES)) SHARED_LIB = lib/libfastpbkdf2.so CXX = g++ CC = gcc CXXFLAGS += -std=c++11 -O3 -c -g -Wall CXXLIBS += -L"./lib" -Wl,-rpath="./lib" -lfastpbkdf2 -L"/usr/lib" -lssl -lcrypto -lcryptopp CFLAGS += -fPIC -std=c99 -O3 -c -g -Wall -Werror -Wextra -pedantic CLIBS += -lcrypto .PHONY: all default openmp clean .PRECIOUS: $(CXXSOURCES) $(CSOURCES) ($CHEADERS) $(SHARED_LIB) default: $(CXXTARGET) @echo "=> Project builded" all: clean openmp $(CXXTARGET): $(SHARED_LIB) $(CXXOBJECTS) @echo "=> Linking project files" @echo "(CXX) $?" @$(CXX) $(CXXOBJECTS) $(CXXLIBS) -o $@ $(CXXOBJECTS): $(CXXSOURCES) @echo "=> Compiling project files" @echo "(CXX) $?" @$(CXX) $(CXXFLAGS) $< -o $@ $(SHARED_LIB): $(COBJECTS) @echo "=> Creating shared library" @echo "(CC) $?" @$(CC) -shared $< -o $@ $(COBJECTS): $(CSOURCES) $(CHEADERS) @echo "=> Compiling fastpbkdf2 sources" @echo "(CC) $?" @$(CC) $(CFLAGS) $(CLIBS) $< -o $@ openmp: CXXFLAGS += -fopenmp -DWITH_OPENMP openmp: CXXLIBS += -fopenmp openmp: CFLAGS += -fopenmp -DWITH_OPENMP openmp: default @echo "WITH OPENMP" clean: @rm -rfv *.o */*.o $(SHARED_LIB) $(CXXTARGET) @echo "=> Cleaning done"
Source: https://habr.com/ru/post/346572/
All Articles