欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

bufffer overflow

程序员文章站 2024-01-29 23:28:22
...

Introduction

The reson for buffer overflow is we set too many data to an array of finite length.
Attackers will utilize the feature,they may be construct a special string to assign values to arrays and construct specific address cover return address(EIP register value),the buffer will overflow and when the ESP pointer point original EIP address,it is already replaced by specific address attackers contructed.Now the return address will point the address attackers appointed.

Condition

it needs three conditions if you want take advantage of buffer overflow successfully:
(1) precise locaiton problem program return,we can overwrite it as any address
(2) ShellCode–providing code what we want
(3) JMP ESP address – taking the return address cover JMP ESP address,which can jump into ShellCode.

Example

Firstly,you should have 2 QQ account,certainly,you can use other account on other platform,but I use QQ account.
bufffer overflow
when you follow the directions to operate,you will gain a vetify code,when you use C program to send email,you should replace password with vetify code.
The code as following:

#ifdef WIN32
#include <windows.h>
#include <stdio.h>
#else

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <unistd.h>
#include <sys/time.h>
#endif
struct data6
{
	unsigned int d4 : 6;
	unsigned int d3 : 6;
	unsigned int d2 : 6;
	unsigned int d1 : 6;
};
// 协议中加密部分使用的是base64方法
char con628(char c6);
void base64(char *dbuf, char *buf128, int len);
void sendemail(char *email, char *body);
int open_socket(struct sockaddr *addr);
#pragma comment(lib, "ws2_32.lib")
int main()
{
	char email[] = "aaa@qq.com";
	char body[] = "From: \"lucy\"<aaa@qq.com>\r\n"
		"To: \"dasiy\"<aaa@qq.com>\r\n"
		"Subject: Hello\r\n\r\n"
		"Hello World, Hello Email!";
	sendemail(email, body);
	return 0;
}

char con628(char c6)
{
	char rtn = '\0';
	if (c6 < 26) rtn = c6 + 65;
	else if (c6 < 52) rtn = c6 + 71;
	else if (c6 < 62) rtn = c6 - 4;
	else if (c6 == 62) rtn = 43;
	else rtn = 47;
	return rtn;
}

// base64的实现
void base64(char *dbuf, char *buf128, int len)
{
	struct data6 *ddd = NULL;
	int i = 0;
	char buf[256] = { 0 };
	char *tmp = NULL;
	char cc = '\0';
	memset(buf, 0, 256);
	strcpy_s(buf, buf128);
	for (i = 1; i <= len / 3; i++)
	{
		tmp = buf + (i - 1) * 3;
		cc = tmp[2];
		tmp[2] = tmp[0];
		tmp[0] = cc;
		ddd = (struct data6 *)tmp;
		dbuf[(i - 1) * 4 + 0] = con628((unsigned int)ddd->d1);
		dbuf[(i - 1) * 4 + 1] = con628((unsigned int)ddd->d2);
		dbuf[(i - 1) * 4 + 2] = con628((unsigned int)ddd->d3);
		dbuf[(i - 1) * 4 + 3] = con628((unsigned int)ddd->d4);
	}
	if (len % 3 == 1)
	{
		tmp = buf + (i - 1) * 3;
		cc = tmp[2];
		tmp[2] = tmp[0];
		tmp[0] = cc;
		ddd = (struct data6 *)tmp;
		dbuf[(i - 1) * 4 + 0] = con628((unsigned int)ddd->d1);
		dbuf[(i - 1) * 4 + 1] = con628((unsigned int)ddd->d2);
		dbuf[(i - 1) * 4 + 2] = '=';
		dbuf[(i - 1) * 4 + 3] = '=';
	}
	if (len % 3 == 2)
	{
		tmp = buf + (i - 1) * 3;
		cc = tmp[2];
		tmp[2] = tmp[0];
		tmp[0] = cc;
		ddd = (struct data6 *)tmp;
		dbuf[(i - 1) * 4 + 0] = con628((unsigned int)ddd->d1);
		dbuf[(i - 1) * 4 + 1] = con628((unsigned int)ddd->d2);
		dbuf[(i - 1) * 4 + 2] = con628((unsigned int)ddd->d3);
		dbuf[(i - 1) * 4 + 3] = '=';
	}
	return;
}
// 发送邮件
void sendemail(char *email, char *body)
{
	int sockfd = 0;
	struct sockaddr_in their_addr = { 0 };
	char buf[1500] = { 0 };
	char rbuf[1500] = { 0 };
	char login[128] = { 0 };
	char pass[128] = { 0 };
#ifdef WIN32
	WSADATA WSAData;
	WSAStartup(MAKEWORD(2, 2), &WSAData);
#endif
	memset(&their_addr, 0, sizeof(their_addr));
	their_addr.sin_family = AF_INET;
	their_addr.sin_port = htons(25);
	their_addr.sin_addr.s_addr = inet_addr("121.51.131.77");//qq smtp 服务器
	// 连接邮件服务器,如果连接后没有响应,则2 秒后重新连接
	sockfd = open_socket((struct sockaddr *)&their_addr);
	memset(rbuf, 0, 1500);
	while (recv(sockfd, rbuf, 1500, 0) == 0)
	{
		printf("reconnect...\n");
		Sleep(2);
		//close(sockfd);
		sockfd = open_socket((struct sockaddr *)&their_addr);

		memset(rbuf, 0, 1500);
	}

	printf("%s\n", rbuf);

	// EHLO
	memset(buf, 0, 1500);
	sprintf_s(buf, "EHLO abcdefg-PC\r\n");
	send(sockfd, buf, strlen(buf), 0);
	memset(rbuf, 0, 1500);
	recv(sockfd, rbuf, 1500, 0);
	printf("%s\n", rbuf);

	// AUTH LOGIN
	memset(buf, 0, 1500);
	sprintf_s(buf, "AUTH LOGIN\r\n");
	send(sockfd, buf, strlen(buf), 0);
	printf("%s\n", buf);
	memset(rbuf, 0, 1500);
	recv(sockfd, rbuf, 1500, 0);
	printf("%s\n", rbuf);

	// USER
	memset(buf, 0, 1500);
	sprintf_s(buf, "XXX");//你的qq号
	memset(login, 0, 128);
	base64(login, buf, strlen(buf));
	sprintf_s(buf, "%s\r\n", login);
	send(sockfd, buf, strlen(buf), 0);
	printf("%s\n", buf);
	memset(rbuf, 0, 1500);
	recv(sockfd, rbuf, 1500, 0);
	printf("%s\n", rbuf);

	// PASSWORD
	sprintf_s(buf, "XXX");//你的qq密码
	//dokidbaotbifdijg 授权码
	memset(pass, 0, 128);
	base64(pass, buf, strlen(buf));
	sprintf_s(buf, "%s\r\n", pass);
	send(sockfd, buf, strlen(buf), 0);
	printf("%s\n", buf);

	memset(rbuf, 0, 1500);
	recv(sockfd, rbuf, 1500, 0);
	printf("%s\n", rbuf);

	// MAIL FROM
	memset(buf, 0, 1500);
	sprintf_s(buf, "MAIL FROM: <aaa@qq.com>\r\n");//your email
	send(sockfd, buf, strlen(buf), 0);
	memset(rbuf, 0, 1500);
	recv(sockfd, rbuf, 1500, 0);
	printf("%s\n", rbuf);

	// RCPT TO 第一个收件人
	sprintf_s(buf, "RCPT TO:<%s>\r\n", email);
	send(sockfd, buf, strlen(buf), 0);
	memset(rbuf, 0, 1500);
	recv(sockfd, rbuf, 1500, 0);
	printf("%s\n", rbuf);

	// DATA 准备开始发送邮件内容
	sprintf_s(buf, "DATA\r\n");
	send(sockfd, buf, strlen(buf), 0);
	memset(rbuf, 0, 1500);
	recv(sockfd, rbuf, 1500, 0);
	printf("%s\n", rbuf);

	// 发送邮件内容,\r\n.\r\n内容结束标记
	sprintf_s(buf, "%s\r\n.\r\n", body);
	send(sockfd, buf, strlen(buf), 0);
	memset(rbuf, 0, 1500);
	recv(sockfd, rbuf, 1500, 0);
	printf("%s\n", rbuf);

	// QUIT
	sprintf_s(buf, "QUIT\r\n");
	send(sockfd, buf, strlen(buf), 0);
	memset(rbuf, 0, 1500);
	recv(sockfd, rbuf, 1500, 0);
	printf("%s\n", rbuf);

	// VC2005 需要使用
	closesocket(sockfd);
	//    close(sockfd);
#ifdef WIN32
	WSACleanup();
#endif
	return;

}
// 打开TCP Socket连接
int open_socket(struct sockaddr *addr)
{
	int sockfd = 0;
	sockfd = socket(PF_INET, SOCK_STREAM, 0);
	if (sockfd < 0)
	{
		fprintf(stderr, "Open sockfd(TCP) error!\n");
		exit(-1);
	}
	if (connect(sockfd, addr, sizeof(struct sockaddr)) < 0)
	{
		fprintf(stderr, "Connect sockfd(TCP) error!\n");
		exit(-1);
	}
	return sockfd;
}

now you have sended email by C program,next we will write buffer overflow code.