1.3 Given a scenario, analyze potential indicators associated with application attacks

  • Privilege Escalation
  • Cross-Site Scripting
  • Injections
    • Structured Query Language (SQL)
    • Dynamic Link Library (DLL)
    • Lightweight Directory Access Protocol (LDAP)
    • Extensible Markup Language (XML)
  • Pointer/Object Dereference
  • Directory Traversal
  • Buffer Overflow
  • Race Conditions
    • Time of Check/Time of Use
  • Error Handling
  • Improper Input Handling
  • Replay Attack
    • Session Replays
  • Integer Overflow
  • Request Forgeries
    • Server-Side
    • Cross-Site
  • Application Programming Interface (API) Attacks
  • Resource Exhaustion
  • Memory Leak
  • Secure Sockets Layer (SSL) Stripping
  • Driver Manipulation
    • Shimming
    • Refactoring
  • Pass the Hash


Privilege Escalation

Privilege Escalation is where a hacker attempts to obtain higher credentials.  In a system, there may be “guest”, ‘user”, and “admin” privileges.  There many be different levels of admin privileges.  If a hacker obtains access to the system as a guest, he could use the guest account to obtain higher level privileges by snooping around.

Some programs, services, or processes may run under elevated/admin privileges.  If there is a security hole in one of these applications, a hacker could take advantage of it to execute code that runs under the same privilege as the original application.

For example, the Cisco VPN application must be able to regularly update itself.  Doing so requires admin privileges.  Therefore, the Cisco VPN application runs under admin privileges, even on a standard user’s account.  If there was a security vulnerability in the Cisco VPN application, a hacker could log in as a guest or regular user and trick the Cisco VPN application into executing a malicious program under the same admin privileges that it has.

How to prevent

  • Implement User Account Control on Windows, or scripts in UNIX

  • Regularly update applications and regularly install operating system updates

  • Do not allow any applications with admin privileges to run under guest accounts

Cross-Site Scripting

In cross-site scripting (XSS), a user includes script as part of their input in a web form or link.  There are three types

  • Non-persistent XSS attack, where the script is executed by the web server immediately and sent back to the browser.

    • For example, a hacker sends a user a link to a legitimate online banking website, but the link includes some code that executes (through the website) in the user’s browser.  The script copies the user’s login credentials and sends them to the hacker.

    • In another example, let’s say I have a website with a contact form.  Instead of typing in legitimate data, the hacker pastes a script and submits it.  The script might convince the server to return sensitive data back to the hacker.  If the server doesn’t have good security, it executes the script and returns sensitive data to the hacker’s browser.


  • Persistent XSS attack, where the script is stored by the web server and executed against others

    • For example, a hacker posts a YouTube comment and includes some HTML and scripts (which includes links and photographs to an ecommerce site).  The HTML executes in each visitor’s web browser, and all visitors see the comment (including the links and photographs).  The script might be designed to copy data from each user that sees it and send the results to the hacker’s server.

  • DOM-based XSS attack, where the script is executed by the browser.  DOM stands for Document Object Model. 

    Many websites are now being written to execute code inside the user’s browser instead of on the server.  This system helps render web pages so that they fit properly in each web browser, regardless of the screen size.  This system may require the browser to download additional data in the background after the page has loaded.

    If we modify the browser environment in a certain way, we can cause the website to behave unexpectedly.

    • The hacker can send the victim a URL to a legitimate DOM page but include a script inside the URL. 

    • The script tells the browser to download content from the hacker’s server.

    • The web page loads like normal and then begins to download the malicious content from the hacker’s server in the background.

How to prevent

  • Use proper input validation in web forms both on the web browser side and on the server side

  • Remove or filter all script characters from web forms, including “<”, “;”, and “|”

  • Use anti-XSS libraries such as ANTIXSS

  • Use Content Security Policy in the website

  • Use an HTML escape string when using JavaScript to execute HTML.  This will prevent the JavaScript from recognizing any code that is later inserted into the HTML space.

Injections

Injection takes the form of SQL injection, DLL injection, XML injection, or LDAP injection.

Most websites are “database driven”.  That is, the front end of the website (the code, the photos, and the videos) are static/dynamic web pages and files, but data (usernames, passwords, comments, video views, etc.) are stored in databases.  The most common database format is SQL (available in MS SQL and MySQL).

Consider a standard form on a website (such as a registration form).  When a user fills out the form and presses the submit button, the data from the form goes to a script that is located on the server (some computer code).  The script processes the data and enters it into a database.

A database is like a giant Microsoft Excel spreadsheet. 

  • It consists of one or more tables.

  • Each table has a unique name

  • Each table has one or more columns

  • Each column must have a unique name and must specify the type of data that can be stored inside it (for example, text, numbers, integers, etc.)

  • Each row in a table is known as a record

  • We can speak to the database through a database language.  Each database has its own unique language.  For example, we can speak to a MySQL database through the MySQL language.  We can tell the database to create a new table, delete a table, add columns to a table, add data to a table, retrieve data from a table, search for data, etc..  There are entire books written about MySQL.

Consider a user named Bob Jones, who registers on our website by filling out a form with three fields: First Name, Last Name, and Username.  We previously created a database table to hold all our user data.  We called this table “username_table”. 

Bob filled out the following information

  • First Name: Bob
  • Last Name: Jones
  • Username: bjones

Bob’s data goes to a script, which generates an SQL statement as follows (this would insert the data ‘Bob’, ‘Jones’, ‘bjones’ as a new line in the table).  The semi-colon indicates the end of the line.

INSERT INTO username_table VALUES (‘Bob’, ‘Jones’, ‘bjones’);

If Bob was sneaky, he could enter bjones’); DROP TABLE username_table;’  as his username.  Drop Table is a command that tells the SQL database to delete the table.

Bob wouldn’t know exactly the name of the table or the format of the script (because he wouldn’t know what kind of database we are using), but he could make a few guesses (or he could discover the name of the table through an error message on the site).  On a side note, a database (or database server) should never talk directly to a user or be exposed to the internet – it should only communicate with a web server.

This results in the following SQL statement (actually two statements now)

INSERT INTO username_table VALUES (‘Bob’, ‘Jones’, ‘‘bjones’); DROP TABLE username_table;

The first half of the statement inserts the data into the table as normal.  But the second half (DROP TABLE username_table;) deletes the entire username table!  SQL injection attacks are easily preventable with the right code.

How to prevent

  • Use prepared statements when working with SQL

  • Sanitize the data (do not allow users to enter special characters unless necessary).  This should be enforced both on the client side and on the server side (malicious users can defeat client-side error handling).  Do not accept invalid data.
    • Why bother with client-side error handling if the server can prevent everything?  Client-side error handling enhances the user experience, for legitimate users.  Client-side error handling also reduces the load on the server.

  • Turn off verbose mode/error outputs in your code.  If there is a bug in the code, or if the application encounters an error, many web languages (such as PHP or ASP) will print the error directly in the web browser.  These errors can contain exact file directories and SQL database information, which would be exposed to all website visitors.

DLL Injection.  A DLL or Dynamic Link Library is a set of codes stored separately from the program.  Many developers use DLLs so that they do not have to rewrite lines of code to perform common functions (such as figure out what time it is, read a file, write to a file, etc.).  They simply reference the DLL.

A hacker can modify a DLL to perform malicious tasks and then insert it in a place where a good DLL was.  The program will run the malicious DLL and execute the tasks placed by the hacker.

LDAP stands for Lightweight Directory Access Protocol or LDAPS (for secure access).  LDAP is essentially an address book.  LDAP is governed by the X.500 standard.

LDAP includes a server called a Directory Server Agent, which typically speaks on port 389 or 636 for LDAPS.  A client connects to the server.

A client can do the following (a client may have permission to do only some of these)

  • Add
  • Delete
  • Modify
  • Search

For example, a photocopier with “scan to email” capabilities would connect to the LDAP server and obtain e-mail address entries for the various users in the office.  It would do so by sending the server an LDAP query.

A hacker can insert special characters into an LDAP query followed by commands.  If the LDAP server is not configured properly, it will understand and execute the commands.  It may be tricked into returning sensitive data.

We can prevent LDAP injections by escaping all LDAP inputs.  An escape character forces the server to read all the inputted data as normal data instead of as a script.  That means that the server will not execute any script data that is inserted into the input fields.

Extensible Markup Language (XML) injection.  XML is a type of code that wraps inputs with tags.  The data is always wrapped with “<tag>” and “</tag>”.  For example, we might have a database table containing our user accounts, which looks like below.  The Admin field tells us whether a user is an administrator.

User IDUser NameFirst NameLast NamePasswordAdmin
1AdminBarryWhiteSdjkfsdfksdYes
2BjonesBobJonesSidfasdlfsdfNo

When a user signs up on our website, the XML might gather the following information

<UserName>amiller</UserName>

<FirstName>Arthur</FirstName>
<LastName>Miller</LastName>
<Password> dsfjksdfsdf </Password>

And insert it into the table.  The User ID is automatically incremented by the server and the “admin” field is automatically set to “No”.  It can be manually changed by an administrator later, if required.

A hacker might be able to attack this database table with either of the following injections.  In the first case below, the hacker convinces the server to create an account and set the “Admin” field as “Yes”.  Now the hacker has an administrator account.

<UserName>amiller</UserName>

<FirstName>Arthur</FirstName>
<LastName>Miller</LastName>
<Password> dsfjksdfsdf </Password>
<Admin>Yes</Admin>

In the second case below, the hacker convinces the server to change the password on the User ID 1.  Now the hacker knows the admin password and can log in as an administrator.

<UserID>1</UserID>
<Password> dsfjksdfsdf </Password>

Obviously, both of these can be prevented if we program our server to only accept specific types of data from the web form.

Pointer/Object Dereference

Some programming languages use pointers.

  • Programming languages use variables to store data.  When we create an application, we store the value of something that changes in a variable.  For example, the total value of the items in your shopping cart can be considered a variable.  A variable can be a number or a string (text).

  • When a programmer wants to use the value stored by the variable, the programmer references the variable.  The data stored in the variable is stored somewhere in the computer’s memory, but the exact location is usually determined by the computer and not relevant to the programmer.

  • In some languages, a pointer is a variable that points to a specific address in the memory where the data is stored.  Instead of calling the variable by its name, we call it by its specific location in the memory.

  • The pointer is asking the computer to return the data stored at a specific address in the memory.  When we are done with the variable, we can release the memory.  This is called a pointer dereference.

  • If the programming is sloppy, three things can happen

    • We ask the computer to dereference a portion of the memory that does not exist.  Our program will crash.

    • We ask the computer to dereference a portion of the memory that belongs to another program.  That causes the other program to crash.

    • We ask the computer to return data from a portion of the memory that belongs to another program.  If the computer does not enforce permissions, we now have a data leak.

Directory Traversal

On a Windows web server, the data for the website is usually stored in C:\inetpub\wwwroot\.  This is known as the root folder.  A visitor to the website will access the files that are stored in that folder, but they will not be able to go up another level and look at other files in the C drive.  They also will not be able to obtain a list of the files in the root folder.

If we have an idea of the server’s file structure (and this is easy to figure out because most web administrators keep the default configuration), then we can easily guess where everything is.

If the server is not secure, we can trick it into returning files that are outside the root folder.  We can also trick it into listing the files in each directory.

We can prevent directory traversal by doing the following

  • Do not accept inputs that contain file names.  If we must, then we should add most of the URL in our script.  For example,

    • if a user is uploading a file to C:\inetpub\wwwroot\userploads\upload8.doc then the user input might be C:\inetpub\wwwroot\userploads\upload8.doc.  This is bad.  If the user was malicious, they might be able to modify the input and store the data somewhere else.  For example, they might write C:\ upload8.doc as the input

    • Instead, our user input should be upload8.doc and our server-side script will add the C:\inetpub\wwwroot\userploads\ portion

  • Store the website data on a different disk drive than the system files.  For example, if the C:\ drive contains the Windows Server operating system, we should store all the website files on the D:\ drive.

  • Use an index instead of an actual file name.  If a user needs to access C:\sensitive\doc7.docx, we would not put this in the script.  We would create a table of values where C:\sensitive\doc7.docx corresponds to the number 7.  Then we would create a script where the user can request file 7.  The server would check the table and see that file 7 corresponds to C:\sensitive\doc7.docx and return the file.

Buffer Overflow

A buffer overflow is one of the most common types of attacks.

What is a buffer?  The buffer is kind of like a lineup at airport security.  The flow of passengers is not steady.  When there are more passengers than security guards, a long lineup develops.  If the airport doesn’t have enough room to hold all the passengers, some might have to wait outside.

The buffer is the same.  Consider a web server or other computing device.  Information is coming in over a wire.  Sometimes the information is coming in quickly, and sometimes it is coming in slowly.  The server must take each piece of data and process it somewhere.  When the levels of traffic are high, the server can’t process all of it in real time.  Thus, all data first enters a buffer, where it lines up to be processed.  The server takes data from the buffer at a steady rate.

  • For example, the traffic ranges from 0.5GB/s to 2GB/s

  • The server can process data at 1GB/s

  • If the traffic is 1GB/s or less, the server can process the traffic in real time.  The traffic passes through the buffer but doesn’t spend any time there.

  • If the traffic is more than 1GB/s, the server can’t process the traffic in real time.  The buffer starts to fill up.

The buffer has limited capacity.  If the buffer fills up, then it should reject additional data.  For example, if the buffer has a capacity of 10GB, and data comes in at a rate of 2GB/s, but the computer can only process 1GB/s, then after 10 seconds, the buffer will be full.  Any future data will be rejected.  If the buffer does not have a way to reject additional data, then a buffer overflow can result.

The buffer may be designed to hold specific sizes of data.  For example, a buffer may be designed to store IP addresses.  Recall that an IP address is 12 digits.  If a hacker sends a piece of data that is larger than what the buffer expects, a buffer overflow results.  For example, if the IP address is 12 digits, and the hacker sends 14 digits, a buffer overflow could result.

In 2014, a major exploit known as Heartbleed caused security vulnerabilities across millions of websites, including Facebook, Google, and Revenue Canada.  How did it work?

  • Websites encrypt their data with an algorithm known as SSL

  • A developer created an app called OpenSSL, which makes it easy for web developers to implement SSL in their website, using minimal code

  • Millions of websites, including millions of the worlds largest websites used the OpenSSL app
  • When a user visits a website, a connection is created.  The user’s computer and the web server keep the connection open for as long as necessary (but for no longer than necessary).  To preserve resources, the server closes the connection when it is no longer required.  It checks if the user is still present through a method known as a “heartbeat”, which is the electronic equivalent of asking the user “are you there?” every minute.  If the user says “yes”, the connection stays open.  If the user doesn’t reply, the server closes the connection.  How does it work?

    • Every minute, the user’s computer sends a small random amount of data to the web server.  The user’s computer sends the web server the length of the data as well.

    • For example, the user’s computer might send “sdkjfasfjksdlfskldflskdf” length:24

    • The web server sends the data back.  Thus, the web server and the user’s computer know that both are still online and agree to keep the connection active.

    • In fact, the server stores the data in a buffer and gives it an address (the address is the spot in the memory where the data starts).  To return the data to the user, the server locates the data at that address, and counts the number of spaces based on the length it was provided.  If the data’s address starts at position 40 in the buffer, then the server will start reading at position and count another 23 positions.  Thus, the server will return the data from position 40 to position 63.

    • A hacker found out that OpenSSL didn’t verify the accuracy of the length that the user’s computer provided.

    • Thus, a hacker could send a small amount of data such as “aaa” and a large length such as length:4523

    • The server would store “aaa” in memory and then send back 4523 bits of data, starting with “aaa”.  If aaa started at position 40, the server would reply with the data from position 40 to position 4562.  What kind of data is stored in the other positions?  Anything is possible.

    • If the hacker repeated these steps many times, eventually he would receive most of the contents of the server’s memory, which could include encryption keys and private banking information.

    • This bug could have been easily prevented with a few lines of code to verify the length of the data that the user sent.

    • Once discovered, it was quickly patched.  But hackers had been using the security hole to steal data undetected for over two years.

How to prevent

  • Proper code and error handling in programs.  The buffer overflow happens because the computer receives data in an unexpected format and doesn’t know what to do.  Buffer overflows can be prevented by writing good code that checks for errors and refuses to accept data that does not meet the required format.  A program shouldn’t crash when it receives invalid data; it should simply reject it.  The program should check that the data has the correct format (length, character type, contents, format, etc.)

Race Conditions

A race condition is a programming error caused when algorithms are not executed in the correct order.  In a typical computer program, the order of operations is that

  • Inputs are collected

  • The program performs operations on the inputs, in a specific order

  • The program outputs the result

Sometimes a program stops doing any work because it is waiting for an input.  It cannot proceed to the next step until it receives the input.  Or a program is busy with a calculation, so it cannot accept another user input.  If we want to write a more efficient program, we can create threads.  Each thread allows the program to run a separate task.  When we create threads, programs may take inputs from different sources or perform the operations in a different order than was intended, especially if some operations are slower than others.  This can also occur with asynchronous code (such as AJAX), where the program does multiple things at the same time.  It means that a program can attempt to perform an operation on an input that does not exist or that is not ready.

Consider a web page that attempts to render the layout before the content has loaded.  When the data arrives, it may not fit correctly.  AJAX is a web programming language that allows web pages to update without being refreshed.  AJAX allows a web page to maintain a connection to the server and reload data when necessary (examples include Facebook and Gmail).  If the page itself needs to perform an operation on data that has not been received, errors can result.

Normal programming errors are typically “all or none”.  Either the error occurs, or it doesn’t.  Race condition errors may occur randomly or provide random results, depending on the timing of the other inputs or operations.  This makes it more difficult to detect race condition errors.

Imagine that we have a highway with four lanes.  Each lane has a camera that counts the number of vehicles passing by.  We create a program with four threads; one per lane.  We also create a variable that is the total number of vehicles.  Each time a camera sees a vehicle, it retrieves the current value of the total, increments it by one, and pastes it back.

For example,

  • Say that the current total is 1009 vehicles

  • A car passes in Lane #2

  • Thread #2 retrieves the total (which is 1009).  It increments the total by one, resulting in a total of 1010.

  • Thread #2 records the total as 1010

  • A car passes in Lane #4

  • Thread #4 retrieves the total (which is 1010).  It increments the total by one, resulting in a total of 1011.

  • Thread #4 records the total as 1011

The problem with this approach is that if two threads see a vehicle at the same time, both might retrieve the same value of the total. 

For example,

  • Say that the current total is 1009 vehicles

  • A car passes in Lane #2

  • Thread #2 retrieves the total (which is 1009). 

  • A car passes in Lane #4 before Thread #2 has time to increment the total

  • Thread #4 retrieves the total (which is still 1009). 

  • Thread #2 increments the total by one, resulting in a total of 1010.

  • Thread #4 increments the total by one, resulting in a total of 1010.

  • Thread #2 records the total as 1010

  • Thread #4 records the total as 1010

Errors can be prevented by

  • Ensure that multi-threaded applications sync their threads.  That means that if two or more operations take place in parallel, they should understand each other.  The second operation should not take actions on piece of data until the first operation is finished with it, and so on.

  • Provide kernel locks.  That means that if a specific thread is working on a piece of data, it can lock it so that no other threads can access it.  If another thread needs the data, it must wait for the first thread to finish.

    In the previous example, each thread should have locked the total until it was updated.  Thread #4 would not have been able to access the value of the total until Thread #2 was finished updating it.

  • With respect to AJAX based web pages, disable the asynchronous mode for algorithms that do not require it.

Entire books have been written on the subject.  Before building your application, you must create a model to understand how the data flows through it.  You must also run many iterations of different inputs at different times to see if the expected result is correct.  Each programming language has its own methods for mitigating race conditions.

A Time of Check / Time of Use race condition is an attack on a file.  It happens like this

  • The application wants to perform an operation on a file (modify it for example)

  • The application first checks that the file exists, and the check is positive

  • Something happens to the file (it gets deleted for example)

  • The application attempts to perform the operation on the file.  The file does not exist, so an error is returned.

This type of error is difficult to protect against.  The reason is that, for security reasons, an application cannot directly interact with a file.  Instead, the application sends commands related to files to the operating system.

For example, when you save a document in Microsoft Word, Microsoft Word is not actually saving the document to the hard disk drive.  It is instead giving the document to Windows, and Windows is saving the document. 

Windows (and other operating systems) receive many different requests (to open, delete, and modify files) from many applications.  An operating system will perform the file operations in the most efficient order, which is not necessarily the order that the commands are issued.  We can’t really force the operating system to complete the commands in the order that we want.

We can however lock files if the file system supports it.  When you open a file in Microsoft Word, Microsoft Word asks Windows to “lock” the file.  That means that no other program can modify or delete the file until Microsoft Word is finished with it.

Error Handling

Despite the best coding and testing, every computer program and web application will run into errors.  Errors are common with agile code development, where new versions of the application are released each week, and with applications that are updated live (while in use).

When a program runs into an error, it should

  • Record the update in a log that is accessible only to the developer/manager.  The logs can be reviewed to detect and correct the sources of the error.

  • Display an error message to the user.  If the cause of the error is known, the program might give the user some details about how to correct it.

We should be careful about how much information to include in an error message.  Errors could contain portions of the source code, SQL scripts, and file locations, especially web-based applications.  A malicious user could use the errors to further exploit the system by understanding file URLs, variable names, and script details.

Improper Input Handling

Consider that any computer program or application has three components

  • The input
    • The input is what we give it

    • The input could be any kind of data

    • The input could be a file, a piece of text, a photograph, a phone number, or data collected from a sensor

    • A program can collect one or more inputs

    • A program can collect inputs by prompting users or automatically by querying other computers or programs

    • The input is collected from the user’s computer (this is known as the ‘client side’) and sent to the server (this is known as the ‘server side’)

  • The algorithm

    • The algorithm is what the program does to the input

    • For example, the program might take a phone number and enter it into a database, or take an e-mail address and send an automatic e-mail, or take a photograph and sharpen it

    • The algorithm can be simple or complicated.  There can be multiple algorithms.

  • The output

    • The output is the result of the program

    • The output can be provided to the user, e-mailed, stored in a database, stored in a file, etc.

    • There can be multiple outputs.  An output can be automatically fed back into the program as an input.

Every programming language is different, but in general, computer programs do not like “special characters”, such as commas, quotation marks, and especially semicolons.  These special characters are used by programming languages to indicate the end of a line or the end of a piece of data.  When inputted by users, they can trick the program into ending prematurely or receiving incorrect data.

The programmer can decide about the type of input that the program should accept.  For example, a phone number has a specific format, which is ten numbers.  An e-mail address has a specific format, which is some characters, followed by the “@”, followed by some characters, followed by a “.”, followed by two or three characters.

The software should check to make sure that inputs are valid

  • The software should check on the ‘client side’ and prompt the user to correct the input if it is in the wrong format.  Checking on the client side is user friendly and takes up less resources from the server.

  • The software should also check on the ‘server side’ because some users are sneaky and will attempt to bypass the error handling that is running on their own computer and send invalid data directly to the server.  This normally applies to web-based applications.

  • We want to make sure that the data we receive is not going to damage our application, and also that it is valid.  We don’t want to receive garbage data.

How to prevent

  • Escape special characters.  Users may enter semicolons, or other special characters that the software does not understand.  Sometimes, these special characters are valid inputs, but they can harm the program because the program interprets them as code instead of as user data.  It is easy to “escape” special characters so that the program can understand them as input and not as part of its own code, but we must take the time to manually program this.

  • Escaping special characters also prevents attacks such as cross-site scripting and cross-site request forgery.

  • Use prepared statements to prevent SQL injection attacks.
  • Users may enter data in the wrong format.  Scripts exist to detect if the user has entered a valid e-mail address (name@domain.com), a valid phone number ((XXX)-(XXX-XXXX)) or a valid address/postal code.  Improper data can be a waste of time for the person inputting data and for the person collecting it.

Replay Attack

A replay attack is when a hacker captures part of an electronic communication and retransmits it.  This can happen even if the message is encrypted, because the hacker is not reading the contents of the message, just capturing and retransmitting it.

For example, if a user transferred money via online banking, the hacker could capture the transmission instructions and resend them to the bank later.  The bank would transfer the money twice.

How to prevent

  • Encrypt all communications with strong algorithms

  • Require all communications to expire after a short period of time

  • Even with encryption, a hacker could steal the encrypted communication and resend it (without knowing the contents).  To prevent, use a cryptographic nonce (a unique randomly generated number) in each communication, such as a session ID.  If the recipient receives two messages with the same nonce, it will reject the second one.

Alice and Bob are trying to communicate securely.  To authenticate herself, Alice sends Bob a password or hash of her password, which Bob verifies.  If Eve spies on the communication, she can intercept the password or hash of the password, and send it to Bob, posing as Alice.

Bob can prevent this type of attack by first sending Alice a one-time token.  Alice uses the token along with her password to calculate a hash, which she sends to Bob.  Bob receives the result from Alice and verifies it by performing the same calculation.

If Eve captures this new hash and sends it to Bob, posing as Alice, Bob will reject it.  The reason is that Bob will be creating a new one-time token for each subsequent communication.  Bob won’t be able to accept the new communication because it contains an old token.  Bob is expecting a hash with the new one-time token, which Eve does not have.

Integer Overflow

Integer Overflow.  An integer overflow is when a program attempts to store a value that is too large. 

Consider that in a programming language, there are many forms of inputs.  We typically store the input in an object known as a variable.  In some programming languages, the programmer must “declare” the variable and its type before attempting to store data in it.  That means we are telling the computer the name of the variable and the type of data that it is going to store.

The most common types of variables are

  • String.  A string is a variable that can contain any type of character and can have a length of up to 256 characters.

  • Integer.  An integer is a type of variable that can contain a whole number such as 1, 3, -1000, 45.  An integer cannot contain a decimal.  So, 3.14 is not an integer.  An integer can also be a negative whole number.

  • Single/Double.  A single/double is a type of variable that can contain a number with a decimal.

Depending on the type of language, the result of attempting to store a decimal value in an integer variable could be that the program crashes, nothing is stored, or a value such as ‘99999999’ (or whatever the maximum value for that variable is) is stored. 

The most common result is called a wraparound.  You can think of it like what happens when an odometer in a car goes past the maximum.  It wraps around and starts at the beginning.  Some programming languages will store the wraparound value in the integer but flag it so that it is known to be an unreliable value.

Sometimes, an integer overflow happens because we try to add two integers and store the sum in another integer value.  Consider the following pseudocode

            declare input1 as integer //we are creating an integer value known as input 1

            declare input2 as integer //we are creating an integer value known as input 2

            declare sum as integer //we are creating an integer value known as sum2

            …

            sum = input1 + input2 //we are adding input1 and input2 and storing the result in sum2

Now let’s say that the maximum value of input1, input2, and sum is 1000.  input1 has a value of 850, and input2 has a value of 500.  When the computer adds them, it obtains a sum of 1350, which it can’t store in sum.  So, it wraps around and stores the value 350.

If I bought an accounting program and I was trying to figure out how much you owe me, I would expect that the program didn’t suffer from overflows because adding a bunch of numbers would create a wraparound that could reduce the total sum.  Integer overflows in software caused rockets to crash unexpectedly.

Request Forgeries

In Cross-Site Request Forgery, a user is authenticated on a website, and while authenticated, a second website hijacks the session and executes an unauthorized action on the first website.

For example, a user is logged in to Bank of America’s online banking site and has transferred money to his mother.  The user is still authenticated by the bank’s website, which will not require him to reauthenticate for subsequent transactions.  If the user visits a malicious website, that website could send data to the bank’s website and place a money transfer without the user’s knowledge.  It does so by embedding a link in the webpage content that runs an action on the Bank of America website.  For example, a link that submits an online money transfer form.  The link can be set to “click” automatically.  Since the URL in the link is being accessed from the legitimate user’s web browser, the Bank of America website does not suspect a forgery.

A successful cross-site attack requires the hacker to guess the contents of the website’s form (the online banking form field names), including secret authentication keys.  If the hacker had previously visited the online bank site and viewed its source code, obtaining the form field names would be trivial.  The authentication keys may change for every session.

Some examples of successful forgeries

  • The old Netflix website allowed hackers to order DVDs on behalf of a user and change the shipping address.

  • Hackers could perform money transfers through the ING Direct bank website.

  • Hackers could change any YouTube settings on a user’s account up to 2008.

  • Some routers were vulnerable.  That meant a hacker could change the settings on the router in your house just by making you visit a specific website.

How to prevent

  • Proper website coding including tokenization (such as Synchronizer Token Pattern, Cookie-to-Header Token) to randomly generate authentication tokens. 

    Synchronizer Token Pattern.  The legitimate server can randomly generate a “token” for each web form input, which is embedded in the page.  The token is a string of random letters and numbers.  This token changes each time a form is submitted, or a new form is loaded.  The hacker won’t be able to submit a second form through a URL because he won’t be able to guess the value of the token.

    Cookie-to-Header Token.  The legitimate server can randomly generate a “token” and store it in the cookie.  The cookie is a small file that the server sends the user’s web browser when it first accesses the site.  The user’s web browser sends the cookie back every time it submits a form.

    A JavaScript script running in the legitimate website’s web page checks the value of the token in the cookie each time a user submits a form.  If the value of the token is not valid, then the form won’t be submitted.  A URL on the hacker’s website won’t be able to read the contents of the cookie, and thus won’t be able to submit a request.

  • Use of Same-Origin Policy.  Same-Origin Policy allows a web browser to execute scripts from one web page on a second webpage only if both pages originated from the same server (same domain name).

    • http://www.example.com/page1.html and http://www.example.com/page2.html will be compatible

    • http://www.example.com/page1.html and http://www.something.com/page2.html will NOT be compatible

  • Browser extensions such as RequestPolicy or uMatrix can prevent Cross-Site Request Forgery attacks.  Users might be encouraged to install these extensions.

  • Use multi-factor authentication where possible.  Require the use of an authentication key for each transaction.

  • Access sensitive sites through an “incognito” web browser window.  Log out of sensitive browser windows when complete.

Server-Side Request Forgery

Server-Side Request Forgery is an idea where the hacker convinces a server to manipulate some data.  The hacker does not have access to the data, but the server does.  The hacker tells the server to perform some action through a URL.  The server may return the changed data to the hacker or may just perform the action.

Let’s say there is a banking application to check your account balance.  Your web browser sends the server a request URL through an API such as

balanceAPI=http://www.bankofamerica.com/onlinebanking/bankbalance.php

A hacker might change this URL to something like

balanceAPI= http://www.bankofamerica.com/admin/index.php

and try to access the admin directory of the website (which he normally can’t reach).  The hacker doesn’t have access to the admin directory.  But the hacker has access to the “balanceAPI” application and the “balanceAPI” application might have access to the admin directory, since it is on the server.  So, the hacker is tricking the balanceAPI application to access the contents of the admin directory and return them to him.  The balanceAPI doesn’t know any better.

We can prevent this type of attack by creating a whitelist of acceptable inputs for each API.  An API that is requesting data outside of the normal parameters should be automatically rejected.

We should also check that the URL does not contain an illegitimate redirection in its parameters.  A URL may contain a legitimate redirect to another web page.  For example, the following might be legitimate

balanceAPI=http://www.bankofamerica.com/onlinebanking/bankbalance.php?redirect= http://www.bankofamerica.com/onlinebanking/index.php

The following might be illegitimate

balanceAPI=http://www.bankofamerica.com/onlinebanking/bankbalance.php?redirect= http://www.bankofamerica.com/admin/index.php

If we validated the “http://www.bankofamerica.com/onlinebanking/bankbalance.php” portion and didn’t look at the value of the parameter, a hacker would be able to redirect a legitimate URL to an area of the server that he is not permitted to access.

Application Programming Interface (API) Attacks

An API or Application Programming Interface is an interface between two computer systems.  Some examples of APIs

  • Facebook has an API that allows external developers to automatically access data about advertising, users, and marketing.

  • Google has several APIs that allow external developers to embed map data, address data, search results, and other types of data within their own applications.

  • The Apple iPhone has an API that allows applications to access system devices such as the speaker, camera, and file system.  If you build an iPhone App, your app can’t directly command the system devices such as the camera.  Your App must send each request directly to the operating system through the API.  This prevents some security vulnerabilities that could be caused by rogue applications.

A good API is well documented.  It will state exactly what your application must say to the other computer to access each type of data or execute a function.  This is known as the syntax

We build APIs because we want external developers to be able to access some types of data on our system, but we don’t want to give them direct access, and we don’t want them to know how our system works internally.

There are several ways that an API can be attacked (and many of them reuse techniques from other types of attacks mentioned earlier)

  • A DoS or DDoS attack.  We send the API so much traffic that it crashes.  Legitimate users can no longer access the data.

  • We inject SQL, XML or other types of code into the API into a request, which the server executes, causing harm.

  • If the API is returning any data that we request, without verifying whether we are permitted to access it, we can take advantage of it and obtain data that we are not entitled to. 

    The API might have secret functions that are not documented.  They may be created for internal users, privileged users, or for testing.  If we can guess what they are, we might be able to use them to execute functions or obtain data without permission.

  • Intercepting data between a legitimate API user and the server through a man in the middle attack or through some other attack.  Many APIs do not use security or do not use good security.

  • An API usually authenticates the external user through a token.  The user provides the API with the token each time he makes a request.  The value of the token usually doesn’t change from request to request.  If we guess the token, we can impersonate the user and make requests.

    An API should verify the token and the source of the request to determine whether it is legitimate.

Resource Exhaustion

Resource Exhaustion is where a system no longer has resources to operate.  Some of the resources that a system requires

  • Memory.  Every system needs memory to run its applications.  When the system does not have adequate memory, it slows down.  It stores data in a page file.  If the program does not have adequate garbage collection (release memory that is no longer in use), it could run out of memory quickly. 

    For example, a hacker might visit a website and add thousands of items to his shopping cart or identify a page with a loop in the code and open this page in multiple browser tabs.  The server would attempt to execute the code multiple times, which could create additional processes that occupy the system’s memory and overload it, slowing it down or preventing it from completing other tasks.  This could cause the system to shut down other running processes.

  • Hard Drive Space.  Every system needs hard drive space.  Programs generate logs and other files that continue to fill up the space, and errors result when the hard drive is full.  For example, hacker could cause the system to run out of hard drive space by uploading files (if the application allows it) or running processes that generate error logs.  When programs are no longer able to save to disk, they may crash.

  • Network Capacity.  Every system needs network capacity to communicate with the outside world and with other hosts on the network.  A hacker could launch a DDoS attack against a system that causes it to stop communicating.

Memory Leak

Memory Leak.  Every computer program occupies computer memory when it is running.  The amount of memory depends on the size of the program and the type of data that it needs to store. 

Each portion of memory has a unique address.  The program can call the memory and ask for data contained at a specific address (if that portion of the memory is assigned to it).  For security reasons, a program should not be able to access memory assigned to a different program or to the operating system.

Once a program is done with a portion of the memory, it should release it.  This is known as “garbage collection”.  Some programming languages have an automatic garbage collection (a programmer doesn’t have to worry about writing extra lines of code to reserve and release portions of memory), but some don’t.

For example, if a photograph is opened in Adobe Photoshop, that photograph is stored in the memory.  If a website is opened in Google Chrome, that website is stored in the memory.  The website shouldn’t be able to access the photograph.  When you close the file in Adobe Photoshop, Adobe Photoshop should tell the operating system that it no longer requires the portion of memory where the photograph is stored.

If the memory is not released, then eventually the memory becomes full of abandoned data from programs that might not even be running.  When the computer runs out of memory, it starts to slow down or crash.  The memory leaks are resolved when the computer reboots, but some computers and servers cannot be rebooted often because they run critical applications.

Secure Sockets Layer (SSL) Stripping

SSL is used to encrypt data between a website and a user.  A URL that uses SSL starts with https:// instead of http://.  If the user and the website agree on SSL, then all their communications will be encrypted.  A legitimate website might be set to refuse unsecure connections.

But hacker in between the user and the website can strip the SSL and intercept the data.  How does this happen?  The hacker intercepts the request that the user first sends to the website, which is not encrypted.  The hacker sends it to the website, pretending that he is the user.  Now the hacker establishes a secure connection between himself and the website.  The website does not suspect anything because the data is encrypted.

Any data that the hacker receives from the website, he sends it to the user in an unencrypted format.  Any data that the hacker receives from the user, he sends it to the website in an encrypted format.  The user thinks that he is directly connected to the website, but the hacker can see all his data.  The user isn’t paying attention and doesn’t observe that his connection is over http instead of over https.

An SSL stripping attack happens because the first page that the user accesses is not encrypted.  This allows a user to send an unencrypted request, which the hacker can intercept.  Some websites only encrypt pages that request or show personal information.  In the past, web developers left static pages unencrypted because encryption unnecessarily consumed system resources.  This is no longer an acceptable practice.  We can prevent an SSL stripping attack by enforcing SSL on every page of our website without exception.

A user may still attempt to access a website insecurely and be susceptible to an attack, even if we have set all our pages to use SSL.  Therefore, we should also enable HSTS.  HSTS stands for HTTP Strict Transport Security.  When we enable HSTS, we are telling the world that our website only accepts communication over SSL. 

Some websites operate a secure SSL version, and a non-secure version.  They do so because they want users without SSL to be able to access their website.  Long term, this is bad for internet security.

If the HSTS flag is set, when a user attempts to access a website over HTTP, then a modern web browser will block the connection.  If a hacker gets into the middle and attempts an SSL downgrade, the web browser will block the connection.

Driver Manipulation

A driver is a piece of software that allows an operating system to communicate with a piece of hardware.  Hackers can manipulate drivers in two ways

  • Shimming.  Shimming places source code between the driver and the operating system.  Shimming is useful because it allows a driver developer to create one version of a driver for multiple versions of an operating system.  The developer then adds a “shim” – a small piece of code – so that the driver can work with multiple operating systems.  Each operating system receives a different shim.  Hackers can insert malicious code into the driver shims.

  • Refactoring.  Refactoring allows the internal code to change without modifying its external functionality.  Refactoring is useful because it allows developers to optimize their code, allowing it to operate faster.  A hacker can insert malicious code into a refactored driver.

How to prevent

  • Only install drivers that are digitally signed.  The digital signature verifies that the driver’s source code is authentic (that it came from the manufacturer).  By default, newer versions of Windows will not accept unsigned drivers (and disabling this feature requires a reboot of the computer).

Pass the Hash

It is bad security practice to store user passwords in plain text.  Most websites and applications store user passwords as hashes.  A hash is a one-way cryptographic function (a hash can be created from the password, but the password cannot be created from the hash). 

When a user signs up at a website, the website hashes the new user’s password and stores the hash.  When the user attempts to log in, the website hashes the password entered by the user.  The website compares the hash of the password entered with the hash of the password stored by the website.  If they match, the user is authenticated.

Websites use store passwords as hashes so that even if the hash database was compromised, the user passwords would not be.  Hash algorithms are complicated and will be discussed in more detail later.

With Pass the Hash, a hacker can capture the hash that was used in the authentication or registration process.  The hacker then injects the hash into a website or Windows process to gain access to the computer, without ever knowing the password.

How to prevent

  • Secure applications so that they do not accept hashes directly from users

  • Use session keys during communication