PicoCTF - not crypto

PicoCTF - not crypto

Source code

:::spoiler IDA Pseudo Source COde

__int64 __fastcall main(int a1, char **a2, char **a3)
{
  __int128 *v4; // rax
  unsigned __int8 v5; // di
  unsigned __int8 v6; // si
  unsigned __int8 v7; // cl
  unsigned __int8 v8; // dl
  unsigned int v9; // r8d
  unsigned __int8 v10; // r11
  int v16; // eax
  __int64 v17; // rdx
  unsigned int v18; // r12d
  char *v20; // r15
  unsigned __int8 v25; // r8
  int v30; // esi
  unsigned __int8 v32; // r12
  unsigned __int8 v36; // r14
  unsigned __int8 v38; // dl
  unsigned __int8 v40; // cl
  char v42; // r12
  char v43; // r14
  char v44; // al
  __int64 v45; // r13
  unsigned __int8 v46; // r10
  unsigned __int8 v47; // bp
  unsigned __int8 v48; // bl
  unsigned __int8 v49; // r8
  unsigned __int8 v50; // r11
  char v51; // dl
  char v54; // r10
  __int64 v63; // rdx
  char v72; // al
  unsigned __int8 v84; // [rsp+Ah] [rbp-1FEh]
  unsigned __int8 v85; // [rsp+Bh] [rbp-1FDh]
  int v86; // [rsp+Ch] [rbp-1FCh]
  int v87; // [rsp+10h] [rbp-1F8h]
  unsigned __int8 v88; // [rsp+14h] [rbp-1F4h]
  unsigned __int8 v89; // [rsp+15h] [rbp-1F3h]
  unsigned __int8 v90; // [rsp+16h] [rbp-1F2h]
  unsigned __int8 v91; // [rsp+17h] [rbp-1F1h]
  unsigned __int8 v92; // [rsp+18h] [rbp-1F0h]
  unsigned __int8 v93; // [rsp+19h] [rbp-1EFh]
  unsigned __int8 v94; // [rsp+1Ah] [rbp-1EEh]
  unsigned __int8 v95; // [rsp+1Bh] [rbp-1EDh]
  unsigned __int8 v96; // [rsp+1Ch] [rbp-1ECh]
  char v97; // [rsp+1Dh] [rbp-1EBh]
  char *v98; // [rsp+20h] [rbp-1E8h]
  unsigned __int8 v99; // [rsp+2Ah] [rbp-1DEh]
  char v100; // [rsp+50h] [rbp-1B8h]
  char v101; // [rsp+52h] [rbp-1B6h]
  char v102; // [rsp+54h] [rbp-1B4h]
  char v103; // [rsp+56h] [rbp-1B2h]
  char v104; // [rsp+58h] [rbp-1B0h]
  char v105; // [rsp+5Ah] [rbp-1AEh]
  char v106; // [rsp+5Ch] [rbp-1ACh]
  char v107; // [rsp+5Eh] [rbp-1AAh]
  __int128 v108; // [rsp+60h] [rbp-1A8h]
  char ptr[64]; // [rsp+70h] [rbp-198h] BYREF
  __int128 v110; // [rsp+B0h] [rbp-158h] BYREF
  char v111; // [rsp+C0h] [rbp-148h] BYREF
  char v112[15]; // [rsp+150h] [rbp-B8h] BYREF
  __int128 v113; // [rsp+160h] [rbp-A8h]
  __int128 v115[4]; // [rsp+180h] [rbp-88h] BYREF
  char v116; // [rsp+1C0h] [rbp-48h] BYREF
  unsigned __int64 v117; // [rsp+1C8h] [rbp-40h]

  v117 = __readfsqword(0x28u);
  puts("I heard you wanted to bargain for a flag... whatcha got?");
  __asm { vmovdqa xmm0, cs:xmmword_21A0 }
  v4 = &v110;
  v5 = -104;
  v6 = 50;
  v7 = 108;
  v8 = 28;
  __asm { vmovdqa [rsp+208h+var_158], xmm0 }
  v9 = 4;
  do
  {
    if ( (v9 & 3) == 0 )
    {
      v10 = byte_20A0[v6];
      v6 = byte_20A0[v7];
      v7 = byte_20A0[v8];
      v8 = byte_20A0[v5];
      v5 = byte_2080[v9 >> 2] ^ v10;
    }
    v5 ^= *v4;
    ++v9;
    v4 = (v4 + 4);
    v6 ^= *(v4 - 3);
    v7 ^= *(v4 - 2);
    v8 ^= *(v4 - 1);
    *(v4 + 12) = v5;
    *(v4 + 13) = v6;
    *(v4 + 14) = v7;
    *(v4 + 15) = v8;
  }
  while ( v9 != 44 );
  __asm
  {
    vmovdqa xmm0, cs:xmmword_21B0
    vmovdqa [rsp+208h+var_A8], xmm0
  }
  fread(ptr, 1uLL, 0x40uLL, stdin);
  __asm
  {
    vmovdqa xmm0, cs:xmmword_21C0
    vmovdqa [rsp+208h+var_88], xmm0
    vmovdqa xmm0, cs:xmmword_21D0
  }
  v108 = v110;
  __asm
  {
    vmovdqa [rsp+208h+var_78], xmm0
    vmovdqa xmm0, cs:xmmword_21E0
    vmovdqa [rsp+208h+var_68], xmm0
    vmovdqa xmm0, cs:xmmword_21F0
    vmovdqa [rsp+208h+var_58], xmm0
  }
  v100 = v112[0];
  v101 = v112[2];
  v102 = v112[4];
  v103 = v112[6];
  v104 = v112[8];
  v105 = v112[10];
  v106 = v112[12];
  v107 = v112[14];
  v98 = v115;
  v16 = 16;
  do
  {
    if ( v16 == 16 )
    {
      v20 = &v111;
      __asm { vmovdqa xmm4, [rsp+208h+var_A8] }
      LOBYTE(v87) = byte_20A0[(v113 ^ v108)];
      __asm { vpextrb rax, xmm4, 4 }
      LOBYTE(v86) = byte_20A0[(BYTE4(v108) ^ _RAX)];
      v94 = byte_20A0[BYTE8(v113) ^ BYTE8(v108)];
      __asm { vpextrb rax, xmm4, 0Ch }
      v93 = byte_20A0[(BYTE12(v108) ^ _RAX)];
      __asm { vpextrb rax, xmm4, 1 }
      v25 = byte_20A0[(BYTE1(v108) ^ _RAX)];
      __asm { vpextrb rax, xmm4, 5 }
      v85 = byte_20A0[(BYTE5(v108) ^ _RAX)];
      __asm { vpextrb rax, xmm4, 9 }
      v84 = byte_20A0[(BYTE9(v108) ^ _RAX)];
      __asm { vpextrb rax, xmm4, 0Dh }
      v92 = byte_20A0[(BYTE13(v108) ^ _RAX)];
      __asm { vpextrb rax, xmm4, 2 }
      LOBYTE(v30) = byte_20A0[(BYTE2(v108) ^ _RAX)];
      __asm { vpextrb rax, xmm4, 6 }
      v32 = byte_20A0[(BYTE6(v108) ^ _RAX)];
      __asm { vpextrb rax, xmm4, 0Ah }
      v91 = byte_20A0[(BYTE10(v108) ^ _RAX)];
      __asm { vpextrb rax, xmm4, 0Eh }
      v96 = v32;
      v88 = v25;
      v90 = byte_20A0[(BYTE14(v108) ^ _RAX)];
      __asm { vpextrb rax, xmm4, 3 }
      v36 = byte_20A0[(BYTE3(v108) ^ _RAX)];
      __asm { vpextrb rax, xmm4, 7 }
      v95 = v36;
      v38 = byte_20A0[(BYTE7(v108) ^ _RAX)];
      __asm { vpextrb rax, xmm4, 0Bh }
      v40 = byte_20A0[(BYTE11(v108) ^ _RAX)];
      __asm { vpextrb rax, xmm4, 0Fh }
      v89 = byte_20A0[(HIBYTE(v108) ^ _RAX)];
      do
      {
        v42 = v91 ^ v89 ^ v87 ^ v85;
        v99 = v87 ^ v89;
        v43 = v90 ^ v95 ^ v86 ^ v84;
        v97 = v30 ^ v38 ^ v94 ^ v92;
        v44 = v40 ^ v96 ^ v93 ^ v88;
        v45 = ((2 * (v86 ^ v95)) ^ (27 * ((v86 ^ v95) >> 7)) ^ v95 ^ v43 ^ v20[7]);
        v46 = v20[10] ^ v97 ^ v30 ^ (27 * ((v30 ^ v38) >> 7)) ^ (2 * (v30 ^ v38));
        v47 = v20[11] ^ v97 ^ v38 ^ (2 * (v38 ^ v94)) ^ (27 * ((v38 ^ v94) >> 7));
        v48 = v88 ^ v44 ^ v20[13] ^ (2 * (v88 ^ v96)) ^ (27 * ((v88 ^ v96) >> 7));
        v49 = v96 ^ v44 ^ v20[14] ^ (27 * ((v40 ^ v96) >> 7)) ^ (2 * (v40 ^ v96));
        v50 = v44 ^ v20[15] ^ v40 ^ (2 * (v40 ^ v93)) ^ (27 * ((v40 ^ v93) >> 7));
        LOBYTE(v87) = byte_20A0[((2 * (v87 ^ v85)) ^ (27 * ((v87 ^ v85) >> 7)) ^ v42 ^ *v20 ^ v87)];
        LOBYTE(v86) = byte_20A0[((2 * (v86 ^ v84)) ^ (27 * ((v86 ^ v84) >> 7)) ^ v86 ^ v43 ^ v20[4])];
        v94 = byte_20A0[((2 * (v94 ^ v92)) ^ (27 * ((v94 ^ v92) >> 7)) ^ v94 ^ v97 ^ v20[8])];
        v93 = byte_20A0[((27 * ((v93 ^ v88) >> 7)) ^ (2 * (v93 ^ v88)) ^ v93 ^ v20[12] ^ v44)];
        v88 = byte_20A0[((2 * (v85 ^ v91)) ^ (27 * ((v85 ^ v91) >> 7)) ^ v85 ^ v42 ^ v20[1])];
        v85 = byte_20A0[((27 * ((v84 ^ v90) >> 7)) ^ (2 * (v84 ^ v90)) ^ v84 ^ v43 ^ v20[5])];
        v84 = byte_20A0[((27 * ((v30 ^ v92) >> 7)) ^ (2 * (v30 ^ v92)) ^ v20[9] ^ v97 ^ v92)];
        v92 = byte_20A0[v48];
        v51 = v91 ^ v42 ^ v20[2];
        v20 += 16;
        v30 = byte_20A0[((2 * (v91 ^ v89)) ^ (27 * ((v91 ^ v89) >> 7)) ^ v51)];
        v96 = byte_20A0[((27 * ((v90 ^ v95) >> 7)) ^ (2 * (v90 ^ v95)) ^ v43 ^ *(v20 - 10) ^ v90)];
        v91 = byte_20A0[v46];
        v90 = byte_20A0[v49];
        v40 = byte_20A0[v47];
        v38 = byte_20A0[v45];
        v95 = byte_20A0[((27 * (v99 >> 7)) ^ (2 * v99) ^ v89 ^ v42 ^ *(v20 - 13))];
        v89 = byte_20A0[v50];
      }
      while ( v112 != v20 );
      LOBYTE(v30) = v105 ^ v30;
      LOBYTE(v87) = v100 ^ v87;
      _R15D = v30;
      __asm { vmovd   xmm5, r15d }
      v54 = v86;
      LOBYTE(v86) = v103 ^ v90;
      _R9D = (v101 ^ v91);
      _R10D = (v102 ^ v54);
      _EDX = (v107 ^ v96);
      _R13D = (v104 ^ v94);
      __asm
      {
        vmovd   xmm4, edx
        vmovd   xmm7, r9d
        vpinsrb xmm5, xmm5, ebx, 1
        vmovd   xmm3, r10d
      }
      v63 = 15LL;
      _ESI = (v106 ^ v93);
      __asm
      {
        vmovd   xmm1, r13d
        vmovd   xmm0, [rsp+208h+var_1F8]
        vmovd   xmm6, [rsp+208h+var_1FC]
        vpinsrb xmm7, xmm7, [rsp+208h+var_1FD], 1
        vpinsrb xmm0, xmm0, eax, 1
        vpinsrb xmm1, xmm1, r11d, 1
        vpunpcklwd xmm0, xmm0, xmm7
      }
      v72 = HIBYTE(v113);
      __asm
      {
        vpinsrb xmm3, xmm3, [rsp+208h+var_1FE], 1
        vpinsrb xmm6, xmm6, [rsp+208h+var_1F4], 1
        vpunpcklwd xmm1, xmm1, xmm5
        vpunpcklwd xmm3, xmm3, xmm6
        vmovd   xmm2, esi
        vpunpckldq xmm0, xmm0, xmm3
        vpinsrb xmm2, xmm2, r8d, 1
        vpinsrb xmm4, xmm4, ecx, 1
        vpunpcklwd xmm2, xmm2, xmm4
        vpunpckldq xmm1, xmm1, xmm2
        vpunpcklqdq xmm0, xmm0, xmm1
        vmovdqa [rsp+208h+var_98], xmm0
      }
      if ( HIBYTE(v113) != 0xFF )
        goto LABEL_14;
      v72 = BYTE14(v113);
      HIBYTE(v113) = 0;
      v63 = 14LL;
      if ( BYTE14(v113) != 0xFF )
        goto LABEL_14;
      v72 = BYTE13(v113);
      BYTE14(v113) = 0;
      v63 = 13LL;
      if ( BYTE13(v113) != 0xFF )
        goto LABEL_14;
      v72 = BYTE12(v113);
      BYTE13(v113) = 0;
      v63 = 12LL;
      if ( BYTE12(v113) != 0xFF )
        goto LABEL_14;
      v72 = BYTE11(v113);
      BYTE12(v113) = 0;
      v63 = 11LL;
      if ( BYTE11(v113) != 0xFF )
        goto LABEL_14;
      v72 = BYTE10(v113);
      BYTE11(v113) = 0;
      v63 = 10LL;
      if ( BYTE10(v113) != 0xFF )
        goto LABEL_14;
      v72 = BYTE9(v113);
      BYTE10(v113) = 0;
      v63 = 9LL;
      if ( BYTE9(v113) != 0xFF )
        goto LABEL_14;
      v72 = BYTE8(v113);
      BYTE9(v113) = 0;
      v63 = 8LL;
      if ( BYTE8(v113) != 0xFF )
        goto LABEL_14;
      v72 = BYTE7(v113);
      BYTE8(v113) = 0;
      v63 = 7LL;
      if ( BYTE7(v113) != 0xFF )
        goto LABEL_14;
      v72 = BYTE6(v113);
      BYTE7(v113) = 0;
      v63 = 6LL;
      if ( BYTE6(v113) != 0xFF )
        goto LABEL_14;
      v72 = BYTE5(v113);
      BYTE6(v113) = 0;
      v63 = 5LL;
      if ( BYTE5(v113) != 0xFF )
        goto LABEL_14;
      v72 = BYTE4(v113);
      BYTE5(v113) = 0;
      v63 = 4LL;
      if ( BYTE4(v113) != 0xFF )
        goto LABEL_14;
      v72 = BYTE3(v113);
      BYTE4(v113) = 0;
      v63 = 3LL;
      if ( BYTE3(v113) != 0xFF )
        goto LABEL_14;
      v72 = BYTE2(v113);
      BYTE3(v113) = 0;
      v63 = 2LL;
      if ( BYTE2(v113) != 0xFF )
        goto LABEL_14;
      v72 = BYTE1(v113);
      BYTE2(v113) = 0;
      v63 = 1LL;
      if ( BYTE1(v113) == 0xFF && (v72 = v113, BYTE1(v113) = 0, v63 = 0LL, v113 == 0xFF) )
      {
        LOBYTE(v113) = 0;
        v16 = 0;
      }
      else
      {
LABEL_14:
        *(&v113 + v63) = v72 + 1;
        v16 = 0;
      }
    }
    v17 = v16++;
    *v98++ ^= *(&v115[-1] + v17);
  }
  while ( &v116 != v98 );
  v18 = memcmp(v115, ptr, 0x40uLL);
  if ( v18 )
  {
    v18 = 1;
    puts("Nope, come back later");
  }
  else
  {
    puts("Yep, that's it!");
  }
  return v18;
}

:::

Recon

這一題一開始要我們輸入些東西,應該是flag,不用管中間的一些操作,可以先考慮最後怎麼判斷是不是回答正確就好,可以看到他最後call了一個memcmp的system function,應該就是用來判斷,所以我們只要continue到那裡,應該就會知道原本的flag是多少了

Exploit

$ gdb not-crypto
gef➤  starti
gef➤  vmmap # 確認目前code sction的base address是多少
gef➤  b *(0x0000555555555000+0x3b9)
gef➤  c
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa # fake flag for temp
gef➤  x/s 0x00007fffffffd730
0x7fffffffd730: "picoCTF{c0mp1l3r_0pt1m1z4t10n_15_pur3_w1z4rdry_but_n0_pr0bl3m?}\n\226\327\377\377\377\177"

Flag: picoCTF{c0mp1l3r_0pt1m1z4t10n_15_pur3_w1z4rdry_but_n0_pr0bl3m?}

Reference

pico reverse - not crypto wp -