PHP常见漏洞(1)--SQL注入攻击

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介:
SQL注入攻击(SQL Injection),是攻击者在表单中提交精心构造的sql语句,改动原来的sql语句,如果web程序没有对提交的数据经过检查,那么就会造成sql注入攻击。 


SQL注入攻击的一般步骤: 
1、攻击者访问有SQL注入漏洞的站点,寻找注入点 
2、攻击者构造注入语句,注入语句和程序中的SQL语句结合生成新的sql语句 3、新的sql语句被提交到数据库中执行 处理 
4、数据库执行了新的SQL语句,引发SQL注入攻击

 

203600942.png

 

 

实例 

数据库 

CREATE TABLE `postmessage` ( 

`id` int(11) NOT NULL auto_increment, 

`subject` varchar(60) NOT NULL default ”, 

`name` varchar(40) NOT NULL default ”, 

`email` varchar(25) NOT NULL default ”, 

`question` mediumtext NOT NULL, 

`postdate` datetime NOT NULL default ’0000-00-00 00:00:00′, 

PRIMARY KEY (`id`) 

) ENGINE=MyISAM DEFAULT CHARSET=gb2312 COMMENT=’运用者的留言’ AUTO_INCREMENT=69 ; 

grant all privileges on ch3.* to ‘sectop’@localhost identified by ’123456′; 

//add.php 插入留言 

//list.php 留言列表 

//show.php 显示留言 页面 

http://www.netsos.com.cn/show.php?id=71 可能存在注入点,我们来测试

http://www.netsos.com.cn/show.php?id=71 and 1=1


203603611.png

 

 

 

203605740.png

 

 

 

一次查询到记录,一次没有,我们来看看源码 
//show.php 12-15行 
// 执行mysql查询语句 

$query = "select * from postmessage where id = ".$_GET["id"]; 

$result = mysql_query($query) or die("执行ySQL查询语句失败:" . mysql_error()); 

参数id传递进来后,和前面的字符串结合的sql语句放入数据库执行 查询

提交 and 1=1,语句变成select * from postmessage where id = 71 and 1=1 这语句前值后值都为真,and以后也为真,返回查询到的数据 

提交 and 1=2,语句变成select * from postmessage where id = 71 and 1=2 这语句前值为真,后值为假,and以后为假,查询不到任何数据 

正常的SQL查询,经过我们构造的语句之后,形成了SQL注入攻击。通过这个注入点,我们还可以进一步拿到权限,比如说运用 union读取管理密码,读取数据库信息,或者用mysql的load_file,into outfile等函数进一步渗透。



防范方法 

整型参数: 运用 intval函数将数据转换成整数
函数原型 
int intval(mixed var, int base) 
    var是要转换成整形的变量 
    base,可选,是基础数,默认是10 
浮点型参数: 
    运用 floatval或doubleval函数分别转换单精度和双精度浮点型参数 


函数原型 
int floatval(mixed var) 
    var是要转换的变量 
int doubleval(mixed var)
    var是要转换的变量 

字符型参数: 
运用 addslashes函数来将单引号“’”转换成“\’”,双引号“"”转换成“\"”,反斜杠“\”转换成“\\”,NULL字符加上反斜杠“\”
函数原型 
string addslashes (string str) 
str是要检查的字符串 
那么刚才出现的代码漏洞,我们可以这样修补 

// 执行mysql查询语句 $query = "select * from postmessage where id = ".intval($_GET["id"]); 

$result = mysql_query($query)

or die("执行ySQL查询语句失败:" . mysql_error()); 

如果是字符型,先判断magic_quotes_gpc能无法 
为On,当不为On的时候运用 addslashes转义特殊字符
if(get_magic_quotes_gpc()) 


$var = $_GET["var"]; 


else 

{

 $var = addslashes($_GET["var"]); 



再次测试,漏洞已经修补!!! OK !


虽然国内很多PHP程序员仍在依靠addslashes防止SQL注入,还是建议大家加强中文防止SQL注入的检查。addslashes的问题在 于黑客 可以用0xbf27来代替单引号,而addslashes只是将0xbf27修改为0xbf5c27,成为一个有效的多字节字符,其中的0xbf5c仍会 被看作是单引号,所以addslashes无法成功拦截。
当然addslashes也不是毫无用处,它是用于单字节字符串的处理,多字节字符还是用mysql_real_escape_string吧。

打开magic_quotes_gpc来防止SQL注入
php.ini中有一个设置:magic_quotes_gpc = Off
   这个默认是关闭的,如果它打开后将自动把用户提交对sql的查询进行转换,
   比如把 ' 转为 '等,对于防止sql注入有重大作用。
     如果magic_quotes_gpc=Off,则使用addslashes()函数
另外对于php手册中get_magic_quotes_gpc的举例

代码如下:

if (!get_magic_quotes_gpc()) {
  $lastname = addslashes($_POST[‘lastname’]);
  } else {
  $lastname = $_POST[‘lastname’];
}


最好对magic_quotes_gpc已经开放的情况下,还是对$_POST[’lastname’]进行检查一下。
再说下mysql_real_escape_string和mysql_escape_string这2个函数的区别:
mysql_real_escape_string 必须在(PHP 4 >= 4.3.0, PHP 5)的情况下才能使用。否则只能用 mysql_escape_string ,两者的区别是:mysql_real_escape_string 考虑到连接的当前字符集,而mysql_escape_string 不考虑。
(1)mysql_real_escape_string -- 转义 SQL 语句中使用的字符串中的特殊字符,并考虑到连接的当前字符集
使用方法如下:

$sql = "select count(*) as ctr from users where 

username02.='".mysql_real_escape_string($username)."' and 03.password='". 

mysql_real_escape_string($pw)."' limit 1";


自定义函数

function inject_check($sql_str) { 
    return eregi
('select|insert|and|or|update|delete|'|/*|*|../|./|union|into|load_file|outfile', $sql_str);
 } 
 function verify_id($id=null) { 
    if(!$id) {
         exit('没有提交参数!'); 
    } elseif(inject_check($id)) { 
        exit('提交的参数非法!');
     } elseif(!is_numeric($id)) { 
        exit('提交的参数非法!'); 
    } 
    $id = intval($id); 
    return $id; 
 function str_check( $str ) { 
    if(!get_magic_quotes_gpc()) { 
        $str = addslashes($str); // 进行过滤 
    } 
    $str = str_replace("_", "_", $str); 
    $str = str_replace("%", "%", $str); 
   return $str; 
 function post_check($post) { 
    if(!get_magic_quotes_gpc()) { 
        $post = addslashes($post);
     } 
    $post = str_replace("_", "_", $post); 
    $post = str_replace("%", "%", $post); 
    $post = nl2br($post); 
    $post = htmlspecialchars($post); 
    return $post; 
}


对于这些修改网站代码的情况,还可使使用一些防注入的工具,像安全狗实验室出的安全狗对于防注入就非常的强大,可以拦住不少的入侵者的脚步。同样还有一些的防注入工具也很强大,大家可以去试试!

END!!!




     本文转自Tar0 51CTO博客,原文链接:http://blog.51cto.com/tar0cissp/1281140,如需转载请自行联系原作者




相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
1月前
|
SQL 监控 安全
SQL注入的实现原理以及防止
SQL注入的实现原理以及防止
|
2月前
|
SQL 数据库
20、绕过去除and、or、union select、空格的sql注入
20、绕过去除and、or、union select、空格的sql注入
30 0
|
2月前
|
SQL 数据库
小课堂 -- 绕过去除特殊字符的sql注入
小课堂 -- 绕过去除特殊字符的sql注入
22 0
|
2月前
|
SQL Java 数据库连接
[SQL]SQL注入与SQL执行过程(基于JDBC)
[SQL]SQL注入与SQL执行过程(基于JDBC)
50 0
|
2月前
|
SQL 关系型数据库 MySQL
【MySQL进阶之路丨第十四篇】一文带你精通MySQL重复数据及SQL注入
【MySQL进阶之路丨第十四篇】一文带你精通MySQL重复数据及SQL注入
46 0
|
1月前
|
SQL Java 应用服务中间件
Java项目防止SQL注入的四种方案
Java项目防止SQL注入的四种方案
37 0
|
2月前
|
SQL 安全 关系型数据库
接上篇文章,在测试宝塔 WAF 的未授权访问漏洞时无意间还发现了一个 SQL 注入漏洞
接上篇文章,在测试宝塔 WAF 的未授权访问漏洞时无意间还发现了一个 SQL 注入漏洞,品相还不错,可执行任意 SQL 语句。 总之,吃了一惊,一个防 SQL 注入的工具居然也有 SQL 注入漏洞。 请看这段代码
414 1
|
3天前
|
SQL 安全 Go
如何在 Python 中进行 Web 应用程序的安全性管理,例如防止 SQL 注入?
在Python Web开发中,确保应用安全至关重要,主要防范SQL注入、XSS和CSRF攻击。措施包括:使用参数化查询或ORM防止SQL注入;过滤与转义用户输入抵御XSS;添加CSRF令牌抵挡CSRF;启用HTTPS保障数据传输安全;实现强身份验证和授权系统;智能处理错误信息;定期更新及审计以修复漏洞;严格输入验证;并培训开发者提升安全意识。持续关注和改进是保证安全的关键。
10 0
|
11天前
|
SQL 安全 PHP
CTF--Web安全--SQL注入之Post-Union注入
CTF--Web安全--SQL注入之Post-Union注入
|
1月前
|
SQL 安全 测试技术
如何在 Python 中进行 Web 应用程序的安全性管理,例如防止 SQL 注入?
如何在 Python 中进行 Web 应用程序的安全性管理,例如防止 SQL 注入?
15 0