***利用fsocketopen,pfsocketopen 及 fsocketopen,pfsocketopen, stream_socket_client区别

一:

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

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

已知使用 fsockopen 函数的程序文件路径(在fsockopen 前加 p, 即fsockopen 修改为 pfsockopen 即可 )

二:

服务器同时禁用了fsockopen 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);

国内主流PHP网站涉及fsockopen函数的网站系统中的文件列表:
DEDECMS:
dede\api_ucenter.php
dede\index_testenv.php
dede\module_main.php
dede\plus_bshare.php
dede\testenv.php
dede\include\dedecollection.func.php
dede\include\dedehttpdown.class.php
dede\include\mail.class.php
dede\include\sphinxclient.class.php
dede\plus\bshare.php



Discuz! 2.5:
source\function\function_core.php  这个文件有2处fsockopen,另外的是pfsockopen,请注意区分
uc_client\client.php  这个文件有2处fsockopen,另外的是pfsockopen,请注意区分
uc_client\lib\sendmail.inc.php
uc_client\model\misc.php 这个文件有2处fsockopen,另外的是pfsockopen,请注意区分
uc_server\install\func.inc.php 这个文件有2处fsockopen,另外的是pfsockopen,请注意区分
uc_server\lib\sendmail.inc.php
uc_server\model\misc.php 这个文件有2处fsockopen,另外的是pfsockopen,请注意区分



ecms(帝国):
e\class\class.smtp.php



ECSHOP:
admin\index.php
demo\includes\lib_updater.php
includes\cls_smtp.php
includes\cls_transport.php
includes\lib_base.php
includes\modules\payment\paypal.php



shopex:
core\api\include\api_utility.php
core\api\tools\1.0\api_b2b_1_0_tools.php
core\func_ext.php
core\lib\nusoap.php
core\lib\uc_client\client.php
instal\svinfo.php
plugins\passport\passport.ucenter.php
plugins\payment\pay.nochek.php
plugins\pay.paypal.php
plugins\pay.paypal.server.php
plugins\pay.paypal_cn.php

 

 

按手册上说,这两个函数的唯一区别是,pfsockopen是是持续连接,而fsockopen不是.
我写了个代码了一下:

Php代码

<?php    

  1.   

  2. $data="1,0,721,73,1,0,0,43290000,0,60D81D509BC00451,3,FFFFFFFF";   

  3. //http://10.144.99.114/SANEX_NEW/modules/subscribemanager/test.php   

  4. $host = '127.0.0.1';   

  5. $url = "/aa.php";   

  6.   

  7. $pffirst = false;   

  8.   

  9. $times = 1000;   

  10.   

  11. $startTime = microtime(true);   

  12.   

  13. for ($index = 0; $index < $times$index++) {   

  14.     echo httpPost($host,$url,$data,$pffirst)."<hr><br />";   

  15. }   

  16. $middleTime = microtime(true);   

  17.   

  18. for ($index = 0; $index < $times$index++) {   

  19.     echo httpPost($host,$url,$data,!$pffirst)."<hr><br />";;   

  20. }   

  21.   

  22. $endTime = microtime(true);   

  23.   

  24.     echo ($pffirst?"pfsocket":"fsocket").":".($middleTime-$startTime);   

  25.     echo "<br />";   

  26.     echo ($pffirst?"fsocket":"pfsocket").":".($endTime-$middleTime);   

  27.        

  28. $count=0;   

  29.   

  30. //发包函数   

  31. function httpPost($host,$url,$data,$p)   

  32. {   

  33. global $count;   

  34.     $func = $p?"pfsockopen":"fsockopen";   

  35.        

  36.     $conn = $func($host,80,$errno$errstr, 30);   

  37.     if (!$conn)    

  38.     {   

  39.         echo "$errstr ($errno)<br />\n";   

  40.         return;   

  41.     }   

  42.        

  43.     $header = "POST ".$url." HTTP/1.1\r\n";   

  44.     $header.= "Host : {$host}\r\n";   

  45.     $header.= "Content-type: application/x-www-form-urlencoded\r\n";   

  46.     $header.= "Content-Length:".strlen($data)."\r\n";   

  47.     $header.= "Connection: Keep-Alive\r\n\r\n";    

  48.     $header.= "{$data}\r\n\r\n";   

  49.        

  50.     fwrite($conn,$header);   

  51.        

  52.     $count++;   

  53.     echo $count.' '.$header."<br /><br />";   

  54.        

  55.     $resp='';   

  56.     //while (!feof($conn)) {   

  57.     //  $resp .= fgets($conn);   

  58.     //}   

  59.     //fclose($conn);   

  60.     return $resp;   

  61. }   

  62.   

  63. ?>  



结果发现:
代码的倒数第二行,如果把//fclose($conn);注释掉,结果是:
fsocket:11.04693198204
pfsocket:0.34867787361145
如果不注释:
fsocket:12.509312152863
pfsocket:11.120275974274

可以看出,fsocketopen默认每次处理结束后,就算协议头是Keep-Alive,连接仍然断掉了.
而pfsocketopen在Keep-Alive条件下,连接可以被下一次重复利用.
一次连接发送大量数据时,推荐使用pfsocketopen

可以看出,fsocketopen默认每次处理结束后,就算协议头是Keep-Alive,连接仍然断掉了.
而pfsocketopen在Keep-Alive条件下,连接可以被下一次重复利用.
一次连接发送大量数据时,推荐使用pfsocketopen