【问题标题】:The Unknown Segmentation Fault on brute-force tool蛮力工具上的未知分割错误
【发布时间】:2020-11-14 15:40:02
【问题描述】:
// gcc -o OUTPUT Input.c -lcrypt
// Ubuntu 18.04 LTS

#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#include<string.h>
#include<unistd.h>
#include<crypt.h>

#define _XOPEN_SOURCE

int findShadowIndex(char *inputUserName, char shadow[][500]) {
    int i = 0; // Tempory Loop variable

    char *userName;

    while (shadow[i] != NULL) {

        strcpy(userName, shadow[i]);
        userName = strtok(userName, ":");

        if (!strcmp(inputUserName, userName))
            return i + 1;

        i++;
    }

    return 0;
}

void setBFValue(char BFValue[]) {
    int i, j = 0;

    BFValue[j++] = '\0';

    for (i = 48; i < 123; i++) {
        if (i >= 58 && i <= 64)
            continue;

        else if (i >= 91 && i <= 96)
            continue;

        BFValue[j] = i;

        j++;
    }

    BFValue[j++] = '!';
    BFValue[j++] = '@';
    BFValue[j++] = '#';
    BFValue[j++] = '$';
    BFValue[j++] = '%';
    BFValue[j] = '^';

    return;
}

int bruteForcing(char *originHash, char *cryptSalt, char *userName) {

    int a = 0, b = 0, c = 0, d = 0, e = 0, f = 0;// Brute Force Loop variable

    char passwd[7] = "";

    char BFValue[100] = { NULL, }; // Brute Force Value
    setBFValue(BFValue);

    for (a = 0; a < 69; a++) {
        passwd[5] = BFValue[a];

        for (b = 0; b < 69; b++)
        {
            passwd[4] = BFValue[b];

            for (c = 0; c < 69; c++)
            {
                passwd[3] = BFValue[c];
                for (d = 0; d < 69; d++) {
                    passwd[2] = BFValue[d];

                    for (e = 0; e < 69; e++) {
                        passwd[1] = BFValue[e];

                        for (f = 1; f < 69; f++) {
                            passwd[0] = BFValue[f];

                            //printf("\nPasswd : %s\n\n", passwd);
                            //printf("\ncryptSalt : %s\n\n", cryptSalt);
                            //printf("\userName : %s\n\n", hashID);
                            //printf("\noroginHash : %s\n\n", originHash);

                            printf("%s, %s\n", passwd, userName);

                            //printf("%d, \n", strcmp(originHash, crypt(passwd, cryptSalt)));

                            if (!strcmp(originHash, crypt(passwd, cryptSalt))) {
                                printf("\n");
                                printf("[-] User Name : %s, Password : %s\n", userName, passwd);
                                printf("\n");

                                return 1;
                            }

                        }

                    }

                }

            }

        }
    }

    return 0;
    //printf("\n[-] Decryption Failed\n\n");

}

int main(int argc, char* argv[]) {
    FILE* fd = NULL; // Shadow File Descripter

    int i = 0; // Tempory Loop variable

    char shadow[100][500] = { {NULL, } }; // List of Shadow File

    char userName[30]; // User Name
    int shadowIdx; // User name index in Shadow File

    char* ptr; // Tempory char pointer

    char *id; // User ID
    char *hash, *hashID, *hashSalt, *hashValue;

    char cryptSalt[100] = "$";
    char originHash[100];

    if (argc < 3) {
        printf("\n[!] Usage >>> sudo ./yu_cracker [Shadow File] [User Name]\n\n");
        exit(1);
    }

    else if (argc == 3) {
        fd = fopen(argv[1], "r");

        if (fd == NULL) {
            printf("\n[!] Can't find Shadow File!!!\n\n");
            exit(1);
        }

        while (!feof(fd)) {
            fgets(shadow[i], 500, fd);
            i++;
        }

        strcpy(userName, argv[2]); // Get User name

        shadowIdx = findShadowIndex(userName, shadow);

        if (!shadowIdx) {
            printf("\n[!] Can't find user name in Shadow File\n\n");
            exit(1);
        }

        ptr = strtok(shadow[shadowIdx - 1], ":");
        id = ptr;

        ptr = strtok(NULL, ":");
        hash = ptr;
        strcpy(originHash, hash);

        ptr = strtok(hash, "$");
        hashID = ptr;

        ptr = strtok(NULL, "$");
        hashSalt = ptr;

        strcat(cryptSalt, hashID);
        strcat(cryptSalt, "$");
        strcat(cryptSalt, hashSalt);

        ptr = strtok(NULL, "$");
        hashValue = ptr;

        printf("[+] Origin Hash >>> %s\n\n", originHash);

        printf("[+] Hash ID >>> %s\n", hashID);
        printf("[+] Salt >>> %s\n", cryptSalt);
        printf("[+] Hash Value >>> %s\n\n", hashValue);

        int result = bruteForcing(originHash, cryptSalt, userName);
    }

    else {
        return 1;
    }

}

此代码是 /etc/shadow 的简单暴力破解工具。

首先,将 /etc/shadow 复制到某个目录 && chmod 777 [SHADOW] 二、从输入的用户名(Hash ID, Hash Salt, Hash Value)中获取文件上具体的hash值 然后,选择候选值并在循环中使用 crypt 函数(#include )计算哈希 如果计算的哈希值与候选值相同,则打印解密文本并返回结果 它似乎工作正常,但在打印解密文本后出现分段错误 请您解释一下为什么会出现分段错误?

希望这些代码和图片能帮助你解决这个问题

How to RUN

Result

【问题讨论】:

  • 嗨。你可以malloc你的username来预留内存空间。
  • 可以把文字输出代替图片吗?
  • 顺便说一句,试试 valgind,它会立即发现错误

标签: c segmentation-fault brute-force crypt


【解决方案1】:

修复

我已经修复了你的代码,我会先向你展示我的修改,然后我会解释它们:

您的findShadowIndex 函数变为:

int findShadowIndex(char *inputUserName, char shadow[][500]) {
    int i = 0; // Tempory Loop variable

    while (shadow[i] != NULL) {
        char currentShadowRow[500];
        strcpy(currentShadowRow, shadow[i]);

        if (!strcmp(inputUserName, strtok(currentShadowRow, ":"))) {
            return i + 1;
        }

        i++;
    }

    return 0;
}

char originHash[100]; 变为char originHash[500];

说明

findShadowIndex

在您最初的findShadowIndex 中,在第一次迭代中,当您调用strcpy(userName, shadow[i]); 时,您正在将地址shadow[i] 中的字符复制到内存位置userName 中。问题是char *userName; 不代表您分配的内存,因此strcpy 正在写入您不拥有的内存,从而导致段错误。

我的版本将您正在检查的当前阴影线复制到本地缓冲区 (char currentShadowRow[500];),然后调用稍后使用的 strtok`` on the copy as to not modify the shadow``` 数组。

originHash 放大到 500 字节

originHash 数组不足以容纳所有哈希(我的密码哈希大于 100 个字符)。

工作版本

如果您想复制/粘贴工作代码,请点击此处:

// gcc -o OUTPUT Input.c -lcrypt
// Ubuntu 18.04 LTS

#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#include<string.h>
#include<unistd.h>
#include<crypt.h>

int findShadowIndex(char *inputUserName, char shadow[][500]) {
    int i = 0; // Tempory Loop variable

    while (shadow[i] != NULL) {
        char currentShadowRow[500];
        strcpy(currentShadowRow, shadow[i]);

        if (!strcmp(inputUserName, strtok(currentShadowRow, ":"))) {
            return i + 1;
        }

        i++;
    }

    return 0;
}

void setBFValue(char BFValue[]) {
    int i, j = 0;

    BFValue[j++] = '\0';

    for (i = 48; i < 123; i++) {
        if (i >= 58 && i <= 64)
            continue;

        else if (i >= 91 && i <= 96)
            continue;

        BFValue[j] = i;

        j++;
    }

    BFValue[j++] = '!';
    BFValue[j++] = '@';
    BFValue[j++] = '#';
    BFValue[j++] = '$';
    BFValue[j++] = '%';
    BFValue[j] = '^';

    return;
}

int bruteForcing(char *originHash, char *cryptSalt, char *userName) {

    int a = 0, b = 0, c = 0, d = 0, e = 0, f = 0;// Brute Force Loop variable

    char passwd[7] = "";

    char BFValue[100] = { '\0' }; // Brute Force Value
    setBFValue(BFValue);

    for (a = 0; a < 69; a++) {
        passwd[5] = BFValue[a];

        for (b = 0; b < 69; b++)
        {
            passwd[4] = BFValue[b];

            for (c = 0; c < 69; c++)
            {
                passwd[3] = BFValue[c];
                for (d = 0; d < 69; d++) {
                    passwd[2] = BFValue[d];

                    for (e = 0; e < 69; e++) {
                        passwd[1] = BFValue[e];

                        for (f = 1; f < 69; f++) {
                            passwd[0] = BFValue[f];

                            //printf("\nPasswd : %s\n\n", passwd);
                            //printf("\ncryptSalt : %s\n\n", cryptSalt);
                            //printf("\userName : %s\n\n", hashID);
                            //printf("\noroginHash : %s\n\n", originHash);

                            printf("%s, %s\n", passwd, userName);

                            //printf("%d, \n", strcmp(originHash, crypt(passwd, cryptSalt)));

                            if (!strcmp(originHash, crypt(passwd, cryptSalt))) {
                                printf("\n");
                                printf("[-] User Name : %s, Password : %s\n", userName, passwd);
                                printf("\n");

                                return 1;
                            }

                        }

                    }

                }

            }

        }
    }

    return 0;
    //printf("\n[-] Decryption Failed\n\n");

}

int main(int argc, char* argv[]) {
    FILE* fd = NULL; // Shadow File Descripter

    int i = 0; // Tempory Loop variable

    char shadow[100][500] = { '\0' }; // List of Shadow File

    char userName[30]; // User Name
    int shadowIdx; // User name index in Shadow File

    char* ptr; // Tempory char pointer

    char *id; // User ID
    char *hash, *hashID, *hashSalt, *hashValue;

    char cryptSalt[100] = "$";
    char originHash[500];

    if (argc < 3) {
        printf("\n[!] Usage >>> sudo ./yu_cracker [Shadow File] [User Name]\n\n");
        exit(1);
    }

    else if (argc == 3) {
        fd = fopen(argv[1], "r");

        if (fd == NULL) {
            printf("\n[!] Can't find Shadow File!!!\n\n");
            exit(1);
        }

        while (!feof(fd)) {
            fgets(shadow[i], 500, fd);
            i++;
        }

        strcpy(userName, argv[2]); // Get User name

        shadowIdx = findShadowIndex(userName, shadow);

        if (!shadowIdx) {
            printf("\n[!] Can't find user name in Shadow File\n\n");
            exit(1);
        }

        id = strtok(shadow[shadowIdx - 1], ":");

        hash = strtok(NULL, ":");

        strcpy(originHash, hash);
        hashID = strtok(hash, "$");

        hashSalt = strtok(NULL, "$");

        strcat(cryptSalt, hashID);
        strcat(cryptSalt, "$");
        strcat(cryptSalt, hashSalt);

        hashValue = strtok(NULL, "$");

        printf("[+] Origin Hash >>> %s\n\n", originHash);

        printf("[+] Hash ID >>> %s\n", hashID);
        printf("[+] Salt >>> %s\n", cryptSalt);
        printf("[+] Hash Value >>> %s\n\n", hashValue);

        int result = bruteForcing(originHash, cryptSalt, userName);
    } else {
        return 1;
    }
}

我希望这回答了你所有的问题!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-07
    • 2018-11-21
    • 1970-01-01
    • 2016-04-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多