1+ #include < iostream>
2+ #include < fstream>
3+ #include < string>
4+ #include < vector>
5+ #include < thread>
6+ #include < mutex>
7+ #include < cstring>
8+ #include < zip.h>
9+ #include < cstdlib>
10+ #include < atomic>
11+ #include < unistd.h>
12+
13+ std::atomic<bool > found (false );
14+ std::string correct_password = " " ;
15+ std::atomic<int > passwords_checked (0 );
16+ std::mutex output_mutex;
17+
18+ // Passwort-Generierung (lazy): a-zA-Z0-9
19+ void generate_passwords (const std::string& charset, size_t length, size_t start, size_t step, std::vector<std::string>& passwords) {
20+ size_t num_combinations = std::pow (charset.size (), length);
21+ for (size_t i = start; i < num_combinations && !found; i += step) {
22+ std::string password (length, charset[0 ]);
23+ size_t temp = i;
24+ for (size_t j = 0 ; j < length; ++j) {
25+ password[j] = charset[temp % charset.size ()];
26+ temp /= charset.size ();
27+ }
28+ passwords.push_back (password);
29+ }
30+ }
31+
32+ // Passwort-Check
33+ bool try_password (const std::string& filepath, const std::string& password) {
34+ int err = 0 ;
35+ zip_t * archive = zip_open (filepath.c_str (), ZIP_RDONLY, &err);
36+ if (!archive) {
37+ return false ;
38+ }
39+ zip_set_default_password (archive, password.c_str ());
40+ zip_file_t * file = zip_fopen_index (archive, 0 , 0 );
41+ if (file) {
42+ zip_fclose (file);
43+ zip_close (archive);
44+ return true ;
45+ }
46+ zip_close (archive);
47+ return false ;
48+ }
49+
50+ // Brute-Force-Worker
51+ void brute_force_worker (const std::string& filepath, const std::vector<std::string>& passwords) {
52+ for (const auto & password : passwords) {
53+ if (found) return ;
54+ passwords_checked++;
55+ if (try_password (filepath, password)) {
56+ std::lock_guard<std::mutex> lock (output_mutex);
57+ found = true ;
58+ correct_password = password;
59+ return ;
60+ }
61+ }
62+ }
63+
64+ // Fortschritt anzeigen
65+ void show_progress (size_t total_passwords) {
66+ while (!found) {
67+ {
68+ std::lock_guard<std::mutex> lock (output_mutex);
69+ double percent = (double (passwords_checked) / total_passwords) * 100 ;
70+ std::cout << " \r Checked: " << passwords_checked
71+ << " / " << total_passwords
72+ << " (" << percent << " %)"
73+ << " Remaining: " << total_passwords - passwords_checked;
74+ }
75+ std::this_thread::sleep_for (std::chrono::milliseconds (500 ));
76+ }
77+ }
78+
79+ int main (int argc, char * argv[]) {
80+ std::string filepath;
81+ size_t num_threads = 1 ;
82+ size_t length = 1 ;
83+ std::string wordlist_path;
84+ bool use_wordlist = false ;
85+
86+ const std::string charset = " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" ;
87+
88+ // Argumente parsen
89+ for (int i = 1 ; i < argc; ++i) {
90+ if (strcmp (argv[i], " -f" ) == 0 || strcmp (argv[i], " --file" ) == 0 ) {
91+ filepath = argv[++i];
92+ } else if (strcmp (argv[i], " -t" ) == 0 || strcmp (argv[i], " --threads" ) == 0 ) {
93+ num_threads = std::stoi (argv[++i]);
94+ } else if (strcmp (argv[i], " -l" ) == 0 || strcmp (argv[i], " --length" ) == 0 ) {
95+ length = std::stoi (argv[++i]);
96+ } else if (strcmp (argv[i], " -w" ) == 0 || strcmp (argv[i], " --wordlist" ) == 0 ) {
97+ wordlist_path = argv[++i];
98+ use_wordlist = true ;
99+ }
100+ }
101+
102+ if (filepath.empty ()) {
103+ std::cerr << " Error: No file provided. Use -f or --file to specify the ZIP file.\n " ;
104+ return 1 ;
105+ }
106+
107+ // Prüfen, ob die Wordlist genutzt werden soll
108+ std::vector<std::string> passwords;
109+ if (use_wordlist) {
110+ std::ifstream wordlist (wordlist_path);
111+ if (!wordlist) {
112+ std::cerr << " Error: Cannot open wordlist file.\n " ;
113+ return 1 ;
114+ }
115+ std::string word;
116+ while (wordlist >> word) {
117+ passwords.push_back (word);
118+ }
119+ } else {
120+ size_t total_passwords = std::pow (charset.size (), length);
121+ passwords.resize (total_passwords);
122+ generate_passwords (charset, length, 0 , 1 , passwords);
123+ }
124+
125+ size_t total_passwords = passwords.size ();
126+ std::cout << " Starting brute-force attack with " << total_passwords << " possible passwords...\n " ;
127+
128+ // Threads erstellen
129+ std::vector<std::thread> threads;
130+ size_t chunk_size = passwords.size () / num_threads;
131+
132+ for (size_t i = 0 ; i < num_threads; ++i) {
133+ size_t start = i * chunk_size;
134+ size_t end = (i + 1 == num_threads) ? passwords.size () : (i + 1 ) * chunk_size;
135+ threads.emplace_back (brute_force_worker, filepath, std::vector<std::string>(passwords.begin () + start, passwords.begin () + end));
136+ }
137+
138+ // Fortschrittsanzeige starten
139+ std::thread progress_thread (show_progress, total_passwords);
140+
141+ // Warten, bis alle Threads fertig sind
142+ for (auto & thread : threads) {
143+ thread.join ();
144+ }
145+ progress_thread.join ();
146+
147+ if (found) {
148+ std::cout << " \n Password found: " << correct_password << " \n " ;
149+ } else {
150+ std::cout << " \n Password not found.\n " ;
151+ }
152+
153+ return 0 ;
154+ }
0 commit comments