Rating:

## get the input sorted

After downloading and starting the program, you are asked to "Enter_the_actual_flag:", without suffix "fb{" and prefix "}", through syscall 0x2000003. These 0x1c Bytes will be stored on the stack [rbp-0x110] and split in three quadwords a = [rbp-0x58], b = [rbp-0x60] and c = [rbp-0x68] and a doubleword d = [rbp-0x6c].

## calculate second halfs of the flag

The three pairs (a,b), (b,c) and (c,d) are xored and compared to saved values. We can easily calculate half of every qword a, b and c because the second half of d is zero.

```
#! /usr/bin/python3

def get_char(number, i):
return chr(int.to_bytes(number, 8, 'big')[i])

def print_table(xor, c1, n1, c2, n2):
print('chr(' + c1 + ') :', ' ', ' ', ' ', ' ',get_char(n1, 4), get_char(n1, 5), get_char(n1, 6), get_char(n1, 7))
print(c1 + ' :', hex(n1)[2:])
print(c2 + ' :', hex(n2)[2:])
print(c1 + '^' + c2 + ' :', hex(xor)[2:], '\n')

c_xor_d = 0x196b561a6b335f66 #copy out of cutter && reverse
d = 0xffffffff00000000
c = d ^ c_xor_d

b_xor_c = 0x4400595a5f413b39
b = c ^ b_xor_c

a_xor_b = 0x686f375755250300
a = b ^ a_xor_b

print_table(a_xor_b, 'a', a, 'b', b)
print_table(b_xor_c, 'b', b, 'c', c)
print_table(c_xor_d, 'c', c, 'd', d)
```

output:
```
chr(a) : a W g _
a : cafbc7e86157675f
b : a294f0bf3472645f
a^b : 686f375755250300

chr(b) : 4 r d _
b : a294f0bf3472645f
c : e694a9e56b335f66
b^c : 4400595a5f413b39

chr(c) : k 3 _ f
c : e694a9e56b335f66
d : ffffffff00000000
c^d : 196b561a6b335f66
```

## calculate first halfs of the flag

Unfortunately we are not able to calculate the first half of each qword or d itself. But we can reduce the possible characters in the alphabet from the given xored values.

```
#! /usr/bin/python3

from itertools import chain

count = 0
ret = ''
solList = [0x68, 0x6f, 0x37, 0x57, 0x55, 0x25, 0x3, 0x00, 0x44, 0x00, 0x59, 0x5a, 0x5f, 0x41, 0x3B, 0x39, 0x19, 0x6b, 0x56, 0x1a]

def myXOR(i,j,sol):
global count
global ret
xor = i^j
if(xor == sol):
count+=1
ret += chr(i)

for s in solList:
myRange = chain(range(48,58), range(0x5F, 0x60), range(65,91), range(97,123))
for i in myRange:
myRange = chain(range(48,58), range(0x5F, 0x60), range(65,91), range(97,123))
for j in myRange:
myXOR(i,j,s)
print(hex(s) + ': ' + ret)
ret = ''
```

output:

```
0x68: 012789_PQXYZ
0x6f: 056789_VWXYZ
0x37: _ABCDEFGMNOPQRSTUVXYZabcdefghmnopqrstuvxyz
0x57: 012345689abcdefgno
0x55: 012346789abcdefglm
0x25: _ABCDFGHIJKLMNOPQRSTUVWabcdfghijklmnopqrstuvwz
0x3: 01234567ABDEFGHIJKLMNOPQRSTUVWYZabdefghijklmnopqrstuvwyz
0x0: 0123456789_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
0x44: 01234567pqrstuvw
0x0: 0123456789_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
0x59: 012345678ahijklmno
0x5a: 0123456789bchijklmno
0x5f: 0123456789fghijklmno
0x41: 0123456789pqrstuvwxy
0x3b: _ABCHIJKLMNOPQRSTUVWXYZabcdhijklmnopqrstuvwxyz
0x39: _ACHIJKLMNOPQRSTUVWXZacfhijklmnopqrstuvwxz
0x19: _ACFHIJKLMNOPQRSTUVWXZachijklmnopqrstuvwxz
0x6b: 123489_RSXYZ
0x56: 012345789abcdefgno
0x1a: _BCEHIJKLMNOPQRSTUVWXYbchijklmnopqrstuvwxy
```

With the given parts of the flag, the alphabets and the r2 fortune power knowledge we make an educated guess.

```
#! /usr/bin/python3

guess = 'Y0UdaWg_'

a_xor_b = 0x686f375755250300
b_xor_c = 0x4400595a5f413b39
c_xor_d = 0x196b561a6b335f66

def get_char(number, i):
return chr(int.to_bytes(number, 8, 'big')[i])

def print_table(xor, c1, n1, c2, n2):
print('chr(' + c1 + ') :', get_char(n1, 0), get_char(n1, 1), get_char(n1, 2), get_char(n1, 3) ,get_char(n1, 4), get_char(n1, 5), get_char(n1, 6), get_char(n1, 7))
print(c1 + ' :', hex(n1)[2:])
print(c2 + ' :', hex(n2)[2:])
print(c1 + '^' + c2 + ' :', hex(xor)[2:], '\n')

def print_tables(my_string):
a = int.from_bytes(str.encode(my_string, 'ascii'), 'big')

b = a ^ a_xor_b
c = b ^ b_xor_c
d = c ^ c_xor_d

print_table(a_xor_b, 'a', a, 'b', b)
print_table(b_xor_c, 'b', b, 'c', c)
print_table(c_xor_d, 'c', c, 'd', d)
print_table(0, 'd', d, '0', 0)

print_tables(guess)
```

I should remember r2 fortunes better and we give it another try after investigating [r2 fun fortunes](https://github.com/radare/radare2/blob/master/doc/fortunes.fun) at row 39. **Indeed! malware unicorn does like radare2 too. :\*:\*:\***

```
#! /usr/bin/python3

guess = 'Y0_daWg_'

...
```

output:

```
chr(a) : Y 0 _ d a W g _
a : 59305f646157675f
b : 315f68333472645f
a^b : 686f375755250300

chr(b) : 1 _ h 3 4 r d _
b : 315f68333472645f
c : 755f31696b335f66
b^c : 4400595a5f413b39

chr(c) : u _ 1 i k 3 _ f
c : 755f31696b335f66
d : 6c34677300000000
c^d : 196b561a6b335f66

chr(d) : l 4 g s
d : 6c34677300000000
0 : 0
d^0 : 0
```

```
fb{Y0_daWg_1_h34rd_u_1ik3_fl4gs}
```

###### Conclusion

I am not sure If this is the recommented solution because there is a bunch more to learn and to explore. Even if you do not like Pokemon or big swimming mamals you will be amazed about what pictures sometimes are used for. You do not know what I am talking about? Check out the binary(s) ;P in this [other write up](https://ctftime.org/writeup/15509) from team 0xD13A.

## Appendix
###### math bay six

```
a,b element of N
^ is bitwise xor

a ^ a == 0
b == b
b == 0 ^ b
b == a ^ a ^ b
```

###### leasons learned

1. know your tools or just use radare2 with cutter ;P
2. always remember the newest radare2 fortunes ... or be part of a fringe group
3. I am not a native speaker and always thaught [Yo dawg](https://www.urbandictionary.com/define.php?term=Dawg) is pirate talk ... now i know better ;P
4. [foreign languages](https://en.wikipedia.org/wiki/Code_talker) nor encoding are substitutes for [true encryption](https://en.wikipedia.org/wiki/Kerckhoffs%27s_principle))
5. parts of the key are sometimes enough to break the whole system
6. math and qualified guesses can become very powerful and always depend on the knowledge of the guesser ... do your homework/recon

###### pitfalls

1. registers store values in big endian and memory in little endian format
2. lose focus
3. get trapped by obfuscation techniques
4. reverse unnesassery code

###### acknowledgements

1. [malware unicorn](http://amanda.secured.org/in-securities-comic/)
2. [cutter](https://github.com/radareorg/cutter)
3. [radare2](https://www.radare.org/r/)

Original writeup (https://youtu.be/2cv0uvHSq_s).