ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [2015 정보보호올림피아드]plzhackme
    CTF 2015. 10. 17. 17:10

    본선문제인데, 서빈이형이랑 나만 풀어서 풀이를 올린다 서빈이형은 아이다 원격디버깅으로 푸심 ㅂㄷㅂㄷ


    이 풀이는 맥 gdb가있어야하는데, 맥 gdb가 꿀인것을 깨달음





    ID를 입력하라한다. 여기서 내게 주어진 아이디는 user5인데, 입력하고 버튼을누르면 내부에서만 연산이되고 스트링은 출력되지않는다.


    예선문제에서는 터미널에 그냥나왔는데 부들부들


    __int64 __fastcall -[appController keygen:](__int64 a1, __int64 a2, __int64 a3)

    {

      void *v3; // rdi@1

      __int64 v4; // rax@1

      void *v5; // rax@1

      __int64 v6; // rax@1

      __int64 v7; // rax@1

      __int64 v8; // rax@1

      __int64 v9; // rax@1

      __int64 v10; // rax@1

      __int64 v11; // rax@1

      __int64 v12; // rax@1

      __int64 v13; // rax@1

      __int64 v14; // rax@1

      __int64 v15; // rax@1

      __int64 v16; // rax@1

      __int64 v17; // rax@1

      __int64 v18; // rax@1

      __int64 v19; // rax@1

      __int64 v20; // rax@1

      __int64 v21; // rax@1

      __int64 v22; // rax@1

      __int64 v23; // rax@1

      __int64 v24; // rax@3

      void *v25; // rax@10

      __int64 v26; // rax@10

      void *v27; // rax@10

      __int64 v28; // rax@10

      void *v29; // rax@10

      __int64 v30; // rax@10

      void *v31; // rax@10

      __int64 v32; // rax@10

      void *v33; // rax@10

      __int64 v34; // rax@10

      __int64 v36; // [sp+0h] [bp-170h]@1

      size_t v37; // [sp+8h] [bp-168h]@10

      size_t v38; // [sp+10h] [bp-160h]@10

      unsigned __int64 v39; // [sp+18h] [bp-158h]@4

      unsigned __int64 v40; // [sp+20h] [bp-150h]@4

      unsigned __int64 v41; // [sp+28h] [bp-148h]@3

      unsigned __int64 v42; // [sp+30h] [bp-140h]@3

      __int64 *v43; // [sp+38h] [bp-138h]@1

      __int64 *v44; // [sp+40h] [bp-130h]@1

      __int64 *v45; // [sp+48h] [bp-128h]@1

      __int64 *v46; // [sp+50h] [bp-120h]@1

      __int64 *v47; // [sp+58h] [bp-118h]@1

      __int64 v48; // [sp+60h] [bp-110h]@1

      __int64 v49; // [sp+68h] [bp-108h]@10

      __int64 v50; // [sp+70h] [bp-100h]@10

      __int64 v51; // [sp+78h] [bp-F8h]@10

      __int64 v52; // [sp+80h] [bp-F0h]@10

      __int64 v53; // [sp+88h] [bp-E8h]@10

      char *v54; // [sp+90h] [bp-E0h]@10

      char *v55; // [sp+98h] [bp-D8h]@10

      __int64 v56; // [sp+A0h] [bp-D0h]@3

      int v57; // [sp+ACh] [bp-C4h]@1

      int v58; // [sp+B0h] [bp-C0h]@1

      int v59; // [sp+B4h] [bp-BCh]@1

      __int64 *v60; // [sp+B8h] [bp-B8h]@1

      __int64 v61; // [sp+C0h] [bp-B0h]@1

      __int64 v62; // [sp+C8h] [bp-A8h]@1

      __int64 v63; // [sp+D0h] [bp-A0h]@1

      __int64 v64; // [sp+D8h] [bp-98h]@1

      __int64 v65; // [sp+E0h] [bp-90h]@1

      __int64 v66; // [sp+E8h] [bp-88h]@1

      __int64 v67; // [sp+F0h] [bp-80h]@1

      __int64 v68; // [sp+F8h] [bp-78h]@1

      __int64 v69; // [sp+100h] [bp-70h]@1

      void *v70; // [sp+108h] [bp-68h]@1

      int v71; // [sp+114h] [bp-5Ch]@1

      int v72; // [sp+118h] [bp-58h]@1

      int v73; // [sp+11Ch] [bp-54h]@1

      int v74; // [sp+120h] [bp-50h]@1

      int v75; // [sp+124h] [bp-4Ch]@1

      char *v76; // [sp+128h] [bp-48h]@1

      char *v77; // [sp+130h] [bp-40h]@1

      char *v78; // [sp+138h] [bp-38h]@1

      char *v79; // [sp+140h] [bp-30h]@1

      char *v80; // [sp+148h] [bp-28h]@1

      __int64 v81; // [sp+150h] [bp-20h]@1

      __int64 v82; // [sp+158h] [bp-18h]@1

      __int64 v83; // [sp+160h] [bp-10h]@1

      __int64 v84; // [sp+168h] [bp-8h]@1


      v84 = *__stack_chk_guard_ptr;

      v83 = a1;

      v82 = a2;

      v81 = 0LL;

      objc_storeStrong(&v81, a3);

      v80 = "helloolympiad";

      v79 = "olympiadisnothing";

      v78 = "welcometoloympiad";

      v77 = "isthisnothing?";

      v76 = "thisiscorrectanswer";

      v75 = strlen("helloolympiad");

      v74 = strlen("olympiadisnothing");

      v73 = strlen("welcometoloympiad");

      v72 = strlen("isthisnothing?");

      v71 = strlen("thisiscorrectanswer");

      v3 = *(void **)(v83 + OBJC_IVAR___appController_label2);

      v48 = *(_QWORD *)objc_msgSend_ptr;

      objc_msgSend_ptr(v3, paSetstringvalue, &cfstr_Helloworld);

      ((void (__fastcall *)(_QWORD, char *, __CFString *))v48)(

        *(_QWORD *)(v83 + OBJC_IVAR___appController_label3),

        paSetstringvalue,

        &cfstr_Helloworld2);

      ((void (__fastcall *)(_QWORD, char *, __CFString *))v48)(

        *(_QWORD *)(v83 + OBJC_IVAR___appController_label4),

        paSetstringvalue,

        &cfstr_Helloworld3);

      ((void (__fastcall *)(_QWORD, _QWORD, __CFString *))v48)(

        *(_QWORD *)(v83 + OBJC_IVAR___appController_label5),

        paSetstringvalue,

        &cfstr_Helloworld4);

      LODWORD(v4) = ((int (__fastcall *)(_QWORD, char *))v48)(

                      *(_QWORD *)(v83 + OBJC_IVAR___appController_label),

                      paStringvalue);

      LODWORD(v5) = objc_retainAutoreleasedReturnValue(v4);

      v70 = v5;

      LODWORD(v6) = ((int (__fastcall *)(_QWORD, char *))v48)(

                      *(_QWORD *)(v83 + OBJC_IVAR___appController_label2),

                      paStringvalue);

      LODWORD(v7) = objc_retainAutoreleasedReturnValue(v6);

      v69 = v7;

      LODWORD(v8) = ((int (__fastcall *)(_QWORD, _QWORD))v48)(

                      *(_QWORD *)(v83 + OBJC_IVAR___appController_label3),

                      paStringvalue);

      LODWORD(v9) = objc_retainAutoreleasedReturnValue(v8);

      v68 = v9;

      LODWORD(v10) = ((int (__fastcall *)(_QWORD, _QWORD))v48)(

                       *(_QWORD *)(v83 + OBJC_IVAR___appController_label4),

                       paStringvalue);

      LODWORD(v11) = objc_retainAutoreleasedReturnValue(v10);

      v67 = v11;

      LODWORD(v12) = ((int (__fastcall *)(_QWORD, _QWORD))v48)(

                       *(_QWORD *)(v83 + OBJC_IVAR___appController_label5),

                       paStringvalue);

      LODWORD(v13) = objc_retainAutoreleasedReturnValue(v12);

      v66 = v13;

      LODWORD(v14) = objc_retainAutorelease(v70);

      LODWORD(v15) = ((int (__fastcall *)(__int64, char *))v48)(v14, paUtf8string);

      v65 = v15;

      LODWORD(v16) = objc_retainAutorelease(v69);

      LODWORD(v17) = ((int (__fastcall *)(__int64, char *))v48)(v16, paUtf8string);

      v64 = v17;

      LODWORD(v18) = objc_retainAutorelease(v68);

      LODWORD(v19) = ((int (__fastcall *)(__int64, _QWORD))v48)(v18, paUtf8string);

      v63 = v19;

      LODWORD(v20) = objc_retainAutorelease(v67);

      LODWORD(v21) = ((int (__fastcall *)(__int64, _QWORD))v48)(v20, paUtf8string);

      v62 = v21;

      LODWORD(v22) = objc_retainAutorelease(v66);

      LODWORD(v23) = ((int (__fastcall *)(__int64, _QWORD))v48)(v22, paUtf8string);

      v61 = v23;

      v60 = &v36;

      v58 = 0;

      v57 = 0;

      v59 = 0;

      v47 = (__int64 *)((char *)&v36 - (((unsigned int)(v75 + 1) + 15LL) & 0xFFFFFFFFFFFFFFF0LL));

      v46 = (__int64 *)((char *)&v36 - (((unsigned int)(v74 + 1) + 15LL) & 0xFFFFFFFFFFFFFFF0LL));

      v45 = (__int64 *)((char *)&v36 - (((unsigned int)(v73 + 1) + 15LL) & 0xFFFFFFFFFFFFFFF0LL));

      v44 = (__int64 *)((char *)&v36 - (((unsigned int)(v72 + 1) + 15LL) & 0xFFFFFFFFFFFFFFF0LL));

      v43 = (__int64 *)((char *)&v36 - (((unsigned int)(v71 + 1) + 15LL) & 0xFFFFFFFFFFFFFFF0LL));

      while ( v59 < v75 )

      {

        v42 = v59;

        v41 = (unsigned __int64)objc_msgSend(v70, paLength);

        v57 = getLCM(*(_BYTE *)(v65 + v42 % v41), (unsigned int)v80[v59]);

        LODWORD(v24) = makeKey();

        v56 = v24;

        setKey(v24);

        if ( 1 == v57 )

        {

          v40 = v59;

          v39 = (unsigned __int64)objc_msgSend(v70, paLength);

          v57 = v80[v59] ^ *(_BYTE *)(v65 + v40 % v39);

        }

        if ( v57 < 65 )

        {

          v57 = 65 - v57;

          v58 = v80[v59] - 65;

          v57 += v58;

        }

        if ( v57 > 90 )

        {

          v58 = v57 - 90;

          v57 -= v59 + v57 - 90;

        }

        *((_BYTE *)v47 + v59) = v57;

        *((_BYTE *)v46 + v59) = v57 + 1;

        *((_BYTE *)v45 + v59) = v57 + 2;

        *((_BYTE *)v44 + v59) = v57 + 3;

        *((_BYTE *)v43 + v59++) = v57 + 4;

      }

      v55 = "select * from yourbrain where olyimpiad = 2015";

      v54 = "insert into yourbrain values(fk2)";

      v38 = strlen("select * from yourbrain where olyimpiad = 2015");

      v37 = strlen(v54);

      v25 = objc_msgSend(&OBJC_CLASS___NSString, paStringwithutf8, v45);

      LODWORD(v26) = objc_retainAutoreleasedReturnValue(v25);

      v53 = v26;

      v27 = objc_msgSend(&OBJC_CLASS___NSString, paStringwithutf8, v47);

      LODWORD(v28) = objc_retainAutoreleasedReturnValue(v27);

      v52 = v28;

      v29 = objc_msgSend(&OBJC_CLASS___NSString, paStringwithutf8, v46);

      LODWORD(v30) = objc_retainAutoreleasedReturnValue(v29);

      v51 = v30;

      v31 = objc_msgSend(&OBJC_CLASS___NSString, paStringwithutf8, v43);

      LODWORD(v32) = objc_retainAutoreleasedReturnValue(v31);

      v50 = v32;

      v33 = objc_msgSend(&OBJC_CLASS___NSString, paStringwithutf8, v44);

      LODWORD(v34) = objc_retainAutoreleasedReturnValue(v33);

      v49 = v34;

      objc_msgSend(*(void **)(v83 + OBJC_IVAR___appController_keylabel), paSetstringvalue, v52);

      objc_msgSend(*(void **)(v83 + OBJC_IVAR___appController_keylabel2), paSetstringvalue, v53);

      objc_msgSend(*(void **)(v83 + OBJC_IVAR___appController_keylabel3), paSetstringvalue, v50);

      objc_msgSend(*(void **)(v83 + OBJC_IVAR___appController_keylabel4), paSetstringvalue, v49);

      objc_msgSend(*(void **)(v83 + OBJC_IVAR___appController_keylabel5), paSetstringvalue, v51);

      objc_storeStrong(&v49, 0LL);

      objc_storeStrong(&v50, 0LL);

      objc_storeStrong(&v51, 0LL);

      objc_storeStrong(&v52, 0LL);

      objc_storeStrong(&v53, 0LL);

      objc_storeStrong(&v66, 0LL);

      objc_storeStrong(&v67, 0LL);

      objc_storeStrong(&v68, 0LL);

      objc_storeStrong(&v69, 0LL);

      objc_storeStrong(&v70, 0LL);

      objc_storeStrong(&v81, 0LL);

      return *__stack_chk_guard_ptr;

    }


    핵심함수의 코드인데, 보면 별거없어보이는데 키젠소스이다.


    일단 오프셋을구해줘야댐


    __text:000000010000238D loc_10000238D:                          ; CODE XREF: -[appController keygen:]+3B3j

    __text:000000010000238D                 lea     rax, aInsertIntoYour ; "insert into yourbrain values(fk2)"

    __text:0000000100002394                 lea     rcx, aSelectFromYour ; "select * from yourbrain where olyimpiad"...

    __text:000000010000239B                 mov     [rbp+var_D8], rcx

    __text:00000001000023A2                 mov     [rbp+var_E0], rax

    __text:00000001000023A9                 mov     rdi, [rbp+var_D8] ; char *

    __text:00000001000023B0                 call    _strlen

    __text:00000001000023B5                 mov     rdi, [rbp+var_E0] ; char *

    __text:00000001000023BC                 mov     [rbp+var_160], rax

    __text:00000001000023C3                 call    _strlen

    __text:00000001000023C8                 mov     rcx, cs:off_1000070F0

    __text:00000001000023CF                 mov     rsi, cs:paStringwithutf8

    __text:00000001000023D6                 mov     rdi, rcx

    __text:00000001000023D9                 mov     rdx, [rbp+var_128]

    __text:00000001000023E0                 mov     [rbp+var_168], rax



    이미 연산이 끝난곳에 브레이크포인트를걸고 실행을해주면 연산이되겠지 하고 브레이크포인트를 걸었다.


    gdb에서 해주면


    (gdb) b *0x00000001000023E0

    Breakpoint 1 at 0x1000023e0

    (gdb) r

    Starting program: /Users/Songsangjun/Downloads/plzhackme.app/Contents/MacOS/plzhackme


    아이디입력창이뜨는데 거기에 user5를 입력하고 제너레이트버튼을 누른다.


    그럼 내부에서 실행되고, 이게 당연히 스택에 있다는걸 알고 rsp 를 확인해봤다.


    (브포 이상한곳에걸면 연산이 끝나고 종료되는곳이나 연산중인건데 키가 이상하게뽑힌다.)


    브레이크포인트를 이쪽에 건이유는 삽질하다가 루프가 돌면서 키가 생성되는데, ni로 하나하나하려했지만 너무 오래걸려서 그냥 브포걸고 끝냈다.


    (gdb) x/100s $rsp

    0x7fff5fbfec80: "OS\\R^YQWRIQSR\177"

    0x7fff5fbfec8f: ""

    0x7fff5fbfec90: "\300\354\277_\377\177"

    0x7fff5fbfec97: ""

    0x7fff5fbfec98: "\335\v\017\210\377\177"

    0x7fff5fbfec9f: ""

    0x7fff5fbfeca0: "NR[Q]XPVQHPRQ"

    0x7fff5fbfecae: ""

    0x7fff5fbfecaf: ""

    0x7fff5fbfecb0: "MQZP\\WOUPGOQP\177"

    0x7fff5fbfecbf: ""

    0x7fff5fbfecc0: "user5"

    0x7fff5fbfecc6: ""

    0x7fff5fbfecc7: ""

    0x7fff5fbfecc8: ""

    0x7fff5fbfecc9: ""

    0x7fff5fbfecca: ""

    0x7fff5fbfeccb: ""

    0x7fff5fbfeccc: ""

    0x7fff5fbfeccd: ""

    0x7fff5fbfecce: ""

    0x7fff5fbfeccf: ""

    0x7fff5fbfecd0: "LPYO[VNTOFNPO"

    ---Type <return> to continue, or q <return> to quit---

    0x7fff5fbfecde: ""

    0x7fff5fbfecdf: ""

    0x7fff5fbfece0: "\003"

    0x7fff5fbfece2: ""

    0x7fff5fbfece3: ""

    0x7fff5fbfece4: "\201\024"

    0x7fff5fbfece7: ""

    0x7fff5fbfece8: "\325\037g\205\377\177"

    0x7fff5fbfecef: ""

    0x7fff5fbfecf0: "KOXNZUMSNEMON"


    보면 맨밑에 키가있다. 그래서 그냥 풀었는데 극혐이였다






    'CTF' 카테고리의 다른 글

    [EKOPARTY]pwn50  (0) 2015.10.26
    [CodeGate 2014]nuclear  (0) 2015.10.22
    [Hansei Wargame]Pwnable  (0) 2015.10.08
    HDCON 2013 exploit  (0) 2015.10.07
    [CSAW 2015]Reversing 500  (0) 2015.10.06

    댓글

Designed by Tistory.