PHP禁用FSOCKOPEN函数的解决办法

发布时间:2014-07-13

sockopen() — Open Internet or Unix domain socket connection

一、如何禁用fsockopen()


下面是两种常用的禁用fsockopen的方法。
1、修改php.ini,将 disable_functions = 后加入 fsockopen
2、修改php.ini,将 allow_url_fopen = On 改为 allow_url_fopen = Off

二、如何解决fsockopen函数被禁用

1、如果服务器没有同时禁用pfsockopen,那么直接将fsockopen函数替换为pfsockopen。
具体操作:搜索程序中的字符串 fsockopen( 替换为 pfsockopen(。示例如下
修改前:
$fp = fsockopen($host, 80, $errno, $errstr, 30);

修改后:
$fp = pfsockopen($host, 80, $errno, $errstr, 30);

2、如果服务器同时禁用了pfsockopen,那么用其他函数代替

如stream_socket_client()。
注意:stream_socket_client()和fsockopen()的参数不同。
具体操作:搜索程序中的字符串 fsockopen( 替换为 stream_socket_client(,然后,将原fsockopen函数中的端口参数“80”删掉,并加到$host。示例如下
修改前:

$fp = fsockopen($host, 80, $errno, $errstr, 30);

修改后
$fp = stream_socket_client($host.”:80″, $errno, $errstr, 30);

3、如果PHP版本低于5.0,fsockopen被禁用,又没有stream_socket_client()怎么办呢?自己写一个函数实现fsockopen的功能,参考代码:

function b_fsockopen($host, $port, &$errno, &$errstr, $timeout) {
$ip = gethostbyname($host);
$s = socket_create(AF_INET, SOCK_STREAM, 0);
if (socket_set_nonblock($s)) {
  $r = @socket_connect($s, $ip, $port);
  if ($r || socket_last_error() == EINPROGRESS) {
   $errno = EINPROGRESS;
   return $s;
  }
}
$errno = socket_last_error($s);
$errstr = socket_strerror($errno);
socket_close($s);
return false;
}

具体操作:

1.首先找到使用fsockopen函数的代码段,将上面代码加至其上端,搜索该代码段中的字符串fsockopen( 替换为 b_fsockopen(。
2.因为fsockopen函数返回文件指针所以可以被文件函数操作,但是这个b_fsockopen函数没能返回文件指针,需要继续修改代码段:用socket_read(替换掉 fread(,用socket_write(替换掉fwrite(,用socket_close(替换掉fclose(。

 

近期黑客利用程序漏洞注入后使用 fsockopen 进行PHPDDOS 攻击,导致部分服务器不稳定,现在将危险函数 fsockopen 暂时禁用,部分程序功能可能有问题,以下列出已知问题及通用解决方法:

通用解决方法:
找到程序里的 fsockopen 函数,替换为:pfsockopen,即可解决所有问题,两个函数的区别在于 pfsockopen 保持 keep-alive,使得黑客无法进行 连接数攻击。

已知使用 fsockopen 函数的程序文件路径(在fsockopen 前加 p, 即fsockopen 修改为 pfsockopen  即可 )[其他程序可通过错误提示的文件路径查看更改]:

Discuz X2  安装提示不支持fsockopen:
将 /include/install_var.php  文件里的
$func_items = array(‘mysql_connect’, ‘fsockopen‘, ‘gethostbyname’, ‘file_get_contents’, ‘xml_parser_create’);
替换为:
$func_items = array(‘mysql_connect’, ‘pfsockopen‘, ‘gethostbyname’, ‘file_get_contents’, ‘xml_parser_create’);
即可正常安装。
X2全部包含fsockopen的文件(如果用邮件只修改邮件即可,其他文件都是自动判断 pfsockopen):
\api\manyou\Manyou.php
\api\trade\api_alipay.php
\install\include\install_function.php
\install\include\install_lang.php
\install\include\install_var.php
\source\admincp\admincp_addons.php
\source\admincp\admincp_checktools.php
\source\admincp\admincp_cloud.php
\source\admincp\admincp_misc.php
\source\admincp\cloud\cloud_doctor.php
\source\class\class_image.php
\source\class\class_sphinx.php
\source\class\block\xml\block_xml.php
\source\function\function_connect.php
\source\function\function_core.php
\source\function\function_filesock.php
\source\function\function_importdata.php
\source\function\function_mail.php      邮件相关
\source\function\function_plugin.php
\source\include\portalcp\portalcp_upload.php
\source\language\lang_admincp_cloud.php
\source\module\forum\forum_ajax.php
\source\module\misc\misc_manyou.php
\uc_client\client.php
\uc_client\lib\sendmail.inc.php         邮件相关
\uc_client\model\misc.php
\uc_server\install\func.inc.php
\uc_server\install\lang.inc.php
\uc_server\lib\sendmail.inc.php         邮件相关
\uc_server\model\misc.php

Discuz 品牌空间不能安装,提示UC地址不正确:
修改 /install/func.inc.php 里的 fsockopen函数为 pfsockopen

Discuz 7.2:(非首次安装,可以只改绿色部分。)
问题:使用 uc 不能登录 , fsockopen函数位于:

include\global.func.php(240): $fp = @fsockopen(($ip ? $ip : $host), $port, $errno, $errstr, $timeout);
include\sendmail.inc.php(54):  if(!$fp = fsockopen($mail['server'], $mail['port'], $errno, $errstr, 30)) {
install\func.inc.php(803):  $fp = @fsockopen(($ip ? $ip : $host), $port, $errno, $errstr, $timeout);
install\var.inc.php(70): $func_items = array('mysql_connect', 'fsockopen', 'gethostbyname', 'file_get_contents', 'xml_parser_create');
uc_client\client.php(211): $fp = @fsockopen(($ip ? $ip : $host), $port, $errno, $errstr, $timeout);
uc_client\lib\sendmail.inc.php(40):  if(!$fp = fsockopen($mail_setting['mailserver'], $mail_setting['mailport'], $errno, $errstr, 30)) {
uc_client\model\misc.php(97): $fp = @fsockopen(($ip ? $ip : $host), $port, $errno, $errstr, $timeout);
uc_server\lib\sendmail.inc.php(40):  if(!$fp = fsockopen($mail_setting['mailserver'], $mail_setting['mailport'], $errno, $errstr, 30)) {
uc_server\model\misc.php(94): $fp = @fsockopen(($ip ? $ip : $host), $port, $errno, $errstr, $timeout);
DEDECMS 问答积分功能出现 service.dedecms.com:
修改  /ask/data/scores.inc.php 里的 fsockopen 为 pfsockopen
附带dedecms 全部含 fsockopen 的文件列表:

./include/dedehttpdown.class.php
./include/sphinxclient.class.php
./include/sphinxclient.class.php
./include/dedecollection.func.php
./include/dedecollection.func.php
./include/mail.class.php
./include/mail.class.php
./include/mail.class.php
./ask/data/scores.inc.php
./dede/module_main.php
./dede/api_ucenter.php
./dede/plus_bshare.php
./plus/bshare.php
UC通信不正常,DEDE整合UC连接不上的解决办法:
修改:
uc_client/client.php
uc_client/model/misc.php
替换里面的 fsockopen  为 pfsockopen
SHOPEX:
./install/svinfo.php:                    $fp = @fsockopen(“unix://”.DB_HOST);
./install/svinfo.php:                    $fp = @fsockopen(“tcp://”.$host, $port, $errno, $errstr,2);
./install/svinfo.php:        $rst = is_callable(‘fsockopen’);
./install/svinfo.php:        $items['fsockopen支持'] = array(
./install/svinfo.php:            $fp = fsockopen(isset($_SERVER['SERVER_ADDR'])?$_SERVER['SERVER_ADDR']:$_SERVER['HTTP_HOST'], $_SERVER['SERVER_PORT'], $errno, $errstr, 2);
./plugins/payment/pay.paypal_cn.php:        $fp = fsockopen (‘www.paypal.com’, 80, $errno, $errstr, 30);
./plugins/payment/pay.paypal_cn.php:        $fp = fsockopen (‘ssl://www.paypal.com’, 443, $errno, $errstr, 30);
./plugins/payment/pay.nochek.php:        $fp = fsockopen (‘www.nochex.com’, 80, $errno, $errstr, 10);
./plugins/payment/pay.paypal.server.php:        $fp = fsockopen (‘www.paypal.com’, 80, $errno, $errstr, 30);
./plugins/payment/pay.paypal.php:        $fp = fsockopen (‘www.paypal.com’, 80, $errno, $errstr, 30);
./plugins/passport/passport.ucenter.php:            $fp=@fsockopen(($ip ? $ip : $host),$port,$errorno,$errorstr,$timeout);
./core/lib/nusoap.php:        $this->debug(‘calling fsockopen with host ‘ . $host . ‘ connection_timeout ‘ . $connection_timeout);
./core/lib/nusoap.php:            $this->fp = @fsockopen( $host, $this->port, $this->errno, $this->error_str, $connection_timeout);
./core/lib/nusoap.php:            $this->fp = @fsockopen( $host, $this->port, $this->errno, $this->error_str);
./core/lib/uc_client/client.php:    $fp = @fsockopen(($ip ? $ip : $host), $port, $errno, $errstr, $timeout);
./core/func_ext.php:    $fp = pfsockopen($url['host'], isset($url['port'])?$url['port']:80, $errno, $errstr, 2);
./core/func_ext.php:    $fp = pfsockopen( $host, $port, $errno, $errstr, $timeout );
./core/api/include/api_utility.php:        $process = fsockopen($this->host, $this->port, $errno, $errstr, 10);
./core/api/include/api_utility.php:        $process = fsockopen($host, 80, $errno, $errstr, 10);
./core/api/tools/1.0/api_b2b_1_0_tools.php:    $fp = fsockopen( $host, $port, $errno, $errstr, $timeout );

PHPWIND 云平台

禁用 fsockopen 函数的解决办法,修改以下文件的 fsockopen 为 pfsockopen:
admin/advanced.php
lib/download.class.php  (两处:function_exists(‘fsockopen’)) 和 $fp=@fsockopen
lib/cloudwind/client/core/public/core.httpclient.class.php
lib/cloudwind/client/defend/service/defend.general.class.php
lib/cloudwind/client/platform/service/platform.checkserver.class.php (除了$fsockopen 以外的 3处)
lib/utility/ftp.class.php (2处)
lib/utility/sphinx.class.php (2处)
lib/utility/captcha/cloudcaptcha.class.php
lib/utility/platformapisdk/client.class.php
require/nusoap.php (@fsockopen 2处)
require/posthost.php
uc_client/model/app.php

PHPCMS V9 fsockopen 禁用解决方案,替换文件:

phpsso_server/api/uc_client_1_5/client.php
phpsso_server/api/uc_client_1_5/lib/sendmail.inc.php
phpsso_server/api/uc_client_1_5/model/misc.php
phpsso_server/api/uc_client/lib/sendmail.inc.php
phpsso_server/phpcms/modules/admin/functions/global.func.php
phpsso_server/phpcms/libs/classes/http.class.php
phpcms/modules/admin/functions/global.func.php
phpcms/modules/search/search_admin.php
phpcms/modules/search/classes/sphinxapi.class.php (两个)
phpcms/modules/pay/classes/pay_abstract.class.php
phpcms/modules/sms/classes/smsapi.class.php
phpcms/modules/member/classes/client.class.php   (会员注册)
phpcms/libs/classes/http.class.php
phpcms/libs/functions/mail.func.php