PHP: Using SOCKS4 with SSL connection – part 2


Part 1: PHP: Using SOCKS4 with SSL connection

The solution is use function stream_socket_enable_crypto to turn encryption on an already connected socket:

function ssl(&$sock)
{
    if (!in_array('ssl', stream_get_transports()))
        return false;

    $modes = array(STREAM_CRYPTO_METHOD_TLS_CLIENT, STREAM_CRYPTO_METHOD_SSLv3_CLIENT,
        STREAM_CRYPTO_METHOD_SSLv23_CLIENT, STREAM_CRYPTO_METHOD_SSLv2_CLIENT);

    $success = false;
    foreach ($modes as $mode)
    {
        $success = @stream_socket_enable_crypto($sock, true, $mode);
        if ($success)
            break;
    }
}

socks4 with ssl

We change function fsocks4sockopen to the new

function fsocks4sockopen($proxyHostname, $proxyPort, $targetHostname, $targetPort =
    80, $timeout = 10)
{
    $sock = @fsockopen($proxyHostname, $proxyPort, $errno, $errstr, $timeout);
    if ($sock === false)
        return false;
    $ip = gethostbyname($targetHostname);
    if (preg_match('/(\d+)\.(\d+)\.(\d+)\.(\d+)/', $ip, $matches))
        $int = pack('C4', $matches[1], $matches[2], $matches[3], $matches[4]);
    else
    {
        fclose($sock);
        return false;
    }
    $request = pack('C2', 0x04, 0x01) . pack('n', $targetPort) . $int . '0' . pack('C', 0x00);
    fwrite($sock, $request);
    $resp = fread($sock, 9);
    if (strlen($resp) != 8)
    {
        fclose($sock);
        return false;
    }
    $answer = unpack('Cvn/Ccd', substr($resp, 0, 2));
    if ($answer['vn'] != 0x00 && $answer['vn'] != 0x04)
    {
        fclose($sock);
        return false;
    }
    if ($answer['cd'] != 0x5A)
    {
        fclose($sock);
        return false;
    }
    if ($targetPort == 443)
    {
        ssl($sock);
    }
    return $sock;
}

Now we can grab data from a HTTPS page:

<?php

set_time_limit(120);

define(CS_URI, '/sock/gate.php');
define(CS_HOST, 'demo.tutorialspots.com');

class socks4
{
    public $packet;
    public $ssl = false;
    public $time;
    public $timeout = 10;
    public $res;

    function __construct($ssl = false)
    {
        $this->ssl = $ssl;
        $this->packet = "GET " . CS_URI . " HTTP/1.1
Host: " . CS_HOST . ":" . ($this->ssl ? 443 : 80) . "
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:8.0.1) Gecko/20100101 Firefox/8.0.1
Connection: close

";
    }

    private function fsocks4sockopen($proxyHostname, $proxyPort, $targetHostname, $targetPort =
        80, $timeout = 10)
    {
        $sock = @fsockopen($proxyHostname, $proxyPort, $errno, $errstr, $timeout);
        if ($sock === false)
            return false;
        $ip = gethostbyname($targetHostname);
        if (preg_match('/(\d+)\.(\d+)\.(\d+)\.(\d+)/', $ip, $matches))
            $int = pack('C4', $matches[1], $matches[2], $matches[3], $matches[4]);
        else
        {
            fclose($sock);
            return false;
        }
        $request = pack('C2', 0x04, 0x01) . pack('n', $targetPort) . $int . '0' . pack('C', 0x00);
        fwrite($sock, $request);
        $resp = fread($sock, 9);
        if (strlen($resp) != 8)
        {
            fclose($sock);
            return false;
        }
        $answer = unpack('Cvn/Ccd', substr($resp, 0, 2));
        if ($answer['vn'] != 0x00 && $answer['vn'] != 0x04)
        {
            fclose($sock);
            return false;
        }
        if ($answer['cd'] != 0x5A)
        {
            fclose($sock);
            return false;
        }
        if ($targetPort == 443)
        {
            self::ssl($sock);
        }
        return $sock;
    }
 

    private static function ssl(&$sock)
    {
        if (!in_array('ssl', stream_get_transports()))
            return false;

        $modes = array(STREAM_CRYPTO_METHOD_TLS_CLIENT, STREAM_CRYPTO_METHOD_SSLv3_CLIENT,
            STREAM_CRYPTO_METHOD_SSLv23_CLIENT, STREAM_CRYPTO_METHOD_SSLv2_CLIENT);

        $success = false;
        foreach ($modes as $mode)
        {
            $success = @stream_socket_enable_crypto($sock, true, $mode);
            if ($success)
                break;
        }
    }

    public function check($ip, $port )
    {  
        $_s = microtime(true);
         
        $sock = call_user_func(array($this, 'fsocks4sockopen'), $ip, $port, CS_HOST, $this->
            ssl ? 443 : 80, $this->timeout);

        if (!$sock)
            return false;

        if (!fwrite($sock, $this->packet))
            return false;
         
        $this->res = stream_get_contents($sock);
         
        $this->time = round(($_time = microtime(true) - $_s) * 1000, -1);
        return true;
    }
}

$check = new socks4(true);

if ($check->check('79.116.216.175','1080'))
    //echo $check->time . ' ms';
    echo $check->res;
else
    echo 'DIE';

Result:

HTTP/1.1 200 OK
Date: Fri, 17 Jun 2016 02:46:43 GMT
Server: Apache/2.2.27 (CentOS)
X-Powered-By: PHP/5.4.45
Content-Length: 1218
Connection: close
Content-Type: text/html; charset=UTF-8

a:26:{s:9:"HTTP_HOST";s:26:"demo.tutorialspots.com:443";s:12:"CONTENT_TYPE";s:33:"application/x-www-form-urlencoded";s:15:"HTTP_USER_AGENT";s:67:"Mozilla/5.0 (Windows NT 6.1; rv:8.0.1) Gecko/20100101 Firefox/8.0.1";s:15:"HTTP_CONNECTION";s:5:"close";s:4:"PATH";s:29:"/sbin:/usr/sbin:/bin:/usr/bin";s:16:"SERVER_SIGNATURE";s:84:"<address>Apache/2.2.27 (CentOS) Server at demo.tutorialspots.com Port 443</address>
";s:15:"SERVER_SOFTWARE";s:22:"Apache/2.2.27 (CentOS)";s:11:"SERVER_NAME";s:22:"demo.tutorialspots.com";s:11:"SERVER_ADDR";s:13:"68.235.32.101";s:11:"SERVER_PORT";s:3:"443";s:11:"REMOTE_ADDR";s:14:"79.116.216.175";s:13:"DOCUMENT_ROOT";s:29:"/home/tutorialspots.com/demo/";s:12:"SERVER_ADMIN";s:14:"root@localhost";s:15:"SCRIPT_FILENAME";s:42:"/home/tutorialspots.com/demo/sock/gate.php";s:11:"REMOTE_PORT";s:5:"37333";s:17:"GATEWAY_INTERFACE";s:7:"CGI/1.1";s:15:"SERVER_PROTOCOL";s:8:"HTTP/1.1";s:14:"REQUEST_METHOD";s:3:"GET";s:12:"QUERY_STRING";s:0:"";s:11:"REQUEST_URI";s:14:"/sock/gate.php";s:11:"SCRIPT_NAME";s:14:"/sock/gate.php";s:8:"PHP_SELF";s:14:"/sock/gate.php";s:18:"REQUEST_TIME_FLOAT";d:1466131603.875;s:12:"REQUEST_TIME";i:1466131603;s:4:"argv";a:0:{}s:4:"argc";i:0;}<br>a:0:{}<br>a:0:{}<br>

Here the code of http://demo/tutorialspots.com/sock/gate.php

<?php
    echo(serialize($_SERVER)).'<br>';
    echo(serialize($_GET)).'<br>';
    echo(serialize($_POST)).'<br>';
?>

1 Comment

Leave a Reply