Infiltration attack and defense Web articles - SQL injection in simple terms

1 Background

Jingdong SRC (Security Response Center) includes a large number of SQL injection vulnerabilities submitted by external white hats. The reasons for the vulnerabilities are mostly caused by SQL statement splicing and improper use of Mybatis.

2 Manual inspection

2.1 Pre-knowledge

There is an important system database information_schema in mysql5.0 and above. Through this database, metadata such as database name, table name, field name, etc. existing in mysql can be accessed. 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) : intercepts the characters of length len from the position of pos and returns it. Note that the pos position here starts from 1, not from 0 of 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 a 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 character, and the quotation marks in the back-end sql statement should be considered.

2.2.2 Classification of injection methods

  • blind note
    • Blind Boolean Note: The Boolean value after execution of the statement can only be inferred from the application return.
    • Time Blind Note: 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 join; then 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 如果要使用原始jdbc,请采用预编译执行
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 Determine the injection point

For character type injection, single quotes are usually tried first to determine whether the single quotes are spliced ​​into the SQL statement. It is recommended to use the browser extension harkbar as a manual testing tool. https://chrome.google.com/webstore/detail/hackbar/ginpbkfigcoaokgflihfhhmglmbchinc

A normal page should look like this:

Adding single quotation marks after admin causes no information to be displayed. The reason is that the back-end sql execution reports an error, indicating that the quotation marks are spliced ​​into the SQL statement.

select * from users where username = 'admin' #正常sql
select * from users where username = 'admin'' #admin'被带入sql执行导致报错无法显示信息

2.3.2 Judging the number of fields

MySQL uses order by to sort, 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. If the order by exceeds the number of fields, an error will be reported. 

Determine the number of fields

When the order by exceeds 4, an error will be reported, so this table has a total of four fields.

SQL statement executed by the backend

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

Here we replace the original username value admin with admin' order by 1 —+, where the single quote after admin is used to close the front quote in the original SQL statement, and —+ is used to annotate the back quote in the SQL statement. The main function of the + sign after — is to provide a space. A space is required after a single-line comment in the SQL statement, and the + will be decoded as 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 is determined by means of a 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.

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

2.3.4 Using the information_schema library to achieve injection

The group_concat() function is used to concatenate query results into strings.

  • Check the existing database

  • View tables in the current database

  • View fields in a specified table

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

3 Automated detection

3.1 sqlmap usage

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

3.1.1 Common Commands

-u 可能存在注入的url链接
-r读取http数据包
--data 指定post数据
--cookie 指定cookie
--headers 指定http头 如采用token认证的情况下
--threads 指定线程数
--dbms 指定后端的数据库
--os 指定后端的操作系统类型
--current-user 当前用户
--users 所有用户
--is-dba 是否是dba
--sql-shell 交互式的sqlshell
-p指定可能存在注入点的参数
--dbs 穷举系统存在的数据库
-D指定数据库
--tables 穷举存在的表
-T指定表
--column 穷举字段
-C指定字段
--dump dump数据

Direct detection
where --cookie is used to specify cookie, --batch is automatically executed, and --dbms specifies database type

Test results

Read the database existing in the system -
dbs reads the database under the current user

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

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

4 Advanced

4.1 Mybatis injection

1) Incorrect use of $ leads to injection  

//采用#不会导致sql注入,mybatis会使用预编译执行
@Select("select * from users where username = #{username}")
User findByUserName(@Param("username") String username);
//采用$作为入参可导致sql注入
@Select("select * from users where username = '${username}'")
List<User> findByUserNameVuln01(@Param("username") String username);

2) Fuzzy query splicing

//错误写法
<select id="findByUserNameVuln02" parameterType="String" resultMap="User">
select * from users where username like '%${_parameter}%'
</select>

//正确写法
<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 not to be found and an error will be reported.

//错误写法
<select id="findByUserNameVuln03" parameterType="String" resultMap="User">
select * from users
<if test="order != null">
order by ${order} asc
</if>
</select>
//正确写法 id指字段id 此表字段共四个 所以id为1-4
<select id="OrderByUsername" resultMap="User">
select * from users order by id asc limit 1
</select>

The above tests are performed locally, please do not perform penetration testing without authorization

5 Recommended articles and materials

slqmap manual: https://octobug.gitbooks.io/sqlmap-wiki-zhcn/content/Users-manual/Introduction.html
Detailed explanation of sql injection: http://sqlwiki.radare.cn/#/

Author: Luo Yu (Logistics Safety Team)

{{o.name}}
{{m.name}}

Guess you like

Origin my.oschina.net/u/4090830/blog/5569859