SQL injection analysis

Before the holidays are over, write a blog to record your network security learning experience, and also take notes to facilitate future review. Roll up brothers!

1. Install the packet capture tool Burp Burp Chinese version installation tutorial

2. Download and configure phpstudy Pikachu installation tutorial

3. Download the local shooting range Pikachu Pikachu installation tutorial

4. Download and configure Firefox Firefox Firefox configuration proxy

As shown in the figure, start to intercept the data packets of the Firefox browser, click to release the packet, and the browser can access the page normally. You can set it in the proxy-option, and pay attention to allowing the interception of local data packets in the setting. After the data packet is intercepted, it can be sent to the repeater for modification and sent to view the response.imgimg img

SQL examples can refer to the following blog sql injection detailed explanation 1. What is sql injection? SQL injection is one of the more common network attack methods. It does not use the BUG of the operating system to realize the attack, but targets the negligence of programmers when writing, and realizes login without account through SQL statements, and even tampers with the database. For example, the account password information input from the webpage is directly brought into the database without filtering.

2. SQL injection steps? 1. First, you need to test whether there is an injection point. You can use a vulnerability scanning tool, or manually try to construct the test statement x' payload.

2. Then obtain information through the injection point

环境信息:数据库类型,数据库版本,操作系统版本,用户信息等。
数据库信息:数据库名称,数据库表,表字段,字段内容(加密内容破解)

Note: You need to know the operating system and database type because the operating system type will affect the case. For example, the Windows system does not distinguish case in the command line, but the Linux system does. There are also differences in the language of different databases (Mysql, Oracle).

3. Finally, after getting enough information through the previous payload, SQL injection can be performed to obtain system permissions.

3. How to prevent SQL injection? 1. Check the variable data type and format

如果你的SQL语句是类似where id={
    
    $id}这种形式,数据库里所有的id都是数字,那么就应该在SQL被执行前,检查确保变量id是int类型;如果是接受邮箱,那就应该检查并严格确保变量一定是邮箱的格式,其他的类型比如日期、时间等也是一个道理。总结起来:只要是有固定格式的变量,在SQL语句执行前,应该严格按照固定格式去检查,确保变量是我们预想的格式,这样很大程度上可以避免SQL注入攻击。

2. Filter special symbols

对于无法确定固定格式的变量,一定要进行特殊符号过滤或转义处理。

3. Bind variables, use precompiled statements

MySQL的mysqli驱动提供了预编译语句的支持,不同的程序语言,都分别有使用预编译语句的方法。实际上,绑定变量使用预编译语句是预防SQL注入的最佳方式,使用预编译的SQL语句语义不会发生改变,在SQL语句中,变量用问号?表示,黑客即使本事再大,也无法改变SQL语句的结构。

This is the blog Pikachu customs clearance tutorial I used for reference at that time. The first few questions briefly introduce the ideas

digital injection

The submission method is post, and the data is submitted in the HTML HEADER. According to the returned result, the judgment statement is

select 字段1,字段2 from 表名 where id = 1

Use Burp to capture packets, modify the id to id or 1=1, it will traverse and return all user names and mailbox information

character injection

The submission method is get, and the data is submitted through the URL. According to the returned result, the judgment statement is

select 字段1,字段2 from 表名 where username = 'x';

We want to form a legal closure. Strings need to be enclosed in single quotes to be legal. We need to comment out the two single quotes before and after. Enter x' or 1=1#The first single quotation mark will close the previous single quotation mark, and the subsequent # sign will comment out the subsequent single quotation mark.

search injection

I also want to find a way to form a legal closure. Here I directly view the code and get the sql statement imghere

select from 表名 where username like ' %k% ';

This is the modified sql statement, with an extra %

select from 表名 where username like ' %x%'or 1=1 #% ';

Type xx injection : View the backend code, enter xx') or 1=1 #

Acquisition based on error information

基于报错的信息获取------三个常用的用来报错的函数
updatexml() :函数是MYSQL对XML文档数据进行查询和修改的XPATH函数。
extractvalue():函数也是MYSQL对XML文档数据进行查询的XPATH函数。
floor(): MYSQL中用来取整的函数。

Or use the character type to input the question, construct the input statement, and return the database version number

Generally, for the convenience of reading, add the hexadecimal separator ~, which is 0x7e in hexadecimal

kobe' and updatexml(1,concat(0x7e,version()),0)#

img

Then try to construct a statement to obtain the table names one by one. limit 0,1 means to obtain 1 record starting from the 0th record position, and you can use limit x,1 to obtain the table names one by one

kobe' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='pikachu' limit 0,1)),0)#

imgSimilarly, you can use the following statement to get the username

kobe' and updatexml(1,concat(0x7e,(select username from users limit 0,1)),0)#

img

Know a user name admin, then you can get the password, since the updatexml return value has a 32-bit length limit, so you have to remove ~ and change 0x7e to 0.

kobe' and updatexml(1,concat(0x7e,(select password from users where username='admin' limit 0,1)),0)#

img img

Get the password after MD5 decryption MD5 online decryption tool img

insert/update injection

Similar to the logic just now, click Register, fill in the following statement in the user's place, and the password is optional

wake' or updatexml(1,concat(0x7e,database()),0) or '

delete injection

Try to enter a few messages first, here you need to use Burp to capture packets, enable interception, and delete messages. imgObviously, the entry point is the id, forward the data to the repeater, and modify the id=56 or updatexml(1,concat(0x7e,database()),0) Here you need to perform URL special character transcoding, send, and return the database name , doneimg

http header injection

Common information in the request header is:

Accept:浏览器可接受的MIME类型
Cookie:这是最重要的请求头信息之一
Host:初始URL中的主机和端口
Referer:包含一个URL,用户从该URL代表的页面出发访问当前请求的页面
User-agent:浏览器类型,如果Servlet返回的内容与浏览器类型有关则该值非常有用

How to judge the injection point?

有些时候,后台开发人员为了验证客户端头信息(比如常用的cookie验证)
或者通过http header头信息获取客户端的一些资料,比如useragent、accept字段等。
会对客户端的http header信息进行获取并使用SQL进行处理

那么我们这里主要对Cookie以及User-agent这两个地方进行检测

Log in according to the prompted account password, and find the information in the returned request header. Try to capture packets with Burp, change the value of User-agent to ', and return the database error statement, indicating that injection can be made here. img imgNext, repeat the trick on User-agent

Payload:firefox ' or updatexml(1,concat(0x7e,database()),0) or '

imgTry cookie injection again, add' after admin to tryimg

You have an error in your SQL syntax;

It’s okay to see this error message, try using the payload:

admin' or updatexml(1,concat(0x7e,database()),0) or '

img

Blind (base on boolian)

盲注的概念:
开发人员把数据库报错信息进行处理,使得信息不会返回前端页面,这样就使我们想要通过union注入或报错注入的攻击方式难以实现。
当不显示报错信息的时候,我们还可以通过盲注的方式来对数据库进行注入攻击。
盲注,就是在页面没有提供明显信息的情况执行的注入方式。
盲注又分为两种,布尔型盲注和时间型盲注。

Our question is based on a Boolean blind note, which is mainly expressed as

--没有报错信息
--不管是输入正确的还是错误的,都只显示两种情况(01--在正确的输入下,输入and 1=1/and 1=2发现可以判断

Enter the correct username to see the returned result and try this imgagain . The and result is true before and after, and the correct result is returned, indicating that it can be injected. imgSo how to construct the injection statement? Need to introduce the method that needs to be used first

Substr()截取字符串函数,string表示目标字符串
格式一:substr(string string int a, int b);a表示起始位置,b表示要截取的长度
格式二:substr(string string, int a);截取a后面所有字符

asii(string) 函数 就是返回指定字符的ascii码
我们只要记住659026个大写英文字母,97122号为26个小写英文字母

Try to construct the payload as: vince ' and asii(substr(database(),1,1))=112 # Of course, this is because the database name Pikachu is already known, and p corresponds to 112. If we don't know it, we can use the dichotomy method to judge:

首先取第一个字符的Ascii值同(65,122)的中间值相比较,如果正好相等,则输出
字符,如果Ascii的值大于中间值,则取中间值到最大值这一范围的中间值继续同
字符的Ascii值比较,重复上述操作直到两个值相等为止,最终输出整个字符串。

The statement is as follows:

vince’ and asii(substr(database(),1,1))>94 #

The return is correct, continue to try with (94,122) intermediate value 108

vince’ and asii(substr(database(),1,1))>108 #

Finally find the value of the first letter asii is 112, the first letter is p, modify the value of a in substr (str, a, b), repeat the above process, and get the database name.

Blind (base on time)

There is not much difference between time-based blind injection and Boolean-based blind injection. Before learning time-based blind injection, let us learn about if function and sleep function.

If(a, b, c)
a:条件语句
b:条件语句为真返回b
c:条件语句不为真返回c

sleep(int $seconds)
表示延时seconds秒执行

I found that whether I entered the correct user name vince, the returned results are the same, imgso previous method is not working, so I use the loading time as the basis for judging, construct the following payload, and found that it did load for 5 seconds

vince ' and if(substr(database(),1,1)='p',sleep(5),null) #

When the database name is not known, use the same dichotomy method as the Boolean-based blind injection to obtain the database name

wide byte injection

This needs to be understood, or to understand the relevant knowledge

MySQL中,有着addslashes,mysql_real_escape_string等转义函数
这些函数会将用户输入的 ‘ 转换为 \’
字符集:
utf-83字节)
gbk(2字节)
ascii(1字节)
PHP中编码为GBK,函数执行添加的是ASCII编码,MYSQL默认字符集是GBK等宽字节字符集。

Injection principle:

首先我们的注入语句存在 ‘ 为了闭合引号,但是addslashes等函数会将 ‘ 转换为 \’
在ascii编码中就是 %27 转换为 %5c%27
%5c 就是\,%27就是 ‘
当我们输入的是 %df%27 时,addslashes函数看到 ‘会转换为 \’
就成为了 %df%5c%27,由于我们的数据库是执行gbk的编码,gbk的编码是2字节
 %df%5c 这两个字节就会被编码成 運 字,剩下 %27这个时候 ‘ 就逃逸出来了

The wide-byte injection we use here is a feature of MySQL. When MySQL uses GBK encoding, it will consider two characters to be a Chinese character (the previous ASCII code must be greater than 128 to reach the range of Chinese characters). This is the characteristic of MySQL, because GBK is a multi-byte encoding, he thinks that two bytes represent a Chinese character, so %DF and the following \, that is, %5c, become a Chinese character "luck", while "escapes come out.

Try to no avail, look at the source code, you can see that the configuration here is the encoding of gbk. imgTry payload=kobe %df ' and 1=1 # , it still doesn't work. Burp captures imgthe packet. The browser encodes % and becomes %25. Then let's change it here in the data package

name=kobe %df' or 1=1#

imgThen you can use union to query other information.

Guess you like

Origin blog.csdn.net/weixin_46356409/article/details/127198872