1 2 Ambtion.com 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 Ambtion.com 279 280 281 Advertise Free on Auto-pilot!
Watch the latest videos on YouTube.com
newgoldenjewels: Trendnet Cameras - I Always Feel Like Somebody'S Watching Me.

Thursday, August 20, 2020

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.
More info

No comments: