Extract valuable information from binaries with radare2


Radare2 is a powerful reverse engineering framework widely used for reverse engineering binaries meant for different architectures. I came across it while dealing with some vulnerabilities of my TENVIS T6812 IP Camera. Later on I started using it on a regular basis for almost everything. I have yet a lot to learn from it, of course! One thing I enjoyed doing was to extract some valuable information from the main server binary of my TENVIS Ip Camera.

Tenvis T6812 Camera.

This IoT device is full of flaws. I have yet to perform more tests, but I found at least two different vulnerabilities: a buffer overflow issue affecting the ipc_server binary in charge of interfacing with the camera and the web server and some information disclosure (a directory named /tmpfs, accessible from the browser and holding the ipc_server binary itself along with some libraries and configuration files).

The ipc_server binary

After being able to download this binary from the tmpfs directory using my browser, I used radare2 in order to analyse it:

r2 tmpfs/ipc_server
[0x00026df0]> aaaa

The authentication method for this particular camera is  based on the HTTP Header “Authorization”, of type basic. Therefore, I was expecting to find the “.htpasswd” string somewhere within the binary:

[0x00025420]> iz~.htpasswd
vaddr=0x000efd50 paddr=0x000e7d50 ordinal=2839 sz=10 len=9 section=.rodata type=ascii string=.htpasswd
vaddr=0x000f0d94 paddr=0x000e8d94 ordinal=3021 sz=55 len=54 section=.rodata type=ascii string= mongoose -A <htpasswd_file> <realm> <user> <passwd>\n

So there were two strings holding the value “.htpasswd”. The second one at 0x000f0d94 was, in fact, a call to the “mongoose” program. I looked for the string “mongoose” inside the binary:

[0x00025420]> iz~mongoose
vaddr=0x000ef440 paddr=0x000e7440 ordinal=2754 sz=18 len=17 section=.rodata type=ascii string=websvr/mongoose.c
vaddr=0x000f0d94 paddr=0x000e8d94 ordinal=3021 sz=55 len=54 section=.rodata type=ascii string= mongoose -A <htpasswd_file> <realm> <user> <passwd>\n
vaddr=0x000f0dcc paddr=0x000e8dcc ordinal=3022 sz=26 len=25 section=.rodata type=ascii string= mongoose <config_file>\n
vaddr=0x000f0de8 paddr=0x000e8de8 ordinal=3023 sz=32 len=31 section=.rodata type=ascii string= mongoose [-option value …]\n
vaddr=0x000f0e30 paddr=0x000e8e30 ordinal=3026 sz=78 len=77 section=.rodata type=ascii string=See http://code.google.com/p/mongoose/wiki/MongooseManual for more details.\n
vaddr=0x000f0e80 paddr=0x000e8e80 ordinal=3027 sz=50 len=49 section=.rodata type=ascii string=Example:\n mongoose -s cert.pem -p 80,443s -d no\n
vaddr=0x000f0efc paddr=0x000e8efc ordinal=3031 sz=14 len=13 section=.rodata type=ascii string=mongoose.conf

So, apparently, the ipc_server was using mongoose. I decided to browse http://code.google.com/p/mongoose/wiki/MongooseManual, extracted from the binary itself. I got an HTTP 403 error. This gave me proof that this mongoose implementation was obsolete indeed. I browsed the main project’s page instead:


And so, I’ve discovered what mongoose was meant for:

Mongoose is an embedded HTTP and WebSocket library that can turn anything into a web server in 5 minutes by adding a few lines of C/C++ code

Getting mongoose version

So I downloaded the latest available version of mongoose from https://code.google.com/archive/p/mongoose/downloads, and I started looking around with cscope. I found out that all the callable functions started with mg_, like mg_version (I found that thanks to the win32 dll definitions):

cat win32/dll.def

I got back to my radare2 session and enumerated functions starting with mg_:

[0x00025420]> afl~mg_
0x0007bed8 3 56 sym.mg_get_option
0x0007d73c 17 584 sym.mg_md5
0x0007c19c 20 688 sym.mg_read
0x0007c414 1 56 sym.mg_write
0x0007c980 1 92 sym.mg_printf
0x0007d500 40 568 -> 844 sym.mg_get_var
0x0007be6c 1 28 sym.mg_GetMediaServerHandle
0x000c61ec 3 56 sym.img_dsp_set_aaa_static_frequency
0x000bbcfc 1 4 -> 60 sym.img_set_aaa_frequency
0x0007e7ec 17 528 sym.mg_modify_passwords_file
0x0007bf20 7 112 sym.mg_get_header
0x0007ea18 12 60 -> 156 sym.mg_stop
0x0007becc 1 8 sym.mg_get_valid_option_names
0x0007ea54 1 40 sym.mg_pause
0x0007be8c 1 28 sym.mg_GetRtspOverHttpHandle
0x0007be0c 1 16 sym.mg_RegisterSnapChn
0x0007bdf8 1 16 sym.mg_RegisterHttpPort
0x0007be38 1 16 sym.mg_RegisterGetUserPass
0x0007be20 1 20 sym.mg_RegisterHttpAuth
0x0007bdc0 1 52 sym.mg_RegisterDistribLink
0x0007bf14 1 8 sym.mg_version
0x000c4e98 12 4 -> 444 sym.img_dsp_set_video_mctf_ex
0x0007be4c 1 28 sym.mg_GetHttpPort
0x0007beac 1 28 sym.mg_GetPlayBackHandle
0x0007ea80 56 1548 sym.mg_start

Indeed; mongoose was being used by ipc_server. In fact, this library was linked statically within the binary. Therefore, I got the sym.mg_version function at address 0x0007bf14.  So I jumped into that function and disassembled it:

According to the previous assembly code snippet, ipc_server was linked against mongoose 3.0:

0x0007bf14 00009fe5 ldr r0, [pc] ; [0xef5cc:4]=0x302e33 ; LEA str.3.0 ; “3.0” @ 0xef5cc

[0x0007bf14]> ps @0xef5cc

Mongoose 3.0 well-known vulnerabilities

Apart from the buffer overflow I have already found, I googled mongoose 3.0 vulnerabilities and this came out:


So this camera ships with another buffer overflow vulnerability as well. This one is a well-known vulnerability, with at least one working exploit for some vendor implementing it here: http://nion.modprobe.de/blog/archives/704-Exploiting-the-UbiquisysSFR-femtocell-webserver-wsalshttpdmongooseyassl-embedded-webserver.html.

And now …

I have contacted TENVIS in order to let them know about my findings and this already reported vulnerability. So far, no answer. I’ll be toying with my camera a lot more, so stay tuned for upcoming posts!