# Reverse / x0rr3al?!!
## Clue
Are you being x0rr3al with me right now?!
## My solution
Expected a lot of xor string obfuscation based on the title of the challenge.I opened up the Binary Ninja, and this is what greeted me when I opened up oneof the functions that looked interesting...
```0000156a  int64_t sub_156a()
0000156a  {00001576      void* fsbase;00001576      int64_t rax = *(int64_t*)((char*)fsbase + 0x28);00001599      int64_t var_38 = 0x71267032217f2271;0000159d      int64_t var_30 = 0x6b327c217a653279;000015b5      int64_t var_28 = 0x357c216073326722;000015b9      int64_t var_20 = 0x2666322323733266;000015bd      int16_t var_18 = 0x797e;000015c3      char var_16 = 0x33;000015f1      for (int32_t var_3c = 0; var_3c <= 0x22; var_3c = (var_3c + 1))000015e7      {000015e2          putchar(((int32_t)(*(int8_t*)(&var_38 + ((int64_t)var_3c)) ^ 0x12)));000015da      }000015f8      putchar(0xa);00001602      int64_t rax_8 = (rax ^ *(int64_t*)((char*)fsbase + 0x28));0000160b      if (rax_8 == 0)00001602      {00001613          return rax_8;00001613      }0000160d      __stack_chk_fail();0000160d      /* no return */0000160d  }```
It looks like it is obviously putting some data into a giant memory buffer,and then xor-ing it all, and then printing it out 1 character at a time.I tried to just cut-and-paste the pseudo-c from Binary Ninja into a littlestandalone C application, and when I ran it I got the following output:
```ck0t{   {R```
I decided to try to take a swag at manually cleaning it up and tweaking the codea little, and tried again to execute the function.
Code that was a little cleaned up:
```nt main(int argc, char** argv){        char buf[0x50];        memset(buf, 0, 0x50);
        uint64_t* ptr = (uint64_t*) buf;
        *ptr = 0x71267032217f2271;        ptr++;        *ptr = 0x6b327c217a653279;        ptr++;        *ptr = 0x357c216073326722;        ptr++;        *ptr = 0x2666322323733266;        ptr++;
        uint16_t* ptr2 = (uint16_t*) ptr;        *ptr2 = 0x797e;        ptr2++;
        uint8_t* ptr3 = (uint8_t*) ptr2;        *ptr3 = 0x33;       for(int i = 0; i < strlen(buf); i++)        {                buf[i] ^= 0x12;        }
        printf("Buf %s\n", buf);
        return 0;}```
When I ran this version:
```$ gcc sub156a.c -o sub156a$ ./sub156a Buf c0m3 b4ck wh3n y0u ar3n't a11 t4lk!```
Cool now we are getting somewhere.  I also tried to deobfuscate what sub1614 wasprinting, and got the following out of it:
```$ ./sub1614 Buf w00t w00t! y0u g0t th3 fl4g!```
Cool, so if I get sub1614 to execute, I'm should have the flag.
The area of code that was checking my password looked like the following:
```00001a82      printf("p4ss m3 th3 fl4g: ", 0x200);00001a9a      void var_48;00001a9a      __isoc99_scanf("%53s", &var_48);00001aaf      if (strlen(&var_48) != 0x35)00001aab      {00001ab6          sub_156a();00001ab6      }00001ac5      else00001ac5      {00001ac5          int32_t var_58_1 = 0;00001b57          while (true)00001b57          {00001b57              if (var_58_1 > 0x34)00001b53              {00001b62                  sub_1614();00001b67                  break;00001b67              }00001b12              if (sub_14f7(((int32_t)sub_150a(*(int8_t*)(&var_48 + ((int64_t)var_58_1)), 0))) != *(int32_t*)((((int64_t)var_58_1) << 2) + &data_40a0))00001b0d              {00001b19                  sub_156a();00001b23                  break;00001b23              }00001b39              if (rax_7 != sub_1483(main, 0x200))00001b29              {00001b40                  sub_16ad();00001b4a                  exit(1);00001b4a                  /* no return */00001b4a              }00001b4f              var_58_1 = (var_58_1 + 1);00001b4f          }00001b4f      }```
I briefly looked at reversing some of the flag obfuscation stuff, and justdecided no, I want this to be a password oracle.  If I can see / print var_58_1,which is a loop index, I can see how many correct password characters I have.I can then brute force the flag 1 character at a time, until I have the entireflag revealed.
So how did I accomplish this non-sense?
## Disable debugging and trace prevention code
The main function called ptrace to detect if I was debugging the binary, Binjamakes it trivial to invert a branch, so I created a new copy of the binarywith that patched that REQUIRED me to be debugging it to continue.
The main function also called sub_17a4, which was obviously checking somethingabout the execution environment. It was calling strstr to check on something, soI decided to LD_PRELOAD my own copy of strstr to determine what it was checkingand then make that check work into may favor / bypass the anti-debugging.
```char* strstr(const char* haystack, const char* needle){	printf("haystack=%s and needle=%s\n", haystack, needle);	return 0;}```
To build the library we are going to inject:
```gcc -shared -o injector.so -fPIC injector.c```
I eventually combined the building of the injector and executing the binaryinto a [script](inject.sh)
Executing that:```$ export LD_PRELOAD=./injector.so $ ./x0rr3alhaystack=-bash and needle=gdbhaystack=-bash and needle=ollydbghaystack=-bash and needle=stracehaystack=-bash and needle=ltracep4ss m3 th3 fl4g: ^C```
So at this point I was free to debug it and poke around in it.  I decided that Ireplaced the call sub_156a which normally signals a failure, with a call to myown function, I could easily inspect the stack and see how many passwordcharacters I had correctly.
I looked at how another part of the code called close() function.  I'm not veryproficient in x86 assembly, so I had to take apart the opcode a little myself,because I tried to get Binary Ninja to let me patch in a direct call to close,,but I couldn't get it to work.
But I soon discovered that the call instruction on x86 is simply 0xe8 followedby a 4 byte signed offset from PC.  PC already pointing to the instruction afterthe call, and the offset to close function in the plt.  So I was able to manuallyin the hex editor patch the call to sub_156a to call close instead.
And then I provided my own custom close function.  Close gets called once alreadybefore this code, so it just keeps track using a static counter how many timesit has been called, and on the second call can do some stack inspection.
This was code to inspect the stack:
```void dumpFrozenStack(int* stackAddr)                                                                                                                       {                                                                                                                                                                     printf("Stack Pointer near %p\n", stackAddr);                                                                                                                  for(int i = 0; i < 0x30; i+= 4)                                                                                                                               {                                                                                                                                                                     printf("0x%04x %08x %08x %08x %08x\n", i, stackAddr[i], stackAddr[i+1], stackAddr[i+2], stackAddr[i+3]);                                              }                                                                                                                                                     }         
int close(int fd)                                                                                                                                             {                                                                                                                                                                     static int closeCallTracker = 0;                                                                                                                              closeCallTracker++;                                                                                                                                           printf("close called %d times on fd = %d\n", closeCallTracker, fd);                                                                                            int dumbVar = 0;                                                                                                                                              if (closeCallTracker == 2)                                                                                                                                    {                                                                                                                                                                     dumpFrozenStack(&dumbVar);                                                                                                                            }                                                                                                                                                              return 0;                                                                                                                                             }```
Close creates a single stack variable, and passes the stack variable to a newfunction. That new function can create as many local variables as it wants, andit won't shift the location of dumbVar on the stack, which should be on top ofthe stack frame for the main function.
I know the flag format is vsctf, so I can try to verify the offset of the stackvariable that is tracking how many correct characters of the password have beenfound so far.  I'm easily able to pick out that stack variable, and then replacethe dump function with a shorter version that just prints out how many correctpassword characters we have:
```void dumpFrozenStack(int* stackAddr)                                                                                                                          {                                                                                                                                                             	printf("Num flag bytes correct = %d\n", stackAddr[11]);                                                                                               }```
I then created a python script to repeatedly call the program with my customfunctions and guess a password.  It just keeps guessing 1 character at a timeuntil the whole flag is revealed.
That script is [oracle_solve.py](oracle_solve.py)
The final [injector.c source](injector.c).
The python script will eventually crash after guessing 5 or 6 letters runningout of file descriptors, so I would just keep adding charcters to the initialflag and letting it brute force the missing characters.
Final Flag:
```vsctf{w34k_4nt1_d3bugg3rs_4r3_n0_m4tch_f0r_th3_31337}```