social-engineer-toolkit/setoolkit

287 lines
9.9 KiB
Text
Raw Normal View History

2020-02-04 00:58:42 +00:00
#!/usr/bin/env python3
# coding=utf-8
2016-01-25 01:23:04 +00:00
import os
2016-07-22 16:52:36 +00:00
import re
2016-01-25 01:23:04 +00:00
import shutil
import subprocess
2016-07-22 16:52:36 +00:00
import sys
# Py2/3 compatibility
# Python3 renamed raw_input to input
try:
input = raw_input
except NameError:
pass
2016-01-25 01:23:04 +00:00
2019-02-23 21:18:18 +00:00
# import main core functionality into SET
import src.core.setcore as core
# check which operating system
operating_system = core.check_os()
if operating_system == "posix":
#
# ROOT CHECK
#
if os.geteuid() != 0:
print("\n The Social-Engineer Toolkit (SET) - by David Kennedy (ReL1K)")
print("\n Not running as root. \n\nExiting the Social-Engineer Toolkit (SET).\n")
core.exit_set()
2016-01-25 01:23:04 +00:00
# if we are running in the path no need to change
if os.path.isfile("setoolkit"):
pass
# check where we are and load default directory
2023-01-08 23:49:41 +00:00
elif os.path.isdir("/usr/local/share/setoolkit"):
2016-01-25 01:23:04 +00:00
if not os.path.isfile("setoolkit"):
2023-01-08 23:49:41 +00:00
os.chdir("/usr/local/share/setoolkit")
sys.path.append("/usr/local/share/setoolkit")
2016-01-25 01:23:04 +00:00
# check where we are and load default directory
2023-01-08 23:49:41 +00:00
elif os.path.isdir("/usr/local/share/set"):
2016-01-25 01:23:04 +00:00
if not os.path.isfile("setoolkit"):
2023-01-08 23:49:41 +00:00
os.chdir("/usr/local/share/set")
sys.path.append("/usr/local/share/set")
2016-01-25 01:23:04 +00:00
# make sure the config file is located in /etc/setoolkit
if not os.path.isdir("/etc/setoolkit/"):
os.makedirs("/etc/setoolkit/")
shutil.copyfile("src/core/config.baseline", "/etc/setoolkit/set.config")
if not os.path.isfile("/etc/setoolkit/set.config"):
shutil.copyfile("src/core/config.baseline", "/etc/setoolkit/set.config")
# here we check to ensure we have the latest version
with open("/etc/setoolkit/set.config") as fileopen:
data = fileopen.read()
2016-08-02 22:28:39 +00:00
2018-07-28 15:46:42 +00:00
if "CONFIG_VERSION=7.7.9" not in data:
2016-07-22 16:52:36 +00:00
print("[*] Overwriting old config for updates to SET. Backing up your old one in /etc/setoolkit/")
2016-01-25 01:23:04 +00:00
shutil.move("/etc/setoolkit/set.config", "/etc/setoolkit/set.config.bak")
shutil.copyfile("src/core/config.baseline", "/etc/setoolkit/set.config")
# import after config checks have been properly created
from src.core.menu import text
from src.core.update_config import update_config
2016-01-25 01:23:04 +00:00
if os.path.isfile(os.path.join(core.userconfigpath, "version.lock")):
os.remove(os.path.join(core.userconfigpath, "version.lock"))
2016-07-21 11:23:56 +00:00
2016-01-25 01:23:04 +00:00
# check directory and make it
if not os.path.isdir("src/logs/"):
os.makedirs("src/logs/")
# check set logfile
if not os.path.isfile("src/logs/set_logfile.log"):
# create new log
with open("src/logs/set_logfile.log", "w") as filewrite:
filewrite.write("")
2016-01-25 01:23:04 +00:00
# use ~/.set
if operating_system == "posix":
if not os.path.isdir(core.userconfigpath):
2016-01-25 01:23:04 +00:00
# create the set variables
os.makedirs(core.userconfigpath)
2016-01-25 01:23:04 +00:00
# if for some reason it failed to pull the path
userdir = os.path.join(os.path.expanduser('~'), '.set')
if not os.path.isdir(userdir):
os.makedirs(userdir)
if not os.path.isdir(os.path.join(core.userconfigpath, "reports")):
os.makedirs(os.path.join(core.userconfigpath, "reports"))
2016-01-25 01:23:04 +00:00
# check to see if we have python-pycrypto
try:
from Crypto.Cipher import AES
except ImportError:
2016-07-22 16:52:36 +00:00
print("[!] The python-pycrypto python module not installed. You will lose the ability to use multi-pyinjector.")
2016-01-25 01:23:04 +00:00
pass
#
2016-01-25 01:23:04 +00:00
# The Social-Engineer Toolkit (SET) #
# Written by: David Kennedy (ReL1K) #
#
2016-01-25 01:23:04 +00:00
#
# this is the main menu structure for SET
# main menu
# update the main config per load
update_config()
# chmod routine
if operating_system == "posix":
# change permissions if nix
subprocess.Popen("chmod +x seautomate;"
"chmod +x set-update;"
"chmod +x setup.py;"
"chmod +x set-proxy;"
"chmod +x src/payloads/ratte/ratteserver;"
"chmod +x src/payloads/set_payloads/listener.py",
stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
2016-01-25 01:23:04 +00:00
2016-07-22 16:52:36 +00:00
dns = core.check_config("DNS_SERVER=")
2016-01-25 01:23:04 +00:00
if dns.lower() == "on":
Move the DNS server into its own module. Refactor how to call to it. This is a relatively large commit because it refactors SET's interface to the build-in DNS server it runs. Instead of a block of code inside of the `setcore.py` file, a new module called `minifakedns` is added, which houses all of the DNS-related code. Note that this commit *only* refactors the DNS interface and its internals, it does not actually fix the exception caused by receiving some DNS query, nor does it complete the work required to set parameters for the DNS server, such as which IP address it should respond with. It is just intended to make these changes easier to introduce moving forward in upcoming chunks of work. This replaces the `core.start_dns()` function with a new helper, whose full path is `src.core.minifakedns.start_dns_server()`. The previous implementation assumed the DNS server would be run from the main thread, and thus have access to SIGINT, but this was never actually possible because a `KeyboardInterrupt` was actually intercepted by SET itself, before the DNS server code ever got to see it. This means that the DNS server would never shut down cleanly. This implementation changes that by using a simplistic sentinel value (called `stop_flag`) that can be set as an instance attribute on the new `MiniFakeDNS` object. When the sentinel value is `True`, the DNS server thread will exit its listening loop. Another change this introduces is the fact that, due to this new design, the DNS server stops when `core.cleanup_routine()` is run. And, as a note about that, this was running twice, once upon *startup* rather than when SET shut down. This looked like a bug to me, and it was causing problems for this DNS server design, so I removed that extra call and performed some simplistic tests of various SET functionality to make sure everything still works. (It seems fine, but might warrant a second look.) Finally, note that this commit breaks Python 2 compatibility due to the use of a context manager handling the UDP socket. Given that the DNS server was not really functional for some period of time before I started looking at it more closely, the fact that Python 2 is officially end-of-life'd (as of January 2020), the relative complexity of writing a Python 2 and Python 3 implementation, and the fact that many comments elsewhere in the SET codebase all seem to be nudging towards a Python 3 compatible upgrade, I am choosing to drop support for Python 2 in my own patches, unless there is some considerable objection.
2020-03-12 23:25:28 +00:00
import src.core.minifakedns
from src.core.setcore import detect_public_ip
src.core.minifakedns.start_dns_server(detect_public_ip())
2016-01-25 01:23:04 +00:00
# remove old files
for root, dirs, files in os.walk(core.userconfigpath):
2016-01-25 01:23:04 +00:00
for f in files:
try:
match = re.search(".svn|entries|all-wcprops|props|text-base|prop-base|tmp", f)
2016-01-25 01:23:04 +00:00
if not match:
os.unlink(os.path.join(root, f))
# if they are being used then ignore
except:
pass
# loop through all the directories
for d in dirs:
try:
match = re.search(".svn|entries|all-wcprops|props|text-base|prop-base|tmp", d)
2016-01-25 01:23:04 +00:00
if not match:
shutil.rmtree(os.path.join(root, d))
except:
pass
# if there isn't a set_config.py file yet, create one
if not os.path.isfile("/etc/setoolkit/set_config.py"):
update_config()
2016-07-22 16:52:36 +00:00
define_version = core.get_version()
2016-01-25 01:23:04 +00:00
# create the set.options routine
with open(os.path.join(core.userconfigpath, "set.options"), "w") as filewrite:
filewrite.write("{This is the main SET configuration file for all options used in SET}\n")
2016-01-25 01:23:04 +00:00
try:
# Remove old Signed_Updates
if os.path.isfile(os.path.join(core.userconfigpath, "Signed_Update.jar")):
os.remove(os.path.join(core.userconfigpath, "Signed_Update.jar"))
2016-01-25 01:23:04 +00:00
# initial user menu
2016-01-25 01:23:04 +00:00
if not os.path.isfile("src/agreement4"):
with open("readme/LICENSE") as fileopen:
for line in fileopen:
print((line.rstrip()))
2016-07-28 23:16:24 +00:00
print("{0}The Social-Engineer Toolkit is designed purely"
" for good and not evil. If you are planning on "
"using this tool for malicious purposes that are "
"not authorized by the company you are performing "
"assessments for, you are violating the terms of "
"service and license of this toolset. By hitting "
"yes (only one time), you agree to the terms of "
"service and that you will only use this tool for "
2016-07-28 23:16:24 +00:00
"lawful purposes only.{1}".format(core.bcolors.RED, core.bcolors.ENDC))
print(core.bcolors.GREEN)
2016-07-22 16:52:36 +00:00
choice = input("\nDo you agree to the terms of service [y/n]: ")
2016-01-25 01:23:04 +00:00
choice += " " # b/c method below
if choice[0].lower() == "y":
with open("src/agreement4", "w") as filewrite:
filewrite.write("user accepted")
2016-07-22 16:52:36 +00:00
print(core.bcolors.ENDC)
2016-01-25 01:23:04 +00:00
else:
print(core.bcolors.ENDC + "[!] Exiting the Social-Engineer Toolkit, have a nice day." + core.bcolors.ENDC)
2016-01-25 01:23:04 +00:00
sys.exit()
while True:
2016-07-22 16:52:36 +00:00
core.show_banner(define_version, '1')
show_main_menu = core.create_menu(text.main_text, text.main_menu)
2016-01-25 01:23:04 +00:00
# special case of list item 99
2016-07-22 16:52:36 +00:00
print('\n 99) Exit the Social-Engineer Toolkit\n')
2016-01-25 01:23:04 +00:00
# main core menu
2016-07-22 16:52:36 +00:00
main_menu_choice = (input(core.setprompt("0", "")))
2016-01-25 01:23:04 +00:00
# funny
if main_menu_choice == "hugs":
core.print_warning("Have you given someone a hug today? Remember a hug can change the world.")
pause = input("\nPlease give someone a hug then press {return} to continue.")
2016-01-25 01:23:04 +00:00
# funny2
if main_menu_choice == "freehugs":
2016-07-22 16:52:36 +00:00
core.print_warning("HUGS ARE ALWAYS FREE! NEVER CHARGE! ALWAYS HUG.")
pause = input("\nDo not press return until giving someone a hug.")
2016-01-25 01:23:04 +00:00
# funny3
if main_menu_choice == "derbycon":
2017-07-22 21:09:48 +00:00
core.print_warning(core.bcolors.BOLD + "YAYYYYYYYYYYYYYYYYYYYYYY DerbyCon.\n\nDerbyCon 7.0 'Legacy' -- September 22th - 24th 2017" + core.bcolors.ENDC)
pause = input(core.bcolors.BOLD + "\nDon't miss it! Sep 23 - Sep 25th! Press {return} to continue." + core.bcolors.ENDC)
2016-01-25 01:23:04 +00:00
# rance
if main_menu_choice == "rance":
core.print_warning(core.bcolors.BOLD + "We miss you buddy. David Jones (Rance) changed a lot of us and you'll always be apart of our lives (and SET). Fuck Cancer." + core.bcolors.ENDC)
2016-07-22 16:52:36 +00:00
pause = input("Press {return} to continue.")
2016-01-25 01:23:04 +00:00
2016-06-25 21:16:27 +00:00
# cavs
if main_menu_choice == "cavs":
core.print_warning(core.bcolors.BOLD + "2015-2016 CHAMPS BABY!!! C l e e e e e e v eeee l a a n n d d d d d d d d d d d " + core.bcolors.ENDC)
2016-07-22 16:52:36 +00:00
pause = input("Press {return} to continue.")
2016-06-25 21:16:27 +00:00
2016-01-25 01:23:04 +00:00
# quit out
if main_menu_choice == 'exit' or main_menu_choice == "99" or main_menu_choice == "quit":
2016-07-22 16:52:36 +00:00
core.exit_set()
2016-01-25 01:23:04 +00:00
# cleans up stale processes from SET
try:
# kill anything python running on 80
2016-07-22 16:52:36 +00:00
core.kill_proc("80", "python")
2016-01-25 01:23:04 +00:00
# kill anything on 443 ruby which is generally a rogue listener
2016-07-22 16:52:36 +00:00
core.kill_proc("443", "ruby")
2016-01-25 01:23:04 +00:00
except:
pass
# load set
if main_menu_choice == '1':
2016-02-15 14:16:19 +00:00
try:
2016-07-22 16:52:36 +00:00
core.module_reload(src.core.set)
2016-02-15 14:24:31 +00:00
except:
2016-02-15 14:16:19 +00:00
import src.core.set
2016-01-25 01:23:04 +00:00
# load fasttrack
if main_menu_choice == '2':
2016-02-15 14:16:19 +00:00
try:
2016-07-22 16:52:36 +00:00
core.module_reload(src.core.fasttrack)
2016-02-15 14:24:31 +00:00
except:
2016-02-15 14:16:19 +00:00
import src.core.fasttrack
2016-01-25 01:23:04 +00:00
# third party modules
if main_menu_choice == '3':
2016-02-15 14:16:19 +00:00
try:
2016-07-22 16:52:36 +00:00
core.module_reload(src.core.module_handler)
2016-02-15 14:24:31 +00:00
except:
2016-02-15 14:16:19 +00:00
import src.core.module_handler
2016-01-25 01:23:04 +00:00
# update set
if main_menu_choice == '4':
2016-07-22 16:52:36 +00:00
core.update_set()
2016-01-25 01:23:04 +00:00
# credits
if main_menu_choice == '5':
update_config()
# update config
if main_menu_choice == '6':
2016-07-22 16:52:36 +00:00
core.help_menu()
2016-01-25 01:23:04 +00:00
# handle keyboard interrupts
except KeyboardInterrupt:
2016-07-28 23:16:24 +00:00
print(("\n\nThank you for {0}shopping{1} with the Social-Engineer Toolkit."
"\n\nHack the Gibson...and remember...hugs are worth more "
"than handshakes.\n".format(core.bcolors.RED, core.bcolors.ENDC)))
2016-01-25 01:23:04 +00:00
# handle exceptions
2018-07-29 16:36:45 +00:00
except Exception as error:
core.log(error)
print("\n\n[!] Something went wrong, printing the error: " + str(error))
2016-01-25 01:23:04 +00:00
# cleanup routine
2016-07-22 16:52:36 +00:00
core.cleanup_routine()