Categories
hexionCTF 2020 Reverse Engineering

“Wannasmile 1”

For the first part of Wannasmile, we need to get the ./wannasmile program on hexionCTF’s shell server to give us a flag. We are given a version of this executable with the flag stripped out, and are not given read permissions to the real version of the program. Looking at radare2’s graph-view disassembly for this program shown below, we can see what this program does before printing the flag.

Loop setup with counter var_4h and condition of <= 0xf

The win condition is gethostbyname returning a hostent for the decoded string. In other words, if the decoded string can be resolved to an IP address, you win and you get the flag!

Given the name of the challenge, you might be reminded of the infamous Wannacry ransomware. It wrecked havoc, automatically spreading across computer networks and encrypting files, until security researcher Marcus Hutchins found that it had a built-in killswitch. The worm would check for a certain domain name’s non-existance before kicking into action, so registering its kill-switch domain stopped it in its tracks. Here, we have a similar kind of routine. The program decodes a seemingly random 16-char buffer into a hostname, and will print a flag if it resolves.

gdb can be used to find the value of the hostname after decoding, but take care while setting the breakpoint and running the program, as this is malware after all. Here are the steps I took to do this:

  • Starting the program with starti will only load it, so we can tell what offset the code loaded at (PIE is enabled) without it having to run.
  • info proc map tells us the program’s base address after loading, which we can add to offset 0x1a8b to stop right before calling gethostbyname.
  • b *0xaddr is used to set the breakpoint. Make sure you get no errors and that x/8i 0xaddr shows the instructions that you expect at that location, which in this case should start with call 0x555555554f10 <[email protected]>.
  • Then, use c to run the program until the breakpoint, and you can x/s $rdi to see the hostname the malware is trying to resolve.
(gdb) starti
Starting program: /home/ungato/wannasmile 

Program stopped.
0x00007ffff7fd1100 in _start () from /lib64/ld-linux-x86-64.so.2
(gdb) info proc map
process 12275
Mapped address spaces:

          Start Addr           End Addr       Size     Offset objfile
      0x555555554000     0x555555556000     0x2000        0x0 /home/ungato/wannasmile
      0x555555756000     0x555555758000     0x2000     0x2000 /home/ungato/wannasmile
      0x7ffff7fcc000     0x7ffff7fcf000     0x3000        0x0 [vvar]
      0x7ffff7fcf000     0x7ffff7fd0000     0x1000        0x0 [vdso]
      0x7ffff7fd0000     0x7ffff7ffb000    0x2b000        0x0 /lib/x86_64-linux-gnu/ld-2.30.so
      0x7ffff7ffc000     0x7ffff7ffe000     0x2000    0x2b000 /lib/x86_64-linux-gnu/ld-2.30.so
      0x7ffff7ffe000     0x7ffff7fff000     0x1000        0x0 
      0x7ffffffde000     0x7ffffffff000    0x21000        0x0 [stack]
  0xffffffffff600000 0xffffffffff601000     0x1000        0x0 [vsyscall]
(gdb) b *0x555555555a8b
Breakpoint 1 at 0x555555555a8b
(gdb) x/8i 0x555555555a8b
   0x555555555a8b:	call   0x555555554f10 <[email protected]>
   0x555555555a90:	test   rax,rax
   0x555555555a93:	jne    0x555555555aad
   0x555555555a95:	mov    rdx,QWORD PTR [rbp-0x20]
   0x555555555a99:	mov    eax,DWORD PTR [rbp-0x14]
   0x555555555a9c:	mov    rsi,rdx
   0x555555555a9f:	mov    edi,eax
   0x555555555aa1:	call   0x55555555589f
(gdb) c
Continuing.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Breakpoint 1, 0x0000555555555a8b in ?? ()
(gdb) x/s $rdi
0x555555757020:	"uaresuchacrybaby"
(gdb)

And so we know that we need to have uaresuchacrybaby resolve to an IP. But how? We have very limited access to the server we need to make this happen on, it’s not like we can just edit /etc/hosts. The answer lies in the man page for gethostbyname.

What’s this HOSTALIASES?

HOSTALIASES allows us to make gethostbyname check a file controlled by us for resolving hostnames before resorting to /etc/hosts or the DNS server. It turns out that even with our limited access, we can still read and write files in /tmp. In /tmp/rgbpwn-hosts, the line uaresuchacrybaby google.com can be placed. Now, when we use HOSTALIASES=/tmp/rgbpwn-hosts ./wannasmile at the shell, gethostbyname will find that uaresuchacrybaby is an alias for google.com which will resolve because the server is connected to the internet. localhost would have probably also worked.

After running wannasmile with our HOSTALIASES, we get the flag: hexCTF{wh0_put5_k1ll_sw1tch3s_in_the1r_m4lw4r3}

Leave a Reply

Your email address will not be published. Required fields are marked *