Advertisement
Lulz-Tigre

doublepulsat_detect.py

Apr 21st, 2017
217
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.54 KB | None | 0 0
  1. #!/usr/bin/python
  2.  
  3. #detect_doublepulsar.py IS Not my code
  4. # it's a tool to detect doublepulsar NSA malware in your computer,
  5. # the original code can be found in
  6. # https://github.com/countercept/doublepulsar-detection-script/blob/master/detect_doublepulsar.py
  7. # so git clone buddies
  8.  
  9. import binascii
  10. import socket
  11. import argparse
  12. import struct
  13. import threading
  14.  
  15.  
  16. # Packets
  17. negotiate_protocol_request = binascii.unhexlify("00000085ff534d4272000000001853c00000000000000000000000000000fffe00004000006200025043204e4554574f524b2050524f4752414d20312e3000024c414e4d414e312e30000257696e646f777320666f7220576f726b67726f75707320332e316100024c4d312e325830303200024c414e4d414e322e3100024e54204c4d20302e313200")
  18. session_setup_request = binascii.unhexlify("00000088ff534d4273000000001807c00000000000000000000000000000fffe000040000dff00880004110a000000000000000100000000000000d40000004b000000000000570069006e0064006f007700730020003200300030003000200032003100390035000000570069006e0064006f007700730020003200300030003000200035002e0030000000")
  19. tree_connect_request = binascii.unhexlify("00000060ff534d4275000000001807c00000000000000000000000000000fffe0008400004ff006000080001003500005c005c003100390032002e003100360038002e003100370035002e003100320038005c00490050004300240000003f3f3f3f3f00")
  20. trans2_session_setup = binascii.unhexlify("0000004eff534d4232000000001807c00000000000000000000000000008fffe000841000f0c0000000100000000000000a6d9a40000000c00420000004e0001000e000d0000000000000000000000000000")
  21.  
  22. # Arguments
  23. parser = argparse.ArgumentParser(description="Detect present of DOUBLEPULSAR implant\n\nAuthor: Luke Jennings\nWebsite: https://countercept.com\nTwitter: @countercept", formatter_class=argparse.RawTextHelpFormatter)
  24. group = parser.add_mutually_exclusive_group(required=True)
  25. group.add_argument('--ip', help='Single IP address to check')
  26. group.add_argument('--file', help='File containing a list of IP addresses to check')
  27. parser.add_argument('--timeout', help="Timeout on connection for socket in seconds", default=None)
  28. parser.add_argument('--verbose', help="Verbose output for checking of commands", action='store_true')
  29. parser.add_argument('--threads', help="Number of connection threads when checking file of IPs (default 10)", default="10")
  30.  
  31. args = parser.parse_args()
  32. ip = args.ip
  33. filename = args.file
  34. timeout = args.timeout
  35. verbose = args.verbose
  36. num_threads = int(args.threads)
  37. semaphore = threading.BoundedSemaphore(value=num_threads)
  38. print_lock = threading.Lock()
  39.  
  40.  
  41. def print_status(ip, message):
  42.     global print_lock
  43.  
  44.     with print_lock:
  45.         print "[*] [%s] %s" % (ip, message)
  46.  
  47.  
  48. def check_ip(ip):
  49.     global negotiate_protocol_request, session_setup_request, tree_connect_request, trans2_session_setup, timeout, verbose
  50.  
  51.     # Connect to socket
  52.     s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  53.     s.settimeout(float(timeout) if timeout else None)
  54.     host = ip
  55.     port = 445
  56.     s.connect((host, port))
  57.  
  58.     # Send/receive negotiate protocol request
  59.     if verbose:
  60.         print_status(ip, "Sending negotation protocol request")
  61.     s.send(negotiate_protocol_request)
  62.     s.recv(1024)
  63.  
  64.     # Send/receive session setup request
  65.     if verbose:
  66.         print_status(ip, "Sending session setup request")
  67.     s.send(session_setup_request)
  68.     session_setup_response = s.recv(1024)
  69.  
  70.     # Extract user ID from session setup response
  71.     user_id = session_setup_response[32:34]
  72.     if verbose:
  73.         print_status(ip, "User ID = %s" % struct.unpack("<H", user_id)[0])
  74.  
  75.     # Replace user ID in tree connect request packet
  76.     modified_tree_connect_request = list(tree_connect_request)
  77.     modified_tree_connect_request[32] = user_id[0]
  78.     modified_tree_connect_request[33] = user_id[1]
  79.     modified_tree_connect_request = "".join(modified_tree_connect_request)
  80.  
  81.     # Send tree connect request
  82.     if verbose:
  83.         print_status(ip, "Sending tree connect")
  84.     s.send(modified_tree_connect_request)
  85.     tree_connect_response = s.recv(1024)
  86.  
  87.     # Extract tree ID from response
  88.     tree_id = tree_connect_response[28:30]
  89.     if verbose:
  90.         print_status(ip, "Tree ID = %s" % struct.unpack("<H", tree_id)[0])
  91.  
  92.     # Replace tree ID and user ID in trans2 session setup packet
  93.     modified_trans2_session_setup = list(trans2_session_setup)
  94.     modified_trans2_session_setup[28] = tree_id[0]
  95.     modified_trans2_session_setup[29] = tree_id[1]
  96.     modified_trans2_session_setup[32] = user_id[0]
  97.     modified_trans2_session_setup[33] = user_id[1]
  98.     modified_trans2_session_setup = "".join(modified_trans2_session_setup)
  99.  
  100.     # Send trans2 sessions setup request
  101.     if verbose:
  102.         print_status(ip, "Sending trans2 session setup")
  103.     s.send(modified_trans2_session_setup)
  104.     final_response = s.recv(1024)
  105.  
  106.     s.close()
  107.  
  108.     # Check for 0x51 response to indicate DOUBLEPULSAR infection
  109.     if final_response[34] == "\x51":
  110.         with print_lock:
  111.             print "[+] [%s] DOUBLEPULSAR DETECTED!!!" % ip
  112.     else:
  113.         with print_lock:
  114.             print "[-] [%s] No presence of DOUBLEPULSAR" % ip
  115.  
  116.  
  117. def threaded_check(ip_address):
  118.     global semaphore
  119.  
  120.     try:
  121.         check_ip(ip_address)
  122.     except Exception as e:
  123.         with print_lock:
  124.             print "[ERROR] [%s] - %s" % (ip_address, e)
  125.     finally:
  126.         semaphore.release()
  127.  
  128.  
  129. if ip:
  130.     check_ip(ip)
  131. if filename:
  132.     with open(filename, "r") as fp:
  133.         for line in fp:
  134.             semaphore.acquire()
  135.             ip_address = line.strip()
  136.             t = threading.Thread(target=threaded_check, args=(ip_address,))
  137.             t.start()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement