打算整理一下SQL注入方面的知识,基本所有的SQL书籍都是从select讲起,但是不会提及SQL作为一门完整的程序语言的特点
SQL是一种图灵完备的程序语言
1.SQL对于大小写不敏感,所以可以采用And,aNd绕过一些过滤
2.SQL中的语句用分号隔开
3.mysql中的注释:
单行注释:# , ‘-- ’(注意空格)
多行注释:/* 注释 */
4.SQL中的单引号:在标准 SQL 中,字符串使用的是单引号。如果字符串本身也包括单引号,则使用两个单引号(注意,不是双引号,字符串中的双引号不需要另外转义)。
其他:在 MySQL 中允许使用单引号和双引号两种表示字符串。
如果查询语句中使用了单引号,就需要另一个单引号闭合。
字符型注入最关键的在于如何闭合SQL语句以及注释掉多余的代码。
一般来说,参考类型使用纯数字,并且在使用用户的输入数据前通过int转换比较安全。纯数字参数不需要单引号
5.利用and和or:
地址栏:learn.me/sql/article.php?id=-1 OR 1 =1
$sql = "SELECT * FROM article WHERE id =",$id
SQL语句:
SELECT *
FROM article
WHERE id =-1 OR 1 =1
# 表达式 id =-1 OR 1 =1 的结果永远为真
6.等于=,不等<> (这两个和一般编程语言不一样)
过滤主要针对单引号,不过可以通过URL编码绕过过滤
利用php中的编解码函数urldecode() 、rawurldecode()、base64_decode()绕过防护。
常用码值:单引号%27 百分号%25
双重url编码:%2527
参考URL编码相关
利用exec执行十六进制SQL语句
针对数据库的注入无非都是三件事:查询数据,读写文件,执行命令
查询版本version()
MySQL5.0及其以上版本提供了信息数据库INFORMATION_SCHEMA,它提供了访问数据库元数据的方式。下面介绍如果从中读取数据库名称、表名称、列名称。
从中读取数据库名称、表名称、列名称。
1、查询用户数据库名称
select schema_name from information_schema.shemata limit 0,1
–从information_schema.shemata表中查询第一个数据库名称
2、查询当前数据库表
select table_name from information_schema.tables where table_schema=(sleect database()) limit 0,1
–查询当前数据库表,只显示第一条数据
3、查询指定表的所有字段
select column_name from information_schema.columns where table_name=‘Student’ limit 0,1
– 查询 table_name为Student的字段名
union查询 用于把来自许多的select语句的结果组合到一个结果集中,且每列的数据类型必须相同。
load_file()函数读取文件操作
into outfile写文件操作
进一步阅读:mysql参考手册