Sunday, September 2, 2018

Hacking The RPi Cam Web Interface

In my spare time, I like to poke around on different open and closed source projects and look for vulnerabilities.  Recently, I turned my attention to a rather popular and cool little Raspberry Pi (RPi) project. The RPi Cam Web Interface is a web interface for the Raspberry Pi Camera module.  It can be used for a wide variety of applications including surveillance, DVR recording and time lapse photography.  A few hours of exploration led to some serious vulnerabilities I'd like to share in this post.  The creator of the project was very receptive to the findings and did a great job communicating and fixing the vulnerabilities.  If you're using the RPi Cam Web Interface, it is highly recommended that you upgrade to the latest version which, at the time of this writing, is 6.4.30.

Command injection via "convert" parameter in preview.php

When looking at PHP applications, one of the first things I grep for are functions accepting user input with the potential to execute an external program.  For reference, I listed these below:

In order to get to this function, the attacker must send a POST request to preview.php with the parameters convert and convertCmd:

Here, the data passed via convert is being manipulated and concatenated in two different ways.  I chose to focus on $tmp.  Here, $tmp is created by concatenating the BASE_DIR with the MEDIA_PATH and the result of the following two functions from config.php:

So, passing ".; id)#aaaaaaa" in convert would result in a $tmp of "/var/www/html/media/; id)#".  When $tmp is concatenated to $cmd, the final command passed to system is:

(/usr/bin/ffmpeg -f image2 -i /var/www/html/media/; id)#/i_%05d.jpg/var/www/html/media/mp4 ; rm -rf /var/www/html/media/; id)#;) >/dev/null 2>&1 &

Which results in our command being executed:

Similarly, the convertCmd parameter can be used to achieve command injection with one caveat, it overwrites whatever is in convertCmd.txt, breaking the conversion process in the future.

As a side note, the default installation of the RPi Cam Web Interface also grants sudo privileges to www-data on /bin/date which, as mentioned in my previous blog post, can aid in privilege escalation and expose sensitive information such as WiFi passwords:

A fix was put in place that first checks if the file is in the media directory and that it exists before trying to convert it and cleans up the getFileType and getFileIndex functions.

While testing this fix, I looked for a way to write a file to disk where I controlled the location and filename.  I found such a place in schedule.php.

Here, I could alter the Fifo_In and Fifo_Out parameters:

And still achieve command injection:

The developer disabled the ability to alter the Fifo_In and Fifo_Out locations and the vulnerability was closed.

Quick PoCs:
  • curl -d "convert=%2e%3b%20%69%64%29%23%61%61%61%61%61%61%61&convertCmd=doesntmatter" -X POST http://vulnerable_host/path/to/preview.php
  • curl -d "convert=doesntmatter&convertCmd=%69%64%29%20%26%26%20%28%65%63%68%6f%20" -X POST http://vulnerable_host/path/to/preview.php

Directory traversal via "download1" parameter in preview.php

The following section of code reveals that a filename passed in the download1 parameter will be retrieved and the contents returned to the attacker:

The dataFilename function requires us to do some additional padding to the filename:

But it's easy to pad a period and any 7 additional characters to achieve directory traversal and read any file www-data has the rights to read:

Quick PoC:
  • curl -d "download1=../../../../../../etc/passwd........" -X POST http://vulnerable_host/path/to/preview.php

Directory traversal via "action=zipSel" and "check_list[]" in preview.php

The last vulnerability I discovered was another directory traversal in preview.php.  This time, I'm taking advantage of the application's ability to zip a selected number of images/videos and allow you to download that archive.

Here a number of check_list[] parameters can be passed to preview.php, along with action=zipSel, to allow an attacker to read a large number of files all at once.  The getZip function handles all the heavy lifting.

Similar to the previous exploit, some extra padding is necessary because of the dataFilename.

Quick PoC:
  • curl -d "action=zipSel&check_list[]=../../../../etc/passwd.v......." -X POST --output - http://vulnerable_host/path/to/preview.php


I decided to throw together a quick, fully functional, exploit for the command injection vulnerability.  It's just a simulated shell written in python that leverages the requests library to make the post requests to preview.php.

Copyright © 2015 Reigning Shells