Search

'레인보우 테이블'에 해당되는 글 2건

  1. 2013.04.25 Creating hashes on the Apple OS X
  2. 2013.04.22 Rainbow Table

Creating hashes on the Apple OS X

CR@K 이야기 2013. 4. 25. 18:05 Posted by TEAMCR@K

저희 TeamCR@K 사무실 한 곳에서 조용하게 자리잡고 있는 식구 하나가 있습니다.


이름하야 Mac Pro...




한동안 너무 바빠 신경 써 주지 못했던 OS X에게 새로운 역할을 줘 보았습니다.

기존 레인보우 테이블에 해시를 생성하던 일을 OS X에서 해 보려고 하는데요.

해시 생성 코드는 리눅스 기반으로 만들고 테스트 했던지라 BSD 유틸 기반인 OS X에서도 잘 동작하리라 생각합니다.


OS X에서 포팅을 준비하면서 테스트코드 하나를 컴파일 해 봤습니다.


#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>


int main(void)

{

        char buf[1024];


        bzero(buf, sizeof(buf));

        strcpy(buf, "test!\n");

        fprintf(stdout, "%s", buf);

        return 0;

}


컴파일 시도 결과 다음과 같은 메세지를 출력하는군요.



보통 리눅스 시스템에서 사용하는 C컴파일러 명령으로는 gcc가 있는데 유닉스 환경과 호환성을 위해 cc 명령으로 심볼릭 링크를 생성해 놓습니다.

OS X 콘솔 터미널에서 컴파일 테스트를 하던 도중 무의식적으로 cc 명령을 사용했는데 gcc 명령과는 다른 Warning 구문을 출력해 주네요.

cc 명령을 사용한 결과에서 함수 원형이 선언되어 있지 않아 출력되는 경고 구문에 대해서는 일반 gcc 결과와 다를게 없었습니다.

그러나 잘 살펴보면 다음 두 가지에 변화가 있다는 것 을 알 수 있습니다.


1. 소스코드 내에서 함수 원형이 선언되어 있지 않은 함수에 대해 기본 시스템 헤더파일들 중 같은 이름으로 선언된 함수의 원형을 출력


2. note 태그를 사용하여 참조된 기본 시스템 헤더파일 정보를 출력


cc 명령의 결과 형태가 XCode IDE에 활용되는지는 아직 잘 모르겠습니다.

그러나 기본 gcc 경고구문보다는 진일보 된 경고구문이 아닐까 생각해봅니다.


cc 명령 결과 형태에 깜짝놀라 이야기가 잠시 딴 곳으로 샜습니다만..

여차저차해서 컴파일을 마무리 했습니다.


만들어져 있던 레인보우 테이블에서 일반 평문에 비해 해시 데이터가 많이 부족하기 때문에 지금 실행하는 프로그램에서 평문 데이터 저장을 잠시 미루도록 했습니다.



fork()를 사용하여 프로세스 별로 해시 데이터를 생성하도록 했는데 전체적으로 시스템에도 크게 지장을 주지 않는 범위내에서 실행되고 있는 것 같습니다.


오늘부터 OS X는 사무실 한 곳에서 묵묵히 그리고 쉼 없이.. 해시 데이터를 생성하게 되겠네요..

Rainbow Table

CR@K 이야기 2013. 4. 22. 22:24 Posted by TEAMCR@K

2012년 연말을 기점으로 저희 팀에 새 식구가 하나 늘었습니다.


동수?.....

는 아니고요...


Buffalo NAS 장비 입니다.

아래 보이는 바로 요 놈 입니다.


Buffalo NAS 장비


요 NAS 장비는 총 12TB 정도의 여유를 가지고 있습니다.

이 여유공간을 어떻게 활용할까 곰곰히 생각해 보다가 Rainbow Table로 일부 활용 해 보기로 했습니다.


DB Schema를 작성하고, DBMS를 구동하고

또 쉼 없이 데이터를 생성하는 프로그램도 작성해서 돌려봅니다.

데이터 작성만 해서는 의미가 없습니다.

작성된 데이터를 활용해 웹에서 해시를 검색하는 웹 UI도 만들어 봅니다.


아래는 만들어진 Rainbow 테이블을 서치 해 볼 수 있는 화면입니다.



일반 평문은 약 3억개 정도이며 각 해시 데이터들이 그 뒤를 잇고 있습니다.

평문에 먼저 데이터를 쌓도록 해 놓은 것이 주로 알파벳 26자와 숫자로 이루어진 단어들이며, 후일에 숫자만으로 된 데이터들도 추가했습니다.

현재 숫자 데이터는 8자리 숫자 데이터까지 검색 가능합니다.


이렇게 써 보다가 약간은 불편한게 생겼습니다.

해시 데이터가 다수 일 때...

물론 삽질을 좋아하는 누군가는 일일이 하나하나의 해시를 검색하고 그 결과를 보는것으로 만족 할 지 모릅니다.

하지만 역시 불편합니다.

그래서 해시 데이터를 파일로 업로드하여 검색하는 기능도 추가했습니다.


일단 해당 기능을 테스트 하기 위해 일반 단어사전을 생성합니다.

리눅스에 기본적으로 존재하는 단어사전에서 그 단어들을 100개 정도 추립니다.



이것을 기준으로 약 100개의 SHA-1 해시를 생성해 봅니다.



해당 데이터를 웹에 업로드 하여 테스트 해 봅니다.



DB에서 찾을 수 있는 해시보다 찾지 못하는 해시가 아직은 더 많습니다.


아래는 레인보우 테이블을 생성하는 코드 중 일부입니다.


>>> snip <<<


pthread_t threads[MAX_THREAD];

int is_interrupt = -1;

int is_pause = -1;

int is_failed = -1;


unsigned char lower_case[] = {

    'a','b','c','d','e','f','g','h','i','j',

    'k','l','m','n','o','p','q','r','s','t',

    'u','v','w','x','y','z', '\0'

};

unsigned char upper_case[] = {

    'A','B','C','D','E','F','G','H','I','J',

    'K','L','M','N','O','P','Q','R','S','T',

    'U','V','W','X','Y','Z', '\0'

};

unsigned char number_case[] = {

    '0','1','2','3','4','5','6','7','8','9', '\0' // 10

};

unsigned char special_case[] = {

    '`','~','!','@','#','$','%','^','&','*',

    '(',')','-','_','=','+','[','{',']','}',

    '\\','|',';',':','\'','"',',','<','.','>',

    '/','?', '\0'

};


unsigned char base[128];


>>> snip <<<


        memset(init_pass, 0x00, sizeof(init_pass));


        for(i = s; i < e; i++) {
            max += pow(count, i) + 0.0;
        }

        for(i = 0; i < max + s; i++) {
            j = 0;
            while(base[j] != '\0') {
                memset(pass, 0x00, sizeof(pass));
                init_pass[sizeof(init_pass) - 1] = init_pass[sizeof(init_pass) - 1] + 1;
                idx = 0;
                for(k = 0; k < sizeof(init_pass); k++) {
                    if(init_pass[k] != '\0') {
                        if(base[init_pass[k] - 1] == '\'') {
                            pass[idx] = '\\';
                            idx++;
                        }
                        if(base[init_pass[k] - 1] == '\\') {
                            pass[idx] = '\\';
                            idx++;
                        }
                        pass[idx] = base[init_pass[k] - 1];
                        idx++;
                    }
                }
                //fprintf(stdout, "[%.0f] Pass: %s\n", total, pass);
                snprintf(sql, sizeof(sql), "INSERT INTO %s(value) VALUES('%s')", info->tblname, pass);
                j++;
                total++;
                if(mysql_query(conn, sql)) {
                    //fprintf(stdout, "%s\n", mysql_error(conn));
                    continue;
                }
            }
>>> snip <<<


지속적으로 데이터를 축적해 나가다 보면 언젠가는 쓸만한 레인보우 테이블이 될 것 같습니다.