[Reverse] 3DS - IRC Bot Takeover


IRC Bot Takeover - 486 Points

WARNING! DON’T EXECUTE THIS SAMPLE IN YOUR OWN PERSONAL MACHINE!!!


Update: We had some problems with a specific step of the challenge (still possible to solve, but more hard) and we updated the binary. The new file has the old version, but you only need the new to solve.

This malware was about controlling a bot net via IRC, we were allowed to access it since the url and port were bot present in the binary, but we didn’t really needed to access it to solve this, unless you infected a machine of yours to debug it to understand better how the malware works(some people actually did this I saw some bots from other players in a channel in IRC we actually could control them lol).

This challenge as in Ransomware and w32.killah is once again to decrypt obfuscated strings, but this time they are encrypting the string two times:

There were two executables, one of them was useless the one that has the encrypted flag was bot.exe.

The code above is present at the sub-routine sub_4012E1 if you use IDA open the binary (bot.exe executable). Once again the xor_encryption2 is exactly like w32.killah, I had to brute force the key once again, but this time since they are encrypting twice I need to brute force two keys instead of one:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import struct
import string

def xor_encrytion(al, ecx, edx):
c = ''
for i in range(ecx):
n = chr((((ord(edx[i]) + ord(al))%256) ^ ord(al)) %256)
s = chr(ord(edx[i]) ^ ord(al))
#print n,s
if s in string.printable:
c += s
else:
c += n
#print c
return c

for j in range(1,0xff):
for i in range(1,0xff):
e = xor_encrytion(al=chr(i), ecx=0x10-1, edx='%<EmqhiYUi0deY\\')
h = xor_encrytion(al=chr(j), ecx=0x10-1, edx=e)
print h, i, j


for j in range(1,0xff):
for i in range(1,0xff):
e = xor_encrytion(al=chr(i), ecx=0x12-1, edx='mckW,sSWisWdak3!u')
h = xor_encrytion(al=chr(j), ecx=0x12-1, edx=e)
print h, i, j

The first part of the flag:

1
2
3
4
5
6
7
8
$ python ircbot.py | grep '3DS{'
3DS{wpwgcw8lsgd 139 8
3DS{who_#o0ls_d 229 98
3DS{who_#o0ls_d 228 99
3DS{who_#o0ls_d 230 99
3DS{who_co0ls_d 133 130
3DS{who_co0ls_d 132 131
3DS{who_co0ls_d 134 131

The rest:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ python ircbot.py | grep '}\s'
...
...
uck_4sS_is_lak3!} 224 100
uow[4^?_[i^?[law?!} 226 100
Ec{_^DsS_ys_la{3!} 232 100
EoGk^D^?_ky^?klaG?!} 234 100
komQ*^?UQo^?Qlam5'} 96 102
ukoS({WSm{Slao7%} 98 102
EmGY"^?]Yy^?YjoG=/} 104 102
EoC[ {_[y{[lmC?-} 106 102
uow[4^?_[i^?[law?!} 224 102
...
...

A simple script to join the parts of the flag since we now know the keys:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import struct
import string

def xor_encrytion(al, ecx, edx):
c = ''
for i in range(ecx):
n = chr((((ord(edx[i]) + ord(al))%256) ^ ord(al)) %256)
s = chr(ord(edx[i]) ^ ord(al))
#print n,s
if s in string.printable:
c += s
else:
c += n
#print c
return c

def sub_4005D0(al, ecx, edx):
c = ''
for i in range(ecx):
c += chr(ord(edx[i]) ^ ord(al))
return c

a = sub_4005D0(al='\x12',ecx=7-1, edx='1`scg{')
b = sub_4005D0(al='\x12',ecx=0x11-1, edx='{`q<t`ww|}vw<|wf')
c = sub_4005D0(al='\x12',ecx=0xa-1, edx='s``}\x7f\x70\x73\x76\x7d')
d = sub_4005D0(al='\x12',ecx=0x8-1, edx='qsfgsps')

f = xor_encrytion(al='\x85', ecx=0x10-1, edx='%<EmqhiYUi0deY\\')
g = xor_encrytion(al='\x82', ecx=0x10-1, edx=f)

h = xor_encrytion(al='\xe4', ecx=0x12-1, edx='mckW,sSWisWdak3!u')
i = xor_encrytion(al='\xc0', ecx=0x12-1, edx=h)

print a,b,c,d
print g+i

Running it

1
2
3
$ python ircbot.py
#raqui irc.freenode.net arrombado catuaba
3DS{who_co0ls_duck_4sS_is_lak3!}

The flag was 3DS{who_co0ls_duck_4sS_is_lak3!}, note that the first line is other obfuscated strings you could decrypt to help you understand the control flow of the binary.