2011년 7월 14일 목요일

분산 기반의 CPU/GPU 해쉬 크랙 프로젝트 'Durandal'

이전에 해쉬 값 크랙과 관련하여 몇번 소개한 적이 있다. 오늘은 분산 기반의 GPU 를 이용한
해쉬 크랙 프로젝트인 'Durandal' 을 알아볼까 한다. 여기서 언급하는 것은,  보안적인 관점에서 소개하는 것이지, 악의적 형태로 이용되기를 원하지는 않는다. 암호화된 패스워드도 얼마나 쉽게 깨질 수 있는지, 왜 패스워드 문자열을 길게 사용해야 하는지 그 이유를 알게될 것이다.

우선 이와 관련해 소개된 이전 블로그를 참고해 보기 바란다.

2010년09월15일 8자리 패스워드는 저리가~ 12자리 패스워드를 사용하자 
2010년11월23일 당신의 패스워드는 안전한가? 클라우드 기반 패스워드 크랙킹
2010년12월01일 자바스크립트기반의 분산 해쉬 크랙킹

일단, Durandal 은 아래 사이트를 방문하면 정보를 얻을 수 있다.
http://durandal-project.org/

윈도우, 리눅스를 지원하며 현재는 64비트만 코드가 공개되어 있다. 32비트도 곧 공개되어 질 것이라고 한다. MD5, SHA1, SHA256, SHA512, NTLMv1, MySQL 의 HASH 를 지원하며, Nvidia 의 CUDA 를 지원한다. 즉, GPU 이용이 가능하며 또 다른 주요 특징으로 분산처리가 지원된다는 점이다.

윈도우 사용자는 바이너리를 다운로드 받아 사용할 수 있으며, 리눅스 사용자라면 아래와 같은 방법으로 하면 된다. 필자가 좋아하는 데비안 사용자라 가정하면, 우선 컴파일에 필요한 패키지를 설치하고 소스를 받아 컴파일을 하면 된다.

$ apt-get install cmake make g++ libboost-serialization-dev libboost-thread-dev libboost-system-dev libboost-filesystem-dev

$ git clone http://durandal-project.org/durandal/

$ cd durandal

$ ./install_linux.sh

컴파일이 완료된 후 부터는 따로 어떤 메뉴얼이 없어서, 직접 실행해 보고야 알았다. 설치된 후 바이너리도 해당 디렉토리 밑에 있는 것이 아니라 한단계 상위 디렉토리인 bin 아래에 들어 있다.

# ls -l
total 48592
-rwxr-xr-x 1 root root 13972420 Jul 12 22:11 admin
-rwxr-xr-x 1 root root 18445133 Jul 12 22:13 agent
-rwxr-xr-x 1 root root    98929 Jul 12 22:13 cudump
-rwxr-xr-x 1 root root 17149247 Jul 12 22:14 durandal

durandal 은 메인 서버로 동작하는 프로그램이다. 실행하게 되면 포트번호 지정과 패스워드
그리고 관리용 포트, 관리용 패스워드를 정의한다.

# ./durandal
________                                  .___        .__
 \______ \  __ ______________     ____   __| _/_____   |  |
 |    |  \|  |  \_  __ \__  \   /    \ / __ | \__  \  |  |
 |    `   \  |  /|  | \// __ \_|   |  | /_/ |  / __ \_|  |__
 /_______  /____/ |__|  (____  /|___|  |____ | (____  /|____/
        \/                  \/      \/     \/      \/
Durandal Server 0.5

Distributing server port ? 1111
Password for distributing server ?
Administration server port ? 1112
Password for administration server ?

Daemonizing server...
서버포트는 1111, 그리고 관리용은 1112 로 지정하였다.  프로세스를 확인해 보면 동작하고
있음을 알 수 있다.

# ps -ef | grep durandal
root     29331     1  0 22:26 ?        00:00:00 ./durandal
root     29335 19079  0 22:26 pts/7    00:00:00 grep durandal
# netstat -na | grep 1111
tcp        0      0 0.0.0.0:1111            0.0.0.0:*               LISTEN

다음으로는 agent 를 동작시켰다. 앞서 정의한 Durandal 서버 접속 주소와 패스워드를 입력한다.
사용될 CPU 는 자동으로 검출되어 8개를 입력하였고, GPU 도 자동으로 잘 인식되었다.
그러면, 몇 가지 Hash 기능등을 테스트 하면서 얼마나 빠른 속도로 가능한지 수치를 보여준다. Bruteforce 로 md5 를 할 경우 초당 138.576 Mhash 가 나왔다. GPU 의 힘인가 보다.

# ./agent

________                                  .___        .__
 \______ \  __ ______________     ____   __| _/_____   |  |
 |    |  \|  |  \_  __ \__  \   /    \ / __ | \__  \  |  |
 |    `   \  |  /|  | \// __ \_|   |  | /_/ |  / __ \_|  |__
 /_______  /____/ |__|  (____  /|___|  |____ | (____  /|____/
        \/                  \/      \/     \/      \/
Durandal Agent 0.5

Durandal server (host:port)? localhost:1111
Password?
Proxy (host:port, empty if no)?
8 CPU(s) detected. How many CPU(s) to use? [default: 8]
1 CUDA-device(s) detected (GeForce GTS 450).
How many device(s) to use? [default: 1]

Intel(R) Core(TM) i7 CPU         870  @ 2.93GHz: 8 hardware threads
CUDA support loaded: 1 CUDA-device(s) (GeForce GTS 450)
Remote Durandal server: localhost:1111
Proxy: no

Evaluating graphic card, your screen may freeze (it can take several
minutes)... done.

Benchmarking hash functions for bruteforce attack... done.

Benchmarking hash functions for dictionary attack... done.

Benchmarking hash functions for markov attack... done.

Benchmarks for bruteforce attack :
md5: 138.576 Mhash/s
sha1: 47.7707 Mhash/s
sha256: 9.47407 Mhash/s
ntlmv1: 91.8744 Mhash/s
mysql: 10.161 Mhash/s
mysqlpre4.1: 195.07 Mhash/s

Benchmarks for dictionary attack :
md5: 19.25 Mhash/s
sha1: 13.8209 Mhash/s
sha256: 7.54898 Mhash/s
ntlmv1: 31.337 Mhash/s
mysql: 8.91741 Mhash/s
mysqlpre4.1: 41.478 Mhash/s

Benchmarks for markov attack :
md5: 39.5677 Mhash/s
sha1: 16.8386 Mhash/s
sha256: 8.2687 Mhash/s
ntlmv1: 43.7967 Mhash/s
mysql: 10.689 Mhash/s
mysqlpre4.1: 55.4634 Mhash/s

Segmentation fault

그런데 나의 경우는 Segmentation 이 발생하였다. 간단히 살펴보았더니, 앞서 서버 접속주소를
localhost 로 사용하였는데, 127.0.0.1 로 다시 지정하니 문제 없었다. 약간의 버그등은 있다.

다시 제대로 실행되면 아래와 같은 문구가 계속 나온다. 즉, 에이전트로서 명령을 기다리고 있다는 것이다.

No running jobs
No running jobs
No running jobs
No running jobs
No running jobs
No running jobs
No running jobs

그럼, 이제 admin 을 접속해 보자. 접속하면 사용 가능한 명령어들이 나오는데, 테스트로
다음의 MD5 를 넣어보았다.

21232f297a57a5a743894a0e4a801fc3

사전방식이 아니라 bruteforce 방식으로 지정했다.
$ ./admin
Usage: ./admin server [-p port] [-k password]
$ ./admin 127.0.0.1 -p 1112 -k 1111
Commands:
add <computation_mode = bf,dico> <hash_type> <hash> [charset]
[time_task] [max_len_pass]
add <computation_mode = markov> <hash_type> <hash> <-time or -level>
<value> <max_len_pass> [time_task]
del <job_id>
show running jobs
show complete jobs
show stats
estimate mkvtime <markov_level> <max_len_pass>
estimate mkvlevel <computation_time> <max_len_pass>
> add bf md5 21232f297a57a5a743894a0e4a801fc3
> show stats
-------------
Global benchmark: 0 MHash/s
> show stats
banana - 127.0.0.1: 138 MHash/s, Intel(R) Core(TM) i7 CPU         870
@ 2.93GHz (8 core(s)), GeForce GTS 450 (1 device(s))
-------------
Global benchmark: 138 MHash/s
Add 를 하게 되면 아래와 같이 agent 콘솔에서 Job 을 받았다는 메시지가 나타난다.

No running jobs
No running jobs
No running jobs
No running jobs
Job#0 Task#0 : Z to miWjFj on 21232f297a57a5a743894a0e4a801fc3 (md5)
No running jobs
No running jobs

금방 작업이 끝난 것 같은데, show complete jobs 로 확인해 보면 HASH 해독 결과가 나타난다.
패스워드는 "admin" 이라고 말이다. 2분도 안되는 시간에 금방 해독이 되었다.

> show stats
> show complete jobs
Job 0 : bruteforce attack on md5 hash 21232f297a57a5a743894a0e4a801fc3
with charset abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ,
task time 120 sec, max length pass 15, result : "admin"
>

다음으로는 조금 더 긴 문자열인 'packetinside' 를 사용하였다. 그런데, 계속 해독작업이 진행되며 Job 이793 번까지 실행되는 과정까지도 해독되지 않았다. 패스워드가 길어짐에 따라, 해독하는 시간도 상당히 증가한 것이다. (2틀이 지난 시점까지도 해독되지 않았다)

No running jobs
Job#2 Task#0 : Z to miWjFj on 48bd28f405a9e3713ac0605a48b2bd0b (md5)
Job#2 Task#1 : miWjFj to zpRsjsZ on 48bd28f405a9e3713ac0605a48b2bd0b (md5)
Job#2 Task#2 : zpRsjsZ to MwMBNAY on 48bd28f405a9e3713ac0605a48b2bd0b (md5)
.
.
.
Job#2 Task#787 : MMxQHTtO to ZTsZlctO on 48bd28f405a9e3713ac0605a48b2bd0b (md5)
Job#2 Task#788 : ZTsZlctO to mboiQksO on 48bd28f405a9e3713ac0605a48b2bd0b (md5)
Job#2 Task#789 : mboiQksO to zijrutrO on 48bd28f405a9e3713ac0605a48b2bd0b (md5)
Job#2 Task#790 : zijrutrO to MpeAYBqO on 48bd28f405a9e3713ac0605a48b2bd0b (md5)
Job#2 Task#791 : MpeAYBqO to ZwZICKpO on 48bd28f405a9e3713ac0605a48b2bd0b (md5)
Job#2 Task#792 : ZwZICKpO to mEURgToO on 48bd28f405a9e3713ac0605a48b2bd0b (md5)
Job#2 Task#793 : mEURgToO to zLPaLboO on 48bd28f405a9e3713ac0605a48b2bd0b (md5)

왜, 패스워드를 단순하게 사용하면 안되는지를 보여주는 것이다. 물론, 컴퓨팅 파워를 상당히 높이면 초당 처리할 수 있는 HASH 는 훨씬 높아질 것이다. 더군다나, 분산기술을 이용하고 GPU 를 사용하니 좋은 성능의 컴퓨터 시스템만 구성하여 배치한다면 해독 시간은 짧아질 것이다.

자, 그렇다면 이제 여러분이 해야 할 일은, "패스워드를 길게 사용합시다" :-)

/Rigel

댓글 없음:

댓글 쓰기