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