Sunday, March 1, 2015

Boston key party 2015 - Community College Reversing 300 Writeup

Hi,
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 :
#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;
}
view raw flag.c hosted with ❤ by GitHub
flag : myheadmateisafredkin!

binary download : here
See you again soon.
Follow me on twitter : here