static int rtmp_auth_compute_adobe(RTMP_AUTH_CTXT_T *pAuth, const AUTH_CREDENTIALS_STORE_T *pcreds) { int rc = 0; size_t sz = 0; char buf[512]; unsigned char hash[MD5_DIGEST_LENGTH]; if((pcreds->username[0] == '\0' && pcreds->pass[0] == '\0') || pAuth->p.salt[0] == '\0' || (pAuth->p.challenge[0] == '\0' && pAuth->p.opaque[0] == '\0')) { return -1; } if(pAuth->challenge_cli[0] == '\0') { rtmp_auth_getrandom_base64(4, pAuth->challenge_cli, sizeof(pAuth->challenge_cli)); } buf[0] = '\0'; if((rc = snprintf(buf, sizeof(buf), "%s%s%s", pcreds->username, pAuth->p.salt, pcreds->pass)) > 0) { sz = rc; } if((rc = md5_calculate((const unsigned char *) buf, strlen(buf), hash)) < 0) { return -1; } if((rc = base64_encode(hash, rc, buf, sizeof(buf))) < 0) { return -1; } sz = rc; if((rc = snprintf(&buf[sz], sizeof(buf) - sz, "%s%s", pAuth->p.opaque ? pAuth->p.opaque : pAuth->p.challenge, pAuth->challenge_cli)) > 0) { sz += rc; } if((rc = md5_calculate((const unsigned char *) buf, sz, hash)) < 0) { return -1; } if((rc = base64_encode(hash, rc, pAuth->response, sizeof(pAuth->response))) < 0) { return -1; } return rc; }
int main(int argc, char **argv) { char *output; int x; int y; struct cuda_device device; int available_words = 1; int current_words = 0; struct wordlist_file file; char input_hash[4][9]; print_info(); if (argc != ARG_COUNT) { printf("Usage: %s WORDLIST_FILE MD5_HASH\n", argv[0]); return -1; } if (process_wordlist(argv[ARG_WORDLIST], &file) == -1) { printf("Error Opening Wordlist File: %s\n", argv[ARG_WORDLIST]); return -1; } if (read_wordlist(&file) == 0) { printf("No valid passwords in the wordlist file: %s\n", argv[ARG_WORDLIST]); return -1; } // first things first, we need to select our CUDA device if (get_cuda_device(&device) == -1) { printf("No Cuda Device Installed\n"); return -1; } // we now need to calculate the optimal amount of threads to use for this card calculate_cuda_params(&device); // now we input our target hash if (strlen(argv[ARG_MD5]) != 32) { printf("Not a valid MD5 Hash (should be 32 bytes and only Hex Chars\n"); return -1; } // we split the input hash into 4 blocks memset(input_hash, 0, sizeof(input_hash)); for(x=0; x < 4; x++) { strncpy(input_hash[x], argv[ARG_MD5] + (x * 8), 8); device.target_hash[x] = htonl(_httoi(input_hash[x])); } // allocate global memory for use on device if (cudaMalloc(&device.device_global_memory, device.device_global_memory_len) != CUDA_SUCCESS) { printf("Error allocating memory on device (global memory)\n"); return -1; } // allocate the 'stats' that will indicate if we are successful in cracking if (cudaMalloc(&device.device_stats_memory, sizeof(struct device_stats)) != CUDA_SUCCESS) { printf("Error allocating memory on device (stats memory)\n"); return -1; } // allocate debug memory if required if (cudaMalloc(&device.device_debug_memory, device.device_global_memory_len) != CUDA_SUCCESS) { printf("Error allocating memory on device (debug memory)\n"); return -1; } // make sure the stats are clear on the device if (cudaMemset(device.device_stats_memory, 0, sizeof(struct device_stats)) != CUDA_SUCCESS) { printf("Error Clearing Stats on device\n"); return -1; } // this is our host memory that we will copy to the graphics card if ((device.host_memory = malloc(device.device_global_memory_len)) == NULL) { printf("Error allocating memory on host\n"); return -1; } // put our target hash into the GPU constant memory as this will not change (and we can't spare shared memory for speed) if (cudaMemcpyToSymbol("target_hash", device.target_hash, 16, 0, cudaMemcpyHostToDevice) != CUDA_SUCCESS) { printf("Error initalizing constants\n"); return -1; } #ifdef BENCHMARK // these will be used to benchmark int counter = 0; struct timeval start, end; gettimeofday(&start, NULL); #endif int z; while(available_words) { memset(device.host_memory, 0, device.device_global_memory_len); for(x=0; x < (device.device_global_memory_len / 64) && file.words[current_words] != (char *)0; x++, current_words++) { #ifdef BENCHMARK counter++; // increment counter for this word #endif output = md5_pad(file.words[current_words]); memcpy(device.host_memory + (x * 64), output, 64); } if (file.words[current_words] == (char *)0) { // read some more words ! current_words = 0; if (!read_wordlist(&file)) { // no more words available available_words = 0; // we continue as we want to flush the cache ! } } // now we need to transfer the MD5 hashes to the graphics card for preperation if (cudaMemcpy(device.device_global_memory, device.host_memory, device.device_global_memory_len, cudaMemcpyHostToDevice) != CUDA_SUCCESS) { printf("Error Copying Words to GPU\n"); return -1; } md5_calculate(&device); // launch the kernel of the CUDA device if (cudaMemcpy(&device.stats, device.device_stats_memory, sizeof(struct device_stats), cudaMemcpyDeviceToHost) != CUDA_SUCCESS) { printf("Error Copying STATS from the GPU\n"); return -1; } #ifdef DEBUG // For debug, we will receive the hashes for verification memset(device.host_memory, 0, device.device_global_memory_len); if (cudaMemcpy(device.host_memory, device.device_debug_memory, device.device_global_memory_len, cudaMemcpyDeviceToHost) != CUDA_SUCCESS) { printf("Error Copying words to GPU\n"); return; } cudaThreadSynchronize(); // prints out the debug hash'es printf("MD5 registers:\n\n"); unsigned int *m = (unsigned int *)device.host_memory; for(y=0; y <= (device.max_blocks * device.max_threads); y++) { printf("------ [%d] -------\n", y); printf("A: %08x\n", m[(y * 4) + 0]); printf("B: %08x\n", m[(y * 4) + 1]); printf("C: %08x\n", m[(y * 4) + 2]); printf("D: %08x\n", m[(y * 4) + 3]); printf("-------------------\n\n"); } #endif if (device.stats.hash_found == 1) { printf("WORD FOUND: [%s]\n", md5_unpad(device.stats.word)); break; } } if (device.stats.hash_found != 1) { printf("No word could be found for the provided MD5 hash\n"); } #ifdef BENCHMARK gettimeofday(&end, NULL); long long time = (end.tv_sec * (unsigned int)1e6 + end.tv_usec) - (start.tv_sec * (unsigned int)1e6 + start.tv_usec); printf("Time taken to check %d hashes: %f seconds\n", counter, (float)((float)time / 1000.0) / 1000.0); printf("Words per second: %d\n", counter / (time / 1000) * 1000); #endif }