【特集】

Mac OS X独自のディレクトリサービスOpen DirectoryとdsLocal(後編) - the inner universe of Leopard

13 リスト8: ntlmv2.c

    白山貴之  [2008/10/29]
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <iconv.h>
    #include <errno.h>
    #include <openssl/md4.h>
    #include <openssl/hmac.h>
    
    
    int toUCS2LE( const char *src, size_t srclen, char *dst, size_t dstlen )
    {
       const char  *p = (char *)src ;
             char  *q = (char *)dst ;
    
       iconv_t    ctx = iconv_open( "UCS-2LE", "ASCII" );
       int        len = iconv( ctx, &p, &srclen, &q, &dstlen );
    
       iconv_close( ctx );
    
       return len;
    }
    
    
    int makeNTLMv2Resnpose( const char         *user,
                            const char         *pass, 
                            const char    *challange, 
                            int         challangelen,
                            const char         *blob, 
                            int              bloblen,
                            const char       *domain, 
                                  char     *response )
    {
        int   i;
        int   userlen   = strlen( user );
        int   domainlen = strlen( domain );
        int   passlen   = strlen( pass   );
        char  uni_pass[ passlen *2 + 1 ];
        char  md4digest[ 16 ] ;
        char  user_domain[ userlen + domainlen ];
        char  uni_user_domain[ sizeof( user_domain ) *2 ];
        char  ntlmv2hash[ 16 ] ;
        int   hashlen = sizeof( ntlmv2hash );
    
        char  challange_blob[ challangelen + bloblen ];
        char  respdigest[ 16 ] ;
        int   resplen = sizeof( respdigest );
    
    
        toUCS2LE( pass, passlen, uni_pass, sizeof( uni_pass ) );
    
        MD4( (unsigned char *)uni_pass, passlen*2, (unsigned char *)&md4digest  );
        //printhex( md4digest, sizeof( md4digest ) );
    
        for( i = 0 ; i < userlen ; i++ )
            user_domain[ i ] = toupper( user[i] );
        for( i = 0 ; i < domainlen ; i++ )
            user_domain[ i+userlen ] = toupper( domain[i] );
        user_domain[ userlen+domainlen ] = '\0'; 
    
        toUCS2LE( user_domain, userlen+domainlen, uni_user_domain, sizeof( uni_user_domain ) );
        //printhex( uni_user_domain, sizeof( uni_user_domain ) );
        HMAC( EVP_md5(), 
                 (unsigned char *)md4digest, sizeof( md4digest ),
           (unsigned char *)uni_user_domain, sizeof( uni_user_domain ),
                (unsigned char *)ntlmv2hash, (unsigned int*) &hashlen );
        //printhex( ntlmv2hash, sizeof( ntlmv2hash ) );
    
        memcpy( challange_blob, challange, challangelen );
        memcpy( challange_blob + challangelen, blob, bloblen );
    
        //printhex( challange_blob, sizeof( challange_blob ) );
        HMAC( EVP_md5(),
              (unsigned char*) ntlmv2hash, sizeof( ntlmv2hash ), 
              (unsigned char*)challange_blob, sizeof( challange_blob ),
              (unsigned char*)respdigest, (unsigned int *)&resplen );
        //printhex( respdigest, sizeof( respdigest ) );
    
        memcpy( response, respdigest, sizeof( respdigest ) );
        memcpy( response +  sizeof( respdigest ), blob, bloblen );
    
        return 1; 
    }
    
    
    
    #ifdef __SINGLE_TEST__
    
    // special thanks for monyo.
    // http://www.monyo.com/technical/samba/translation/ntlm.html
    char *domain      = "DOMAIN" ;
    char *user        = "user" ;
    char *pass        = "SecREt01" ;
    char  challange[] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef };
    char  blob[]    = { 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // signature & reserved
                        0x00, 0x90, 0xd3, 0x36, 0xb7, 0x34, 0xc3, 0x01, // timestamp 
                        0xff, 0xff, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, // client once
                        0x00, 0x00, 0x00, 0x00, // unknown 1
                        0x02, 0x00, 0x0c, 0x00, 0x44, 0x00, 0x4f, 0x00, // target information
                        0x4d, 0x00, 0x41, 0x00, 0x49, 0x00, 0x4e, 0x00,
                        0x01, 0x00, 0x0c, 0x00, 0x53, 0x00, 0x45, 0x00,
                        0x52, 0x00, 0x56, 0x00, 0x45, 0x00, 0x52, 0x00,
                        0x04, 0x00, 0x14, 0x00, 0x64, 0x00, 0x6f, 0x00,
                        0x6d, 0x00, 0x61, 0x00, 0x69, 0x00, 0x6e, 0x00,
                        0x2e, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00,
                        0x03, 0x00, 0x22, 0x00, 0x73, 0x00, 0x65, 0x00,
                        0x72, 0x00, 0x76, 0x00, 0x65, 0x00, 0x72, 0x00,
                        0x2e, 0x00, 0x64, 0x00, 0x6f, 0x00, 0x6d, 0x00,
                        0x61, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x2e, 0x00,
                        0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x00, 0x00,
                        0x00, 0x00, 0x00, 0x00, 
                        0x00, 0x00             // unknown 2 
                      };
    char answer[]   = { 0xcb, 0xab, 0xbc, 0xa7, 0x13, 0xeb, 0x79, 0x5d,  // hmac-md5
                        0x04, 0xc9, 0x7a, 0xbc, 0x01, 0xee, 0x49, 0x83,
                        0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  // blob
                        0x00, 0x90, 0xd3, 0x36, 0xb7, 0x34, 0xc3, 0x01,
                        0xff, 0xff, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44, 
                        0x00, 0x00, 0x00, 0x00, 
                        0x02, 0x00, 0x0c, 0x00, 0x44, 0x00, 0x4f, 0x00, 
                        0x4d, 0x00, 0x41, 0x00, 0x49, 0x00, 0x4e, 0x00,
                        0x01, 0x00, 0x0c, 0x00, 0x53, 0x00, 0x45, 0x00, 
                        0x52, 0x00, 0x56, 0x00, 0x45, 0x00, 0x52, 0x00, 
                        0x04, 0x00, 0x14, 0x00, 0x64, 0x00, 0x6f, 0x00,
                        0x6d, 0x00, 0x61, 0x00, 0x69, 0x00, 0x6e, 0x00,
                        0x2e, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00,
                        0x03, 0x00, 0x22, 0x00, 0x73, 0x00, 0x65, 0x00,
                        0x72, 0x00, 0x76, 0x00, 0x65, 0x00, 0x72, 0x00, 
                        0x2e, 0x00, 0x64, 0x00, 0x6f, 0x00, 0x6d, 0x00,
                        0x61, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x2e, 0x00, 
                        0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x00, 0x00,
                        0x00, 0x00, 0x00, 0x00   
                      };
    
    
    int main( )
    {
        int  ret ;
        char response[1024];
    
        makeNTLMv2Resnpose( user, pass, 
                            challange, sizeof( challange ),
                            blob,      sizeof( blob ),
                            domain, response ) ;
    
        ret = memcmp( response, answer, sizeof(answer) );
        printf( "%s\n", ( ret ? "wrong" : "OK" ) );
    
        exit( 0 );
    }
    
    #endif
    

    関連記事

    関連サイト

    関連したタグ

    新着記事

    特設サイトの情報

      人気記事

      一覧

      イチオシ記事

      新着記事

      特別企画

      マイナビニュースマガジン