Friday, April 4, 2014

Faraday's New features: ZSH and Command History

We are back in our journey to the perfect collaborative pentesting tool, a Multiuser Penetration Test IDE, designed for collaborative data sharing. AKA Faraday!

We are proud to present two new features that will enhace the Faraday experience.
Taking feedback from our users we took account that each of them had particular needs from their consoles (completion, size, fonts, so on so forth)  and their need to be able to know what commands where run during an engagement.
  • A brand new ZSH based Terminal UI
  • The Command Run execution history
Our new ZSH Terminal:

Faraday controller

Faraday ZSH terminal

First of all we decoupled the UI from QT3. QT3 is deprecated, is not open source and it's outdated. That's why now you can use your own zsh terminal to interact seamlessly with Faraday from you favorite terminal emulator !

Command History:

Faraday Dashboard

The second feature we like to tell you about is a Command Execution History panel in our dashboard.

As pentesters we most often need to share the gathered information, and a big bunch of it is the commands we executed. So we now keep the commands that were executed within the parameters, epoch and duration of the execution.

Assume Bob and Harry are pentesting an internal B class network. As Bob runs a quick-and-dirty nmap to the whole subnet, Harry is eager to run his.

How could each other notice or communicate the command runs so they won't duplicate efforts? By email? By phone? No! By Faraday!

Stay tunned!

Monday, December 16, 2013

Faraday Developer Awards

After 3 years of development, we are releasing Faraday, a Multiuser Penetration Test IDE, Designed for collaborative data sharing, indexation and analysis of the generated knowledge during the engagement of a penetration test without changing the way you work. The main purpose of Faraday is to reuse the tools available in the community to get more advantage from them, in a multiuser way.
We are incorporating "Faraday Developer Awards" a benefit to open source developers of security tools which Faraday has fed for its functionality.
We have build a plugin system, where all the I/O from the terminal gets interpreted. If we have a plugin for the command, the output is processed and added to the knowledge base in a transparent way.
We will be releasing an Open Source version, but we are also developing a commercial version with professional features, such as reporting and advanced filters and visualizations.
The idea of the developer awards is that every buyer of a Faraday Professional & Enterprise license must necessarily select a beneficiary from a list of supported open source tools. We think this kind of support will help on the continuity of great open source security projects.
At the moment these are the projects who already have agreed to be part of the awards:

Release: Faraday Penetration Test IDE

We are happy to announce our first release of Faraday (beta), an open source collaborative Penetration Test IDE console that uses the same tools you use every day.

Faraday introduces a new concept (IPE) Integrated Penetration-Test Environment

We built a plugin system, where all the I/O from the terminal gets interpreted, if we have a plugin for the command, the output is processed and added to a knowledge base in a transparent way.

Our idea was to build a tool that helps from the perspective of a pentester without changing the way you work, adding the support for multi user collaboration on security testing projects.

Developed with a specialized set of functionalities that help users improve their own work adding collaborative data sharing, indexation and analysis of the generated knowledge during the engagement of a security audit. 

* +40 Plugins (Metasploit, Amap, Arachini, Dnsenum, Medusa, Nmap, Nessus, w3af, Zap and More!)
* Collaborative support  
* Information Highlighting
* Knowledge Filtering
* Information Dashboard
* Conflict Detection
* Support for multiple Workspaces
* IntelliSense Support
* Easy Plugin Development
* XMLRPC, XML and Regex Parsers

Get it now: 

#faraday-dev on

We hope you enjoy it!

Thursday, August 8, 2013

Perverting embedded devices - Lexmark N4000e Print Server (Part - I)

Lexmark n4000e - Print Serve
During an engagement it's normal to find a number of embedded devices, access controllers, faxes, routers, print servers, etc. Their presence is often overlooked but from an attacker perspective it's ideal for persistence and stealth activity on a network.

This devices are full blown computers and they live in the core networks of every organization ,without hardening, no firmware updates and no maintenance. They are not critical in the network ecosystem but that's mainly why these devices are an Achilles heel of every networking environment.

Network Printers can be found everywhere, grab a rock, throw it and you'll hit one. They can be found exposed on the Internet and even in a full segmented network their VLAN have access to most of the other segments making it perfect as entry or pivot point device.

This subject has been discussed a number of times but this blog post is aimed into auditing a specific device using different approaches. This is mainly a work in progress so feel free to comment.


We will analyse a Lexmark N4000E which we had laying around in our office. This print server at first sight has the following hardware features: 
  • 1 x RJ45 10/100 Mbps
  • 1 x USB
In order to see all the potential of this device, we will have to see what's under the hood. One of our goals is to be able to access the OS to execute arbitrary commands in the device, and maybe replace the default firmware and transform it to a pen test drop box during our work as a Red Team. To do so we will have to do some of the following:
  • Analyze exposed services.
  • Search for a UART/JTAG debugging port.
  • Uncover flaws and exploit one of the exposed services.
  • Reverse engineer the firmware.

Network Services

During the audit of a device, sometimes we look for the complicated way to it but I have seen many time that this kind of systems are vulnerable to simple OS command injection flaws in their administration services or sometimes it is possible to upload a binary using TFTP to an arbitrary directory. Either way it is always recommended to spend some time checking for these kind of vulnerabilities.

A quick port scan, reveals a number of exposed services which is good, since our chances to find flaws are more likely.

Host is up (0.021s latency).
Not shown: 992 closed ports
21/tcp    open  ftp
79/tcp    open  finger
80/tcp    open  http
515/tcp   open  printer
631/tcp   open  ipp
9000/tcp  open  net-config
9100/tcp  open  jetdirect
10000/tcp open  lexdebug

This Lexmark print server has a number of administration services, three to be exact. One of those is located in the 10000/TCP, which has a hand full of commands which can be useful during the recon phase.

Escape character is '^]'.
LXK: ls

LXK: netstat

   Type  Local IP        Port   Remote IP       Port   State        Out Q    In Q
   tcp         515         0      Listen       0        0
   tcp         9000         0      Listen       0        0
   tcp         9100         0      Listen       0        0
   tcp         79         0      Listen       0        0
   tcp         80         0      Listen       0        0
   tcp         10000         0      Listen       0        0
   tcp         21         0      Listen       0        0
   tcp         631         0      Listen       0        0
   tcp    10000    57069  Established  0        0
   udp         161         0                   0        0
   udp         38184         0                   0        0
   udp         69         0                   0        0
   udp         5353         0                   0        0

If we autenticate ourselves using the enable command a couple of new options are given, one of them is the familiar ps:

LXK: ps
root         1  0.0  1.9   356   136  ?  S    00:00   0:00 init
root         2  0.0  0.0     0     0  ?  SW   00:00   0:00 (khubd)
root         3  0.0  0.0     0     0  ?  SW   00:00   0:00 (svcerrd)
root         4  0.0  0.0     0     0  ?  SW   00:00   0:00 (kswapd)
root         5  0.0  0.0     0     0  ?  SW   00:00   0:00 (kflushd)
root         6  0.0  0.0     0     0  ?  SW   00:00   0:00 (kupdate)
root         7  0.0  0.0     0     0  ?  SW   00:00   0:00 (khubd)
root        27  0.0  1.5   368   108  ?  S    00:00   0:00 /bin/dbprint -in -id
root        30  5.7  2.3   408   164  ?  S    00:00   0:11 /bin/Nvram -e -c
root        32  0.0  1.1   356    80  ?  S    00:00   0:00 ./flashmon
root        40  0.0  2.2   392   156  ?  S    00:00   0:00 ./lexutils -d
root        41  0.0  1.5   432   108  ?  S    00:00   0:00 flashsrv
root        47  0.1  3.2   520   228  ?  S    00:00   0:00 NVRamServer
root        48  0.0  3.3   440   232  ?  S    00:00   0:00 ErrorExit
root        54  0.0  3.2   448   228  ?  S    00:00   0:00 StringsServer
root        55  0.1  4.3   564   304  ?  S    00:00   0:00 VacuumServer
root        57  0.0  4.3   564   304  ?  S    00:00   0:00 VAC_Slave_56
root        58  0.0  4.3   564   304  ?  S    00:00   0:00 VAC_Slave_56
root        61  0.0  4.8   624   340  ?  S    00:00   0:00 StatusServer
root        62  0.0  4.8   624   340  ?  S    00:00   0:00  \_ VAC_Slave_61
root        63  0.0  4.8   624   340  ?  S    00:00   0:00  \_ VAC_Slave_61
root        64  0.0  4.8   624   340  ?  S    00:00   0:00  \_ VAC_Slave_61
root        65  0.0  4.8   624   340  ?  S    00:00   0:00  \_ VAC_Slave_61
root        67  0.0  4.8   624   340  ?  S    00:00   0:00  \_ SA_Slave_61
root        68  0.0  4.8   624   340  ?  S    00:00   0:00 SA_Slave_66
root        70  0.0  2.7   444   196  ?  S    00:00   0:00 enaid
root        74  0.0  2.7   444   196  ?  S    00:00   0:00  \_ SA_Slave_70
root        76  0.0  4.4   508   312  ?  S    00:00   0:00 NPAP_Server
root        80  0.0  4.4   508   312  ?  S    00:00   0:00  \_ NPAP_DSA
root        81  0.0  4.4   508   312  ?  S    00:00   0:00  \_ NPAP_Upd_Config
root        82  0.0  4.4   508   312  ?  S    00:00   0:00  \_ NPAP_Reverse
root        84  0.0  4.4   508   312  ?  S    00:00   0:00  |   \_ NPAP_Slave_82
root        85  0.0  4.4   508   312  ?  S    00:00   0:00  \_ NPAP_Internal
root        86  0.0  4.4   508   312  ?  S    00:00   0:00  \_ SA_Slave_76
root        77  0.0  3.9   544   276  ?  S    00:00   0:00 NPA_Port_MUX
root        78  0.0  3.9   544   276  ?  S    00:00   0:00  \_ VAC_Slave_77
root        79  0.0  3.9   544   276  ?  S    00:00   0:00  \_ SA_Slave_77
root        87  0.0  4.3   588   304  ?  S    00:00   0:00 SA_Slave_83
root       107  0.0  4.3   588   304  ?  S    00:00   0:00 VAC_Slave_83
root       108  0.0  4.3   588   304  ?  S    00:00   0:00 VAC_Slave_83
root       116  0.0  2.3   428   168  ?  S    00:00   0:00 LinkMonitor 0
root       117  0.0  3.8   488   272  ?  S    00:00   0:00 Hbn
root       118  0.0  3.8   488   272  ?  S    00:00   0:00  \_ SA_Slave_117
root       166  0.0  3.8   488   272  ?  S    00:00   0:00  \_ VAC_Slave_117
root       121  0.0  3.0   444   212  ?  S    00:00   0:00 addrconf
root       122  0.0  3.0   444   212  ?  S    00:00   0:00  \_ SA_Slave_121
root       124  0.0  2.7   436   192  ?  S    00:00   0:00 SA_Slave_123
root       130  0.0  3.0   452   216  ?  S    00:00   0:00 wins
root       134  0.0  3.0   452   216  ?  S    00:00   0:00  \_ SA_Slave_130
root       132  0.0  2.6   368   188  ?  S    00:00   0:00 inetd
root       172  0.0  3.0   456   212  ?  S    00:02   0:00  \_ lexdebug
root       176  0.0  3.9   412   280  ?  R    00:03   0:00      \_ ps auxf
root       139  0.0  2.7   432   196  ?  S    00:00   0:00 Ntp
root       140  0.0  5.0   756   356  ?  S    00:00   0:00 snmpd
root       167  0.0  5.0   756   356  ?  S    00:00   0:00  \_ VAC_Slave_140
root       169  0.0  5.0   756   356  ?  S    00:00   0:00  \_ NPAP_Slave_140
root       170  0.0  5.0   756   356  ?  S    00:00   0:00  \_ SA_Slave_140
root       141  0.0  3.7   696   260  ?  S    00:00   0:00 http
root       156  0.0  3.2   436   228  ?  S    00:00   0:00 tftp
root       157  0.0  3.5   440   252  ?  S    00:00   0:00 host-config
root       158  0.0  4.2   476   300  ?  S    00:00   0:00 ZeroConfig
root       159  0.0  4.2   476   300  ?  S    00:00   0:00  \_ SA_Slave_158

As you can see, it definitely looks like a Linux system. Another hint is that all the services are running as root because  if we find a vulnerability in any of these services we won't have to do any privilege escalation.
After reviewing all the services we still haven't found any flaw that would allow us to execute commands in the system but we found some things that can be useful in your next Penetration Test.

Lexmark's kinky secrets

Lexmark decided to make our devices full of undocumented features, specially for debugging and troubleshooting.

On the port 79/TCP we have to access the good old finger service, normally used to check which users are logged in a UNIX system but Lexmark decided to use it as a status service of the back end printer, but there was more behind that.

The finger service when requested replies: 

Nothing interesting. I tried a couple of usernames, so I used the common ones and between them there was the user setup:

Escape character is '^]'.

Ethernet 10/100

Network Card
   Status:                       Connected
   Speed, Duplex:                100 Mbps, Full Duplex (Auto)
   Current Date and Time:        1971-02-01 07:01

   End-of-Job Timeout:           90

So this service supports commands? We decided to check a little bit more as you may know: "When in doubt, use brute force"

$ for i in `ls /usr/sbin`; do echo $i | nc 79; done

USB port 1
Printer Type: Epson Stylus T25
Print Job Status: No Job Currently Active
Printer Status: 0 Ready

USB port 1
Printer Type: Epson Stylus T25
Print Job Status: No Job Currently Active
Printer Status: 0 Ready

Suddenly something appears...

USB port 1
Printer Type: Epson Stylus T25
Print Job Status: No Job Currently Active
Printer Status: 0 Ready


   Sector Count: 192
   Sector Size: 128
   Bad Sectors: 0
   Used Sectors: 35
   Free Sectors: 157
   Page Count: 3
   Page Size: 8192
   Page 0 Cycles: 0
   Page 1 Cycles: 0
   Page 2 Cycles: 0

Block ID: 0x01  Sub ID: 0x01 Size 152
0x00000000: 00 00 00 03 00 5A 00 00 00 00 5A 11 12 6A 5B 63  :.....Z....Z..j[c:
0x00000010: 54 18 00 0E 45 73 74 65 62 61 6E 20 51 75 69 74  :T...Esteban Quit:
0x00000020: 6F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  :o...............:
0x00000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  :................:
0x00000040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  :................:
0x00000050: 00 00 00 00 0C 4F 66 69 63 69 6E 61 20 36 36 36  :.....Oficina 666:
0x00000060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  :................:
0x00000070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  :................:
0x00000080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  :................:
0x00000090: 00 00 00 00 00 00 04 00                          :........        :

So what's the nasty part? The dump of the NVRAM includes the SNMP community used in the device and there is no way to password protect or disable this service.

SNMP Community leak

There are a couple of commands supported in this service, after a little bit of googling someone has published some other commands, if you are interested you can check this post. If we had access to this binary we might be able to discover other undocumented commands.

The web administration panel has also some "features" for us. If we set our browser to the /se directory a engineering menu is shown, there is no way to password protect it either. The amount of commands depends on the printer version.

Lexmark n4000e 
 An attacker could take advantage of this information, the SNMP community leak also works using this panel. If we check the same directory in an expensive printer there are a lot of debugging logs that may include usernames and if it is used as a fax machine, the callers are also shown.
Lexmark Optra MFP 

We had discovered a couple interesting flaws, but none of these are useful enough for our goal of having access to it. These services have a lot of interesting options but it's a little bit out of the scope of this blog post.

What's next? It's time to break this thing apart and hook some cable into it.

Searching for a UART serial port

Most of the embedded devices hide a hardware debugging port. If you have never done it before the first idea seems like this, but detecting it is quite simple and this provides a great tool during the assessment of a embedded device since if we succeed we might get:
  • Access to a shell (could be password protected)
  • Access to the boot loader
  • Access to a non-interactive debugging console
All of the possible outcomes are great so, how do we detect a UART port? First of all a visual inspection of the device. Normally we should look for unsoldered test pads/probe points, they should be aligned, but this changes from device to device.

Initial Inspection

If take a closer look, we can notice a number of interesting things:

Debug UART
  • JT1 - 2 pins - 3,3v and GND 
  • JT2 - Extra unsoldered USB connector, could be useful to add storage
  • Unamed - 22 pins -  JTAG ? Possible expansion bus?
  • J4 - Debug - 4 pins - Seems quite interesting!
A UART serial normally has this elements:
  • VCC
  • GND
  • TX
  • RX

Ground Pin

The first thing we need to do is to detect the Ground (GND) pin and to do so the easy way is to use a continuity test of a multimeter. With the device unplugged, connect one of the probes to the metallic shielding of the RJ45 or the USB shield and with the other probe we will cycle around the suspected pins. When you get an audible tone confirms that those two points of the circuit are connected between each other.


Normally this is used to power up the serial cable interface. We will not be using it but we will need to identify it. First we have to power up the device and mesure using the previously identified GND and cycling around the other pins using the other probe. The reading should say 3,3v.

RX/TX Pins

Using the multimeter to detect VCC we should detect one of the pins with no voltage for RX and one pin with 3,3v. But in this case the other two had the same voltage and connecting both TX and RX blindly to this device could lead in having a burned adaptor. If you really want to connect the RX you should use a 1k OHM to prevent that. 

The easiest way is detecting TX first. For it I normally use a BusPirate which is a great tool and is quite useful but you could use any other UART adapter, one of my favorites is the CP2102 which not only works out of the box with Linux. We could setup custom baudrate using this which could be quite handy.

Bus Pirate cheatsheet

With the device off we connect GND and the MISO cable from the bus pirate to the suspected TX pin, then we configure the serial settings such as baudrate, I first applied 115200 which normally works with most of this kind of devices. 

After everything is connected we power on the device to see what happens... nothing. Just a couple of garbage characters, so I switched to the other suspected pin and power the device again.

Garbage, a lot of it which is quite promising. This normally happens when using the wrong baudrate. There are many ways to detect the correct speed.  We now know that the pinout is something like this.
  • DEBUG 
    • 1 - 3,3v(UNKOWN)
    • 2 - 3,3v (TX)
    • 3 - 3,3v (UNKOWN)
    • 4 - GND   
To detect the correct speed we could do manually and see if it works. We could automate this process using baudrate or if you are lazy and have a bus pirate, the auto-baud detection macro could save the day.

I now know the possible baudrate, using my CP2102  serial adapter connected to the Lexmark debug port and I powered on:

$ screen /dev/ttyUSB0 38400

Linux version 2.4.0-test6 (Lexmark@lexmark) (gcc) #1

Processor: ARM/VLSI Arm920sid(wb) revision 0
Architecture: Lexmark F-ARM controller
On node 0 totalpages: 2048
zone(0): 2048 pages.
zone DMA  25 50 75   rs=2048  sz=2048
zone(1): 0 pages.
zone(2): 0 pages.
Setting lxk_pool_size to 0 because we have <= 8MB
COMMAND: 'porkeys=0 rw hda=autotune hdb=none root=/dev/flasha3 ro xtramem=0 PORKEYS=0 SERDBG=0 lbringsize=65536 DBPRINT=0 NETCRCFAIL=0 KCONFIG=40000000'
Kernel command line: porkeys=0 rw hda=autotune hdb=none root=/dev/flasha3 ro xtramem=0 PORKEYS=0 SERDBG=0 lbringsize=65536 DBPRINT=0 NETCRCFAIL=0 KCONFIG=40000000
sai 0 c00e9d24
Calibrating delay loop... 86.84 BogoMIPS
Memory: 8MB = 8MB total
Memory: 6968KB available (853K code, 150K data, 40K init)
Dentry-cache hash table entries: 512 (order: 0, 4096 bytes)
Buffer-cache hash table entries: 1024 (order: 0, 4096 bytes)
Page-cache hash table entries: 1024 (order: 0, 4096 bytes)
Inode-cache hash table entries: 512 (order: 0, 4096 bytes)
POSIX conformance testing by UNIFIX
usb.c: registered new driver hub
Linux NET4.0 for Linux 2.4
Based upon Swansea University Computer Society NET3.039
NET4: Unix domain sockets 1.0/SMP for Linux NET4.0.
NET4: Linux TCP/IP 1.0 for NET4.0
IP Protocols: ICMP, UDP, TCP, IGMP
IP: routing cache hash table of 512 buckets, 4Kbytes
TCP: Hash tables configured (established 512 bind 512)
Starting kswapd v1.7
Lexmark Standard Serial driver version 1.17

pty: 4 Unix98 ptys configured
Initialize the flash file system for 2 Devices, 16 partitions per device...
flashEnablePhysicalDevice: 0 Base: e0000000 Size: 8Mb

Reading partition table for device: 0

         0: s: 0x0000c000 l: 0x00058000
         2: s: 0x00064000 l: 0x000fc000
         3: s: 0x00160000 l: 0x00320000
         4: s: 0x00480000 l: 0x00344000
        13: s: 0x007ce000 l: 0x00008000
        14: s: 0x007d6000 l: 0x00002000
Register flash driver...
RAMDISK driver initialized: 1 RAM disks of 4096K size 1024 blocksize
usb.c: registered new driver hub
IP-Config: No network devices available.
ip_conntrack (64 buckets, 512 max)
VFS: Mounted root (cramfs filesystem) readonly.
Freeing unused kernel memory: 40k init
Read profile...
Executing root login script: /.profile
Executing in mode 0
The old path is: /bin
The old BASEDIR is: []
The current path is: /bin
The new BASEDIR is: []
Mounting Ram Disk
mke2fs 1.12, 9-Jul-98 for EXT2 FS 0.5b, 95/08/09
===> dev_size=4096 00001000
Linux ext2 filesystem format
Filesystem label=
1024 inodes, 4096 blocks
204 blocks (4.98%) reserved for the super user
First data block=1
Block size=1024 (log=0)
Fragment size=1024 (log=0)
1 block group
8192 blocks per group, 8192 fragments per group
1024 inodes per group

Writing inode tables: done
Writing superblocks and filesystem accounting information: done
Alloc 1584 bytes...due to bug in sde-mips4.0
Install system asicset driver. serial_console =  0
Alloc 12688 bytes...due to bug in sde-mips4.0
Trying to free free IRQ1
sai 1 c013c3e0
*** Engine Serial Port Control Initialized: Mode = ES_NOT_ENABLED

 sscgProfile loading: 1

Alloc 2544 bytes...due to bug in sde-mips4.0
mount: block device /dev/flasha4 is write-protected, mounting read-only
No Engine Partition
mount: block device /dev/flasha7 is write-protected, mounting read-only
Request part end of partition: 7 end: 200 l: 0
end_request: I/O error, dev 02:07 (flash), sector 0
wrong magic
mount: wrong fs type, bad option, bad superblock on /dev/flasha7,
       or too many mounted file systems
rd_ioctl: cmd: 1260 (1261 1260)
       (aren't you trying to mount an extended partition,
       instead of some logical partition inside?)
Alloc 2368 bytes...due to bug in sde-mips4.0
Standard Network
  Ethernet Driver: loaded.
Alloc 544 bytes...due to bug in sde-mips4.0
Alloc 1056 bytes...due to bug in sde-mips4.0
usb.c: registered new driver usblp
printer.c: v0.11: USB Printer Device Class driver
printer.c: $Id: printer.c,v 1.21 2003/08/14 17:20:17 stivers (null) $
Alloc 1808 bytes...due to bug in sde-mips4.0
Alloc 352 bytes...due to bug in sde-mips4.0
usb-ohci.c: USB OHCI at membase 0xf0000980, IRQ 512
usb-ohci.c: USB HC reset_hc usb-lawrin: ctrl = 0x0 ;
usb.c: new USB bus registered, assigned bus number 1
usb.c: kmalloc IF c013c600, numif 1
usb.c: new device strings: Mfr=0, Product=2, SerialNumber=1
usb.c: USB device number 1 default language ID 0x0
Product: USB OHCI Root Hub
SerialNumber: f0000980
hub.c: USB hub found
hub.c: 1 port detected
hub.c: standalone hub
hub.c: ganged power switching
hub.c: no over-current protection
hub.c: Port indicators are not supported
hub.c: power on to power good time: 0ms
hub.c: hub controller current requirement: 0mA
hub.c: port removable status: R
hub.c: local power source is good
hub.c: no over-current condition exists
hub.c: enabling power on all ports
usb.c: hub driver claimed interface c013c600
usb-ohci.c: OHCI controller usb-lawrin state
usb-ohci.c: control: 0x00000083 HCFS=operational CBSR=3
usb-ohci.c: cmdstatus: 0x00000000 SOC=0
usb-ohci.c: intrstatus: 0x00000044 RHSC SF
usb-ohci.c: intrenable: 0x80000013 MIE UE WDH SO
usb-ohci.c: hcca frame #001e
usb-ohci.c: roothub.a: 00001201 POTPGT=0 NOCP NPS NDP=1
usb-ohci.c: roothub.b: 00000000 PPCM=0000 DR=0000
usb-ohci.c: roothub.status: 00000000
usb-ohci.c: roothub.portstatus [0] = 0x00010100 CSC PPS
Process Id Log Created
hub.c: port 1, portstatus 100, change 1, 12 Mb/s
hub.c: port 1 connection change
hub.c: port 1, portstatus 100, change 1, 12 Mb/s
LOG: <30>Jan  1 00:00:02 ErrorExit[48]: Daemonizing Complete...
LOG: <30>Jan  1 00:00:02 VacuumServer[55]: Daemonizing Complete...
LOG: <30>Jan  1 00:00:02 StringsServer[54]: Daemonizing complete...
LOG: <30>Jan  1 00:00:03 StatusServer[61]: Daemonizing complete...
LOG: <30>Jan  1 00:00:06 NPAP_Server[76]: Daemonizing complete...
LOG: <30>Jan  1 00:00:06 NPA_Port_MUX[77]: Daemonizing complete...
LOG: <28>Jan  1 00:00:06 StatusServer[61]: Unable to read! (errno 9)
LOG: <28>Jan  1 00:00:06 NPA_Port_MUX[77]: OpenPrinter (213): Can't open /dev/usblp0 (0x13, Operation not supported by device)...Retrying
LOG: <28>Jan  1 00:00:07 StatusServer[61]: Unable to read! (errno 9)
    Ethernet Driver: got AUTOCMPLT
    Ethernet Driver: opened (phyADDR = 1).
send: not found
LOG: <30>Jan  1 00:00:07 Hbn[111]: Daemonizing complete...
LOG: <31>Jan  1 00:00:12 snmpd[137]: SNMP started: using port UDP 161
LOG: <30>Jan  1 00:00:12 http[138]: Daemonizing complete...
LOG: <31>Jan  1 00:00:12 http[138]: OEM byte supported and is 0
LOG: <30>Jan  1 00:00:12 http[138]: Server listening on port 80
LOG: <30>Jan  1 00:00:12 http[138]: Server listening on port 631
LOG: <54>Jan  1 00:00:12 tftp[144]: The tftp daemon is now servicing requests.
LOG: <30>Jan  1 00:00:12 ZeroConfig[157]: Daemonizing complete...
LOG: <30>Jan  1 00:00:12 host-config[155]: Daemonizing complete...
eth0      Link encap:Ethernet  HWaddr 00:20:00:40:2F:51
          inet addr:  Bcast:  Mask:
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1 errors:0 dropped:0 overruns:0 carrier:0

sync: not found
LOG: <28>Jan  1 00:00:16 Hbn[111]: Waking Up Hbn
LOG: <30>Jan  1 00:00:16 Hbn[111]: Set socket opt returned0

Voila! Now there is no doubt that this is a Linux system. We now have a serial debug console, the main issue is that it is not an interactive console as we hoped. The RX pin seems to be inactive or could be something from the Serial Debug configuration that prevent us to send commands to the Lexmark print server. Another possibility is that a resistance could be in place filtering all the information being transmitted.

Uncover and exploit one of the exposed services

At this stage, we now have plenty of information about the device. It's a Linux ARMv920. All the services run as root and we have a realtime debug serial console, Source code review could be an option since they are using GPL licensed code so Lexmark is forced to publish any modded source. In the user manual they claim to have the sources in a FTP located in but the service seems down...for the past year

Since we don't have source, fuzzing any of the exposed services is a good option, we could be able to exploit a flaw and finally have command execution.

If you never fuzzed before, I recommend using the Sulley framework which is quite easy to build your own fuzzer modules, but you could use many other tools to do this job.

We hook to the serial console and we start fuzzing the HTTP service, after a little bit we start to see some progress:

LOG: <28>Jan  1 00:15:09 http[359]: http_Parse: shutdown Failed 107, Transport endpoint is not connected
LOG: <28>Jan  1 00:15:09 http[363]: http_Parse: shutdown Failed 107, Transport endpoint is not connected
LOG: <28>Jan  1 00:15:09 http[365]: http_Parse: shutdown Failed 107, Transport endpoint is not connected
LOG: <28>Jan  1 00:15:09 http[366]: http_Parse: shutdown Failed 107, Transport endpoint is not connected
LOG: <28>Jan  1 00:15:10 http[372]: http_Parse: shutdown Failed 107, Transport endpoint is not connected

After a couple of minutes, the device is still reachable but the services stopped working so I checked against the debug console and the following pops out:

LBTRACE TRIGGER, frames rem: 0 Save: 1

[900 Service     RIP Software    162 http_Parse SIGSEGV illegal access to 50b6b38c epc=0x00401360 ra=0x0040124c]
Time:   00000c38 0004baf0
UpTime: 3128310 mSec

Dumping regs from 0xc039dfb8
r0:50505050 r1:00000129 r2:50505050 r3:50b6b388
r4:00666210 r5:00000128 r6:0046048c r7:00666338
r8:00000000 r9:0063d2c8 r10:006669b0
fp:00000000 ip:00665ca0 sp:00665c88 lr:0040124c pc:00401360
cpsr:00000010 orig_r0:0040124c

It seems like classic stack-overflow but in order to fully exploit it then it'd be easier having a debugger.  We could use QEMU in user mode if we had the binaries so it's time to download the firmware.

To be continued...


Thursday, August 1, 2013

Go Deep Pro (1 de 2)

GO Deep Pro
Analizando el WIFI de la GoPro
En esta pequeña entrada analizaremos el trafico de portátil, diminuta pero potente GoPro Hero 3.
Por ahí alguno aun no lo sabe, pero las nuevas GoPro Hero en su serie 3 incluyen conectividad wifi para poder operarlas remotamente. También existe el adaptador para convertir tu "vieja" hero 1 y 2 en wifi también. que funciona casi de la misma manera.

La camara posee un boton directo para prender la funcion wifi sin encender la camara en si. Este boton dispara el modulo de wifi y levanta un navegador web internamente en la camara. Por defecto es algo asi como GOPRO-BP-######, donde # el numero de serie de la camara, y sin password. Para poder cambiar el SSID y ponerle password hay que descargar una tool de gopro, que baja el firmware y lo edita con la configuracion que nosotros elijamos y re-flashea la camara (en resumen no es algo de todos los dias andar cambiando la configuracion de la wifi).
Para poder acceder a la camara desde la GOPRO o desde la pc (como mostraremos) necesitamos conectarnos a esa red wifi que no da (si, la camara queda en modo AP). 

Al conectanos nos otorga una IP en el rango en adelante, y siendo siempre la la IP de la camara, (la respuesta de DHCP tambien asigna como puerta de enlace la ip, dns y sec

La aplicacion oficial de GoPro de android al abrirse dispara 2 peticiones:

1 - DNS Query a
2 - Connection HTTP a 

Si el query de DNS responde, la app comienza a hacer peticiones de URL al servidor de GoPro y de Youtube para luego cargar los videos destacados de la semana, sino resuelve no intenta abrir ningun link.

Si la conneccion a es correcta comienza a hacer una serie de peticiones bastantes peculiares que las analizaremos a continuacion:

1: GET /bacpac/cv HTTP/1.1\r\n 
La respuesta de la peticion es un archivo llamado cv, que contiene la SSID de la wifi de la camara, o sea si configuramos nuestra camara para que la wifi se llamara "pepe" el archivo CV contendra "pepe"

2: GET /bacpac/sd HTTP/1.1\\r\\n
La respuesta de la peticion es un archivo llamado sd, que contiene la password de la wifi de la camara, o sea si configuramos para que sea 1234, el contendi de este archivo sera 1234.

La contraseña de la wifi es la que nos dara acceso al servidor web. Imagino yo (y es una opinion personal) con el afan de hacer la aplicacion facil y sin mucha configuracion, los programadores hicieron esto de que la camara devuelva la contraseña tras una peticion especifica, total hay que tener la contraseña para poder conectarte a la wifi en una primera instancia, y siendo que la APP no puede obtener la contraseña del wifi almacenada en el celular (al menos no sin acceso root).

3: GET /bacpac/se?t=1234
Esto es una especie de "ping". El software hace esta peticion cada 2 segundos, para saber que la camara aun sigue ahi. La respuesta es un archivo llamado se, de 14 bytes, en este archivo le dice a la app en que modo esta la camara (video, photo, burst, etc) y el nivel de bateria. Notese tambien que de ahora en adelante toda la comunicacion con la camara se realiza con el parametro t con el contenido (si, en plano y por url) la contraseña.

De esta manera ya nos vamos dando cuenta que toda la comunicacion con la camara es mediante peticiones GET, no por post.

Comandos encontrados:

PW: (Power)
A: GET /bacpac/PW?t=1234&p=%01
Comando PW: Encender y apagar camara, el valor %01 enciende la camara y el valor la apaga. (o sea haciendo esta peticion desde cualquier navegador, hacia la ip de la camara la encenderá o apagara)

PV: (Preview)
B: GET /camera/PV?t=1234&p=%01
(notese que el directorio de la peticion cambio a "camara") Comando PV: Este comando nos permite activar y desactivar el modo streamning de la camara siendo el valor %01 off y el %02 on.
Cuando activamos el streamming (la aplicacion de android lo hace para mostrar el preview en pantalla del celular) el SO de la camara abre el puerto 8080

Live Stream: (Una ves activdo el commando PV)
C: GET /live/amba.m3u8 (peticion realizada en el puerto 8080)
Esto inicia la descarga del archivo de datos de stream AMBA.m3u8. Si usamos un cliente de stream como el VLC podremos ver la camara computadora. 

A esta altura todo ya viaja sin autenticacion (ni basica), o sea, si la camara tiene habilitado el "preview" o streaming, con ir directo a esa URL ya podremos ver la camara, o hasta podremos pedir los archivos separados de secuencia:

con hacer un get directo de cualquier archivo .ts del listado tendremos un video de 2 segundos directo de la camara.

SH: (Shooter)
D: GET /bacpac/SH?t=1234&p=%01
Comando SH: Activa el disparo, dependiendo de el modo en que se encuentre la camara, si es video comienza a grabar, si es foto, saca una foto, es virtualmente simil a precionar el boton de disparo de la camara (fisicamente), se encuentra la variable esta funciona solo en modo video o time lapse, que detiene la grabacion.

CM: (ChangeMode)
E: GET /camera/CM?t=1234&p=
El comando CM cambia el modo de la camara (el modo actual de la camara, al apagar la camara y encender volvera a iniciar con el modo predefinido). Modificadores:

: Modo Video
%01: Modo Foto
%02: Modo Burst (Foto secuencia)
%03: Modo 
Time Lapse (Foto cada X segundos)

VR: (VideoRecording)
F: GET /camera/VR?t=1234&p=
El comando VR cambia las opciones del modo de grabacion de Video. Modificadores:

: WVGA 60
%02: 720 30
%03: 720 60
%04: 960 30
%06: 1080 30

TM: (Time)
G: GET /camera/TM?t=1234&p=%0d%07%07%10%2b%2d
El comando TM setea la fecha de la cam.

LL: (Locate)
H: GET /camera/LL?t=1234&p=%01
El commando LL inicia una serie de pitidos en la camara para encontrarla. Esta segura pitando hasta que se le pase el comando con el modificador

CN: (ChangeName)
I: GET /camera/CN?t=1234&p=%09Nombre_Nuevo
El comando CH cambia el nombre interno de la camara (no la SSID de la wifi). Este nombre figurara en la APP cuando se conecte a esta camara.

DL: (Delete)
J: GET /camera/DL?t=1234
El comando DL borra el ultimo archivo de la SD

DA: (Delete All)
K: GET /camera/DA?t=1234
Borra todo el contenido de la SD (Incluyendo los archivos ocultos .LRV que genera la camara cuando graba video.  No toca ningun archivo que no tenga el formato de nombre de gopro (o sea, generado por la camara). 

Otras Curiosidades:
La camara al encender genera un archivo dentro de /MISC/version.txt donde contiene los datos de la camara. Este archivo es consultado desde el servidor web (en modo preview en el puerto 8080) por la aplicacion.

"info version":"1.1",
"firmware version":"HD3.01.01.10",
"wifi version": "",
"wifi bootloader version": "0.2.2",
"wifi mac":"xx:xx:xx:xx:xx:xx",
"camera type":"Hero3-White Edition",

Tambien la aplicacion de actualizacion de gopro (java) consulta este archivo.

Opinion sobre seguridad.

Mas alla de lo obvio, de la peticion en plano, del protocolo http (y no ssl o ttl), y si nos conformaramos con que la seguridad sea el saber la pass de la wifi, igual surgen pequeñeces:

  • Si desconectas el wifi del celu, por ejemplo te acordastes de chekear un correo o mandar un mensaje por internet, y te cambias de wifi a uno con acceso a internet, la app de gopro, sigue enviando el "ping" a la camara para ver si aun sigue ahi, con la password en plano en la peticion. Por lo que quedara pegado por todos lados la contraseña de la camara.
  • Lo mismo pasa si apagas el wifi de la camara, algo bastante normal. Si te has cansado de jugar con la camara o se quedo sin bateria, el celular al no tener conexion con la wifi, se conectara a la proxima en  su lista, y la app de la gopro enviara la peticion con la contraseña, hacia ese AP. 
  • Debido a que tarde o temprano el soft de gopro se conecta enviando la contraseña en plano por la url, cuando configuras la firmware para ponerle una contraseña, el software no te deja poner caracteres "raros" ni espacios. Por lo que ya sabemos que la contraseña de la gopro tendra solo caracteres alfanumericos (por ahi facilitando un poquito mas un ataque de bruteforce).
  • Si tienes acceso a la red wifi de la camara, tienes acceso a todo. Reflashear un firmware no es algo que cualquiera haga, ni que se realice todos los dias. Muchas camaras quedaran con la wifi por defecto, y quienes le hayan puesto una, si se descubre la contraseña (ya sea viendo los de un ap o accediendo al telefono o pc donde se guardo la red wifi) es dificil que el dueño de la camara vuelva a pasar por todo el proceso de flasheo para cambiar periodicamente la contraseña (recordemos que es la unica manera de cambiar la SSID y PASS del wifi de la gopro).
  • La firmware es procesada localmente por el soft y luego enviada a la camara, por lo que facilita el trabajo a quienes gusten modificar el firmware a gusto y flashearselo (claro, con el riesgo que conlleva "brikear" la cam).

     Habilitando el modo streaming, la camara abre el puerto 8080, sin restricciones (cualquiera conectado a la red wifi tiene acceso a la memoria de la camara de forma directa, al igual que al streaming en vivo)
GoPro Connector PIN-Out

  1. GND
  2. R video out – component Pb/Cb or composite (composite video out activated by grounding ID3 and ID4, component video out activate by grounding ID2 – only valid for old firmwares, current versions require eeprom).
  3. G video out – component Y
  4. B video out – component Pr/Cr
  5. USB +5V power
  6. as above
  7. USB Data+
  8. USB Data-
  9. GND
  10. Audio out Right
  11. Audio out Left
  12. Pwr/Mode button (tie to ground to activate)
  13. Playback mode button (tie to ground to activate)
  14. Audio in Right
  15. Audio in Left
  16. IR input
  17. Trig digital output
  18. GND (?)
  19. ID1 digital input
  20. ID2 digital input
  21. ID3 digital input
  22. ID4 digital input
  23. Adapter output – power output for external equipment (follows internal battery power).
  24. as above, but only powered when camera is on
  25. VBat+ external power input ?
  26. as above
  27. GND
  28. DATA interface I2C
  29. CLK interface I2C
  30. GND