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.56k stars 1.07k forks source link

segfault while proxying ssh on OpenBSD-current [OpenSSH_7.1 LibreSSL 2.3.2] #96

Open shaxo opened 8 years ago

shaxo commented 8 years ago

Hi, I don't know if it is an OpenBSD specific issue. I got a segfault in proxychains-ng when using a socks5 proxy to tunnel a ssh connection. SSH print "get_hostfile_hostname_ipaddr: getnameinfo failed" which causes the segfault.

tail -n 1 /tmp/px.conf

socks5 127.0.0.1 8888

./proxychains4 -f /tmp/px.conf ssh -vvvvvv root@192.168.130.5

Below is the gdb output with DEBUG activated. A more verbose output with SSH debug activated on http://pastebin.com/ZEwxmfYm

Starting program: /usr/bin/ssh root@192.168.130.5 DEBUG:init_lib_wrapper called from gcc_init DEBUG:pid[1209]:at_init [proxychains] DLL init: proxychains-ng 4.10 DEBUG:loaded symbol 'connect' real addr 0x1c671ccc7060 wrapped addr 0x1c66b3595f2a DEBUG:loaded symbol 'sendto' real addr 0x1c671ccc64e0 wrapped addr 0x1c66b35969ab DEBUG:loaded symbol 'gethostbyname' real addr 0x1c670a38bdc0 wrapped addr 0x1c66b359656e DEBUG:loaded symbol 'getaddrinfo' real addr 0x1c670a387840 wrapped addr 0x1c66b35965dd DEBUG:loaded symbol 'freeaddrinfo' real addr 0x1c670a3b2200 wrapped addr 0x1c66b35966a2 DEBUG:loaded symbol 'gethostbyaddr' real addr 0x1c670a38bb90 wrapped addr 0x1c66b3596887 DEBUG:loaded symbol 'getnameinfo' real addr 0x1c670a389230 wrapped addr 0x1c66b3592344 DEBUG:loaded symbol 'close' real addr 0x1c671ccc7120 wrapped addr 0x1c66b3595e61 DEBUG:pid[1209]:wait_data DEBUG:[play] socks5 127.0.0.1:8888 DEBUG:getaddrinfo: 192.168.130.5 22 DEBUG:pid[1209]:proxy_getaddrinfo DEBUG:pid[1209]:mygetservbyname_r DEBUG:pid[1209]:pc_getnameinfo DEBUG:pid[1209]:connect DEBUG:target: 192.168.130.5 DEBUG:port: 22 DEBUG:pid[1209]:connect_proxy_chain DEBUG:[play] socks5 127.0.0.1:8888

DEBUG: connect ret=0 DEBUG:pid[1209]:chain_step ... 192.168.130.5:22 DEBUG:pid[1209]:tunnel_to DEBUG:host dns ... OK DEBUG:pid[1209]:pc_getnameinfo DEBUG:freeaddrinfo 0x1c66e6008600 DEBUG:pid[1209]:proxy_freeaddrinfo DEBUG:pid[1209]:pc_getnameinfo get_hostfile_hostname_ipaddr: getnameinfo failed Program exited with code 0377.

rofl0r commented 8 years ago

can you add some debug code to pc_getnameinfo to see which branches are taken etc ?

shaxo commented 8 years ago

Here are my debug comments: http://pastebin.com/eJeWZRX1 here is the output i got in gdb:

Starting program: /usr/bin/ssh root@192.168.1.10 DEBUG:init_lib_wrapper called from gcc_init DEBUG:pid[24931]:at_init [proxychains] DLL init: proxychains-ng 4.10 DEBUG:loaded symbol 'connect' real addr 0x1d524ae04060 wrapped addr 0x1d531fb62f2a DEBUG:loaded symbol 'sendto' real addr 0x1d524ae034e0 wrapped addr 0x1d531fb63965 DEBUG:loaded symbol 'gethostbyname' real addr 0x1d52cb71a4e0 wrapped addr 0x1d531fb6356e DEBUG:loaded symbol 'getaddrinfo' real addr 0x1d52cb716260 wrapped addr 0x1d531fb635dd DEBUG:loaded symbol 'freeaddrinfo' real addr 0x1d52cb741480 wrapped addr 0x1d531fb636a2 DEBUG:loaded symbol 'gethostbyaddr' real addr 0x1d52cb71a2b0 wrapped addr 0x1d531fb63841 DEBUG:loaded symbol 'getnameinfo' real addr 0x1d52cb717dc0 wrapped addr 0x1d531fb5f344 DEBUG:loaded symbol 'close' real addr 0x1d524ae04120 wrapped addr 0x1d531fb62e61 DEBUG:[play] socks5 127.0.0.1:8888 DEBUG:getaddrinfo: 192.168.1.10 22 DEBUG:pid[24931]:proxy_getaddrinfo DEBUG:pid[24931]:mygetservbyname_r DEBUG:pid[24931]:pc_getnameinfo DEBUG:BRANCH 2 DEBUG:salen=16, sizeof=16 ssh_connect_direct: getnameinfo failed ssh: connect to host 192.168.1.10 port : No such file or directory Program exited with code 0377.

rofl0r commented 8 years ago
        if(!proxychains_resolver) {
                return true_getnameinfo(sa, salen, host, hostlen, serv, servlen, flags);
        } else {
                if(salen < sizeof(struct sockaddr_in) || SOCKFAMILY(*sa) != AF_INET)
                        return EAI_FAMILY;
                if(hostlen) {
                        pc_stringfromipv4((unsigned char*) &(SOCKADDR_2(*sa)), ip_buf);
                        if(snprintf(host, hostlen, "%s", ip_buf) >= hostlen)
                                return EAI_OVERFLOW;
                }
                if(servlen) {
                        if(snprintf(serv, servlen, "%d", ntohs(SOCKPORT(*sa))) >= servlen)
                                return EAI_OVERFLOW;
                }
        }

which branch does it take ? the if(hostlen) one ? if so we'd need to know the value of hostlen

rofl0r commented 8 years ago

also check if SOCKFAMILY(*sa) == AF_INET or AF_INET6

PDEBUG("SOCKFAMILY(*sa) == AF_INET: %d\n", SOCKFAMILY(*sa) == AF_INET);
PDEBUG("SOCKFAMILY(*sa) == AF_INET6: %d\n", SOCKFAMILY(*sa) == AF_INET6);
rofl0r commented 8 years ago

would be helpful if openssh's ssh_connect_direct() would print gai_strerror(ret) rather than just reporting unspecified failure.

shaxo commented 8 years ago

Sorry for my previous post. The branch if(hostlen) is taken. hostlen is 256, servlen changes (32 and zero). In gbd:

Breakpoint 1, pc_getnameinfo (sa=0x3e541e64030, salen=16, host=0x7f7ffffe7cb0 "192.168.1.10", hostlen=256, serv=0x7f7ffffe7db0 "22", servlen=32, flags=3) at src/libproxychains.c:484

Breakpoint 1, pc_getnameinfo (sa=0x7f7ffffe7850, salen=16, host=0x7f7ffffe7950 "127.0.0.1", hostlen=256, serv=0x0, servlen=0, flags=1) at src/libproxychains.c:484

Breakpoint 1, pc_getnameinfo (sa=0x3e2eb6acee0, salen=0, host=0x7f7ffffe6760 " l\177\177", hostlen=256, serv=0x0, servlen=0, flags=1) at src/libproxychains.c:484

get_hostfile_hostname_ipaddr: getnameinfo failed

Here is the output:

DEBUG:pid[12385]:pc_getnameinfo DEBUG:SOCKFAMILY(_sa) == AF_INET: 1 DEBUG:SOCKFAMILY(_sa) == AF_INET6: 0 DEBUG:hostlen=256 DEBUG:servlen=32 DEBUG:BRANCH 2 DEBUG:salen=16, sizeof=16 DEBUG:BRANCH 3 DEBUG:BRANCH 4 DEBUG:OUT... DEBUG:RETURN 0! DEBUG:pid[12385]:connect DEBUG:target: 192.168.1.10 DEBUG:port: 22 DEBUG:pid[12385]:connect_proxy_chain DEBUG:[play] socks5 127.0.0.1:8888

DEBUG: connect ret=0 DEBUG:pid[12385]:chain_step ... 192.168.1.10:22 DEBUG:pid[12385]:tunnel_to DEBUG:host dns ... OK DEBUG:pid[12385]:pc_getnameinfo DEBUG:SOCKFAMILY(_sa) == AF_INET: 1 DEBUG:SOCKFAMILY(_sa) == AF_INET6: 0 DEBUG:hostlen=256 DEBUG:servlen=0 DEBUG:BRANCH 2 DEBUG:salen=16, sizeof=16 DEBUG:BRANCH 3 DEBUG:BRANCH 4 DEBUG:OUT... DEBUG:RETURN 0! DEBUG:freeaddrinfo 0xce46ba17000 DEBUG:pid[12385]:proxy_freeaddrinfo DEBUG:pid[12385]:pc_getnameinfo DEBUG:SOCKFAMILY(_sa) == AF_INET: 1 DEBUG:SOCKFAMILY(_sa) == AF_INET6: 0 DEBUG:hostlen=256 DEBUG:servlen=0 DEBUG:BRANCH 2 DEBUG:salen=0, sizeof=16 DEBUG:RETURN EAI_FAMILY get_hostfile_hostname_ipaddr: getnameinfo failed

rofl0r commented 8 years ago

i've pushed new getnameinfo code, maybe it fixes the issue; although it looks very weird that salen is 0, possibly there's some memory corruption going on. also note that this time the function get_hostfile_hostname_ipaddr fails, while earlier it was ssh_connect_direct

rofl0r commented 8 years ago

from sshconnect.c:

        switch (hostaddr == NULL ? -1 : hostaddr->sa_family) {
        case -1:
                addrlen = 0;
                break;

something called get_hostfile_hostname_ipaddr with hostaddr == NULL, likely the code that checks if the ssh key is in known_hosts (check_host_key())

shaxo commented 8 years ago

No change apparently with the updated pc_getnameinfo. I'll try to have a closer look the coming week.

rkanavath commented 7 years ago

any update on this issue?

anoduck commented 3 years ago

@shaxo Issue is old and parts are more than likely not relevant anymore, needs to be closed out.

rofl0r commented 3 years ago

i don't think this should be closed until the issue is researched more thoroughly by a skilled openbsd user.