Programming - cpueblo.com

Network 해킹과 보안


글쓴이 : 유광희 날짜 : 2002-05-13 (월) 17:53 조회 : 6601

지금까지 너무도 많은 분들이 네트워크 해킹과 보안에 굉장히 많은 관심을 가지고 계셨을 거라 생각합니다.

먼저 네트워크 해킹에는 어떤한 장비나 환경이 꾸며져 있어야 하는지 알아보겠습니다.


■ 네트워크 해킹 준비물 ■

1.인터넷 접속을 위한 장비 인터넷 전용선을 사용하는 분이라면 자신의 PC(단말기)에 LAN카드가 있어야 겠죠?
전화선을 이용해서 인터넷에 접속을 해야하는 분은 Modem이 달려 있어야 합니다.
물론 Modem을 통해 인터넷에 접속을 위해서는 인터넷 서비스에 가입이 되어 있어야 겠죠?


2. NetWork와 Mutitasking이 지원되는 OS(Win95/NT, Linux 등) 실제로 해킹과정에서는 단말기를 여러개 띄워야 할 경우가 많습니다. 그래서 Mutitasking이 지원되면 좋습니다.


3. 네트워크 용 프로그램(NetTerm, WS-FTP 등) 다른 시스템에 접근을 하기 위해서는 Telnet이나 Ftp 등을사용합니다. 네트워크가 가능한 OS에서는 기본적으로 제공을 하지만 좀더 편리한 전용 프로그램을 사용하세요.


4. 해킹도중에는 자신의 컴퓨터에서 하는 일은 그리 많지 않기 때문에 하드웨어 사양은 그리 상관은 없지만 좋으면 좋을
수록 좋겠죠? 하지만 Modem은 속도가 빠른 것을 사용하십시오. 전화비 문제도 있고... 참고로 자신의 PC에 Windows NT server를 사용하고 다른 NT Server에 전화를 걸어 접속한 후 Call Back 서비스를 받으면 전화비를 들이지 않고도 인터넷을 마음대로 사용할 수 있습니다. 좋겠죠?


■ Root 암호 알아내기 ■

자! 모든것이 준비가 되었다면 이제 시작해 봅시다.
대분분 네트워크 서비스를 하는 서버들은 OS를 UNIX계열을 사용합니다.
그래서 유닉스 공부를 하셔야 합니다.
보통 네트워크 상의 해킹은 어떤 한 서버에 접속해서 그곳에 root의 계정을 알아 내서 그 시스템을 내 마음대로 주무르는 것(?)을 골자로 합니다. 그럼 루트 계정은 어떻게 알아낼 수 있을까요?
① root가 root계정으로 접속할 때 옆에서 지켜보며 암호를 알아내는 방법
② 루트의 계정으로 접속되어있는 단말기(terminal)에서 root권한을 가진 사람이 잠깐 자리를 비웠을때 Back Door를 만드는 방법
③ Cracker 등을 이용하여 root암호를 알아내는 방법
④ OS자체의 버그를 이용해서 시스템에 접근하는 방법
⑤ Sniffering을 통한 암호알아내기 방법
등등 여러가지 방법이 있습니다.

자! 이제 한 가지씩 차근 차근 이야기를 하도록 하겠습니다.
설명을 할때에는 기본적인 유닉스 사용법은 이야기 하지 않습니다.
유닉스의 기본적인 내용과 기본 유틸리티의 사용법은 미리 미리 공부하시기 바랍니다.
위에서는 유닉스의 기본은 정리해 놓았습니다.


*눈치 코치로 암호 알아내기

이번에 소개할 방법은 설명이 별루 필요없습니다. 가능성도 희박하지만...
만약 시스템 관리를 하는 친구가 있다면 그 친구에게 찾아가서 같이 노는 방법이라고나 할까요?
그냥 친구가 관리하는 것을 보다가 친구가 로그인 과정에서 손가락으로 어느키를 누르는가를 순서까지 알아내는
것입니다. 정말 친하다면 잘 꼬셔서 차라리 말로 알려달라는 것이 편하겠군요.


*개 구멍(Back Door)을 만들자!

이번에는 전에 말한 친구가 잠깐 화장실에 갔을때 할 수 있는 방법입니다.
여기서 부터는 설명이 많이 필요합니다.
UNIX에서의 모든 파일은 소유 ID와 소유 Group ID를 가지고 있습니다.
만약 그 파일이 실행 파일이라면 Set User ID와 Set Group ID를 가질 수도 있습니다.
Set User ID나 Set Group ID가 설정되어 있는 실행 파일을 실행 시킨다면 그 파일을 실행 시키는 동안은 그 파일의 실제 소유자의 권한이나 소유 Group 권한을 갖게 됩니다. 물론 파일의 실행이 끝나면 다시 자신의 권한으로 되돌아
옵니다. 만약 그 파일이 실행 도중 어떤한 이유에서든지 비정상적으로 프로세스를 빠져나온다면 그때는 그 파일의 소유자나 소유 Group 권한으로 빠져 나오게 됩니다. 이를 응용한다면 root의 소유로 되어 있는 프로그램을 실행시켜 비정상적으로 빠져나오게 하면 root의 권한을 그대로 사용할 수 있습니다. 그러한 방법으로 root친구가 잠깐 화장실에 같을때 다음과 같은 내용을 실제로 작성해서 컴파일 과정을 거쳐 실행 파일로 만들어 눈에 잘 띄지않고 자신이 들어갈 수 있는
디렉토리에 숨겨 놓습니다.
그런 후 자신의 계정으로 그 시스템에 당당히 접속해서 숨겨놓은 프로그램을 실행시키는 것이지요. 다음의 Source는 자신의 프로세스에서 /bin/csh을 실제로 호출해서 명령어 모드로 빠져 나가는 것입니다. 컴파일 한 후에는 실행 파일의 Permission을 4755이상으로 설정해야 합니다.

--다음--

다음에 실제 테스트를 거친 후에 공개 하겠습니다.

그러면 시스템 관리자의 입장에서 생각한다면 이런 생각이
드실 것 입니다.
왜 Set User ID나 Set Group ID같은 것을 유닉스는 만들어서 이렇게 해킹이 가능하게 하는 것일까?
우리가 전자우편을 보낼때 사용하는 명령 mail을 생각해 봅시다.
mail은 그 시스템의 모든 사용자가 사용을 해야 되지만 e-mail을 실제로 보내주는 작업을 일반 사용자가 할 수는 없으므로 mail이라는 실행 파일에 setuid를 설정해서 mail을 보내는 동안에는 super user의 권한을 갖게 하는 것입니다. 실제 ls -l /bin/mail명령을 사용해서 살펴보면 mail 파일에 setuid Permission이 설정되어있다는 걸 알수 있습니다.
--s--x--x 1 root 23414 jan 2 00:23 mail

그럼 이러한 방법에 의한 해킹을 막기 위해서는 관리자는 어떻게 해야 하는가하면... 자신의 시스템내의 모든 setuid나 setgid를 갖는 프로그램이 정상 작동을 하는지 주기적으로 체크를 해야 되겠지요.
알고 보면 간단하죠?


*Cracker로 무식하게 알아내기

이 앞번 해킹 방법까지는 root라는 super user를 개인적으로 잘 알고 있어야 할 수 있는 방법이었습니다. 실제로 대부분의 사람들은 아는 사람들 중에 suprer user가 있을리가 없죠? 그렇다고 로비를 한다는 것도 우습구요. 이번에는 자신의 계정으로 접속을 해서 실제로 root를 포함한 다른 사용자의 암호를 알아내는 방법을 소개해 드리겠습니다. 보통 대부분의 UNIX시스템은 /etc/passwd라는 파일에 그 시스템의 모든 사용자들의 이름, ID, 암호등을 적어놓고 관리를 하고 있습니다. passwd파일을 실제로 읽어서 암호를 알아내면 되는데 각 사용자 별로 한줄씩 구성되어 있습니다. 한 사용자의 passwd파일 정보는 다음의 형식을 따릅니다.

유저이름:암호:유저ID:그룹ID:실제이름:홈디렉토리:기본Shell

예를 든다면 jch:Ag8hkqPu0mCxg:10:10:Jo Hee Chang:/home/jch;/bin/csh

입니다. 풀어 보자면 각각의 구분자는 콜론:이구요. jch는 로그인할때 쓰이는 사용자 이름이며 Ag8hkqPu0mCxg는 로그인할때 쓰이는 암호, 10은 사용자 ID입니다. 이것은 사용자를 숫자로서 구별하는 코드로 사용자가 직접 사용하지는 않습니다. 그 다음의 10은 그룹ID. jhc가 속한 그룹에 대한 번호입니다.
갑자기 이런걸 다 설명해야 하는가 라는 생각이 드는 군요. 그래도 시작을 했으니...
Jo Hee Chang는 실제 사용자의 이름입니다. 이건 없어도 무방합니다. 실제 사용자의 이름이 아니고 그냥 인사말 정도를 넣는 경우도 있습니다. 다음은 사용이 허가 되어 있는 홈디렉토리입니다. 그 다음은 로그인이 되면 막바로 사용해야하는 shell을 가르키는 것이죠? 다 아시는 사실을 줄줄히 설명을 하지 않았나 모르겠습니다. 그런데 문제는 실제로 알고자 하는 암호는 암호화 되어 있다는 것이죠. 말이 엉켰네요. 그럼 이렇게 말을 하지요. Password는 암호화가 되어 있습니다. 유닉스에는 crypt라는 암호함수가 있는데 이 함수의 특징은 역함수가 존재하지 않는다는 것이죠. 갑자기 수학이야기를 하는 것 같습니까? 그런데 실제로 수학이야기 예요. A라는 상태에서 B라는 상태는 갈 수 있어도 B에서 A라는 상태로는 갈 수 없다는 것이죠.
그렇다면은 실제 로그인 과정에서 우리가 직접 적어넣는 암호는 어떻게 판단이 될까요?
유닉스 시스템에서는 우리가 로그인 과정에서 적어넣은 password를 crypt함수로 암호화를 시켜 /etc/passwd파일과
비교를 해서 사용자 이름과 password가 암호화 된 것과 똑같은 경우에만 사용을 허가해 줍니다. 그럼 해킹을 어떻게 하자고 이렇게 너절하게 이야기를 했을까요?
/etc/passwd파일은 보통 누구다 볼 수 있도록 공개를 해 놓습니다.
이 passwd파

일을 갖다가 crypt함수를 이용해서 아무 글자나 집어넣어서 암호화된 password를 알아낼때까지 roop를 돌리는
것입니다.
무식한 무식하게 알아낸다고 말을 했쟎아요.
여기서 말하는 roop를 도는 프로그램이 바로 cracker라는 녀석이고 아무 글자라고 하는 것이 바로 단어 사전입니다.
다음은 간단한 cracker의 실제 Source입니다.
crack의 방법은 passwd파일에서 암호가 없는 사용자를 찾고 그다음으로 사용자 이름과 암호과 같은 것을 찾고 그다음 단어 사전의 단어들을 비교해가면서 찾습니다. 시간이 무지 오래 걸리는 작업이지만 알고리즘을 수정한다면 더 빠른 cracker를 만들 수 있을 것입니다.
#include
#include

#define fetch(a,b,c,d) fgets(a,130,b);c=strtok(a,":");d=strtok('\\0',":");

main()
{
FILE *p,*o,*w;
char i[50];
char pes[130],pas[50],pps[50],pws[50];
char *es=pes,*as=pas,*ps=pps,*ws=pws;
printf("\\nTinyCrack v1.0 Bluesman 1/95\\n\\n");

printf("Password File: ");
gets(i);
p=fopen(i,"r");

printf("WordList File: ");
gets(i);
w=fopen(i,"r");

printf("Results File: ");
gets(i);
o=fopen(i,"w");

fprintf(o,"*** PASS 1: NULL PASSWORDS ***\\n");
while(ps)
{
fetch(es,p,as,ps);
if(ps) if(ps[-1]==':') fprintf(o,"|User[%s] has no password!\\n",as);
}
fflush(o);
rewind(p);

fprintf(o,"*** PASS 2: ACCOUNT NAMES ***\\n");
do
{
fetch(es,p,as,ps);
if(ps) if(!strcmp((char *)crypt(as,ps),ps))
fprintf(o,"|User[%s]has password [%s]\\n",as,as);
}while(ps);
fflush(o);
rewind(p);
fprintf(o,"*** PASS 3: DICTIONARY WORDS ***\\n");
do{
rewind(w);
fetch(es,p,as,ps);
do
{
fgets(ws,130,w);
ws[strlen(ws)-1]=0;
if(!strcmp((char *)crypt(ws,ps),ps))
{
fprintf(o,"| User [%s] has password [%s]\\n",as,ws);
fflush(o);
break;
}
}while(!feof(w));
}while(!feof(p));
fprintf(o,"*** FINISHED SESSION ***\\n");
exit(1);
}

이방법에 의해서는 root뿐만이 아니라 다른 일반 사용자의 계정도 알아 낼 수 있습니다. 시간만 여유롭다면... 보안의 관점에서 생각한다면 이러한 해킹의 방법을 숙지하고 자신의 password를 정할때 어떤 단어로 이루져 있거나 자신의 사용자 이름을 직접 또는 간접적으로 이용했거나하는 경우는 피해야 하고 주기적인 password변경에 의해 password관리를 해야 겠습니다.
이와 같은 해킹방법의 관점에서 생각할 때 자신의 지금의 password에 특수문자를 끼워 넣는다면 password가 cracker에 의해 도용될 가능성은 몇 백배 줄어 들게 됩니다. 또 시스템 관리자라면 passwd파일을 위와 같은 방식으로 저장하지 않고 shadow파일을 만들어 password와 다른 사용자 정보를 분리시켜 놓는 것도 권장할 만한 것 입니다. 그런데 사실 shadow파일에 대한 해킹 방법도 알려져 있어서 문제가 되긴 하겠지만 시간과 해킹방법의 난의도에 의해 많은 해킹을 막을 수 있습니다.
shadow파일에 대한 이야기는 다음에 하겠습니다.


*벌레(Bug)로 집 갈가 먹기

유닉스 시스템에는 엄청나게 많은 프로그램 파일들이 존재합니다.
유닉스의 기본 철학이 "작은 도구들을 여러가지 이용하여 큰 일을 해결하자"(??? 라고 저도 들었어요.)입니다.
그래서 아주 크기가 작은 유틸리티나 명령어 들이 많죠.
그 많은 파일들을 사람이 만들었겠죠? 사람이 하는 일이다 보니 실수도 있는법이죠.