Hacking & Fuzzing Home Surveillance Camera
Back Story
Earlier this year we decided to install a new surveillance camera. I knew the lack of “security” on those so I had to try hacking my way through.
Dumping the framework
I tried searching the internet for the mysterious vendor that manufactured this camera and found nothing so I had to dump it myself. I decided to use their android app since it already has an update feature
I was skeptical at first but do it anyway. I just ran tcpdump on my android thinking that it might have some sort of a custom protocol for updates:-
tcpdump -s0 -w /sdcard/emulator.cap
And to my surprise but also disappointment I found that this model was communicating over Plain Text HTTP connection
I had to do some changes to the update request to force it to send a new update image https://reqbin.com/c-zwbudat1
Extracting the ROM was just a matter of running binwalk -e update.img
it’s a minimal Linux environment and The folder hierarchy was pretty simple
abin - custom made binaries
bin - mostly tools from github/linux
lib - custom made libaries
modules - custom made linux kernal modules
wav - sounds for the camera
www - a minial and pretty vulnerable web application
userdata - empty
sysinfo - hardware informations
Setting up QEMU
The camera had a 32bit ARM processor. and ALL of the binaries was dynamically linked with “/lib/ld-uClibc.so.0” so I had to setup the toolchain this actually was painful -as always-;
- Installing QEMU
sudo apt-get install qemu
2. Setup toolchain
$ wget http://crosstool-ng.org/download/crosstool-ng/crosstool-ng-1.23.0.tar.xz
$ tar xf crosstool-ng-1.23.0.tar.xz
$ cd crosstool-ng/
$ ./configure
$ make
$ sudo make install
$ ct-ng arm-unknown-linux-uclibcgnueabi
$ ct-ng build
Some additional libraries were needed from https://gfiber.googlesource.com/toolchains/bruno/+/849791dda3c302156da6dbaea229e44c6bfd8469/arm-linux-uclibcgnueabi/sys-root/lib
Now we are able to run 32bit ARM binaries from the camera on the host machine (x64)
Setting up AFL (American Fuzzy Lop)
American Fuzzy Lop is a brute-force fuzzer coupled with an exceedingly simple but rock-solid instrumentation-guided genetic algorithm. It uses a modified form of edge coverage to effortlessly pick up subtle, local-scale changes to program control flow.
Since we don’t have the source code for the binaries we will use AFL with qemu mode which allows fuzzing binary-only programs. note that it’s not as fast as the normal mode
$ git clone https://github.com/AFLplusplus/AFLplusplus
$ cd AFLplusplus/
$ make
$ cd qemu_mode/
$ export CPU_TARGET=arm
$ ./build_qemu_support.sh
$ cd ..
$ make install
Now we are ready to start Fuzzing!
Target Mapping
A full port Nmap scan on 192.168.1.100
“camera’s IP” revealed a number of interesting services running
PORT STATE SERVICE
23/tcp open telnet
80/tcp open http
443/tcp open https
843/tcp open unknown
1234/tcp open hotline
1300/tcp open h323hostcallsc
6688/tcp open clever-tcpip
6980/tcp open unknown
8554/tcp open rtsp-alt
8699/tcp open vnyx
9505/tcp open unknown
MAC Address: EA:76:74:BC:95:E1 (Unknown)
Port 80/443
Both served the same web application located at /www/
the application had a backdoor username super_yg
found at “/doc/script/login.js” which allowed me to access the console.
Later I found that an unauthenticated attacker is able to control the camera using a simple GET request to the following URLs
[RIGHT] http://192.168.1.100/PSIA/YG/PTZCtrl/channels/0/continuous?pan=1&tilt=0
[LEFT] http://192.168.1.100/PSIA/YG/PTZCtrl/channels/0/continuous?pan=-1&tilt=0
[UP] http://192.168.1.100/PSIA/YG/PTZCtrl/channels/0/continuous?pan=0&tilt=1
[DOWN] http://192.168.1.100/PSIA/YG/PTZCtrl/channels/0/continuous?pan=0&tilt=-1
With some focus and zoom abilities
http://192.168.1.100/PSIA/YG/PTZCtrl/channels/0/continuous/focus?data=1
http://192.168.1.100/PSIA/YG/PTZCtrl/channels/0/continuous/zoom?data=1
http://192.168.1.100/PSIA/YG/PTZCtrl/channels/0/continuous/iris?data=1
There’s also a way to get an unauthenticated live feed however I’ll publish it not to get abused by script kiddies. however, it’s easy to spot you’ll also need to implement your client
Port 1300/843
Both were controlled by “/abin/noodles”. and Oh man this binary was a recipe for disaster. it allowed anyone to execute commands on the camera and download/upload files even flashing a new ROM. All unauthenticated!
it was a very interesting target, so I knew I had to find more interesting bugs :)
Fuzzing “noodles”
The main problem that was for AFL to interact with the binary it needed to receive the input from stdin since AFL doesn’t play very well with sockets I had to use an old trick. I used LD_PRELOAD to override the standard “recv” function with this one. which reads from /tmp/input
to the passed buffer thus allowing AFL to interact with the binary without using socket connections
Using the following command to build desock.so
$ ~/arm-unknown-linux-uclibcgnueabi/bin/arm-unknown-linux-
uclibcgnueabi-gcc -fPIC -lpthread -Wall -Wextra desock.c -shared -ldl -o desock.so
AFL supports LD_PRELOAD however it’s advised to use AFL_PRELOAD. I also used the persistent mode to prevent AFL from starting the binary all over again each time it mutates the input this gave me a 35 execution per second which is slow but acceptable
$ AFL_PRELOAD=./desock-arm32.so AFL_PERSISTENT=1 afl-fuzz -Q -f /tmp/input -i in -o out -- ./noodles-patched
If you haven’t noticed already I patched the noodles binary to make it easier for AFL as I was not interested in some branches. I left AFL running for a month and it found 36 unique crashes 31 of them was at the XML parsing logic with no harm other than crashing the target it also found 5 exploitable bugs — I intend not to publish those
Port 1234/8554/1935
Those were for live streaming each with a custom streaming protocol
1234 - http-flv
8554 - rtsp
1935 - rtmp
Connecting to rtsp://192.168.1.100:8558/profile0
using VLC player give me a login form. and I couldn’t guess the username and password however I plan to try a brute-force attack later.
Connecting to rtmp://192.168.1.100:8558/profile0
using rtmpdump was successful however no feed was obtained from it
The flv://
protocol was new to me so I decided to leave it for some other time. it may be vulnerable. who knows ¯\_( ͡❛ ͜ʖ ͡❛)_/¯
Port 6688
A simple HTTP server was running on 6688. however, it allowed anyone to capture a screenshot camera’s live feed just by sending a GET request to http://192.168.1.100:6688/snapshot.jpg
At this point, I got bored of the target since I already confirmed my suspicion. it certainly has more vulnerabilities to discover but there is no good in doing that it’s pretty vulnerable as it is and to sum up all the findings.
- Remote Code Execution — /abin/noodles
- Unauthenticated File Upload/Download — /abin/noodles
- 36 Discovered Crashes — /abin/noodles
- Unauthenticated Target Control — web:80,443
- Unauthenticated Live Access to Camera’s feed — web:80,443
- Unauthenticated Screenshot from feed — web:6688
- Manufacture pre-installed Backdoor
- Flash Image Update over HTTP
You might need to check your home camera for these findings as most of the Chinese vendors are reusing the same ROM
Closing Word
Not everyone has the time nor the skills required to verify the strength of their home IoT devices so please keep those out of your main network preferably keep it on an isolated network with no internet access. also, stay away from Chinese products — Stay Safe!