3 php windows irc proxy fsockopen
我已经使用PHP fsockopen和相关功能编写了一个非恶意,非垃圾邮件的IRC僵尸程序。有用。但是,问题是我需要支持代理(最好是SOCKS5,但是如果以某种方式更简单,HTTP也可以,我对此表示怀疑)。不支持此功能fsockopen。
我已经遍历了“ PHP fsockopen代理”和相关查询的所有搜索结果。我知道所有无效的内容,因此请不要链接到其中之一。
fsockopen的PHP手册页中提到的功能stream_socket_client()为
类似,但提供了更丰富的选项集,包括非阻塞连接和提供流上下文的功能。
乍一看,这听起来很有希望,可能是让我可以通过“流上下文” 将fsockopen呼叫替换为stream_socket_client并指定代理,但事实并非如此。还是呢?我对手册感到非常困惑。
请注意,它必须是PHP代码解决方案。我无法支付“ Proxifier”或使用任何其他外部软件来“包装”。
我尝试过的所有事情似乎总是导致我从服务器获得一堆空输出,然后强制关闭套接字。请注意,当我使用具有相同网络的HexChat(普通IRC客户端)时,我尝试使用的代理有效,因此,代理本身并不是问题。
据我所知,没有默认选项可为fsockopen或设置SOCKS或HTTP代理stream_socket_client(我们可以创建上下文并在HTTP选项中设置代理,但这不适用于stream_socket_client)。但是,我们可以手动建立连接。
连接到HTTP代理非常简单:
function connect_to_http_proxy($host, $port, $destination) {
$fp = fsockopen($host, $port, $errno, $errstr);
if ($errno == 0) {
$connect = "CONNECT $destination HTTP/1.1\r\n\r\n";
fwrite($fp, $connect);
$rsp = fread($fp, 1024);
if (preg_match('/^HTTP\/\d\.\d 200/', $rsp) == 1) {
return $fp;
}
echo "Request denied, $rsp\n";
return false;
}
echo "Connection failed, $errno, $errstr\n";
return false;
}
Run Code Online (Sandbox Code Playgroud)
如果连接成功,则此函数返回文件指针资源,否则返回FALSE。我们可以使用该资源与目标主机进行通信。
$proxy = "138.204.48.233";
$port = 8080;
$destination = "api.ipify.org:80";
$fp = connect_to_http_proxy($proxy, $port, $destination);
if ($fp) {
fwrite($fp, "GET /?format=json HTTP/1.1\r\nHost: $destination\r\n\r\n");
echo fread($fp, 1024);
fclose($fp);
}
Run Code Online (Sandbox Code Playgroud)
SOCKS5代理的通信协议稍微复杂一些:
更多详细信息:SOCKS协议版本5。
function connect_to_socks5_proxy($host, $port, $destination) {
$fp = fsockopen($host, $port, $errno, $errstr);
if ($errno == 0) {
fwrite($fp, "\05\01\00");
$rsp = fread($fp, 2);
if ($rsp === "\05\00" ) {
list($host, $port) = explode(":", $destination);
$host = gethostbyname($host); //not required if $host is an IP
$req = "\05\01\00\01" . inet_pton($host) . pack("n", $port);
fwrite($fp, $req);
$rsp = fread($fp, 10);
if ($rsp[1] === "\00") {
return $fp;
}
echo "Request denied, status: " . ord($rsp[1]) . "\n";
return false;
}
echo "Request denied\n";
return false;
}
echo "Connection failed, $errno, $errstr\n";
return false;
}
Run Code Online (Sandbox Code Playgroud)
此功能的工作方式与相同connect_to_http_proxy。尽管两个功能都经过测试,但是最好使用一个库。该代码主要用于教育目的。
SSL支持和身份验证。
我们无法fsockopen使用ssl://或tls://协议创建SSL连接,因为那样会尝试与代理服务器而非目标主机创建SSL连接。但是stream_socket_enable_crypto,在与代理服务器建立连接之后,可以启用SSL并与目标建立安全的通信通道。这需要禁用对等验证,这可以stream_socket_client使用自定义上下文来完成。请注意,禁用对等验证可能是一个安全问题。
对于HTTP代理,我们可以在Proxy-Authenticate标头中添加身份验证。此标头的值是身份验证类型,后跟以base64编码的用户名和密码(基本身份验证)。
同样,对于SOCKS5代理,身份验证过程更加复杂。看来我们必须将身份验证代码fron 0x00(无需身份验证)更改为0x02(用户名/密码身份验证)。我尚不清楚如何使用身份验证值创建请求,因此无法提供示例。
function connect_to_http_proxy($host, $port, $destination, $creds=null) {
$context = stream_context_create(
['ssl'=> ['verify_peer'=> false, 'verify_peer_name'=> false]]
);
$soc = stream_socket_client(
"tcp://$host:$port", $errno, $errstr, 20,
STREAM_CLIENT_CONNECT, $context
);
if ($errno == 0) {
$auth = $creds ? "Proxy-Authorization: Basic ".base64_encode($creds)."\r\n": "";
$connect = "CONNECT $destination HTTP/1.1\r\n$auth\r\n";
fwrite($soc, $connect);
$rsp = fread($soc, 1024);
if (preg_match('/^HTTP\/\d\.\d 200/', $rsp) == 1) {
return $soc;
}
echo "Request denied, $rsp\n";
return false;
}
echo "Connection failed, $errno, $errstr\n";
return false;
}
$host = "proxy IP";
$port = "proxy port";
$destination = "chat.freenode.net:6697";
$credentials = "user:pass";
$soc = connect_to_http_proxy($host, $port, $destination, $credentials);
if ($soc) {
stream_socket_enable_crypto($soc, true, STREAM_CRYPTO_METHOD_ANY_CLIENT);
fwrite($soc,"USER test\nNICK test\n");
echo fread($soc, 1024);
fclose($soc);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
787 次 |
| 最近记录: |