对于此作业,我必须使用 C 语言中的 pthreads 来制作暴力密码破解程序。
下面的代码使用 for 循环生成一个 6 个字母的密码(最好是 8 个字母长),然后我使用 crypt_r 对其进行哈希处理,并将其与我在执行时为程序提供的哈希值和加盐值进行比较。
散列和盐在开始时被接收,存储在一个名为 dataStr 的结构中,然后将其提供给 pthreadCreate。
这看起来很简单,但即使我将数组 memset 为空终止字符,在执行时程序仍将整个内容设置为“aaaaaa”。这个问题是它忽略了 1-4 个字符长的密码。
这是我使用的数据结构:
typedef struct {
char * hash; //hashed code given in argv[1]
char * salt; //salt for hashed code given in argv[2]
int start; //starting char in alphabet for first letter
int end; //ending char in alphabet for first letter
int id; //thread id
} dataStruct;
尺寸定义:
//Definitions
#define PW_SIZE 8
#define ALPHABET_SIZE 66
#define HASH_MAX_SIZE 128
这是代码本身
void * thread(void * arg) {
struct timespec start, finish; //Data structure for time.h library
clock_gettime(CLOCK_MONOTONIC, &start); //Start chronometer
double elapsed;
struct crypt_data* cdata = (struct crypt_data *)malloc(sizeof(struct crypt_data));
cdata->initialized = 0;
dataStruct dataStr = *((dataStruct*)(arg)); //receive structure in arguement
const char * alphabet = get_alphabet(); //create alphabet
bool pw_found = false; //boolean used for
int retDone = 1;
char * pwd = malloc(PW_SIZE * sizeof(char));
memset(pwd, '\0', PW_SIZE);
int i,j,k,l,m,n;
for (i = dataStr.start; i <= dataStr.end; i++) {
for (j = 0; j <= ALPHABET_SIZE; j++) {
for (k = 0; k <= ALPHABET_SIZE; k++) {
for (l = 0; l <= ALPHABET_SIZE; l++) {
for (m = 0; m <= ALPHABET_SIZE; m++) {
for (n = 0; n <= ALPHABET_SIZE; n++) {
if (pw_found) {
clock_gettime(CLOCK_MONOTONIC, &finish);
elapsed = finish.tv_sec - start.tv_sec;
elapsed += (finish.tv_nsec - start.tv_nsec) / 1000000000.0;
printf("Time elapsed : %f sec(s) \n\n", elapsed); //Time
pthread_exit(&retDone);
}
pwd[0] = alphabet[i];
pwd[1] = alphabet[j];
pwd[2] = alphabet[k];
pwd[3] = alphabet[l];
pwd[4] = alphabet[m];
pwd[5] = alphabet[n];
printf("%s\n", pwd);
char * hash = crypt_r(pwd, dataStr.salt, cdata);
if (strcmp(hash, dataStr.hash) == 0) {
printf("\nPassword : %s\n", pwd);
pw_found = true;
}
}
}
}
}
}
}
pthread_exit(&retDone);
}
这是它在执行时产生的结果:
我想了解如何以某种方式更改 6 个循环,以便让程序首先仅搜索 1 个字母字符,然后搜索 2 个,然后搜索 3 个,然后从那里递增。
感谢任何帮助。非常感谢!
PS - 我不介意通过电子邮件向某人发送全局 View 的代码。
最佳答案
可以使用指针来实现这一点。 ppw
将指向 pw
数组中的某处。 pch
将指向 characters
数组中的某处。递增 (++) 和递减 (--) 指针会在各自数组的元素内移动指针。 Dereferencing(*) 可以访问指针指向的值。 used
是 pw
中已使用的元素数。第一个元素从 0 开始,并向 SIZE
递增。 characters
可以修改为包括有效的字母、数字和符号。请注意不要重复。例如,如果字母 u
出现不止一次,程序将进入无限循环。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 5
int main( void)
{
char pw[SIZE + 1] = "";
char *ppw = NULL;
char *pch = NULL;
char characters[] = "abcdefghijklmnopqrstuvwxyz";
int used = 0;
int out = 1;
int last = strlen ( characters) - 1;
//set pw
pw[used] = characters[0];
pw[used + 1] = '\0';
while ( used < SIZE) {//loop until all elements of pw have been used
ppw = &pw[used];//set ppw to point to last used element of pw
while ( ppw >= pw) {//so ppw always points to an element of pw
if ( ( pch = strchr ( characters, *ppw)) != NULL) {//get pointer into characters for current value that ppw point to
if ( out) {//print when appropriate
printf ( "%s\n", pw);
}
if ( pch < &characters[last]) {//pch does not point to last element of characters
++pch;//pch points to next element of characters
*ppw = *pch;//set what ppw points to to be the same as what pch points to
if ( ppw != &pw[used]) {//ppw is not pointing to last element of pw
ppw = &pw[used];
}
out = 1;//allow printing
}
else {//pch is pointing to last element of characters
*ppw = characters[0];//set what ppw points to to be the first element of characters
ppw--;//ppw points to next lower element of pw. ex from pw[n] to pw[n-1]
out = 0;//disable printing
}
}
}//exit loop when ppw points to address less than pw
used++;//increase elements in use
memset ( pw, characters[0], used);//reset all elements to first element of characters
pw[used + 1] = '\0';//just in case, terminate
}//exit loop when all elements have been used
exit ( 0);
}
这似乎有效。添加了两行以将 out
设置为 1,并将 used + 1
添加到对 memset 的调用。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// one more than the desired size
#define SIZE 4
int main( void)
{
char pw[SIZE] = "";
char *ppw = NULL;
char *pch = NULL;
char characters[] = "abc";
int used = 0;
int out = 1;
int last = strlen ( characters) - 1;
//set pw as character[0]
pw[used] = characters[0];
pw[used + 1] = '\0';
while ( used < SIZE - 1) {//loop until all elements of pw have been used
ppw = &pw[used];//set ppw to point to last used element of pw
out = 1;
while ( ppw >= pw) {//so ppw always points to an element of pw
if ( ( pch = strchr ( characters, *ppw)) != NULL) {//get pointer into characters for current value that ppw point to
if ( out) {//print when appropriate
printf ( "%s\n", pw);
}
out = 1;
if ( pch < &characters[last]) {//pch does not point to last element of characters
++pch;//pch points to next element of characters
*ppw = *pch;//set what ppw points to to be the same as what pch points to
if ( ppw != &pw[used]) {//ppw is not pointing to last element of pw
ppw = &pw[used];
}
}
else {//pch is pointing to last element of characters
*ppw = characters[0];//set what ppw points to to be the first element of characters
ppw--;//ppw points to next lower element of pw. ex from pw[n] to pw[n-1]
out = 0;//disable printing
}
}
}//exit loop when ppw points to address less than pw
used++;//increase elements in use
memset ( pw, characters[0], used + 1);//reset all elements to first element of characters
pw[used + 1] = '\0';//just in case, terminate
}//exit loop when all elements have been used
exit ( 0);
}
关于c - 我怎样才能让这个蛮力算法逐步检查字母,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40389271/