26 October 2017



>HooToo TM6 vulnerabilities

Hi I’m Mikhail, the Director of R&D at Synack. Being a builder and a hacker at heart, my interests are in vulnerability analysis, automation, malware and reverse engineering. I’ve gotten the opportunity to conduct and present my own research on these topics at conferences around the world.  Here is part 4 of 4 – read and enjoy!


Part 4: Finding vulnerabilities in a router is cool, but what’s cooler is exploiting them. The vendor has been informed of the vulnerabilities and they were recorded in the CVE database (CVE-2017-9026 and CVE-2017-9025). So, hopefully they are no longer a major threat. These vulnerabilities could be exploited in many different ways, even from an Android phone [0]. I wanted to follow through and see what useful things we could do from an attacker perspective.

Attack Use Cases

There are many reasons why an attacker might want to exploit one of these devices. One obvious reason is to gain access to the user’s information or manipulate user activity. Having malware on the router means that an attacker could potentially see unencrypted traffic, modify their DNS lookups to enable man-in-the-middle attacks, or inject malicious content into traffic. For example, an attacker might want the ability to inject iframes for browser exploitation or catch vulnerable update mechanisms [1].

Other reasons for leveraging the vulnerabilities in the travel routers are a bit more indirect. One is to obfuscate attack sources and make attribution harder by creating a jump point [2]. Another is to use the router to infect other systems. A person using the travel router would likely be traveling a lot and touching many different networks from a position of some trust. These networks could include hotels, Airbnbs, private residences, cafes, and enterprises. And so, having malware on the device would give an attacker a foothold inside another network.


As was mentioned in earlier posts, it was easier to exploit the heap overflow rather than the stack overflow. It was easier to exploit because the request body is stored on the heap; the heap does not move around, and the allocations on the heap are predictable. The latter part was a pleasant surprise, but this is probably because IOOS (the embedded webserver [3]) is a single threaded application and embedded heap libraries try to be as memory conservative as possible.

Below is the exploit script. The concept is very simple. Put the long string into the Cookie header to overflow the buffer. Then place the shellcode as the body of the POST request. This will seed the heap with our data. Then we point the function pointer of the cgi_tab structure to the shellcode at address 0x0059735c. The great thing about this vulnerability is that we get to use the last \0 appended by strcpy as part of the little-endian address. Otherwise, it would’ve been tough to add a NULL into a string operation of the HTTP parser.

The script will read the shellcode from shellcode.bin binary file and insert it as the body of the message. Luckily for us, the POST message is designed for any kind of data and so we didn’t have to do any encoding. Of course, in a real situation, it would be good to have some sort of encoding to avoid IDS detection.


Now that we are able to control the Program Counter and point it a reliable location of a buffer we control, we can start building shellcode that does something useful. Unlike regular programs, shellcode won’t get to be loaded by a loader. All we get is the ability to execute raw machine code. So, all bootstraping, linking and such would have to be handled manually.


Initially the Program Counter will point to the entry label. This preable is necessary in order to allow the following position independant code (PIC) to execute – main executable. The preamble fixes up the Global Offset variable. Even through the PIC is supposed to be position independent, it still relies on a pointer that it stores as a variable just after the machine code. This pointer is supposed to point to the beginning of the PIC. This way the code knows how to compute a relative offset. However, since the compilation is happening locally, the compiler does not know the initial value of GPOFFSET. So we have to set it.

At the time of exection, the location of the shellcode buffer will be stored in register $t9. Our task is to set the GPOFFSET value to the top of the code compiled from the below C program. We do this by offsetting 16 bytes from the start of the shellcode – to skip the preamble. Then, we make sure that the register $t9 actually points to the beginning of the compiled code.

main executable:

The above code is the the main shellcode logic. You will notice that there is a do_cmd function. We coopt this function from the IOOS main binary. All it does is execute a shell command. This is perfect for our purposes. The command I’ve chosen to execute is the one that restarts the service. This is a very quick operation and leaves little trace. Basically, I was too lazy to construct a cleaner cleanup method. However, with a device such as this with such poor quality of security, I feel this is the appropriate level of effort and will not be caught by 99% of users. So, the shellcode will never actually return to the execution path that it interrupted.

After compilation, the shellcode binary looks something like this. You can clearly see the preamble with some NOP alignment and the compiled main function following that. We can see that at the beginning of the fuction, the $t9 register is expected to be pointing to the top of the main executable that starts at address 0x10.

The build script was a modification of the ShellcodeWrapper script written by Google’s ProjectZero [4]. It was made for ARM64, but with some modifications it was possible to get it to produce useful MIPS shellcode.

Building the MIPS tool chain for cross compilations can be quite a chore, but with the resources below I got to the promise land, with Ubuntu, relatively quickly:

The Attack

Now that we have arbitrary execution on the device and we know how to build the shellcode, the possibilities are limitless. We could build and install implants and/or reconfigure the device. I’ve decided to explore one option of reconfiguring the device by forcing it to reroute HTTP traffic via a malicious server.

The device is a router that runs a version of Linux, so almost by definition we should be able to play with the iptables firewall rules. So, we install a rule that will NAT port 80 traffic from client via a public proxy at

On the proxy we run an instance of the MITM Proxy [6] with flags to forward any request to its intended destination. This will give us the ability to transparently observe or modify the user’s traffic. According to Google’s transperancy report [5], there are still quite a lot of major sites that do not use TLS by default. Just another example that one can never trust network infrastructure [7].


To review, we have taken a device off the shelves. Explored its attack surface. Got a terminal where we could perform dynamic analysis with a debugger. Then, found vulnerabilities in the CGI webserver and exploited them. In this article we have seen one possible scenario how an attacker could start taking advantage of the vulnerabilities to change users’ traffic. The attacker could potentially use this vector to deploy browser exploits or collect sensitive user information.


Synack provides initiatives to help foster the researcher community and engage top talent; technology to optimize researcher efficiency and accelerate vulnerability discovery; opportunities to work on unique targets; personalized support, and skills development. We do this through the Synack platform and our SRT Levels program that includes fun competitions, interactive gamification elements, mentorship, and specialized projects.

Apply to join the Synack Red Team. Become one of the few and fully experience our platform – it’s designed by hackers for hackers. If you’re up for the challenge, apply today, and use code “SRTBLOGS” in your application.