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.
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 callinggethostbyname
.b *0xaddr
is used to set the breakpoint. Make sure you get no errors and thatx/8i 0xaddr
shows the instructions that you expect at that location, which in this case should start withcall 0x555555554f10 <[email protected]>
.- Then, use
c
to run the program until the breakpoint, and you canx/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
.

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}