[SUCTF 2019]EasySQL1 题目分析与详解

2024-02-25 09:12

本文主要是介绍[SUCTF 2019]EasySQL1 题目分析与详解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、题目介绍

1、题目来源:

BUUCTF网站,网址:https://buuoj.cn/challenges

2、题目描述:

通过以上信息,拿到flag。


二、解题思路

首先打开靶机,尝试输入1查看回显,回显如图所示:

尝试将 1 和 or 一起输入,即 1 or 1=1。

显示 nonono,表明 or 被过滤了,这时我们就需要检查哪些关键字被过滤掉了,来判断此时应该使用什么注入方式。

首先利用 Burpsuite 进行抓包。

利用关键字字典对query进行爆破。

爆破完成,查看response,Length=560的关键字都是被过滤掉的。

得出最终结论,被过滤的关键字有:

prepare|flag|unhex|xml|drop|create|insert|like|regexp|outfile|readfile|where|from|union|update|delete|if|sleep|extractvalue|updatexml|or|and|&|" 作者:雨落雪辰 https://www.bilibili.com/read/cv11014857/ 出处:bilibili

由此观之,报错注入,union联合注入,盲注皆不可行,所以我们尝试进行堆叠注入

堆叠注入:将多条SQL语句放在一起,并用分号;隔开。

进行堆叠注入,先尝试查看数据库名称。

成功查询到数据库的名称,这表明堆叠注入是可行的,我们接着顺势查询表明。

看到表Flag,我们基本可以确定,flag在表Flag中。我们首先想到利用from来查询Flag,可是通过抓包分析可知,from关键字被过滤掉了,所以只能另寻他法。

此时我们想到,开始时我们输入1有会显,我们不妨再尝试输入0试试。

输入0发现无回显,我们尝试输入字母试试。

输入abc发现依然没有回显。这时我们可以总结出一条规律,输入非0数字--有会显,输入0或字母--没有回显,我们由此可以猜测后端代码含有 ||或运算符


补充:|| 或or 运算符讲解:

select command1 || command2 

情况一:若command1为非0数字,则结果为1。

情况二:若command1为0或字母,command2为非0数字,则结果为1。

情况三:command1和command2都不为非0数字,则结果为0。


通过以上分析,我们可以判断后端代码中存在或运算符。

查看本题的后端代码,事实与我们的判断相吻合。

$sql = "select ".$post['query']."||flag from Flag"; 

方法一:使用 sql_mode 中的 PIPES_AS_CONCAT 函数。

PIPES_AS_CONCAT:将 || 或运算符 转换为 连接字符,即将||前后拼接到一起。

select 1 || flag from Flag的意思将变成 先查询1 再查询 flag,而不是查询1flag,只是查询的结果会拼接到一起,不要弄混淆了。

所以查询语句如下:

1;sql_mode=PIPES_AS_CONCAT;select 1

查询结果如下:

1的查询结果为1,被flag的查询结果拼接到了一起,get到flag。


方法二:利用非预期漏洞获取flag。

1、非预期漏洞的概念:

若输入1,1。那么sql语句就变成了 select 1, 1 || flag from Flag。其中由 [1] 和 [1 || flag] 两部分组成,而非 [1,1] || [flag]。非预期漏洞是利用数据库对符号判断的不准确形成的漏洞。

2、如何拿到flag:

输入 *,1 后,sql语句就变成了 select * , 1 || flag from Flag。

其中分为两部分: (1) select * from Flag(2) select 1 || flag from Flag。

select * from Flag 通过查看表Flag中的所有数据可以 get到flag。

这篇关于[SUCTF 2019]EasySQL1 题目分析与详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/745035

相关文章

C++ move 的作用详解及陷阱最佳实践

《C++move的作用详解及陷阱最佳实践》文章详细介绍了C++中的`std::move`函数的作用,包括为什么需要它、它的本质、典型使用场景、以及一些常见陷阱和最佳实践,感兴趣的朋友跟随小编一起看... 目录C++ move 的作用详解一、一句话总结二、为什么需要 move?C++98/03 的痛点⚡C++

MySQL中between and的基本用法、范围查询示例详解

《MySQL中betweenand的基本用法、范围查询示例详解》BETWEENAND操作符在MySQL中用于选择在两个值之间的数据,包括边界值,它支持数值和日期类型,示例展示了如何使用BETWEEN... 目录一、between and语法二、使用示例2.1、betwphpeen and数值查询2.2、be

python中的flask_sqlalchemy的使用及示例详解

《python中的flask_sqlalchemy的使用及示例详解》文章主要介绍了在使用SQLAlchemy创建模型实例时,通过元类动态创建实例的方式,并说明了如何在实例化时执行__init__方法,... 目录@orm.reconstructorSQLAlchemy的回滚关联其他模型数据库基本操作将数据添

Java中ArrayList与顺序表示例详解

《Java中ArrayList与顺序表示例详解》顺序表是在计算机内存中以数组的形式保存的线性表,是指用一组地址连续的存储单元依次存储数据元素的线性结构,:本文主要介绍Java中ArrayList与... 目录前言一、Java集合框架核心接口与分类ArrayList二、顺序表数据结构中的顺序表三、常用代码手动

Spring Boot Interceptor的原理、配置、顺序控制及与Filter的关键区别对比分析

《SpringBootInterceptor的原理、配置、顺序控制及与Filter的关键区别对比分析》本文主要介绍了SpringBoot中的拦截器(Interceptor)及其与过滤器(Filt... 目录前言一、核心功能二、拦截器的实现2.1 定义自定义拦截器2.2 注册拦截器三、多拦截器的执行顺序四、过

JAVA线程的周期及调度机制详解

《JAVA线程的周期及调度机制详解》Java线程的生命周期包括NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING和TERMINATED,线程调度依赖操作系统,采用抢占... 目录Java线程的生命周期线程状态转换示例代码JAVA线程调度机制优先级设置示例注意事项JAVA线程

详解C++ 存储二进制数据容器的几种方法

《详解C++存储二进制数据容器的几种方法》本文主要介绍了详解C++存储二进制数据容器,包括std::vector、std::array、std::string、std::bitset和std::ve... 目录1.std::vector<uint8_t>(最常用)特点:适用场景:示例:2.std::arra

C++构造函数中explicit详解

《C++构造函数中explicit详解》explicit关键字用于修饰单参数构造函数或可以看作单参数的构造函数,阻止编译器进行隐式类型转换或拷贝初始化,本文就来介绍explicit的使用,感兴趣的可以... 目录1. 什么是explicit2. 隐式转换的问题3.explicit的使用示例基本用法多参数构造

Android使用java实现网络连通性检查详解

《Android使用java实现网络连通性检查详解》这篇文章主要为大家详细介绍了Android使用java实现网络连通性检查的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录NetCheck.Java(可直接拷贝)使用示例(Activity/Fragment 内)权限要求

MyBatis中的两种参数传递类型详解(示例代码)

《MyBatis中的两种参数传递类型详解(示例代码)》文章介绍了MyBatis中传递多个参数的两种方式,使用Map和使用@Param注解或封装POJO,Map方式适用于动态、不固定的参数,但可读性和安... 目录✅ android方式一:使用Map<String, Object>✅ 方式二:使用@Param