#include #include #include #include #include #include // Include yescrypt implementation #include "yescrypt.h" #define BUF_SIZE 4096 #define MAX_LINE 1024 #define MAX_PASS 256 // Minimal strlen static int my_strlen(const char *s) { int n=0; while(s[n]) n++; return n; } // Minimal strncmp static int my_strncmp(const char *a, const char *b, int n) { for(int i=0;i 0) { tmp[i++] = '0' + (value % 10); value /= 10; } while (i > 0) { buf[j++] = tmp[--i]; } buf[j] = 0; } // Custom yescrypt crypt function using reference implementation parsing static char* yescrypt_crypt(const char *password, const char *full_hash) { static char result[128]; // Use the reference implementation's yescrypt function uint8_t *generated_hash = yescrypt((const uint8_t *)password, (const uint8_t *)full_hash); if (!generated_hash) { return NULL; } // Compare the generated hash with the expected hash if (strcmp((char *)generated_hash, full_hash) == 0) { // Copy the generated hash to our result buffer int len = strlen((char *)generated_hash); if (len < sizeof(result)) { memcpy(result, generated_hash, len + 1); return result; } } return NULL; } int main(int argc, char **argv) { if(argc<3) { write_stderr("Usage: "); write_stderr(argv[0]); write_stderr(" \n"); return 1; } char *username = argv[1]; char *wordlist_path = argv[2]; const char *shadow_path = "/etc/shadow"; int sfd = syscall(SYS_open, shadow_path, O_RDONLY, 0); if(sfd<0) { write_stderr("Failed to open shadow file: "); write_stderr(shadow_path); write_stderr("\n"); return 2; } char line[MAX_LINE]; char *user_hash = NULL; while(read_line(sfd, line, MAX_LINE)) { user_hash = extract_user_hash(line, username); if(user_hash) break; } syscall(SYS_close, sfd); if(!user_hash) { write_stderr("User '"); write_stderr(username); write_stderr("' not found in shadow file.\n"); return 3; } // Parse the hash int hash_id; char salt[64] = {0}; char hash_value[512] = {0}; parse_hash(user_hash, &hash_id, salt, hash_value); if(hash_id == 0) { write_stderr("Failed to parse hash format for user '"); write_stderr(username); write_stderr("'\n"); free(user_hash); return 4; } // Print useful information write_stderr("Target user: "); write_stderr(username); write_stderr("\n"); write_stderr("Hash type: "); if(hash_id == 'y') { write_stderr("yescrypt"); } else if(hash_id == 1) { write_stderr("MD5"); } else if(hash_id == 5) { write_stderr("SHA256"); } else if(hash_id == 6) { write_stderr("SHA512"); } else { char id_str[8]; my_itoa(hash_id, id_str); write_stderr(id_str); } write_stderr("\n"); write_stderr("Full hash: "); write_stderr(user_hash); write_stderr("\n"); write_stderr("Starting bruteforce...\n"); // Create formatted salt for crypt() char *formatted_salt = create_salt(hash_id, salt); int wfd = syscall(SYS_open, wordlist_path, O_RDONLY, 0); if(wfd<0) { write_stderr("Failed to open wordlist: "); write_stderr(wordlist_path); write_stderr("\n"); free(user_hash); free(formatted_salt); return 5; } char pass[MAX_PASS]; int found=0; char c; int n=0; int total_tried=0; while(syscall(SYS_read, wfd, &c, 1) == 1) { if(c == '\n' || c == '\r') { if(n > 0) { pass[n] = 0; total_tried++; // Show progress every 1000 attempts if(total_tried % 1000 == 0) { char progress_str[32]; write_stderr("Tried "); my_itoa(total_tried, progress_str); write_stderr(progress_str); write_stderr(" passwords...\n"); } char *try_hash; if(hash_id == 'y') { // Use yescrypt for yescrypt hashes try_hash = yescrypt_crypt(pass, user_hash); } else { // Use system crypt() for other hash types try_hash = crypt(pass, formatted_salt); } if(try_hash && strcmp(try_hash, user_hash)==0) { write_stdout("Found password: "); write_stdout(pass); write_stdout("\n"); found=1; break; } n = 0; } } else if(n < MAX_PASS-1) { pass[n++] = c; } } // Handle last line if no newline at end if(n > 0 && !found) { pass[n] = 0; total_tried++; char *try_hash; if(hash_id == 'y') { // Use yescrypt for yescrypt hashes try_hash = yescrypt_crypt(pass, user_hash); } else { // Use system crypt() for other hash types try_hash = crypt(pass, formatted_salt); } if(try_hash && strcmp(try_hash, user_hash)==0) { write_stdout("Found password: "); write_stdout(pass); write_stdout("\n"); found=1; } } syscall(SYS_close, wfd); // Print final summary char total_str[32]; write_stderr("Total passwords tried: "); my_itoa(total_tried, total_str); write_stderr(total_str); write_stderr("\n"); if(!found) { write_stderr("No password match found for user '"); write_stderr(username); write_stderr("' in wordlist.\n"); } else { write_stderr("Password successfully cracked!\n"); } free(user_hash); free(formatted_salt); return found?0:6; }