Request Membership
Categories
Posts By Month
Bloggers
Related Links
Input Validation RSS

Failing to Check Error Conditions Could Get You Sued

The Ontario Lottery and Gaming Corp. is in a bit of hot water after refusing to pay a $42.9 million jackpot:

According to the statement, Kusznirewicz was playing an OLG slot machine called Buccaneer at Georgian Downs in Innisfil, Ont., on Dec. 8 when it showed he had won $42.9 million.

When the machine’s winning lights and sounds were activated, an OLG floor attendant initially told Kusznirewicz to go to the “winners circle” to claim his prize, according to the statement. But other OLG employees immediately arrived and told him that the corporation would not be paying, because there had been a “machine malfunction.”

They offered him a free dinner for four at the casino’s buffet.

In a press release, OLG described the malfunction as follows:

“The single Buccaneer-themed slot machine in question is a two cent per play machine with a base game reward of $300 and an absolute maximum payout of $9,025,” the release states.

“The $42 million figure is not a possible award given this machine’s configuration and pay table settings.”

Of course the lawsuit will probably be thrown out, or OLG will settle with the guy for a lesser amount. But from a technical perspective, it’s amusing to think about what happened to cause this scenario. You can imagine the slot machine software looking something like this:

void do_spin() {
  spin_reels();
  if (winning_combination) {
    unsigned int winnings = calculate_payout_in_cents();
    send_to_display("You've won $%u!n", winnings/100);
    add_to_balance(winnings/100);
  }
}

int calculate_payout_in_cents() {
  int rv;
  if (rv = lookup_payout_amount())
    return rv;
  else
    return -1;
}

For some reason, something caused lookup_payout_amount() to return NULL, which meant calculate_payout_in_cents() returned -1, signifying an error. Then, in addition to implicitly casting the signed result to an unsigned type, do_spin() fails to check for the error condition! It assumes success and announces the payout via the slot machine’s display. In this case, the -1, represented as 0xFFFFFFFF in two’s complement, gets interpreted as an unsigned number, 4294967295, due to the implicit cast, and the display prints “You’ve won $42949672!”

Today’s lesson: remember to check your error conditions!

Anti-Debugging Series - Part IV

In this final part of the anti-debugging series we’re going to discuss process and thread block based anti-debugging. Processes and threads must be maintained and tracked by the operating system. In user space, information about the processes and threads are held in memory in structures known as the process information block (PIB), process environment block (PEB) and the thread information block (TIB). These structures hold data pertinent to the operation of that particular process or thread which is read by many of the API based anti-debugging methods we discussed previously.

When a debugger or reverse engineer tries to get aggressive and hook calls to anti-debugging related APIs we can move lower than the API and directly access the process and thread information to detect the attached debugger. By side stepping the operating system provided methods for querying process and thread information, we can effectively bypass some API based hooking techniques used in anti-anti-debugging efforts.

For example, in part II of this anti-debugging series I demonstrated how to make a call to IsDebuggerPresent() to detect if the debugger present process flag is set.

Prototype: BOOL WINAPI IsDebuggerPresent(void); 

if (IsDebuggerPresent()) {
    //Debugger Detected - Do Something Here
} else {
    //No Debugger Detected - Continue
}

If we analyzed what this API call actually does we would notice that it reads a flag from the PEB which indicates the presence of a debugger. Instead of directly calling the API, it is possible to emulate what the IsDebuggerPresent() function does and directly query the PEB ourselves.

The first step in analyzing data within the PEB structure is to locate the PEB structure in memory. To do this we can use a number of different methods, some more direct and low level that others. The method that is easiest to grasp is to call the function NtQueryInformationProcess with a second parameter of ProcessBasicInformation. This returns a pointer to the process information block (PIB) for the requested process. Once we have access to this PIB structure we look at the PebBaseAddress member to determine the base address of the PEB. Finally, we look at the boolean member BeingDebugged to return the same result that would be returned had we called the function IsDebuggerPresent().

The following code demonstrates our example:

hmod = LoadLibrary(L"Ntdll.dll");
_NtQueryInformationProcess = GetProcAddress(hmod, "NtQueryInformationProcess");

hnd = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, GetCurrentProcessId());
status = (_NtQueryInformationProcess) (hnd, ProcessBasicInformation, &pPIB, sizeof(PROCESS_BASIC_INFORMATION), &bytesWritten);

if (status == 0 ) {
  if (pPIB.PebBaseAddress->BeingDebugged == 1) {
    MessageBox(NULL, L"Debugger Detected Using PEB!IsDebugged", L"Debugger Detected", MB_OK);
  } else {
    MessageBox(NULL, L"No Debugger Detected", L"No Debugger Detected", MB_OK);
  }
}

There are a number of different ways that we can query the PEB and TIB blocks to detect the presence of a debugger. Let’s divert from the straight forward and instead look at a novel and interesting method of detecting a debugger specifically designed to operate under Windows Vista. In Vista, when a process is started without a debugger present, the main thread environment block contains a pointer to a Unicode string referencing a system DLL such as kernel32.dll. If the process is started under a debugger, that system DLL name is replaced with the Unicode string “HookSwitchHookEnabledEvent”. Thus if we know that the process we are trying to protect is running within a Windows Vista environment, we can use this technique to determine if the processes was launched from within a debugging environment.

To use this technique, the anti-debugging function should first check that it is running on the Windows Vista operating system. After confirming the operating system revision, the technique should locate the TIB. The TIB can be accessed as an offset of segment register FS as in the following code:

void* getTib()
{
  void *pTib;
  __asm {
    mov EAX, FS:[18h] //FS:[18h] is the location of the TIB
    mov [pTib], EAX
  }
  return pTib;
}

Once the location of the TIB is found, the offset 0xBFC from the start of the TIB is read and the pointer checked. If this value is 0x00000C00 we then read the string at offset 0xC00 and compare this value to the Unicode string “HookSwitchHookEnabledEvent”. We check the pointer to ensure that we have a string located in the pointed to address and as a second level of assurance for the accuracy of this method. If we pass this final test we can be sure that our process running under Windows Vista was started from within a debugger.

wchar_t *hookStr = _TEXT("HookSwitchHookEnabledEvent");
strPtr = TIB+0xBFC;

delta = (int)(*strPtr) - (int)strPtr;
if (delta == 0x04) {
   if (wcscmp(*strPtr, hookStr)==0) {
      MessageBox(NULL, L"Debugger Detected Via Vista TEB System DLL PTR", L"Debugger Detected", MB_OK);
    } else {
      MessageBox(NULL, L"No Debugger Detected", L"No Debugger", MB_OK);
    }
} else {
   MessageBox(NULL, L"No Debugger Detected", L"No Debugger", MB_OK);
}

In the four parts of this series we have discussed classes of anti-debugging methods, a few basic API based anti-debugging techniques, some slightly more advanced API techniques, and finally two methods that directly access process and thread information to detect the presence of a debugger.

Instead of continuing this series in blog format, I’ve decided to release a paper outlining the details of nearly 35 different anti-debugging methods. I’ll be presenting the paper (and associated slides) at the SOURCE Boston 2009 security conference which starts March 11th, 2009 and finishes up March 13, 2009. The paper and presentation are geared towards developers and software engineers who may not understand the assembly dump of some anti-debugging code but can understand what I’ve presented to you thus far.

The pre-registration rates for SOURCE Boston end on February 28, 2009. So get your ticket at a discount while you still can! It’s going to be a fantastic conference with some of the best information security topics and presenters in the industry.

Additionally, as a speaker, I’ve been given one ticket at half price to do with as I choose. As of yet I haven’t given it away. If anyone would like a half off ticket to SOURCE Boston and can attend please let me know. I’ll get the discount code over to you ASAP. I look forward to seeing you all at the conference, please come up and say hello!

How To Protect Your Users From Password Theft

Monster.com recently disclosed yet another major breach that compromised the personal data of over 1.3 million users. This is not unlike the previous breach in August 2007, though the attack vector was likely different. From a notice on their website (emphasis mine):

We recently learned our database was illegally accessed and certain contact and account data were taken, including Monster user IDs and passwords, email addresses, names, phone numbers, and some basic demographic data. The information accessed does not include resumes.

Considering the well-known tendency to use the same password on multiple websites, compounded with the fact that Monster pledged a comprehensive security review after the first breach, it’s just embarrassing that they are still storing passwords in the clear.

So let’s talk about how to properly store passwords for a web application.

Use a one-way cryptographic hash

Don’t store your passwords in the clear! If you do, an attacker just needs to find one SQL Injection vulnerability and he’s got the password for every one of your users. The idea behind using a one-way algorithm is that the hash value can’t be reversed to “decrypt” the password. So how does authentication work? When a user attempts to login, you apply the same one-way algorithm to convert the user-provided password into the hash value, and then compare the two hashes. If they match, then the user-provided password was correct. At no time is the password ever stored in the clear.

Often, developers will hear the advice “use a hash” and interpret that as “run the plaintext password through MD5 or SHA-1 and store the result.” But that only solves part of the problem — the part about using an irreversible algorithm. It doesn’t protect against pre-computation. Let’s say you’ve used SHA-1 to hash your passwords, and your USERS table looks like this in the database:

USER          PASSWORD_HASH
admin         5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8
bob           fbb73ec5afd91d5b503ca11756e33d21a9045d9d
jim           7c6a61c68ef8b9b6b061b28c348bc1ed7921cb53

So if you wanted to obtain the original passwords you’d have to run a dictionary or brute force attack, hashing all possible password options with SHA-1 and comparing the output to the stored hashes. This would take a long time but eventually you’d figure some of them out. But what if you already had a list of all 8-character permutations and their corresponding SHA-1 hashes? Now all you have to do is look up the hashes, rather than computing them on-the-fly. This is the idea behind rainbow tables.

An attacker with a SHA-1 rainbow table covering 8-character alphanumeric combinations would quickly look up those three hashes and obtain the original passwords of “password”, “p4ssword”, and “passw0rd” respectively.

Use a salt

The best defense against pre-computation of raw hashes is salting. To salt a password, you append or prepend a random string of bits to the plaintext password and hash the result. You then store the salt value alongside the hash so that it can be used by the authentication routine. Look in the /etc/shadow file of any modern Unix system and you’ll see something like this:

user1:$1$lKorlp4C$RD5TSM6PaZ6oaWRVUuXT40:13740:0:99999:7:::
user2:$1$qOmA0CUm$I6IdbZDTDl6B6m7s77VPe1:13650:0:99999:7:::
user3:$1$nIEInNo5$PSxcLtvGIJArL8r2AQl74.:13749:0:99999:7:::

Let’s look at the “user1″ entry in the example above, paying attention to the second field which contains a bunch of alphanumeric characters separated by dollar signs. The first token, 1, is a version number, The second token, lKorlp4C, is the salt. The third token, RD5TSM6PaZ6oaWRVUuXT40, is the one-way hash that was calculated using lKorlp4C as the salt.

When the user attempts to login, the system passes the user-provided password along with the stored salt into the hash routine (in this case, md5crypt), and compares the result to the stored hash.

Each bit of salt used doubles the amount of storage and computation required for a pre-computed table. For instance, if we used one bit of salt — either 0 or 1 — the rainbow table would have to account for two variations of every password. Eight bits of salt require 2^8, or 256 variations of every password. Use a sufficiently large salt and pre-computation becomes infeasible. For example, the md5crypt utility uses 48 bits of salt (and for an extra layer of protection, it runs 1000 iterations of MD5 to slow down dictionary attacks).

There are a couple of common mistakes that people make with regard to salting. First, don’t use the same salt every time. If you do, you’re not really increasing the search space because the attacker only has to account for a single salt value. Second, don’t worry about protecting the salt values, they’re not secrets. The added security is derived not from the secrecy of the salt but rather by the amount it increases the resources required for pre-computation.

If you have OpenSSL installed you can play around with various salt mechanisms and see what the output looks like:

$ openssl passwd -h
Usage: passwd [options] [passwords]
where options are
-crypt             standard Unix password algorithm (default)
-1                 MD5-based password algorithm
-apr1              MD5-based password algorithm, Apache variant
-salt string       use provided salt
-in file           read passwords from file
-stdin             read passwords from stdin
-noverify          never verify when reading password from terminal
-quiet             no warnings
-table             format output as table
-reverse           switch table columns

$ openssl passwd -1 password
$1$LH1SwzJI$0ho4XuPVfGlbWIcNuGIap/
$ openssl passwd -1 password
$1$eAUtQOBh$GlvJwVsyb8In5KKkvnR0E0
$ openssl passwd -1 password
$1$PgaSiWTy$ElLh6uy83Y6T4Y70AGmV20

A quick Google search shows that there is a lot of confusion about salting.

But wait, now my password recovery feature won’t work

What’s that? You say your application has one of those “Forgot My Password” features where a user can type in their username and their current password will be sent to the e-mail address on file? Clearly, that requirement depends on passwords being stored either in the clear or using a reversible mechanism such as symmetric encryption.

The answer here is to redesign your password recovery feature. Don’t let an unnecessary requirement force you into poor security practices. If you must e-mail a password, generate a temporary password that’s only valid for a short time period, and require the user to login immediately and select a new password. This obviates the need to retrieve the original, forgotten password.

Why not just use symmetric encryption?

Instead of storing passwords in the clear, you could encrypt them using a symmetric algorithm such as AES and have the application encrypt/decrypt as needed. While this solves the plaintext storage problem, it creates a new problem: key management. Where do you store the key? How often does it change? How many people have access to it? What do you do if/when the key is compromised? And so on. The tradeoff really isn’t worth it for something that’s more elegantly solved with salted hashes.

Layered defenses

While you’re rethinking password storage, it might be a good time to consider other common flubs such as password complexity and brute-force protections.

In conclusion

  • Storing passwords in the clear puts your users at unnecessary risk if (when) your application database is compromised
  • Use salted hashes instead of storing passwords in a recoverable format
  • Password recovery mechanisms can be implemented without needing to obtain the original password
  • As with any aspect of security architecture, use layered defenses

Have fun refactoring!

Anti-Debugging Series - Part III

It’s time for part three in the Anti-Debugging Series. With this post we will stay in the realm of “API based” anti-debugging techniques but go a bit deeper into some techniques that are more complex and significantly more interesting. Today we will analyze one method of detecting an attached debugger, and a second method that can be used to detach a debugger from our running process.

Advanced API Based Anti-Debugging

There are a number of functions and API calls within the Windows operating system that are considered internal to the operating system and thus not documented well for the average developer. Many of these functions have undergone extensive research and reverse engineering to be able to understand how they operate and what can be achieved using them. One such poorly documented API function is the NtQueryInformationProcess function which is used to retrieve information about a target process. The function prototype looks like the following:

NTSTATUS WINAPI NtQueryInformationProcess(
    __in HANDLE ProcessHandle,
    __in PROCESSINFOCLASS ProcessInformationClass,
    __out PVOID ProcessInformation,
    __in ULONG ProcessInformationLength,
    __out_opt PULONG ReturnLength
);

This function resides within the Ntdll.dll file and is not an exported function. Because of this, we must use run-time dynamic linking to gain access to the functionality. Run-time dynamic linking is the dynamic loading of a library and mapping of functions within the library to a function pointer allowing it to be called and executed. To load our function, “NtQueryInformationProcess”, we first call LoadLibrary(”ntdll.dll”) and then execute GetProcAddress(HMODULE, “NtQueryInformationProcess”) to receive a pointer to our required function.

HMODULE hmod;
FARPROC _NtQueryInformationProcess;
hmod = LoadLibrary(L"ntdll.dll");
_NtQueryInformationProcess = GetProcAddress(hmod, "NtQueryInformationProcess");

Note: The dynamic linking method is slightly different when using C++ due to declaration differences.

Once we have a function pointer to the NtQueryInformationProcess function, we can call the API. The function call takes five parameters, the first two of which are the most interesting to our anti-debugging efforts. The first parameter is a HANDLE to the target process that we wish to interrogate. Since we are trying to determine information about our own process, we will use a HANDLE that points to ourselves. By default, a HANDLE value of -1 will instruct the function to use the current process as the target. The second parameter is a value indicating what type of information is being requested from the target process. In the Microsoft MSDN documentation there are four documented values for this parameter ProcessBasicInformation (0), ProcessDebugPort (7), ProcessWow64Information (26), and ProcessImageFileName (27). There are other undocumented values that can be passed in, some of which allow for interesting anti-debugging techniques, however we will focus on the ProcessDebugPort (7) value. This value, when used as the second parameter in the NtQueryInformationProcess function will return a DWORD, returned in the address of the third parameter, indicating the DebugPort that is currently available for the process. If a non-zero value is returned, indicating that a DebugPort exists, we can be sure that a debugger is attached and act accordingly.

status = (_NtQueryInformationProcess) (-1, 0x07, &retVal, 4, NULL);

if (retVal != 0) {
    //Debugger Detected - Do Something Here
} else {
   //No Debugger Detected - Continue
}

The second anti-debugging method we will look at today also uses run-time dynamic linking of the Ntdll.dll library along with GetProcAddress() to gain access to the NtSetInformationThread function. This function’s primary purpose is to modify thread specific data for a targeted thread.

NTSTATUS NTAPI NtSetInformationThread(
    __in HANDLE ThreadHandle,
    __ in THREAD_INFORMATION_CLASS ThreadInformationClass,
    __in PVOID ThreadInformation
    __in ULONG ThreadInformationLength
)

For the anti-debugging use of this function we are again only interested in two particular parameters. The first parameter is an identifier to the thread we wish to target and the second parameter is the particular information we wish to modify on the target thread. To get a pointer to our current thread we will use a call to GetCurrentThread(). We will submit that as the first parameter and the enum value for ThreadHideFromDebugger, 0x11, as the second parameter. If a debugger is attached and we pass in 0x11 to NtSetInformationProcess, our process will immediately detach any attached debugger and terminate the process.

lib = LoadLibrary(L"ntdll.dll");
_NtSetInformationThread = GetProcAddress(lib, "NtSetInformationThread");

(_NtSetInformationThread) (GetCurrentThread(), 0x11, 0, 0);

MessageBox(NULL, L"Debugger Detached", L"Debugger Detached", MB_OK);

Many of the Microsoft API calls are intentionally not well documented to discourage their use/abuse. In this case we can make calls to two non-exported functions within the Ntdll.dll library to achieve our goals of detecting or detaching a debugger from our process. There are a number of other methods of API based anti-debugging, feel free to comment about them below.

Stay tuned for our next installment as we touch on process and thread block anti-debugging.

Tallying Twitter’s Application Security Best Practice Violations

If you were paying attention the last few days, you’ve probably read about the wave of attacks launched against the popular Twitter service. It started over the weekend, with a series of phishing attacks sent to unsuspecting Twittizens via Direct Message. Then, on Monday morning, Fox News announced Bill O’Riley (sic) was gay, CNN anchor Rick Sanchez tweeted that he was high on crack, and the Barack Obama transition team decided to raise a few bucks using affiliate referral links to survey websites. All told, 33 celebrity accounts were compromiwsed before Twitter caught on and took control of the hacked accounts.

Naturally, people wanted to know how it was done. A Twitter blog entry provided some vague detail:

The issue with these 33 accounts is different from the Phishing scam aimed at Twitter users this weekend. These accounts were compromised by an individual who hacked into some of the tools our support team uses to help people do things like edit the email address associated with their Twitter account when they can’t remember or get stuck.

What’s interesting about that paragraph is that the celebrity account hacks were not related to the phishing attacks, as one might assume, and they had nothing to do with an exploitable vulnerability in the Twitter app itself. Just a case of somebody getting hold of an admin account. Ho-hum.

Tonight, the “hacker” explained to Wired Magazine how he did it. I’ll try to summarize the attack, but you might have to read it several times because it’s subtle and complicated. Ready? Brace yourself… He used a dictionary attack to brute force a password.

Continue reading here after you’ve picked yourself up off the floor. Here’s the money quote:

The hacker, who goes by the handle GMZ, told Threat Level on Tuesday he gained entry to Twitter’s administrative control panel by pointing an automated password-guesser at a popular user’s account. The user turned out to be a member of Twitter’s support staff, who’d chosen the weak password “happiness.”

Now let’s consider the application security best practices that Twitter could have followed when designing their service, any of which would have foiled the attack.

  • Password complexity. In case you were wondering, the only restriction on Twitter passwords is a minimum length of six characters. No mixed case, no numbers, no special characters, none of that. Although they do encourage you to “Be tricky!”
  • Brute-force protections. Clearly there’s no account lockout mechanism, unless of course “happiness” was at the top of the word list. While there is no perfect solution to brute force attacks, it would appear Twitter didn’t even try.
  • Segregation of administrative functionality. I won’t underestimate the amount of effort required to segregate the admin interface. That being said, the attack would’ve failed if Twitter admins had to perform privileged functions via a dedicated internal interface.

Any others? Leave them in the comments.

In all fairness, it’s hard to make security a top priority in ANY company, much less a startup with overworked non-security-aware developers using an agile methodology with tight iterations (making some educated guesses here about Twitter). Ideally you want to start prioritizing security before you become an attractive target. Twitter missed the boat on that one, but I bet they’re paying attention now.

Anti-Debugging Series - Part II

Welcome back to the series on anti-debugging. Hopefully you have your debugger and development environment handy as we are about to dive into the first round of anti-debugging code. In the first post to this series we discussed six different types of anti-debugging techniques that are in common use today. To refresh, the classifications buckets that we chose to use are:

  • API Based Anti-Debugging
  • Exception Based Anti-Debugging
  • Process and Thread Block Anti-Debugging
  • Modified Code Anti-Debugging
  • Hardware and Register Based Anti-Debugging
  • Timing and Latency Anti-Debugging

Basic API Anti-Debugging

We’ll continue this series of posts by going into a bit more depth on the easiest of API based anti-debugging techniques. An application programming interface (API) is used to support requests made from other applications for resources or functionality within a target service or library. In our case we will be primarily focused on the Microsoft Windows operating system API. There are a number of calls built directly into the operating system API that make detection of a debugger possible. Minor differences in thread and process meta-data is present when processes are run within a debugger. These calls typically facilitate a process or thread examination technique in order to determine if the target thread has a debugger attached.

When learning about anti-debugging, a developer will typically first be introduced to the IsDebuggerPresent() function. This function analyzes the process block of a target process to determine if the processes is running under the context of a debugging session. We’ll save the details of how this actually works for a later article, however suffice it to say that the target process has a flag that will contain a non-zero value if the process is being debugged. This flag is queried and returned when IsDebuggerPresent() is called. A very basic debugging detection routine would be to call this function and execute different code paths based on the response.

Prototype: BOOL WINAPI IsDebuggerPresent(void); 

if (IsDebuggerPresent()) {
    //Debugger Detected - Do Something Here
} else {
    //No Debugger Detected - Continue
}

We could also use the API function CheckRemoteDebuggerPresent(). Contrary to first thought, this function does not target a process on a remote machine, nor does it even require that it target a process remote to itself. The call can use a parameter pointing to itself to determine if it is running inside of a debugger. In the example below we pass in a handle to our current process by calling the GetCurrentProcess() function along with a variable to hold the return value from the CheckRemoteDebuggerPresent() call.

Prototype: BOOL WINAPI CheckRemoteDebuggerPresent(__in HANDLE hProcess,
           __inout PBOOL pbDebuggerPresent);

BOOL pbIsPresent = FALSE;
CheckRemoteDebuggerPresent(GetCurrentProcess(), &pbIsPresent);
if (pbIsPresent) {
    //Debugger Detected - Do Something Here
} else {
    //No Debugger Detected - Continue
}

While these two methods are probably the easiest and most straightforward methods of anti-debugging, they are also the most likely to be understood by a person wishing to bypass them. We can mix it up a bit and use a call to OutputDebugString() instead. OutputDebugString() is typically used to output a string value to the debugging data stream. This string is then displayed in the debugger. Due to this fact, the function OutputDebugString() acts differently based on the existence of a debugger on the running process. If a debugger is attached to the process, the function will execute normally and no error state will be registered; however if there is no debugger attached, LastError will be set by the process letting us know that we are debugger free. To execute this method we set LastError to an arbitrary value of our choosing and then call OutputDebugString(). We then check GetLastError() and if our error code remains, we know we are debugger free.

Prototype: void WINAPI OutputDebugString(__in_opt  LPCTSTR lpOutputString);

DWORD Val = 123;
SetLastError(Val);
OutputDebugString(L"random");
if(GetLastError() == Val) {
    //Debugger Detected - Do Something Here
} else {
    //No Debugger Detected - Continue
}

These three methods are the basic starting point for a developer wishing to implement anti-debugging into their code base. The methods are so simple they could even be implemented as macros making a call quick and easy. Numerous other API based detection methods exist with a vast array of complexity. In the next post in this series we will discuss slightly more advanced API anti-debugging techniques that will make reverse engineering and debugging even more difficult.

Anti-Debugging Series - Part I

For those that don’t know, anti-debugging is the implementation of one or more techniques within computer code that hinders attempts at reverse engineering or debugging a target process. Typically this is achieved by detecting minute differences in memory, operating system, process information, latency, etc. that occur when a process is started in or attached to by a debugger compared to when it is not. Most research into anti-debugging has been conducted from the vantage point of a reverse engineer attempting to bypass the techniques that have been implemented. Limited data has been presented that demonstrates anti-debugging methods in a high level language that the average developer can understand. It is with this in mind that I hope to begin a series of posts that present some of the methods of anti-debugging in a clear, concise, and well documented fashion. The end goal of this series is to arm developers with the techniques and knowledge that will allow them to add a layer of protection to their software while simultaneous educating reverse engineers in some of the anti-debugging methods used by malware authors today.

Before we delve into the intricacies of individual methods of anti-debugging let’s use this post to define the classes of anti-debugging that we will be discussing. While other classes may exist, the definition of these classes is an attempt to include the majority of anti-debugging methods in use today. There is some overlap between classifications and we may have left out some methods due to limited exposure or effectiveness.

API Based Anti-Debugging
API based anti-debugging is the most straightforward and possibly the easiest to understand for a typical developer. Using both documented and undocumented API calls, these methods query process and system information to determine the existence or operation of a debugger. From single line calls such as IsDebuggerPresent() and CheckRemoteDebugger() to slightly more complex methods including debugger detaching and CloseHandle() checks. These methods are generally trivial to add to an existing code base and many can even be implemented in as few as two or three lines.

Exception Based Anti-Debugging
Exception based anti-debugging is slightly different than your basic API based techniques. Many times when a debugger is attached to a process, exceptions are trapped and handled by the debugger without regard to passing the exception back to the application for continued execution. Occasionally these exceptions can even crash or terminate a process when run under a debugger and be handled gracefully when running clean. It is these discrepancies that makes exception based anti-debugging techniques possible.

Process and Thread Block Anti-Debugging
Some of the API based anti-debugging methods use published functions to query information from within the process and thread blocks for our running code. Many API based detections can be subverted within a debugger by hooking the API call and returning values that indicate a clean process. One way around this subversion is to directly query the process and thread blocks, bypassing the API calls. Direct analysis of the process and thread blocks, while more complex, can lead to a more accurate and high assurance result.

Modified Code Anti-Debugging
One of the methods that a debugger uses to signal a breakpoint is to insert a break byte into the running code at the location that it wishes to stop execution. The process execution breaks when this value is seen, giving control to the debugger. When the program is resumed, the breakpoint value is removed and replaced with the original byte, the execution backed up one byte, and the program is resumed. Detection of software based breakpoints can be achieved by analyzing the process for modifications from the expected norm.

Hardware and Register Based Anti-Debugging
A second way that a debugger can break the execution of a process is by using a hardware breakpoint. A hardware breakpoint relies upon CPU registers to store the pertinent information and to detect when the target break addresses are seen on the bus. A break interrupt is triggered at the appropriate time based on these register values. Reading or modifying the hardware can allow for the detection of a debugger.

Timing and Latency Anti-Debugging
Finally timing and latency can be used as an effective anti-debugging method. When executing a program within a debugger, specifically when single stepping, a much larger latency occurs between execution of instructions. This latency can be detected and compared against a reasonable threshold to detect the existence of a debugger attached to our process.

Each of the classes of anti-debugging outlined above has merit when used individually to protect a process. While none of them can be assured to ever protect a program from a determined reverse engineer or debugger, implementation of these techniques (or many of them if appropriate) can sufficiently slow down the debugging process and hopefully make the attacker spend his time on other, easier, ventures. In the remainder of this series on anti-debugging we will review in depth some of the more interesting methods of each of the above classes. So bring along your debugger and your development environment and let the games begin.

Microsoft Fixes 8-year Old Design Flaw in SMB

With regard to the recent Patch Tuesday fix, there has been an issue fixed regarding NTLM Relaying, that has been around for more than eight years.

In 2000, I wrote an advisory about NTLM relaying (CVE-2000-0834). The problem turned out to be significantly larger than I originally suggested in the advisory. The attack extended to other NTLM-based authentications on other protocols and allowed general-purpose credential theft via a man-in-the-middle attack.

The SMBRelay tool was published in 2001 by Sir Dystic of Cult Of The Dead Cow, and that really took it to the next level. The protocol completely fell apart. It kicked off a number of other analyses of the NTLM protocol that finally resulted in this patch. Eight years after it’s discovery.

At least they got around to it. Thanks!

US Government Detects Attacks on Obama and McCain Computers

Now that the presidential race is over Newsweek is reporting that the US Government, through the FBI and Secret Service, notified the Obama and McCain campaigns that their computers had been compromised and sensitive documents copied.

…the FBI and the Secret Service came to the campaign with an ominous warning: “You have a problem way bigger than what you understand,” an agent told Obama’s team. “You have been compromised, and a serious amount of files have been loaded off your system.” The following day, Obama campaign chief David Plouffe heard from White House chief of staff Josh Bolten, to the same effect: “You have a real problem … and you have to deal with it.” The Feds told Obama’s aides in late August that the McCain campaign’s computer system had been similarly compromised.

This information demonstrates that the US government has a sophisticated intrusion detection capability. This is likely part of the NSA internet surveillance system that was made public by an AT&T technician in 2006.

It is likely that the system has a set of watch IP ranges that are sensitive from a national security perspective. The campaigns’ computers were probably on this list. The traffic between foreign IP addresses and these watch IPs is then scrutinized for espionage. The pattern of activity flagged would be Microsoft Office documents and PDFs being retrieved or other intruder signs such as an encrypted tunnel with a foreign endpoint.

This shows that the US Government has the capability to detect some types foreign attacks although they probably have to be selective of the IP ranges they monitor. It’s nice to know that if the White House computers were leaking documents to China or Russia that there is some detection capability, but the fact that this is done at the Internet backbone level means any IP could be targeted and it might not just be to look for foreign intrusions.

MBTA vs MIT Students Case Continues

A hearing will be held in Boston tomorrow to decide whether or not the restraining order gagging the MIT students from talking about the vulnerabilities they have found should be lifted. Even though the Defcon presentation is widely available and the MBTA disclosed the “Confidential” memo from the MIT students in their court filings, they are seeking a permanent speech injunction. An august group of computer scientists has signed a letter which will be entered into the record for the case. This list includes: Dave Farber of Carnegie Mellon University, Steve Bellovin from Columbia University, David Wagner from UC Berkeley, Dan Wallach from Rice University, Matt Blaze from the University of Pennsylvania, and Bruce Schneier. An excerpt:

We write to express our firm belief that research on security vulnerabilities, and the sensible publication of the results of the research, are critical for scientific advancement, public safety and a robust market for secure technologies. Generally speaking, the norm in our field is that researchers take reasonable steps to protect the individuals using the systems studied. We understand that the student researchers took such steps with regard to their research, notably by planning not to present a critical element of a flaw they found. They did this so that their audience would be unable to exploit the security flaws they uncovered. . . .

The restraining order at issue in this case also fosters a dangerous information imbalance. In this case, for example, it allows the vendors of the technology and the MBTA to claim greater efficacy and security than their products warrant, then use the law to silence those who would reveal the technologies’ flaws. In this case, the law gives the public a false sense of security, achieved through law, not technical effectiveness. Preventing researchers from discussing a technology’s vulnerabilities does not make them go away - in fact, it may exacerbate them as more people and institutions use and come to rely upon the illusory protection. Yet the commercial purveyors of such technologies often do not want truthful discussions of their products’ flaws, and will likely withhold the prior approval or deny researchers access for testing if the law supports that effort. . . .

Yet at the same time that researchers need to act responsibly, vendors should not be granted complete control of the publication of such information, as it appears MBTA sought here. As noted above, vendors and users of such technologies often have an incentive to hide the flaws in the system rather than come clean with the public and take the steps necessary to remedy them. Thus, while researchers often refrain from publishing the technical details necessary to exploit the flaw, a legal ban on discussion of security flaws, such as that contained in the temporary restraining order, is especially troubling.

It will be interesting to see what arguments the MBTA uses to keep the students from speaking on a topic where all the important vulnerability information seems to have already disclosed. Sure the students haven’t presented a cookbook exploit tool but they have also stated they have no intention of doing so.

Perhaps the court will investigate what the MBTA’s and their technology vendors response has been to the MiFare card vulnerabilities that were disclosed responsibly. If there has been no vigorous response to responsibly disclosed vulnerabilities of many months ago how can they say with a straight face that are truly responding to new security information and just need more time.

Next Page »
 

Powered by WordPress