I'm trying to make a simple implementation of the Heartbleed Bug in C/C++ over Linux (Using ElementaryOS on vmplayer). From my understanding of the heartbleed bug, it involves the client sending a heartbeat request to the server, specifying a greater size for the included payload than the actual size of the payload, which results in the server including contents from memory that will be laid out after the local payload buffer, in the response.
What I have so far is a client/server application. The client connects to the server and sends a piece of sensitive information, in this case, a password. Next, the client sends a heartbeat request to the server, specifying the wrong size for the payload. I declare my local variables like this:
char password[30];// = new char[30]; //Some sensitve data, that will be accessed using the Heartbleed Bug
char temp[15];// = new char[15];
char payload[45];// = new char[45];
I retrieve the content from the heartbeat request like this:
int payloadSize = atoi(strtok(buffer, " "));
temp = strtok(NULL, "\n");
In the heartbeat request, the payload is "payload", and the size is 45. I then make a call to memcpy() like this:
memcpy(payload, temp, payloadSize /* 45 in this case */);
I'm expecting the payload variable to be hold the value "payload", followed by contents from the password variable. However payload holds the value "payload" only.
cout<<payload<<endl; //prints payload
Can anyone point out what I'm doing wrong?
All code:
int main()
{
ofstream log("ServerLog.txt");
int listeningSocket = socket(AF_INET, SOCK_STREAM, 0);
sockaddr_in serverAddress, clientAddress;
socklen_t clientLen;
serverAddress.sin_addr.s_addr = inet_addr("127.0.0.1");
serverAddress.sin_family = AF_INET;
serverAddress.sin_port = 54321;
if(bind(listeningSocket, (sockaddr *) &serverAddress, sizeof(serverAddress)) < 0)
{
cout<<strerror(errno)<<endl;
}
else
{
cout<<"Socket bound to port 12345"<<endl;
if(listen(listeningSocket, 5) < 0)
{
cout<<strerror(errno)<<endl;
}
else
{
log<<"Listening for connections now..."<<endl;
int commSocket = accept(listeningSocket, (sockaddr *) &clientAddress, &clientLen);
log<<"Now connected to a client..."<<endl;
int N = 0;
char buffer[100];// = new char[100];
char password[30];// = new char[30]; //Some sensitve data, that will be accessed using the Heartbleed Bug
char *temp = new char[15];
char payload[45];// = new char[45];
N = recv(commSocket, password, 100, 0); //Receive sensitive data, in this case, a password
if(N == 0) //Check for remote socket close
{
cout<<"The remote connection has been closed."<<endl;
}
else if(N < 0) //In case there is an error
{
cout<<strerror(errno)<<endl;
}
else //All good, move on
{
//cout<<N<<" "<<password<<endl;
log<<"Password received from client: "<<password<<" of length: "<<N<<endl;
N = recv(commSocket, buffer, 100, 0); //recv heartbeat request
if(N == 0) //Check for remote socket close
{
cout<<"The remote connection has been closed."<<endl;
}
else if(N < 0) //In case there is an error
{
cout<<strerror(errno)<<endl;
}
else
{
log<<"Heartbeat request received from client: "<<buffer<<endl;
int payloadSize = atoi(strtok(buffer, " "));
temp = strtok(NULL, "\n");
memcpy(payload, temp, 45);
if(N < 0)
{
cout<<strerror(errno)<<endl;
}
}
}
}
}
return 0;
}