Wednesday, April 29, 2009

BUFFER OVERFLOW: WHEN THE DATA BECOMES INSTRUCTIONS

Buffer overflow is on of the oldest computer security problem. Beginning from Morris's Worm this type of remote exploitation is one of the most common and dangerous. If you look into last security holes found by big security research companies such as BugTraq or Packet Storm, you will see that minimum about 1/3 of them are buffer overflows. Buffer overflow is actual on ALL operation systems.

Let's demonstrate the buffer overflow on a small example. All code in this article written in C and must be compiled under Windows (I am using Microsoft Visual C++ 5.0).

==========================================

/* bo.exe */

#include
int oveflowing_func(char *big)
{
char vulnerable_buffer[100]; // overflowing buffer [100 bytes]
strcpy(vulnerable_buffer,big); // copy big_buffer to vulnerable_buffer
return 0; // leave function
}

int main (int argc, char *argv[])
{
char big_buffer [1024]; // buffer for keyboard input [1024 bytes]

gets(big_buffer); // entering the string from keyboard
oveflowing_func(big_buffer); // call valurnable function
return 0;
}

======================================

First the user enters the string [big_buffer], when we call [oveflowing_func] with [big_buffer] as param and in oveflowing_func we copy [big_buffer] to [vulnerable_buffer]. The main idea is that [vulnerable_buffer] is smaller than [big_buffer]. If the [big_buffer] will be bigger than 100 symbols/bytes the [vulnerable_buffer] will be overflowed and we can exploit it. Now let's compile this program as Win32 console application. So let's run it and enter the string more than 100 symbols long:

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

... in the result we get abnormal program termination and the following error message:

Exception: access violation. Address: 0x61616161

Let's see what happened. When the procedure/function is called, the program puts return address in stack. The return address points to the next command after the function call , in our example: return 0. Also in stack function keeps it's local variables. So at the moment before overflow (strcpy(valurnable_buffer,big)) stack has the following structure:

___________________
| |
_|___________________|
| | |
| | | *************************
100 bytes = | | vulnerable_buffer | !!! stack grows down !!!
| | | *************************
| |___________________ |_
| | |
| return address | | = 4 bytes
|___________________ | |
|____________________|

It's clear that strcpy(valurnable_buffer,big) with [big] large than [valurnable_buffer] will cause the change of return address.

We managed to give control to address placed in our string. Now we can create a string for input, containing a small code (processor's instructions) that will do everything we need, and by changing the return address give control to it. We have th e exploit.

At the beginning we need to know which position in the string will be placed in the return address. Using only our listing we cannot find these positions. There is two methods of finding it. We can disassembly our program, for example with Interactive Disassembler, but we need to know exactly in what function the overflow is. And there is experimental way to do it. We will use it. At first, we need to form a string with all symbols with ASCII codes from 32 to 255

=========================================
/* ascii.exe */

#include
void main(void)
{
int i;
for (i=32;i<256;i++) printf("%c",i);
}

===========================================

Pay attention to one thing: the exploit string must NOT contain the end-of-line symbols:NULL(0x00), LF(0x0a), CR(0x0c), EOF(0x1a). In case that one of this symbols will be in string the strcpy function will copy only a part of our string until these s ymbols. That's why we use codes from 32-255.

Compile and run:

c:\bo.exe | ascii.exe

And we have:

Exception: access violation. Address: 0x8b8a8988

Address 0x8b8a8988 (remember about reversed order in the machine word: from right to left:0x8b8a8988 - correct, 0x88898a8b - wrong) means that begging from 0x88 - 0x20(32) = 104th (the count begins from 0 but our string starts at 32) our string will intercept with the return address. That means - we need to form such a string that symbols in positions 104th, 105th, 106ht and 107th (size of return address is 4 bytes - machine word) will contain the address to give control to.

Now we need to decide how we will form the code. There is 2 possibilities: from the beginning to 104th and from 108th. The first method gives us only 104 bytes for code that's why we choose the second one. The string before 104th position we can fill with code of 'NOP' (No OPerand) 0x90.

Next we need to determine what address we will place instead of the return address. Let's look into registers and memory after the instruction 'RET' (= 'return' in C). Let's look into stack again:

___________________
| |
0|___________________|
| |
| | *************************
| vulnerable_buffer | !!! stack grows down !!!
| | *************************
104|___________________|
| |
| return address |
108|___________________|
|___________________| <- ESP

On the left there are positions in string. As you can see after the 'RET' command the ESP register will point to 108th position in our string. So all we need is to execute instruction: jmp esp. In order to do it we should find in memory the combination of 2 bytes: 0xff 0xe4 (jmp esp). The address of this 2 bytes will be new return address. So we have the following execution order:

RET -> JMP ESP -> exploit code

This combination can be found in the our program memory or in DLL memory area. The best variant is the first one or DLL that is connected to the program.The image of DLL in memory is placed beginning from Image base. We can easily found it using any utility analysing PE headers.

D:\exploit>listdlls bo
. . .
Base Size Version Path
0x00400000 0x27000 C:\bo.exe
0x77f60000 0x5c000 4.00.1381.0130 D:\WINNT\System32\ntdll.dll
0x77f00000 0x5e000 4.00.1381.0133 D:\WINNT\system32\KERNEL32.dll

Here Base - is Image base of the program. Now we have information about placement of program and DLLs in memory. We can search for these 2 bytes (jmp esp) in the executable file(*) or in memory(**). The last one looks more comfortable for me as we don't need to count the offset in file.
Let's use a debugger, for example Soft ICE for Windows. Run Soft ICE service and choose bo.exe and making a buffer overflow as we have done it earlier. When the exception will be raised - we will see the Soft ICE console. Let's search for our combination, type this command: s 1000000 l ffffffffff e4 - it means search for byte combination 0xff 0xe4 beginning with address 0x0100000(it's the first address that doesn't contain highest zero byte) to 0xFFFFFFFF, In result we have:

Pattern found at 0023:77f327e5 (77f327e5)


The combination was found at 0x77f327e5. Well done ! This address doesn't contain the end-of-line codes: 0x00, 0x0a, 0x0c, 0x1a, so we can easily use it. This instruction is inside KERNEL32.DLL (range from 0x77f00000-0x77f5e000) and depends on the service pack installed - probably this address will differ on your machine.

If you search it in file you will see that the bo.exe will be placed in the range 0x77f00000 : 0x77f5e000 - that means the highest byte is always zero - we cannot use these addresses.

KERNEL32.DLL is in range 0x77f00000 : 0x77f5e000 - that means: use any hex viewer and search for 0xff 0xe4 - than we add to the found offset the Image base and we will have the same result: 0x77f327e5.

Now you have everything you need: you know where to place binary code, you know what value to place instead the return address. That's all. Everything you need is to create an exploit.

Tuesday, April 28, 2009

10 REASONS WEBSITES GET HACKED

1. Cross site scripting (XSS)

The problem: The “most prevalent and pernicious” Web application security vulnerability, XSS flaws happen when an application sends user data to a Web browser without first validating or encoding the content. This lets hackers execute malicious scripts in a browser, letting them hijack user sessions, deface Web sites, insert hostile content and conduct phishing and malware attacks.

Attacks are usually executed with JavaScript, letting hackers manipulate any aspect of a page. In a worst-case scenario, a hacker could steal information and impersonate a user on a bank’s Web site.

Real-world example: PayPal was targeted last year when attackers redirected PayPal visitors to a page warning users their accounts had been compromised. Victims were redirected to a phishing site and prompted to enter PayPal login information, Social Security numbers and credit card details.

How to protect users: Use a whitelist to validate all incoming data, which rejects any data that’s not specified on the whitelist as being good. This approach is the opposite of blacklisting, which rejects only inputs known to be bad. Additionally, use appropriate encoding of all output data. Validation allows the detection of attacks, and encoding prevents any successful script injection from running in the browser.


2. Injection flaws

The problem: When user-supplied data is sent to interpreters as part of a command or query, hackers trick the interpreter which interprets text-based commands into executing unintended commands. Injection flaws allow attackers to create, read, update, or delete any arbitrary data available to the application. In the worst-case scenario, these flaws allow an attacker to completely compromise the application and the underlying systems, even bypassing deeply nested firewalled environments.

Real-world example: Russian hackers broke into a Rhode Island government Web site to steal credit card data in January 2006. Hackers claimed the SQL injection attack stole 53,000 credit card numbers, while the hosting service provider claims it was only 4,113.

How to protect users: Avoid using interpreters if possible. If you must invoke an interpreter, the key method to avoid injections is the use of safe APIs, such as strongly typed parameterized queries and object relational mapping libraries.

3. Malicious file execution

The problem: Hackers can perform remote code execution, remote installation of rootkits, or completely compromise a system. Any type of Web application is vulnerable if it accepts filenames or files from users. The vulnerability may be most common with PHP, a widely used scripting language for Web development.

Real-world example: A teenage programmer discovered in 2002 that Guess.com was vulnerable to attacks that could steal more than 200,000 customer records from the Guess database, including names, credit card numbers and expiration dates. Guess agreed to upgrade its information security the next year after being investigated by the Federal Trade Commission.

How to protect users: Don’t use input supplied by users in any filename for server based resources, such as images and script inclusions. Set firewall rules to prevent new connections to external Web sites and internal systems.

4. Insecure direct object reference

The problem: Attackers manipulate direct object references to gain unauthorized access to other objects. It happens when URLs or form parameters contain references to objects such as files, directories, database records or keys.

Banking Web sites commonly use a customer account number as the primary key, and may expose account numbers in the Web interface.

References to database keys are frequently exposed. An attacker can attack these parameters simply by guessing or searching for another valid key. Often, these are sequential in nature.

Real-world example: An Australian Taxation Office site was hacked in 2000 by a user who changed a tax ID present in a URL to access details on 17,000 companies. The hacker e-mailed the 17,000 businesses to notify them of the security breach.

How to protect users: Use an index, indirect reference map or another indirect method to avoid exposure of direct object references. If you can’t avoid direct references, authorize Web site visitors before using them


5. Cross site request forgery

The problem simple and devastating this attack takes control of victim’s browser when it is logged onto a Web site, and sends malicious requests to the Web application. Web sites are extremely vulnerable, partly because they tend to authorize requests based on session cookies or “remember me” functionality. Banks are potential targets.

Ninety-nine percent of the applications on the Internet are susceptible to cross site request forgery.

Real-world example: A hacker known as Samy gained more than a million “friends” on MySpace.com with a worm in late 2005, automatically including the message “Samy is my hero” in thousands of MySpace pages. The attack itself may not have been that harmful, but it was said to demonstrate the power of combining cross site scripting with cross site request forgery. Another example that came to light one year ago exposed a Google vulnerability allowing outside sites to change a Google user’s language preferences.

How to protect users: Don’t rely on credentials or tokens automatically submitted by browsers. The only solution is to use a custom token that the browser will not ‘remember'.

6. Information leakage and improper error handling

The problem: Error messages that applications generate and display to users are useful to hackers when they violate privacy or unintentionally leak information about the program’s configuration and internal workings.

Web applications will often leak information about their internal state through detailed or debug error messages. Often, this information can be leveraged to launch or even automate more powerful attacks.

Real-world example: Information leakage goes well beyond error handling, applying also to breaches occurring when confidential data is left in plain sight. The ChoicePoint debacle in early 2005 thus falls somewhere in this category. The records of 163,000 consumers were compromised after criminals pretending to be legitimate ChoicePoint customers sought details about individuals listed in the company’s database of personal information. ChoicePoint subsequently limited its sales of information products containing sensitive data.

How to protect users: Use a testing tool such as OWASP’S WebScarab Project to see what errors your application generates. Applications that have not been tested in this way will almost certainly generate unexpected error output.


7. Broken authentication and session management

The problem: User and administrative accounts can be hijacked when applications fail to protect credentials and session tokens from beginning to end. Watch out for privacy violations and the undermining of authorization and accountability controls.

Flaws in the main authentication mechanism are not uncommon, but weaknesses are more often introduced through ancillary authentication functions such as logout, password management, timeout, remember me, secret question and account update .

Real-world example: Microsoft had to eliminate a vulnerability in Hotmail that could have let malicious JavaScript programmers steal user passwords in 2002. Revealed by a networking products reseller, the flaw was vulnerable to e-mails containing Trojans that altered the Hotmail user interface, forcing users to repeatedly reenter their passwords and unwittingly send them to hackers.

How to protect users: Communication and credential storage has to be secure. The SSL protocol for transmitting private documents should be the only option for authenticated parts of the application, and credentials should be stored in hashed or encrypted form.

Another tip: get rid of custom cookies used for authentication or session management.

8. Insecure cryptographic storage

The problem: Many Web developers fail to encrypt sensitive data in storage, even though cryptography is a key part of most Web applications. Even when encryption is present, it’s often poorly designed, using inappropriate ciphers.

These flaws can lead to disclosure of sensitive data and compliance violations.

Real-world example: The TJX data breach that exposed 45.7 million credit and debit card numbers. A Canadian government investigation faulted TJX for failing to upgrade its data encryption system before it was targeted by electronic eavesdropping starting in July 2005.
How to protect users: Don’t invent your own cryptographic algorithms. Only use approved public algorithms such as AES, RSA public key cryptography, and SHA-256 or better for hashing.

Furthermore, generate keys offline, and never transmit private keys over insecure channels.


9. Insecure communications

The problem: Similar to No. 8, this is a failure to encrypt network traffic when it’s necessary to protect sensitive communications. Attackers can access unprotected conversations, including transmissions of credentials and sensitive information. For this reason, PCI standards require encryption of credit card information transmitted over the Internet.

Real-world example: TJX again. Investigators believe hackers used a telescope-shaped antenna and laptop computer to steal data exchanged wirelessly between portable price-checking devices, cash registers and store computers, the Wall Street Journal reported.

“The $17.4-billion retailer’s wireless network had less security than many people have on their home networks,” the Journal wrote. TJX was using the WEP encoding system, rather than the more robust WPA.

How to protect users: Use SSL on any authenticated connection or during the transmission of sensitive data, such as user credentials, credit card details, health records and other private information. SSL or a similar encryption protocol should also be applied to client, partner, staff and administrative access to online systems. Use transport layer security or protocol level encryption to protect communications between parts of your infrastructure, such as Web servers and database systems.


10. Failure to restrict URL access

The problem: Some Web pages are supposed to be restricted to a small subset of privileged users, such as administrators. Yet often there’s no real protection of these pages, and hackers can find the URLs by making educated guesses.

The attacks targeting this vulnerability are called forced browsing, which encompasses guessing links and brute force techniques to find unprotected pages.

Real-world example: A hole on the Macworld Conference & Expo Web site this year let users get “Platinum” passes worth nearly $1,700 and special access to a Steve Jobs keynote speech, all for free. The flaw was code that evaluated privileges on the client but not on the server, letting people grab free passes via JavaScript on the browser, rather than the server.

How to protect users: Don’t assume users will be unaware of hidden URLs. All URLs and business functions should be protected by an effective access control mechanism that verifies the user’s role and privileges. Make sure this is done … every step of the way, not just once towards the beginning of any multistage process.