sql注入详解

sql注入详解

1.什么是sql注入?

sql注入攻击是网站在处理用户请求的参数,在没有检验或者检验不严谨的情况下直接插入到sql语句中执行,导致用户可以构造恶意参数获取敏感数据。

2.sql注入的工作原理

实例1

看下面的一段代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
<?php

if( isset( $_REQUEST[ 'Submit' ] ) ) {
// Get input
$id = $_REQUEST[ 'id' ];

switch ($_DVWA['SQLI_DB']) {
case MYSQL:
// Check database
#构造需要执行的sql语句
$query = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
#执行sql语句
$result = mysqli_query($GLOBALS["___mysqli_ston"], $query ) or die( '<pre>' . ((is_object($GLOBALS["___mysqli_ston"])) ? mysqli_error($GLOBALS["___mysqli_ston"]) : (($___mysqli_res = mysqli_connect_error()) ? $___mysqli_res : false)) . '</pre>' );

// Get results
while( $row = mysqli_fetch_assoc( $result ) ) {
// Get values
#构造返回结果
$first = $row["first_name"];
$last = $row["last_name"];

// Feedback for end user
$html .= "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
}

mysqli_close($GLOBALS["___mysqli_ston"]);
break;
case SQLITE:
global $sqlite_db_connection;

#$sqlite_db_connection = new SQLite3($_DVWA['SQLITE_DB']);
#$sqlite_db_connection->enableExceptions(true);

$query = "SELECT first_name, last_name FROM users WHERE user_id = '$id';";
#print $query;
try {
$results = $sqlite_db_connection->query($query);
} catch (Exception $e) {
echo 'Caught exception: ' . $e->getMessage();
exit();
}

if ($results) {
while ($row = $results->fetchArray()) {
// Get values
$first = $row["first_name"];
$last = $row["last_name"];

// Feedback for end user
$html .= "<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>";
}
} else {
echo "Error in fetch ".$sqlite_db->lastErrorMsg();
}
break;
}
}

?>

在上述代码中我们可以发现参数id是由用户传递的,并且参数id并没有经过服务器的任何处理直接插入到sql语句中执行,由于id是由用户 传递的,因此id参数对于用户来说可控,因此用户可以通过构造参数id实现自己想执行的sql语句

比如如果用户输入1’ and 1=2 union select version();–+

这个时候拼凑成要执行的sql语句就是

1
SELECT first_name, last_name FROM users WHERE user_id = '1' and 1=2 union select 1,version();--+'

由于1=2为假,因此这条sql语句执行的结果其实是我们构造的sql语句select 1, version()(一个mysql函数,返回数据库的版本信息)的执行结果,因此最终服务器会返回1,和数据库的版本信息。

3.sql注入类型

1.报错注入

注入过程中只有错误时目标服务器才有回显

2.布尔盲注

注入过程中只会出现正确和错误两种回显,并不会回显查询数据

3.延时注入

注入过程中怎么样都是正确的,但是在执行延时函数的时候能明显发现目标服务器回应时间出现了明显的变化。

4.宽字节注入

由于编码问题,注入库在处理指定的输入参数使用了gbk编码,导致用户输入的参数和闭合字符被当成一个字符处理。

5.http-header注入

注入位置在http请求头(如User-Agent,Cookie等)中

4.sql注入的步骤

1.测试sql注入的位置

2.确定闭合方式

3.探测回显位置

4.获取数据库敏感信息

5.sqlmap

sqlmap是一个自动化的sql注入漏洞探测工具,由python开发,可以自行指定探测位置,以及设置相关参数。

sqlmap常用命令
1
2
3
4
5
6
7
8
9
sqlmap -u "https://www.baidu.com/index.php?id=1" -p "id" --proxy http://localhost:1080 --banner
-u 指定探测的url
-p 指定探测的参数
--banner 探测目标数据库的版本
--dbs 探测目标数据库的所有数据库
--tables 探测指定目标数据库的所有的表
--columns 探测指定目标数据库指定表的指定列
--os-shell 获取目标服务器的shell
--sql-shell 获取目标服务器数据库的shell

sql注入详解
https://dreamaccount.github.io/2022/10/06/sql注入/
作者
404NotFound
发布于
2022年10月6日
许可协议