Tags: reverse 

Rating:

We have [file named triptych](https://github.com/KosBeg/ctf-writeups/raw/master/UIUCTF_2018/triptych)
```
pc@pc:~/ctfs$ file triptych
triptych: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=cff282fd463037bb5f9e2cb8febae912fa7603eb, not stripped
```
Load into disassembler or debugger. In main we have
```
void main(void) {
char flag[25];

fgets(flag, 25, stdin);
mprotect(&dword_400000, 0x1000, 7); // set RWX for range(0x400000, 0x401000)
the_first(flag);
}
```
->
```
void the_first(char *flag) {
int i;
char key[42];

strcpy(key, "lskvbsjcjflsksjcuyqocjmdnv66321i]';'falq[ ");
for ( i = 0; i < 245; ++i )
*(the_second + i) ^= key[i % 42]; // dynamic decryption of the_second
the_second(flag);
}
```
the_second after decryption ->
```
void the_second(char *flag) {
int i;
char key[42];

strcpy(key, "sjdsahhhhsiojcojjvb kwvavbkdsabk||'f8923;> ");
for ( i = 0; i < 245; ++i )
*(the_third + i) ^= key[i % 42]; // dynamic decryption of the_third
the_third(flag);
}
```
the_third after decryption ->
```
void the_third(char *flag) {
int i;
char key[42];

strcpy(key, "&^$^$slaivdgskg 32fir2igkgkds (*zop`~ !sia");
for ( i = 0; i < 352; ++i )
*(validate + i) ^= key[i % 42]; // and finally! dynamic decryption of validate
validate(flag);
}
```
validate ->
```
void validate(char *flag) {
int i, j, k;
char crypted[32];
char table[32];

strcpy(table, "_'qwertyuiop{}asdfghjklzxcvbnm|");
for ( i = 0; i <= 2; ++i )
{
if ( flag[i] <= 94 || flag[i] > 125 ) // only small letters and _`{|
exit(0);
for ( j = 0; j <= 23; ++j )
flag[j] = table[flag[j] - 95]; // some encryption
}
strcpy(crypted, "zmu}jnd{o{f_ndo{{_hz_{ga");
for ( k = 0; k <= 24; ++k )
{
if ( flag[k] != crypted[k] ) // compare crypted flag to hardcored string
exit(0);
}
puts("haha nice!"); // we win :D
}
```
So let's write script to decode it!
```
table = "_'qwertyuiop{}asdfghjklzxcvbnm|"
flag = list("zmu}jnd{o{f_ndo{{_hz_{ga")
for k in range(3):
for i, byte in enumerate(flag):
flag[i] = chr(table.find(byte) + 95)

print ''.join(flag) # flag{theres_three_of_em}
```