Reputation: 9
// 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
Upvotes: 0
Views: 63
Reputation: 909
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];
.
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.
originHash
to 500 bytesThe originHash
array wasn't big enough to fit all hashes (my password's hash was bigger than 100 characters).
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