-
[2015 정보보호올림피아드]plzhackmeCTF 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