rofl0r / proxychains-ng

proxychains ng (new generation) - a preloader which hooks calls to sockets in dynamically linked programs and redirects it through one or more socks/http proxies. continuation of the unmaintained proxychains project. the sf.net page is currently not updated, use releases from github release page instead.
http://sourceforge.net/projects/proxychains-ng/files
GNU General Public License v2.0
9.82k stars 1.08k forks source link

Proxy don't work with php script #363

Open azuusiek1 opened 3 years ago

azuusiek1 commented 3 years ago

Hi, I tried proxychains to use a PHP script as a sockets client (socket_connect - port 6666 if important). Proxychains bypass the proxy and connect over a public ip. Trying to connect to the same server via the Python script, the proxy works, but for me it is very important to execute the PHP script. Best regards.

rofl0r commented 3 years ago

i dunno, what's the output of proxychains when you run your script ? does it use UDP? is php binary statically linked?

azuusiek1 commented 3 years ago

Hello. Its TCP connection. Look here, curl works perfectly, but php not. https://pasteboard.co/JMzpwhn.png When I use python on the same protocol, the proxy works. Thank you for reply!

W dniu śr., 3.02.2021 o 00:53 rofl0r notifications@github.com napisał(a):

i dunno, what's the output of proxychains when you run your script ? does it use UDP? is php binary statically linked?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/rofl0r/proxychains-ng/issues/363#issuecomment-772096402, or unsubscribe https://github.com/notifications/unsubscribe-auth/APW4RWMAH7K67TB7GK5CFFTS5CF7FANCNFSM4W7QFX6A .

rofl0r commented 3 years ago

run

file  `which php`

and paste output

azuusiek1 commented 3 years ago

/usr/bin/php: symbolic link to /etc/alternatives/php

azuusiek1 commented 3 years ago

Everything leads me to PHP7.1, where the output is: /usr/bin/php7.1: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=3b8304194657edad8f54b5ee553ae2c7e0668732, stripped Firing directly with php7.1 also doesn't work.

rofl0r commented 3 years ago

can you paste the strace output of running php directly on your script ?

strace -f -o log php my.php

then remove credentials and other secrets from "log".

azuusiek1 commented 3 years ago

Here it is: https://pastebin.com/MZPWz5P1

rofl0r commented 3 years ago

first connection is done via UDP (SOCK_DGRAM) so it's expected it doesn't work:

9425 socket(PF_INET, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_IP) = 3 9425 connect(3, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("213.186.33.99")}, 16) = 0

however second one should be proxified regardless. that didn't happen either ?

oh wait, the udp connection is actually a DNS request...

edit: let's see your proxychains config (apart from the [proxylist])

azuusiek1 commented 3 years ago

Proxychains config:

random_chain
proxy_dns 
remote_dns_subnet 224
tcp_read_time_out 15000
tcp_connect_time_out 8000

[ProxyList]
deleted content
rofl0r commented 3 years ago

turned out that php built for e.g. ubuntu, if it uses raw sockets like in this small example:

<?php                                                                                                                       
error_reporting(E_ALL);                                                                                                     
/* Get the port for the WWW service. */                                                                                     
$service_port = getservbyname('www', 'tcp');                                                                                
/* Get the IP address for the target host. */                                                                               
$address = gethostbyname('www.google.com');                                                                                 
/* Create a TCP/IP socket. */                                                                                               
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);                                                                     
socket_set_option($socket, SOL_TCP, TCP_NODELAY, 1);                                                                        
if ($socket === false) {                                                                                                    
    echo "socket_create() failed: reason: " .                                                                               
         socket_strerror(socket_last_error()) . "\n";                                                                       
}                                                                                                                           

echo "Attempting to connect to '$address' on port '$service_port'...";                                                      
$result = socket_connect($socket, $address, $service_port);                                                                 
if ($result === false) {                                                                                                    
    echo "socket_connect() failed.\nReason: ($result) " .                                                                   
          socket_strerror(socket_last_error($socket)) . "\n";                                                               
}                                                                                                                           
$in = "HEAD / HTTP/1.1\r\n";                                                                                                
$in .= "Host: www.google.com\r\n";                                                                                          
$in .= "Connection: Close\r\n\r\n";                                                                                         
$out = '';                                                                                                                  
echo "Sending HTTP HEAD request...";                                                                                        
socket_write($socket, $in, strlen($in));                                                                                    
echo "OK.\n";                                                                                                               
echo "Reading response:\n\n";                                                                                               
while ($out = socket_read($socket, 2048)) {                                                                                 
    echo $out;                                                                                                              
}                                                                                                                           

?>                                                                                                                          

somehow ends up calling glibc's __libc_connect directly instead of calling connect, thereby circumventing proxychains-ng. how that happens is a mystery to me since the function is not exported by glibc and only exists in libpthread.so as a local symbol. since the ubuntu 20.04 version of php ships with crucial debug symbols removed, i built my own version of php 7.4.3 using these options:

CFLAGS="-g3 -O0" ./configure --enable-debug --enable-sockets
make
make install

and the resulting binary in /usr/local/bin works with proxychains without issues. so the problems seems to be caused by some build options used by the ubuntu/debian build recipe.

here's the backtrace for the connect call we're interested in:

#0  connect (sock=1275118314, addr=0x5555563ea7e9, len=3185214976) at src/libproxychains.c:556
#1  0x0000555555980f9f in zif_socket_connect (execute_data=0x7ffff5813300, return_value=0x7ffff58131e0)
    at /root/php-7.4.3/ext/sockets/sockets.c:1560
#2  0x0000555555bfd47c in ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER () at /root/php-7.4.3/Zend/zend_vm_execute.h:1314
#3  0x0000555555c6429e in execute_ex (ex=0x7ffff5813020) at /root/php-7.4.3/Zend/zend_vm_execute.h:53797
#4  0x0000555555c692a1 in zend_execute (op_array=0x7ffff587f300, return_value=0x0)
    at /root/php-7.4.3/Zend/zend_vm_execute.h:57913
#5  0x0000555555b89448 in zend_execute_scripts (type=8, retval=0x0, file_count=3) at /root/php-7.4.3/Zend/zend.c:1665
#6  0x0000555555ae6b99 in php_execute_script (primary_file=0x7fffffffd300) at /root/php-7.4.3/main/main.c:2617
#7  0x0000555555c6be94 in do_cli (argc=2, argv=0x55555698b040) at /root/php-7.4.3/sapi/cli/php_cli.c:961
#8  0x0000555555c6d06a in main (argc=2, argv=0x55555698b040) at /root/php-7.4.3/sapi/cli/php_cli.c:1356

so we should evaluate how zif_socket_connect gets compiled by ubuntu. one thing i noticed is that the function ends up in a file called "sockets.so" with ubuntu stock php, not so with the self-built php.

azuusiek1 commented 3 years ago

what could i use instead to make it work?

W dniu śr., 3.02.2021 o 20:22 rofl0r notifications@github.com napisał(a):

turned out that php built for e.g. ubuntu, if it uses raw sockets like in this small example:

<?php error_reporting(E_ALL); / Get the port for the WWW service. / $service_port = getservbyname('www', 'tcp'); / Get the IP address for the target host. / $address = gethostbyname('www.google.com'); / Create a TCP/IP socket. / $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); socket_set_option($socket, SOL_TCP, TCP_NODELAY, 1); if ($socket === false) { echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n"; } echo "Attempting to connect to '$address' on port '$service_port'..."; $result = socket_connect($socket, $address, $service_port); if ($result === false) { echo "socket_connect() failed.\nReason: ($result) " . socket_strerror(socket_last_error($socket)) . "\n"; } $in = "HEAD / HTTP/1.1\r\n"; $in .= "Host: www.google.com\r\n"; $in .= "Connection: Close\r\n\r\n"; $out = ''; echo "Sending HTTP HEAD request..."; socket_write($socket, $in, strlen($in)); echo "OK.\n"; echo "Reading response:\n\n"; while ($out = socket_read($socket, 2048)) { echo $out; } ?>

somehow ends up calling glibc's __libc_connect directly instead of calling connect, thereby circumventing proxychains-ng. how that happens is a mystery to me since the function is not exported by glibc and only exists in libpthread.so as a local symbol. since the ubuntu 20.04 version of php ships with crucial debug symbols removed, i built my own version of php 7.4.3 using these options:

CFLAGS="-g3 -O0" ./configure --enable-debug --enable-sockets make make install

and the resulting binary in /usr/local/bin works with proxychains without issues. so the problems seems to be caused by some build options used by the ubuntu/debian build recipe.

here's the backtrace for the connect call we're interested in:

0 connect (sock=1275118314, addr=0x5555563ea7e9, len=3185214976) at src/libproxychains.c:556

1 0x0000555555980f9f in zif_socket_connect (execute_data=0x7ffff5813300, return_value=0x7ffff58131e0)

at /root/php-7.4.3/ext/sockets/sockets.c:1560

2 0x0000555555bfd47c in ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER () at /root/php-7.4.3/Zend/zend_vm_execute.h:1314

3 0x0000555555c6429e in execute_ex (ex=0x7ffff5813020) at /root/php-7.4.3/Zend/zend_vm_execute.h:53797

4 0x0000555555c692a1 in zend_execute (op_array=0x7ffff587f300, return_value=0x0)

at /root/php-7.4.3/Zend/zend_vm_execute.h:57913

5 0x0000555555b89448 in zend_execute_scripts (type=8, retval=0x0, file_count=3) at /root/php-7.4.3/Zend/zend.c:1665

6 0x0000555555ae6b99 in php_execute_script (primary_file=0x7fffffffd300) at /root/php-7.4.3/main/main.c:2617

7 0x0000555555c6be94 in do_cli (argc=2, argv=0x55555698b040) at /root/php-7.4.3/sapi/cli/php_cli.c:961

8 0x0000555555c6d06a in main (argc=2, argv=0x55555698b040) at /root/php-7.4.3/sapi/cli/php_cli.c:1356

so we should evaluate how zif_socket_connect gets compiled by ubuntu. one thing i noticed is that the function ends up in a file called "sockets.so" with ubuntu stock php, not so with the self-built php.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/rofl0r/proxychains-ng/issues/363#issuecomment-772756697, or unsubscribe https://github.com/notifications/unsubscribe-auth/APW4RWIPG5T5YMRI6BWSXMTS5GO5XANCNFSM4W7QFX6A .

rofl0r commented 3 years ago

you could compile your own php, for example.

azuusiek1 commented 3 years ago

it works, thank you.

W dniu śr., 3.02.2021 o 21:30 rofl0r notifications@github.com napisał(a):

you could compile your own php, for example.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/rofl0r/proxychains-ng/issues/363#issuecomment-772801708, or unsubscribe https://github.com/notifications/unsubscribe-auth/APW4RWIPPU3KIXZRYFPQA3TS5GW5DANCNFSM4W7QFX6A .