Web Penetration Attack and Defense – Simple SQL Injection

Time:2022-11-25

1 background

JD SRC (Security Response Center) has collected a large number of sql injection vulnerabilities submitted by external white hats. Most of the vulnerabilities are caused by splicing sql statements and improper use of Mybatis.

Web Penetration Attack and Defense - Simple SQL Injection

2 manual detection

2.1 Prerequisite knowledge

There is an important system database information_schema in mysql5.0 and above, through which you can access metadata such as database name, table name, and field name in mysql. There are three tables in information_schema that become the key to sql injection construction.

1)infromation_schema.columns:
table_schema database name
table_name table name
column_name column name

2)information_schema.tables
table_schema database name
table_name table name

3)information_schema.schemata
schema_name database name
SQL injection commonly used SQL functions

length(str): returns the length of the string str
substr(str, pos, len) : Intercept the characters of length len from str starting from position pos to return. Note that the pos position here starts from 1, not from 0 in the array
mid(str, pos, len): Same as above, intercept the string
ascii(str) : Returns the ASCII code value of the leftmost character of the string str
ord(str) : Convert character or Boolean type to ascll code
if(a,b,c) : a is the condition, a is true, return b, otherwise return c, such as if(1>2,1,0), return 0

2.2 Injection type

2.2.1 Classification of parameter types
integer injection
For example, ?id=1, where id is the injection point and the type is int.

character injection
For example, ?id=”1”, where id is the injection point and the type is a character, and the quotation marks in the closed back-end SQL statement should be considered.

2.2.2 Classification of injection methods

blind note
Blind Boolean injection: The Boolean value after statement execution can only be inferred from the application return.
Blind time injection: The application does not have a clear echo, and can only be judged by using a specific time function, such as sleep, benchmark, etc.
Error injection: the application will display all or part of the error message
Stack injection: Some applications can be added; execute multiple statements at a time
other

2.3 Manual detection steps (character injection as an example)

// sqli vuln code
            Statement statement = con.createStatement();
            String sql = "select * from users where username = '" + username + "'";
            logger.info(sql);
            ResultSet rs = statement.executeQuery(sql);
// fix code If you want to use the original jdbc, please use precompiled execution
            String sql = "select * from users where username = ?";
            PreparedStatement st = con.prepareStatement(sql);

Use the unprecompiled original jdbc as the demo. Note that the sql statement parameters in this demo are enclosed in single quotes.

2.3.1 Determining the injection point
For character type injection, usually single quotes are tried first to determine whether the single quotes are spliced ​​into the SQL statement. The browser extension harkbar is recommended as a manual testing tool.https://chrome.google.com/web…

A normal page should look like this:

Web Penetration Attack and Defense - Simple SQL Injection

Adding single quotes after admin results in no information echo, because the backend sql executes an error, indicating that the quotes are spliced ​​into the SQL statement

Web Penetration Attack and Defense - Simple SQL Injection

Web Penetration Attack and Defense - Simple SQL Injection

select * from users where username = 'admin' # Normal sql
select * from users where username = 'admin'' #admin' is brought into SQL execution, resulting in an error and unable to display information

2.3.2 Judgment number of characters
In mysql, order by is used for sorting, which can be not only the field name but also the field serial number. Therefore, it can be used to judge the number of fields in the table, and an error will be reported if the number of order by exceeds the number of fields.

Web Penetration Attack and Defense - Simple SQL Injection

Judgment number of characters

When the order by exceeds 4, an error will be reported, so there are four fields in this table.

Web Penetration Attack and Defense - Simple SQL Injection

The sql statement executed by the backend

select * from users where username = 'admin' order by 1-- '

Here we replace the value admin of the original username with admin’ order by 1 —+, where the single quotes after admin are used to close the front quotes in the original sql statement, and —+ is used to comment the back quotes in the sql statement. The main function of the + sign after — is to provide a space. There must be a space after the single-line comment of the sql statement, and the + will be decoded into a space.

2.3.3 Determine the echo position

It is mainly used to locate the position of the back-end sql field displayed on the front-end, and it is determined by joint query. Note that the fields before and after the joint query need to be consistent, which is why we do the second step.

As can be seen from the figure below, the field positions queried and echoed by the backend are 2 and 3 digits.

Web Penetration Attack and Defense - Simple SQL Injection

The fields after the joint query can be arbitrary. This time, the numbers 1 to 4 are used, which are intuitive and convenient.

Web Penetration Attack and Defense - Simple SQL Injection

2.3.4 Using the information_schema library to achieve injection
The group_concat() function is used to concatenate query results into strings.

View existing database

Web Penetration Attack and Defense - Simple SQL Injection

view the tables in the current database

Web Penetration Attack and Defense - Simple SQL Injection

View the fields in the specified table

Web Penetration Attack and Defense - Simple SQL Injection

Use the above information to read the username and password in the users table

Web Penetration Attack and Defense - Simple SQL Injection

3 Automatic detection

3.1 sqlmap use
sqlmap is compatible with python2 and python3, and can automatically detect various injections and almost all database types.

3.1.1 Common commands

-u There may be injected url links
-r read http packets
--data specify post data
--cookie specified cookie
--headers specifies the http header such as token authentication
--threads specify the number of threads
--dbms specifies the database for the backend
--os specifies the operating system type of the backend
--current-user current user
--users all users
--is-dba is dba
--sql-shell interactive sqlshell
-p specifies parameters that may have injection points
--dbs Exhaustive list of databases that exist in the system
-D specifies the database
--tables exhaustively list existing tables
-T specifies the table
--column exhaustive column
-C specifies the field
--dump dump data

direct detection
Among them—cookie is used to specify cookies,—batch is automatically executed, and—dbms specifies the database type

Web Penetration Attack and Defense - Simple SQL Injection

Test results

Web Penetration Attack and Defense - Simple SQL Injection

Read the existing database in the system
—dbs read the database under the current user

Web Penetration Attack and Defense - Simple SQL Injection

Read the table under the specified library
-D java_sec_code —tables

Web Penetration Attack and Defense - Simple SQL Injection

dump users table data
-D java_sec_code -T users —dump

Web Penetration Attack and Defense - Simple SQL Injection

4 advanced

4.1 Mybatis injection

1) Misuse of $ leads to injection

//Using # will not cause sql injection, mybatis will use precompiled execution
    @Select("select * from users where username = #{username}")
    User findByUserName(@Param("username") String username);
//Using $ as an input parameter can lead to sql injection
    @Select("select * from users where username = '${username}'")
    List<User> findByUserNameVuln01(@Param("username") String username);

2) Fuzzy query splicing

// wrong wording
  <select id="findByUserNameVuln02" parameterType="String" resultMap="User">
        select * from users where username like '%${_parameter}%'
    </select>
 //Correct spelling
 <select id="findByUserNameVuln02" parameterType="String" resultMap="User">
        select * from users where username like concat(‘%’,#{_parameter}, ‘%’)  
    </select>

3) order by injection
If #{} is used after order by, an error will be reported, because #{} adds quotation marks by default, which will cause the field to be found and an error will be reported.

// wrong wording 
<select id="findByUserNameVuln03" parameterType="String" resultMap="User">
        select * from users
        <if test="order != null">
            order by ${order} asc
        </if>
    </select>
//The correct way of writing id refers to the field id. There are four fields in this table, so the id is 1-4
    <select id="OrderByUsername" resultMap="User">
        select * from users order by id asc limit 1
    </select>

The above tests are all performed locally, please do not conduct unauthorized penetration testing

5 Recommended articles and materials
slqmap manual:https://octobug.gitbooks.io/s…
Detailed sql injection:http://sqlwiki.radare.cn/#/

Author: Luo Yu (Logistics Security Squad)