GGONGCHI
GGONGCHI

Reputation: 9

The Unknown Segmentation Fault on brute-force tool

// 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;
    }

}

This code is a simple brute force tool for /etc/shadow.

First, copy the /etc/shadow on somewhere directory && chmod 777 [SHADOW] Second, get the specific hash value on file from input user name (Hash ID, Hash Salt, Hash Value) And then, select the candidate value and calculate hash with crypt function (#include <crypt.h>) in loop If calculated hash value is same with candidate value, print decrypted text and return result It seems to be working fine, but occur segmentation fault after printed the decrypted text Please can you explain to me why segmentation fault is occured?

I hope these code and picture helps to you solve this question

How to RUN

Result

Upvotes: 0

Views: 63

Answers (1)

Henry Le Berre
Henry Le Berre

Reputation: 909

Fixes

I've fixed your code, I'll first show you my modifications and then I'll explain them:

Your findShadowIndex function becomes:

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;
}

and char originHash[100]; becomes char originHash[500];.

Explanation

In findShadowIndex

In your oginal findShadowIndex, on the first iteration, when you called strcpy(userName, shadow[i]); you were copying characters from the address shadow[i] into the memory location userName. The issue is that char *userName; didn't represent memory you had allocated so strcpy was writing to memory you didn't own, causing a segfault.

My version copies the current shadow line you are examinating into a local buffer (char currentShadowRow[500];) and then calls strtok`` on the copy as to not modify the shadow``` array that is used later.

Enlarging originHash to 500 bytes

The originHash array wasn't big enough to fit all hashes (my password's hash was bigger than 100 characters).

Working Version

If you want to copy/paste the working code, here you go:

// 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;
    }
}

I hope this answered all of your questions!

Upvotes: 0

Related Questions