The binary is a c++ compiled code under MIPS architecture that takes the flag as a command line argument. It uses a c++ list to store the whole flag in binary form and a class called Wires to store 3 'bits' (words in fact) in 3 different fields. In order to access those field the class has 4 different functions, one to initialize the 3 fields, and others to retrieve the value of the each one of them.
A vector of type Wires is created in order to store the flag , e.i : the previously created list is converted to that vector. The difference is that each field of the vector stores 3 'bits' now and each new field is pushed onto the back of the vector.
After setting up the vector, the binary start to somehow shuffle (check script) the bits around using a recursive function that calls itself 8196 times. Finally, the result vector is converted to a string a compared to another string in memory :
"0001101001000111110001100001101011000110010110111100010011001010100110011...etc"
Here's a C script automating the process and printing the flag :
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <conio.h> | |
#define last (sizeof(Vector1)/sizeof(Wires))-1 | |
#define size sizeof(Vector1)/sizeof(Wires) | |
typedef struct | |
{ | |
int First; | |
int Second; | |
int Third; | |
} Wires; | |
/*The binary string*/ | |
Wires Vector1[56] = {{0,0,0},{1,1,0},{1,0,0},{1,0,0},{0,1,1},{1,1,1},{0,0,0},{1,1,0},{0,0,0},{1,1,0},{1,0,1},{1,0,0},{0,1,1},{0,0,1},{0,1,1},{0,1,1},{1,1,0},{0,0,1},{0,0,1},{1,0,0},{1,0,1},{0,1,0},{0,1,1},{0,0,1},{1,0,1},{1,1,0},{1,0,0},{0,1,0},{0,1,0},{1,1,0},{1,0,0},{1,1,0},{0,1,0},{0,0,1},{1,1,0},{0,1,0},{1,1,0},{0,1,1},{1,0,0},{1,0,1},{0,1,1},{1,1,0},{0,0,0},{0,0,1},{1,0,1},{1,0,1},{0,0,1},{0,1,1},{1,1,1},{1,0,1},{1,0,0},{0,0,0},{0,1,1},{0,1,1},{0,0,0},{1,1,0}}; | |
Wires Vector2[56]; | |
void MixThingsUp(int Value) | |
/* | |
This is similar to the original routine | |
*/ | |
{ | |
int i; | |
int tmp; | |
if(Value > 0) | |
{ | |
//ModifyVectorWires | |
for(i=0;i<size;i++) | |
{ | |
if(Vector1[i].First == 1) | |
{ | |
tmp = Vector1[i].Second; | |
Vector1[i].Second = Vector1[i].Third; | |
Vector1[i].Third = tmp; | |
} | |
} | |
//ReverseWireThirdField | |
memcpy(Vector2,Vector1,sizeof(Vector1)); | |
for(i=0;i<size;i++) | |
{ | |
if(i == 0) | |
{ | |
Vector2[0].First = Vector1[last].Third; | |
Vector2[0].Second = Vector1[0].First; | |
Vector2[0].Third = Vector1[0].Second; | |
} | |
else | |
{ | |
Vector2[i].First = Vector1[i-1].Third; | |
Vector2[i].Second = Vector1[i].First; | |
Vector2[i].Third = Vector1[i].Second; | |
} | |
} | |
memcpy(Vector1,Vector2,sizeof(Vector2)); | |
MixThingsUp(Value-1); | |
} | |
} | |
void ReversedMixThingsUp(int Value) | |
/* | |
The reversed routine | |
*/ | |
{ | |
int i; | |
int tmp; | |
if(Value > 0) | |
{ | |
memcpy(Vector2,Vector1,sizeof(Vector1)); | |
//ReverseWireThirdField | |
for(i=0;i < size ;i++) | |
{ | |
if(i == 0) | |
{ | |
Vector2[i].First = Vector1[i].Second; | |
Vector2[i].Second = Vector1[i].Third; | |
Vector2[last].Third = Vector1[0].First; | |
} | |
else | |
{ | |
Vector2[i].First = Vector1[i].Second; | |
Vector2[i].Second = Vector1[i].Third; | |
Vector2[i-1].Third = Vector1[i].First; | |
} | |
} | |
memcpy(Vector1,Vector2,sizeof(Vector1)); | |
//ModifyVectorWires | |
for(i=0;i<size;i++) | |
{ | |
if(Vector1[i].First == 1) | |
{ | |
tmp = Vector1[i].Second; | |
Vector1[i].Second = Vector1[i].Third; | |
Vector1[i].Third = tmp; | |
} | |
} | |
ReversedMixThingsUp(Value-1); | |
} | |
} | |
void BinToStr(char flag[],char bin[],int sz) | |
{ | |
int i,j; | |
char c; | |
for(i=0;i<sz;i+=8) | |
{ | |
c = 0; | |
for(j=0;j<8;j++) | |
{ | |
c = c << 1; | |
c |= bin[i+j]; | |
} | |
flag[i/8] = c; | |
} | |
} | |
int main() | |
{ | |
int i,j=0; | |
char flag[32] = {0}; | |
char bin[256]; | |
ReversedMixThingsUp(8196); | |
for(i=0;i<size;i++) | |
{ | |
bin[j++] = (char) Vector1[i].First; | |
bin[j++] = (char) Vector1[i].Second; | |
bin[j++] = (char) Vector1[i].Third; | |
} | |
BinToStr(flag,bin,j); | |
printf("Flag is : %s",flag); | |
return 0; | |
} |
binary download : here
See you again soon.
Follow me on twitter : here