当前位置: 首页 > news >正文

短路语法 [SUCTF 2019]EasySQL1

打开题目

输入字符的时候啥也不回显。只有输入数字的时候页面有回显

但是当我们输入union,from,sleep,where,order等,页面回显nonono,很明显过滤了这些关键词

 最开始我的思路是打算尝试双写绕过

1;ununionion  select 1,2,3

发现依旧被过滤了。

那我们试试堆叠注入

1;show databases;

发现页面有6个数据库

1;show tables;

有一个名为Flag的表

那我们试试能不能直接查看Flag的表结构

1;desc `Flag`;

同样,这里被过滤了flag字段,所以我们不能直接查询到Flag表下的字段

上面的测试我们知道from和order都被过滤了

本来想试试句柄handler命令查询的,结果一试,handler也被过滤了。

那就用不了堆叠注入,也用不了联合查询。

解法一

看了大佬的wp后知道

既然输入字符无回显,输入数字才有回显。

他的后端既然能做到数字回显,字母不回显,说明有一个 或 结构,而且不直接回显flag,但作为一道题目,from一定是from flag

所以大佬猜测的后端为:

select $_POST['query'] || flag from Flag

结合我们刚刚上面做的堆叠注入的查询知道,确实有个名为Flag的表

所以上面的猜测成立,不会是from别的地方。

我们对上面的代码简单审计一下,$query 是通过 POST 请求获取的用户输入,所以后端通过获取用户输入的数据,这里的“或”符号(“ | | ”)的意思是,作为逻辑或用于短路逻辑,如果前者的语句为真,则整个语句为真,不理会后面的语句是真还是假直接输出结果。

所以我们这直接利用短路语法

payload:

*,1

这里的原理是

sql=select.post['query']."||flag from Flag";
如果$post['query']的数据为*,1,sql语句就变成了select *,1||flag from Flag,
就是select *,1 from Flag,这样就直接查询出了Flag表中的所有内容
输入  *,1   这里会增加一个临时列,他的列名为1,然后那一列的值都为1。

当我们只关心数据表有多少记录行而不需要知道具体的字段值时,类似“select 1 from table_Name”是一个很不错的SQL语句写法,它通常用于子查询。这样可以减少系统开销,提高运行效率,因为这样子写的SQL语句,数据库引擎就不会去检索数据表里一条条具体的记录和每条记录里一个个具体的字段值并将它们放到内存里,而是根据查询到有多少行存在就输出多少个“1”,每个“1”代表有1行记录,同时选用数字1还因为它所占用的内存空间最小,当然用数字0的效果也一样。在不需要知道具体的记录值是什么的情况下这种写法无疑更加可取。
 

得到flag

解法二

payload:

1;set sql_mode=PIPES_AS_CONCAT;select 1

这里看英文就知道这里把管道符||当做了连接符号

我们原先猜测的后端代码为

select $_POST['query'] || flag from Flag

变成了

select $_POST['query'] and flag from Flag

在 SQL 注入攻击中,concat 是一个用于连接字符串的 SQL 函数。它接受两个或多个字符串作为参数,并返回这些字符串连接在一起的结果。

知识点:

  • “ || ”符号的三种用法

<1>作为符号命令执行上下文在一些特殊的上下文中,特别是在 命令执行或 shell 脚本 中, ||  可以表示一个截断符号,只有在前一个命令失败(返回非零状态码)时才执行下一个命令。

例如:command1 || command2

如果 command1 失败(返回非零状态码),则执行 command2。这种用法可以用于处理错误情况或依赖于前一个命令的成功执行。

<2>作为逻辑或:|| 表示逻辑或运算符,即只要两边的表达式之一为真,整个条件就为真。

例如:

if condition1 or condition2:
    # 如果 condition1 或 condition2 为真,则执行这里的代码

只要 condition1 或者 condition2 中有一个为真,整个条件就为真,而不需要等待另一个条件的计算结果。

<3>用于短路逻辑:在某些情况下,|| 可能被用于实现短路逻辑,这意味着如果第一个表达式为真,就不再计算第二个表达式。如果第一个表达式为假,那么才会计算第二个表达式。这种行为利用了逻辑或的性质,只要有一个条件为真,整个表达式就为真。

例如:var result = expression1 || expression2;

在这里,如果 expression1 为真,expression2 将不会被计算

  • 短路语法:

举例说明:

“||”运算符检查第一个表达式是否返回“true”,如果是“true”则结果必为“true”,不再检查其他内容。“a/0”是个明显的错误!但短路运算“||”先执行“a==b”判断,返回“true”,遂造成短路,也就不进行“a/0”操作了,程序会打出"That's in my control."。这个时候,交换一下“||”左右两边的表达式,程序立即抛出异常“java.lang.ArithmeticException: / by zero”。

class Logic{public ststic void main(String[] args){int a=1;int b=1;if(a==b || b<a/0){System.out.println("That's in my control.");}else{System.out.println("Oh,That's Impossible!!!");}}
}

参考文章:java中“&&”和“||”短路详解_java中||-CSDN博客

  • 在计算机逻辑语言中,1代表逻辑真,0代表逻辑假

  • select 1 from table_Name的原理

在我自己本地的数据库下有个users表,表的结构如下

我们用select 1 from users;

这个语句在这里的作用就是查询users表下有多少行数据,有多少行就输出多少行的1,而select 1 from就是建立一个临时列,这个列的所有初始值都设为1。而为什么选用数字1呢,因为数字1所占的内存最小。用其他数字效果也是一样的。

而使用select *,1 from users;

也就是本题的payload,效果如下

select *,1 from users;

这个语句显示了users表下的所有列,以及我们的临时列1

  • sql_mode

sql_mode 是一个MySQL系统变量,用于设置数据库操作的不同方面

文章参考wp为:[SUCTF 2019]EasySQL 1 Writeup(超级详细)-CSDN博客

http://www.lryc.cn/news/233058.html

相关文章:

  • 鉴源实验室 | DoIP协议网络安全攻击
  • 腾讯云服务器新用户购买优惠多少钱?腾讯云新用户购买优惠
  • 超全整理,Pytest自动化测试框架-多进程(pytest-xdist)运行总结...
  • jbase实现通用码表
  • 工业镜头中的远心镜头与普通镜头的光路
  • 【Qt之QWizardPage】使用
  • 自动化测试,5个技巧轻松搞定
  • EasyWeChat调用企业微信接口获取客户群数据
  • sql 左联 右联
  • k8s中的端口hostPort、port、nodePort、targetPort
  • 自动发微博脚本工具,可批量定时发送,按键精灵完全开源版
  • 2023版Idea创建JavaWeb时,右键new没有Servlet快捷键选项
  • 数据结构(c语言版本) 二叉树的遍历
  • Django 配置 Email Admin 详细指南
  • Apache阿帕奇安装配置
  • 时间序列预测实战(十六)PyTorch实现GRU-FCN模型长期预测并可视化结果
  • 如何提升软件测试效率?本文为你揭示秘密
  • 参数估计和非参数估计
  • Apache Airflow (八) :DAG任务依赖设置
  • 使用 com.jacob.activeX 库实现 Word 到 PDF
  • 2023亚太杯数学建模思路 - 案例:FPTree-频繁模式树算法
  • Dart利用私有构造函数_()创建单例模式
  • 简述如何使用Androidstudio对文件进行保存和获取文件中的数据
  • 面向配电网韧性提升的移动储能预布局与动态调度策略(matlab代码)
  • 内网信息收集
  • windows cmd设置代理
  • English:small classified word(continuously update)
  • JQuery ajax 提交数据提示:Uncaught TypeError:Illegal invocation
  • java实现选择排序
  • 蓝桥杯 大小写转换