Skip to content

Latest commit

 

History

History
151 lines (125 loc) · 3.26 KB

thr3ads.md

File metadata and controls

151 lines (125 loc) · 3.26 KB

thr3ads (reverse, 400)

Solution

In main, it will launch 5 threads to run each stage:

    if ( pthread_create(&th1, 0LL, (void *(*)(void *))stage1, 0LL) ) {
        ...
    }
    if ( pthread_create(&th2, 0LL, (void *(*)(void *))stage2, &arg) ) {
        ...
    }
    if ( pthread_create(&th3, 0LL, (void *(*)(void *))stage3, 0LL) ) {
        ...
    }
    if ( pthread_create(&th4, 0LL, (void *(*)(void *))stage4, 0LL) ) {
        ...
    }
    if ( pthread_create(&th5, 0LL, (void *(*)(void *))stage5, 0LL) )
    {
        ...
    }

If all stages were qualified, the flag will be printed.

stage1

signed __int64 __fastcall stage1(void *arg) {
  arch = getenv("ARCH");
  ...
  for ( i = 0; ; ++i ) {
    pos = i;
    if ( pos >= strlen(arch) )
      break;
    s1[i] = arch[i] ^ 0xA;
  }
  if ( !strcmp(s1, "B:m]kx=y") ) {
    ...
    printf("\x1B[32m\n [:)] Stage 1 Qualified\x1B[0m", v3);
  }
}

Set ARCH to "B:m]kx=y" ^ 0xA, which is H0gWar7s to pass this stage.

stage2

signed __int64 __fastcall stage2(void *arg) {
  if ( *(_DWORD *)arg == *((char *)arg + 4) ) {
    printf("\x1B[32m\n [:)] Stage 2 Qualified\x1B[0m");
  }
}

int main(...) {
  ...
  arg = 'A';
  v8 = **(_BYTE **)(v6 + 8);
  if ( pthread_create(&th2, 0LL, (void *(*)(void *))stage2, &arg) )
}

This stage will pass if the argv[1] of the program is 'A'.

stage3

char *__fastcall stage3(void *a1) {
  printf("\x1B[35m\n Enter password for stage 3 :\x1B[33m");
  v1 = (unsigned __int64)fgets(s, 25, stdin);
  if ( v1 != -1 && strlen(s) == 24 ) {
    if ( !strcmp(s, "He_who_must_not_be_named") ) {
      printf("\x1B[32m [:)] Stage 3 Qualified\x1B[0m");
    }
  }
}

Input He_who_must_not_be_named to pass this stage.

stage4

void *__fastcall stage4(void *a1) {
  s2[0] = 'm';
  s2[1] = 'C';
  s2[2] = 'D';
  s2[3] = 'D';
  s2[4] = 'S';
  s2[5] = '\0';
  fp = fopen(".hidden.txt", "r");
  if ( fp ) {
    fgets(hidden, 6, fp);
    if ( strlen(hidden) == 5 ) {
      v4 = 42;
      for ( i = 0; i <= 4; ++i )
        hidden[i] ^= v4;
      if ( !strcmp(hidden, s2) ) {
        printf("\x1B[32m\n [:)] Stage 4 Qualified\x1B[0m", s2);
      }
    }
  }
}

Can pass this stage if the content of .hidden.txt is "mCDDS" ^ 42, which is Ginny.

stage5

void *__fastcall stage5(void *a1) {
  if ( getcwd(&buf, 0x400uLL) ) {
    if ( strlen(&buf) != 26 || buf[22] != 'a' ) {
      pthread_mutex_lock(&mutex);
      printf("\x1B[31m\n [:(] Stage 5 Failed\x1B[0m", 1024LL);
      pthread_mutex_unlock(&mutex);
    }
  }
}

We can pass this stage if the path length is 26 and the 22nd character of the path is 'a'.

So, finally, move the binary to a path where length is 26 and 22nd chracter is 'a', then run the following script.

#!/bin/bash

echo "He_who_must_not_be_named" | env ARCH="H0gWar7s" ./chall A
$ ./chall.sh
 [:)] Stage 5 Qualified
 [:)] Stage 1 Qualified
 [:)] Stage 2 Qualified
 Enter password for stage 3 : [:)] Stage 3 Qualified
 [:)] Stage 4 Qualified
[-->] No of stages cleared : 5
 -------------------------------------------
Verifying........
 [:)]  You seem to have Wizard origins
---------------------------------------------------------------------------
 The Vault is open
 Your Flag is == flag{W1th_L0v3_Fr0m_R3x!}