Repository restructuring

This commit is contained in:
2026-04-30 19:53:18 +02:00
parent 31af1f4423
commit f233fe8264
98 changed files with 4216 additions and 1392 deletions

View File

@@ -1,12 +0,0 @@
import os
import sys
__doc__ = __doc__ or ""
__all__ = [
"util", "fileserver", "xss_handler", "rev_shell",
"xp_cmdshell", "dnsserver", "sqli", "smtpserver",
"upload_file", "pcap_file_extract"
]
inc_dir = os.path.dirname(os.path.realpath(__file__))
sys.path.append(inc_dir)

View File

View File

View File

Binary file not shown.

View File

Binary file not shown.

View File

@@ -125,6 +125,7 @@ TIP_DOCKER_ROOTLESS="In rootless mode privilege escalation to root will not be p
TIP_CVE_2019_5021="Alpine linux version 3.3.x-3.5.x accidentally allow users to login as root with a blank password, if we have command execution in the container we can become root using su root" TIP_CVE_2019_5021="Alpine linux version 3.3.x-3.5.x accidentally allow users to login as root with a blank password, if we have command execution in the container we can become root using su root"
TIP_CVE_2019_13139="Docker versions before 18.09.4 are vulnerable to a command execution vulnerability when parsing URLs" TIP_CVE_2019_13139="Docker versions before 18.09.4 are vulnerable to a command execution vulnerability when parsing URLs"
TIP_CVE_2019_5736="Docker versions before 18.09.2 are vulnerable to a container escape by overwriting the runC binary" TIP_CVE_2019_5736="Docker versions before 18.09.2 are vulnerable to a container escape by overwriting the runC binary"
TIP_CVE_2025_9074="Docker Desktop versions between 4.25 to 4.44.2 on Windows and MacOS are vulnerable to a container escape via a malicious image. See https://github.com/PtechAmanja/CVE-2025-9074-Docker-Desktop-Container-Escape"
TIP_SYS_MODULE="Giving the container the SYS_MODULE privilege allows for kernel modules to be mounted. Using this, a malicious module can be used to execute code as root on the host." TIP_SYS_MODULE="Giving the container the SYS_MODULE privilege allows for kernel modules to be mounted. Using this, a malicious module can be used to execute code as root on the host."
@@ -378,7 +379,7 @@ userCheck() {
groups=$(groups| sed "s/\($DANGEROUS_GROUPS\)/${LG}${EX}&${NC}${DG}/g") groups=$(groups| sed "s/\($DANGEROUS_GROUPS\)/${LG}${EX}&${NC}${DG}/g")
printStatus "$groups" "None" printStatus "$groups" "None"
if ! [ $isUserRoot ]; then if ! [ "$isUserRoot" ]; then
printQuestion "Sudo ...................." printQuestion "Sudo ...................."
if [ -x "$(command -v sudo)" ]; then if [ -x "$(command -v sudo)" ]; then
if sudo -n -l 2>/dev/null; then if sudo -n -l 2>/dev/null; then
@@ -631,7 +632,7 @@ containerPrivileges() {
fi fi
} }
containerExploits() { containerExploitAlpine() {
# If we are on an alpine linux disto check for CVE20195021 # If we are on an alpine linux disto check for CVE20195021
if [ -f "/etc/alpine-release" ]; then if [ -f "/etc/alpine-release" ]; then
alpineVersion=$(cat /etc/alpine-release) alpineVersion=$(cat /etc/alpine-release)
@@ -648,6 +649,62 @@ containerExploits() {
fi fi
} }
containerExploitAPI() {
# Check if docker api is exposed (including CVE-2025-9074)
api_available="0"
api_host=""
api_hosts="192.168.65.7:2375 172.17.0.1:2375"
printQuestion "Docker API exposed ......"
if [ -x "$(command -v curl)" ] || [ -x "$(command -v wget)" ]; then
for host in $api_hosts; do
if [ -x "$(command -v curl)" ]; then
if curl -s --connect-timeout 1 "http://$host/version" >/dev/null 2>&1; then
api_available="1"
api_host="$host"
break
fi
else
if wget -O - "http://$host/version" --connect-timeout=1 --tries=1 -q >/dev/null 2>&1; then
api_available="1"
api_host="$host"
break
fi
fi
done
if [ "$api_available" = "0" ]; then
printNo
return
fi
printSuccess "Yes ($api_host)"
printQuestion "└── CVE-2025-9074 ......."
if [ -x "$(command -v curl)" ]; then
if curl -s --connect-timeout 1 "http://$api_host/containers/json" >/dev/null 2>&1; then
printYesEx
printTip "$TIP_CVE_2025_9074"
else
printNo
fi
elif wget -O - "http://$api_host/containers/json" --connect-timeout=1 --tries=1 -q >/dev/null 2>&1; then
printYesEx
printTip "$TIP_CVE_2025_9074"
else
printNo
fi
else
printError "Unknown (curl/wget not installed)"
fi
}
containerExploits() {
containerExploitAlpine
containerExploitAPI
}
enumerateContainers() { enumerateContainers() {
printSection "Enumerating Containers" printSection "Enumerating Containers"

View File

File diff suppressed because one or more lines are too long

View File

@@ -1,7 +1,7 @@
#!/bin/bash #!/bin/bash
# #
# Copyright (c) 2016-2023, https://github.com/mzet- # Copyright (c) 2016-2026, https://github.com/mzet-
# #
# linux-exploit-suggester.sh comes with ABSOLUTELY NO WARRANTY. # linux-exploit-suggester.sh comes with ABSOLUTELY NO WARRANTY.
# This is free software, and you are welcome to redistribute it # This is free software, and you are welcome to redistribute it
@@ -9,7 +9,7 @@
# file for usage of this software. # file for usage of this software.
# #
VERSION=v1.1 VERSION=v1.2
# bash colors # bash colors
#txtred="\e[0;31m" #txtred="\e[0;31m"
@@ -852,6 +852,18 @@ author: wbowling (orginal exploit author); bcoles (author of exploit update at '
EOF EOF
) )
EXPLOITS[((n++))]=$(cat <<EOF
Name: ${txtgrn}[CVE-2018-14634]${txtrst} Mutagen Astronomy
Reqs: pkg=linux-kernel,x86_64,ver>=4.14.1,ver<=4.14.54
Tags: debian=8,RHEL=6|7
Rank: 1
analysis-url: https://www.qualys.com/2018/09/25/cve-2018-14634/mutagen-astronomy-integer-overflow-linux-create_elf_tables-cve-2018-14634.txt
exploit-db: 45516
Comments: systems with less than 32GB of RAM are unlikely to be affected by this issue
author: Qualys
EOF
)
EXPLOITS[((n++))]=$(cat <<EOF EXPLOITS[((n++))]=$(cat <<EOF
Name: ${txtgrn}[CVE-2018-18955]${txtrst} subuid_shell Name: ${txtgrn}[CVE-2018-18955]${txtrst} subuid_shell
Reqs: pkg=linux-kernel,ver>=4.15,ver<=4.19.2,CONFIG_USER_NS=y,sysctl:kernel.unprivileged_userns_clone==1,cmd:[ -u /usr/bin/newuidmap ],cmd:[ -u /usr/bin/newgidmap ] Reqs: pkg=linux-kernel,ver>=4.15,ver<=4.19.2,CONFIG_USER_NS=y,sysctl:kernel.unprivileged_userns_clone==1,cmd:[ -u /usr/bin/newuidmap ],cmd:[ -u /usr/bin/newgidmap ]
@@ -916,6 +928,18 @@ author: chompie1337
EOF EOF
) )
EXPLOITS[((n++))]=$(cat <<EOF
Name: ${txtgrn}[CVE-2021-3493]${txtrst} Ubuntu OverlayFS
Reqs: pkg=linux-kernel,ver>=3.13,ver<5.14,x86_64
Tags: ubuntu=(14.04|16.04|18.04|20.04|20.10)
Rank: 1
analysis-url: https://ssd-disclosure.com/ssd-advisory-overlayfs-pe/
src-url: https://raw.githubusercontent.com/briskets/CVE-2021-3493/refs/heads/main/exploit.c
Comments: Only Ubuntu is affected.
author: ssd-disclosure
EOF
)
EXPLOITS[((n++))]=$(cat <<EOF EXPLOITS[((n++))]=$(cat <<EOF
Name: ${txtgrn}[CVE-2021-22555]${txtrst} Netfilter heap out-of-bounds write Name: ${txtgrn}[CVE-2021-22555]${txtrst} Netfilter heap out-of-bounds write
Reqs: pkg=linux-kernel,ver>=2.6.19,ver<=5.12-rc6 Reqs: pkg=linux-kernel,ver>=2.6.19,ver<=5.12-rc6
@@ -937,11 +961,25 @@ Tags: ubuntu=(20.04|21.04),debian=11
Rank: 1 Rank: 1
analysis-url: https://dirtypipe.cm4all.com/ analysis-url: https://dirtypipe.cm4all.com/
src-url: https://haxx.in/files/dirtypipez.c src-url: https://haxx.in/files/dirtypipez.c
bof-url: https://raw.githubusercontent.com/The-Z-Labs/bof-launcher/refs/heads/main/bofs/src/dirtypipe.zig
Comments: BOF version o the exploit available to be run with bof-launcher.
exploit-db: 50808 exploit-db: 50808
author: blasty (original exploit author: Max Kellermann) author: blasty (original exploit author: Max Kellermann)
EOF EOF
) )
EXPLOITS[((n++))]=$(cat <<EOF
Name: ${txtgrn}[CVE-2022-0995]${txtrst} watch_queue
Reqs: pkg=linux-kernel,ver>=5.8,ver<5.16.5,x86_64
Tags: ubuntu=21.10{kernel:5.13.0.37-generic}
Rank: 1
analysis-url: https://github.com/Bonfee/CVE-2022-0995
src-url: https://github.com/Bonfee/CVE-2022-0995/archive/refs/heads/main.zip
Comments: Not 100% reliable, may need to be run a couple of times. It rare cases it may panic the kernel.
author: Bonfee (vulnerability discovery and PoC: Jann Horn)
EOF
)
EXPLOITS[((n++))]=$(cat <<EOF EXPLOITS[((n++))]=$(cat <<EOF
Name: ${txtgrn}[CVE-2022-2586]${txtrst} nft_object UAF Name: ${txtgrn}[CVE-2022-2586]${txtrst} nft_object UAF
Reqs: pkg=linux-kernel,ver>=3.16,CONFIG_USER_NS=y,sysctl:kernel.unprivileged_userns_clone==1 Reqs: pkg=linux-kernel,ver>=3.16,CONFIG_USER_NS=y,sysctl:kernel.unprivileged_userns_clone==1
@@ -967,6 +1005,30 @@ author: vulnerability discovery: EDG Team from NCC Group; Author of this exploit
EOF EOF
) )
EXPLOITS[((n++))]=$(cat <<EOF
Name: ${txtgrn}[CVE-2023-0386]${txtrst} OverlayFS suid smuggle
Reqs: pkg=linux-kernel,ver>=5.11,ver<=6.2,CONFIG_USER_NS=y,sysctl:kernel.unprivileged_userns_clone==1
Tags: ubuntu=22.04.1{kernel:5.15.0-57-generic}
Rank: 1
analysis-url: https://securitylabs.datadoghq.com/articles/overlayfs-cve-2023-0386/
src-url: https://github.com/xkaneiki/CVE-2023-0386/archive/refs/heads/main.zip
Comments: CONFIG_USER_NS needs to be enabled && kernel.unprivileged_userns_clone=1 required
author: vuln discovery: Miklos Szeredi; exploit author: xkaneiki
EOF
)
EXPLOITS[((n++))]=$(cat <<EOF
Name: ${txtgrn}[CVE-2024-1086]${txtrst} double-free in nf_tables
Reqs: pkg=linux-kernel,x86_64,ver>=5.14,ver<=6.6,CONFIG_NF_TABLES=y,CONFIG_USER_NS=y,sysctl:kernel.unprivileged_userns_clone==1
Tags: debian=12,ubuntu=22.04
Rank: 1
analysis-url: https://pwning.tech/nftables/
src-url: https://github.com/Notselwyn/CVE-2024-1086/archive/refs/heads/main.zip
Comments: CONFIG_USER_NS and CONFIG_NF_TABLES need to be enabled && kernel.unprivileged_userns_clone=1 required
author: notselwyn
EOF
)
############ USERSPACE EXPLOITS ########################### ############ USERSPACE EXPLOITS ###########################
n=0 n=0
@@ -1539,6 +1601,17 @@ author: berdav
EOF EOF
) )
EXPLOITS_USERSPACE[((n++))]=$(cat <<EOF
Name: ${txtgrn}[CVE-2025-32463]${txtrst} sudo-chwoot
Reqs: pkg=sudo,ver>=1.9.14,ver<=1.9.17
Tags: ubuntu=24.04.1,fedora=41
Rank: 1
analysis-url: https://www.stratascale.com/resource/cve-2025-32463-sudo-chroot-elevation-of-privilege/
src-url: https://github.com/mirchr/CVE-2025-32463-sudo-chwoot/archive/refs/heads/main.zip
author: Rich Mirch
EOF
)
########################################################### ###########################################################
## security related HW/kernel features ## security related HW/kernel features
########################################################### ###########################################################
@@ -1828,11 +1901,11 @@ EOF
version() { version() {
echo "linux-exploit-suggester "$VERSION", mzet, https://z-labs.eu, March 2019" echo "linux-exploit-suggester $VERSION by mzet"
} }
usage() { usage() {
echo "LES ver. $VERSION (https://github.com/mzet-/linux-exploit-suggester) by @_mzet_" echo "LES ver. $VERSION (https://github.com/mzet-/linux-exploit-suggester) by mzet"
echo echo
echo "Usage: linux-exploit-suggester.sh [OPTIONS]" echo "Usage: linux-exploit-suggester.sh [OPTIONS]"
echo echo
@@ -2626,6 +2699,7 @@ for EXP_TEMP in "${SORTED_EXPLOITS[@]}"; do
EXPLOIT_DB=$(echo "$EXP" | grep "exploit-db: " | awk '{print $2}') EXPLOIT_DB=$(echo "$EXP" | grep "exploit-db: " | awk '{print $2}')
analysis_url=$(echo "$EXP" | grep "analysis-url: " | awk '{print $2}') analysis_url=$(echo "$EXP" | grep "analysis-url: " | awk '{print $2}')
ext_url=$(echo "$EXP" | grep "ext-url: " | awk '{print $2}') ext_url=$(echo "$EXP" | grep "ext-url: " | awk '{print $2}')
bof_url=$(echo "$EXP" | grep "bof-url: " | awk '{print $2}')
comments=$(echo "$EXP" | grep "Comments: " | cut -d' ' -f 2-) comments=$(echo "$EXP" | grep "Comments: " | cut -d' ' -f 2-)
reqs=$(echo "$EXP" | grep "Reqs: " | cut -d' ' -f 2) reqs=$(echo "$EXP" | grep "Reqs: " | cut -d' ' -f 2)
@@ -2679,6 +2753,7 @@ for EXP_TEMP in "${SORTED_EXPLOITS[@]}"; do
[ -n "$tags" ] && echo -e " Tags: $tags" [ -n "$tags" ] && echo -e " Tags: $tags"
echo -e " Download URL: $src_url" echo -e " Download URL: $src_url"
[ -n "$ext_url" ] && echo -e " ext-url: $ext_url" [ -n "$ext_url" ] && echo -e " ext-url: $ext_url"
[ -n "$bof_url" ] && echo -e " bof-url: $bof_url"
[ -n "$comments" ] && echo -e " Comments: $comments" [ -n "$comments" ] && echo -e " Comments: $comments"
# handles --full filter option # handles --full filter option

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

@@ -58,6 +58,8 @@ CALL :ColorLine " %E%41mWinPEAS should be used for authorized penetration test
CALL :ColorLine " %E%41mAny misuse of this software will not be the responsibility of the author or of any other collaborator.%E%40;97m" CALL :ColorLine " %E%41mAny misuse of this software will not be the responsibility of the author or of any other collaborator.%E%40;97m"
CALL :ColorLine " %E%41mUse it at your own networks and/or with the network owner's permission.%E%40;97m" CALL :ColorLine " %E%41mUse it at your own networks and/or with the network owner's permission.%E%40;97m"
ECHO. ECHO.
ECHO. [i] Best Linux PE and hardening course: https://hacktricks-training.com/courses/lhe/
ECHO.
:SystemInfo :SystemInfo
CALL :ColorLine "%E%32m[*]%E%97m BASIC SYSTEM INFO" CALL :ColorLine "%E%32m[*]%E%97m BASIC SYSTEM INFO"
@@ -71,7 +73,7 @@ CALL :T_Progress 2
:ListHotFixes :ListHotFixes
where wmic >nul 2>&1 where wmic >nul 2>&1
if %errorlevel% equ 0 ( if %errorlevel% equ 0 (
wmic qfe get Caption,Description,HotFixID,InstalledOn | more wmic qfe get Caption,Description,HotFixID,InstalledOn
) else ( ) else (
powershell -command "Get-HotFix | Format-Table -AutoSize" powershell -command "Get-HotFix | Format-Table -AutoSize"
) )
@@ -204,7 +206,7 @@ CALL :T_Progress 1
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 where wmic >nul 2>&1
if %errorlevel% equ 0 ( 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
) else ( ) else (
powershell -command "Get-CimInstance -Namespace root/SecurityCenter2 -ClassName AntiVirusProduct | Select-Object -ExpandProperty displayName" powershell -command "Get-CimInstance -Namespace root/SecurityCenter2 -ClassName AntiVirusProduct | Select-Object -ExpandProperty displayName"
) )
@@ -238,7 +240,7 @@ CALL :ColorLine " %E%33m[+]%E%97m MOUNTED DISKS"
ECHO. [i] Maybe you find something interesting ECHO. [i] Maybe you find something interesting
where wmic >nul 2>&1 where wmic >nul 2>&1
if %errorlevel% equ 0 ( if %errorlevel% equ 0 (
wmic logicaldisk get caption | more wmic logicaldisk get caption
) else ( ) else (
fsutil fsinfo drives fsutil fsinfo drives
) )
@@ -405,7 +407,7 @@ 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, SeDebugPrivilege
ECHO. [?] https://book.hacktricks.wiki/en/windows-hardening/windows-local-privilege-escalation/index.html#users--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"
@@ -670,7 +672,7 @@ if "%long%" == "true" (
ECHO. ECHO.
where wmic >nul 2>&1 where wmic >nul 2>&1
if !errorlevel! equ 0 ( if !errorlevel! equ 0 (
for /f %%x in ('wmic logicaldisk get name ^| more') do ( for /f %%x in ('wmic logicaldisk get name') do (
set tdrive=%%x set tdrive=%%x
if "!tdrive:~1,2!" == ":" ( if "!tdrive:~1,2!" == ":" (
%%x %%x

View File

Binary file not shown.

View File

Binary file not shown.

0
win/PetitPotam.py → tools/exploits/PetitPotam.py Normal file → Executable file
View File

View File

@@ -5,8 +5,6 @@ import os
import re import re
import sys import sys
import pty import pty
import util
import upload_file
import time import time
import random import random
import threading import threading
@@ -16,6 +14,9 @@ import select
import argparse import argparse
import signal import signal
from hackingscripts.utils import util
from hackingscripts.tools.misc import upload_file
try: try:
import SocketServer import SocketServer
except ImportError: except ImportError:

View File

118
tools/misc/tcp_template.py Normal file
View File

@@ -0,0 +1,118 @@
#!/usr/bin/env python
import re
import sys
import json
import argparse
import urllib.parse
def generate_template(listen_address, listen_port, remote_host, remote_port):
# we could all need that
imports = [
"os",
"socket",
"threading"
]
partial_imports = {
"hackingscripts.utils": ["util"],
"hackingscripts.utils.packeter": ["Packer", "Parser"]
}
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))
return f"""#!/usr/bin/env python
#
# THE BASE OF THIS FILE WAS AUTOMATICALLY GENERATED BY {' '.join(sys.argv)}
# For more information, visit: https://git.romanh.de/Roman/HackingScripts
#
{imports}
BUFFER_SIZE = 4096
class Packet:
def __init__(self):
pass
@staticmethod
def from_data(data):
packet = Packet()
parser = Parser(data)
# TODO: auto-generated method stub
return packet
def pack(self):
buf = Packer()
# TODO: auto-generated method stub
return buf.get()
def forward(source, destination):
try:
while True:
data = source.recv(BUFFER_SIZE)
if not data:
break
# TODO: Parse / Manipulate packet
# packet = Packet.from_data(data)
# repacked = packet.pack()
destination.sendall(data)
except Exception:
pass
finally:
source.close()
destination.close()
def handle_client(client_socket, remote_host, remote_port):
try:
remote_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
remote_socket.connect((remote_host, remote_port))
except Exception as e:
print(f"Failed to connect to remote: {{e}}")
client_socket.close()
return
# Start bidirectional forwarding
threading.Thread(target=forward, args=(client_socket, remote_socket), daemon=True).start()
threading.Thread(target=forward, args=(remote_socket, client_socket), daemon=True).start()
def start_proxy(local_host, local_port, remote_host, remote_port):
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind((local_host, local_port))
server.listen(100)
print(f"[*] Forwarding from {{local_host}}:{{local_port}} to {{remote_host}}:{{remote_port}}")
while True:
client_socket, addr = server.accept()
print(f"[+] Connection from {{addr[0]}}:{{addr[1]}}")
threading.Thread(
target=handle_client,
args=(client_socket, remote_host, remote_port),
daemon=True
).start()
if __name__ == "__main__":
start_proxy({repr(listen_address)}, {listen_port}, {repr(remote_host)}, {remote_port})
"""
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="Exploit Template for tcp application attacks",
formatter_class=argparse.RawTextHelpFormatter
)
parser.add_argument("la", type=str, help="Listen Address")
parser.add_argument("lp", type=int, help="Listen Port", choices=range(1,65535+1))
parser.add_argument("rh", type=str, help="Remote Host")
parser.add_argument("rp", type=int, help="Remote Port", choices=range(1,65535+1))
args = parser.parse_args()
template = generate_template(args.la, args.lp, args.rh, args.rp)
print(template)

View File

@@ -2,9 +2,10 @@
import sys import sys
import os import os
import util
import argparse import argparse
from hackingscripts.utils import util
def serve_file(listen_sock, path, forever=False): def serve_file(listen_sock, path, forever=False):
try: try:
while True: while True:

View File

@@ -17,7 +17,8 @@ def generate_template(base_url, features):
partial_imports = { partial_imports = {
"bs4": ["BeautifulSoup"], "bs4": ["BeautifulSoup"],
"hackingscripts": ["util", "rev_shell"], "hackingscripts.utils": ["util"],
"hackingscripts.tools.exploits": ["rev_shell"],
"urllib3.exceptions": ["InsecureRequestWarning"] "urllib3.exceptions": ["InsecureRequestWarning"]
} }

View File

0
dnsserver.py → tools/server/dnsserver.py Normal file → Executable file
View File

0
ftpserver.py → tools/server/ftpserver.py Normal file → Executable file
View File

0
smtpserver.py → tools/server/smtpserver.py Normal file → Executable file
View File

0
sshserver.py → tools/server/sshserver.py Normal file → Executable file
View File

View File

@@ -1,14 +1,15 @@
#!/usr/bin/env python #!/usr/bin/env python
import argparse import argparse
from http.server import BaseHTTPRequestHandler, HTTPServer
from urllib.parse import urlparse
import threading import threading
import requests import requests
import time import time
import os import os
import ssl import ssl
import util from http.server import BaseHTTPRequestHandler, HTTPServer
from urllib.parse import urlparse
from hackingscripts.utils import util
from hackingscripts.tools.server.xss_handler import generate_payload as generate_xss_payload
class FileServerRequestHandler(BaseHTTPRequestHandler): class FileServerRequestHandler(BaseHTTPRequestHandler):
@@ -357,7 +358,6 @@ 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 = generate_xss_payload(payload_type, file_server.get_full_url("/exfiltrate", ip_address)) xss = generate_xss_payload(payload_type, file_server.get_full_url("/exfiltrate", ip_address))
file_server.addFile("/xss", xss) file_server.addFile("/xss", xss)

View File

@@ -39,26 +39,25 @@ get_latest_version () {
} }
echo "Updating scripts…" echo "Updating scripts…"
download https://raw.githubusercontent.com/initstring/uptux/master/uptux.py uptux.py download https://raw.githubusercontent.com/initstring/uptux/master/uptux.py payloads/linux/uptux.py
download https://raw.githubusercontent.com/pentestmonkey/unix-privesc-check/master/upc.sh unix-privesc-check.sh download https://raw.githubusercontent.com/pentestmonkey/unix-privesc-check/master/upc.sh payloads/linux/unix-privesc-check.sh
download https://github.com/DominicBreuker/pspy/releases/latest/download/pspy64 pspy64 download https://github.com/DominicBreuker/pspy/releases/latest/download/pspy64 payloads/linux/pspy64
download https://github.com/DominicBreuker/pspy/releases/latest/download/pspy32 pspy download https://github.com/DominicBreuker/pspy/releases/latest/download/pspy32 payloads/linux/pspy
download https://raw.githubusercontent.com/flozz/p0wny-shell/master/shell.php p0wny-shell.php download https://raw.githubusercontent.com/flozz/p0wny-shell/master/shell.php payloads/web/p0wny-shell.php
download https://raw.githubusercontent.com/diego-treitos/linux-smart-enumeration/master/lse.sh lse.sh download https://raw.githubusercontent.com/diego-treitos/linux-smart-enumeration/master/lse.sh payloads/linux/lse.sh
download https://raw.githubusercontent.com/mzet-/linux-exploit-suggester/master/linux-exploit-suggester.sh linux-exploit-suggester.sh download https://raw.githubusercontent.com/mzet-/linux-exploit-suggester/master/linux-exploit-suggester.sh payloads/linux/linux-exploit-suggester.sh
download https://github.com/rebootuser/LinEnum/raw/master/LinEnum.sh LinEnum.sh download https://github.com/rebootuser/LinEnum/raw/master/LinEnum.sh payloads/linux/LinEnum.sh
download https://github.com/stealthcopter/deepce/raw/main/deepce.sh deepce.sh download https://github.com/stealthcopter/deepce/raw/main/deepce.sh payloads/linux/deepce.sh
download https://raw.githubusercontent.com/topotam/PetitPotam/main/PetitPotam.py PetitPotam.py
echo "" echo ""
echo "Updating LinPEAS + WinPEAS…" echo "Updating LinPEAS + WinPEAS…"
peas_version=$(get_latest_version peass-ng/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/peass-ng/PEASS-ng/releases/download/$peas_version/linpeas.sh linpeas.sh download https://github.com/peass-ng/PEASS-ng/releases/download/$peas_version/linpeas.sh payloads/linux/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/winPEASx86.exe payloads/windows/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/winPEASx64.exe payloads/windows/winPEASx64.exe
download https://github.com/peass-ng/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 payloads/windows/winPEAS.bat
else else
echo "Unable to determine latest PEAS version" echo "Unable to determine latest PEAS version"
fi fi
@@ -66,24 +65,24 @@ fi
# TODO: add others # TODO: add others
echo "" echo ""
echo "Updating windows tools…" echo "Updating windows tools…"
download https://live.sysinternals.com/accesschk.exe win/accesschk.exe download https://live.sysinternals.com/accesschk.exe payloads/windows/accesschk.exe
download https://live.sysinternals.com/accesschk64.exe win/accesschk64.exe download https://live.sysinternals.com/accesschk64.exe payloads/windows/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/nc.exe payloads/windows/nc.exe
download https://github.com/int0x33/nc.exe/raw/master/nc64.exe win/nc64.exe download https://github.com/int0x33/nc.exe/raw/master/nc64.exe payloads/windows/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/x86/jp32.exe payloads/windows/JuicyPotato.exe
download https://github.com/k4sth4/Juicy-Potato/raw/main/x64/jp.exe win/JuicyPotato64.exe download https://github.com/k4sth4/Juicy-Potato/raw/main/x64/jp.exe payloads/windows/JuicyPotato64.exe
download https://github.com/uknowsec/SweetPotato/raw/master/SweetPotato-Webshell-new/bin/Release/SweetPotato.exe win/SweetPotato.exe download https://github.com/uknowsec/SweetPotato/raw/master/SweetPotato-Webshell-new/bin/Release/SweetPotato.exe payloads/windows/SweetPotato.exe
download https://github.com/BeichenDream/GodPotato/releases/latest/download/GodPotato-NET4.exe win/GodPotato.exe download https://github.com/BeichenDream/GodPotato/releases/latest/download/GodPotato-NET4.exe payloads/windows/GodPotato.exe
download https://raw.githubusercontent.com/topotam/PetitPotam/main/PetitPotam.py win/PetitPotam.py download https://raw.githubusercontent.com/topotam/PetitPotam/main/PetitPotam.py tools/exploits/PetitPotam.py
echo "" 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"
curl -s -L "https://github.com/jpillora/chisel/releases/download/v${chisel_version}/chisel_${chisel_version}_linux_386.gz" | gzip -d > chisel curl -s -L "https://github.com/jpillora/chisel/releases/download/v${chisel_version}/chisel_${chisel_version}_linux_386.gz" | gzip -d > payloads/linux/chisel
curl -s -L "https://github.com/jpillora/chisel/releases/download/v${chisel_version}/chisel_${chisel_version}_linux_amd64.gz" | gzip -d > chisel64 curl -s -L "https://github.com/jpillora/chisel/releases/download/v${chisel_version}/chisel_${chisel_version}_linux_amd64.gz" | gzip -d > payloads/linux/chisel64
curl -s -L "https://github.com/jpillora/chisel/releases/download/v${chisel_version}/chisel_${chisel_version}_windows_386.gz" | gzip -d > win/chisel.exe curl -s -L "https://github.com/jpillora/chisel/releases/download/v${chisel_version}/chisel_${chisel_version}_windows_386.gz" | gzip -d > payloads/windows/chisel.exe
curl -s -L "https://github.com/jpillora/chisel/releases/download/v${chisel_version}/chisel_${chisel_version}_windows_amd64.gz" | gzip -d > win/chisel64.exe curl -s -L "https://github.com/jpillora/chisel/releases/download/v${chisel_version}/chisel_${chisel_version}_windows_amd64.gz" | gzip -d > payloads/windows/chisel64.exe
else else
echo "Unable to determine latest chisel version" echo "Unable to determine latest chisel version"
fi fi
@@ -91,14 +90,14 @@ fi
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 Sharphound 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 payloads/windows/ SharpHound.exe SharpHound.ps1
fi fi
socat_version=$(get_latest_version "3ndG4me/socat" v) socat_version=$(get_latest_version "3ndG4me/socat" v)
if [ ! -z "$socat_version" ]; then if [ ! -z "$socat_version" ]; then
echo "Got socat version: $socat_version" 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}/socatx86.bin payloads/linux/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}/socatx64.bin payloads/linux/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}/socatx86.exe payloads/windows/socat.exe
download https://github.com/3ndG4me/socat/releases/download/v${socat_version}/socatx64.exe win/socat64.exe download https://github.com/3ndG4me/socat/releases/download/v${socat_version}/socatx64.exe payloads/windows/socat64.exe
fi fi

0
utils/__init__.py Normal file
View File

View File

133
utils/packeter.py Normal file
View File

@@ -0,0 +1,133 @@
import struct
class StructWrapper:
@staticmethod
def _endian(e):
return ">" if e else "<"
@staticmethod
def _format_size(f):
format_sizes = {
"c": 1,
"h": 2, "H": 2,
"i": 4, "I": 4,
"q": 8, "Q": 8,
}
assert f in format_sizes
return format_sizes[f]
class Parser(StructWrapper):
def __init__(self, data, big_endian=False):
self.data = data
self.offset = 0
self.big_endian = big_endian
def eof(self):
return self.offset >= len(self.data)
def remaining_size(self):
return len(self.data[self.offset:])
def _struct_unpack(self, big_endian, f):
size = self._format_size(f)
assert self.remaining_size() >= size
# grab default endianess, when none is given
if big_endian is None:
big_endian = self.big_endian
value = struct.unpack(self._endian(big_endian) + f, self.data[self.offset:self.offset+size])[0]
self.offset += size
return value
def read_byte(self):
return self._struct_unpack(big_endian, "c")
def read_char(self):
return chr(self.read_byte())
def read_signed_short(self, big_endian=None):
return self._struct_unpack(big_endian, "h")
def read_unsigned_short(self, big_endian=None):
return self._struct_unpack(big_endian, "H")
def read_signed_int(self, big_endian=None):
return self._struct_unpack(big_endian, "i")
def read_unsigned_int(self, big_endian=None):
return self._struct_unpack(big_endian, "I")
def read_signed_long(self, big_endian=None):
return self._struct_unpack(big_endian, "q")
def read_unsigned_long(self, big_endian=None):
return self._struct_unpack(big_endian, "Q")
def read_bin(self, length):
d = self.data[self.offset:self.offset+length]
assert len(self.data[self.offset:]) >= length
self.offset += length
return d
def read_until(self, byte):
data = b""
while not self.eof():
c = self.read_byte()
if c == byte:
break
data += c
return data
class Packer(StructWrapper):
def __init__(self, big_endian=False):
self.buffer = b""
self.offset = 0
self.big_endian = big_endian
def get(self):
return self.buffer
def length(self):
return len(self.buffer)
def _struct_pack(self, big_endian, f, value):
# grab default endianess, when none is given
if big_endian is None:
big_endian = self.big_endian
size = self._format_size(f)
self.buffer += struct.pack(self._endian(big_endian) + f, value)
self.offset += size
def write_byte(self, value):
self._struct_pack(big_endian, "c", value)
def write_char(self, value):
self._struct_pack(big_endian, "c", value.encode())
def write_signed_short(self, value, big_endian=None):
self._struct_pack(big_endian, "c", value)
def write_unsigned_short(self, value, big_endian=None):
self._struct_pack(big_endian, "H", value)
def write_signed_int(self, value, big_endian=None):
self._struct_unpack(big_endian, "i", value)
def write_unsigned_int(self, value, big_endian=None):
self._struct_unpack(big_endian, "I", value)
def write_signed_long(self, value, big_endian=None):
self._struct_unpack(big_endian, "q", value)
def rwrite_unsigned_long(self, value, big_endian=None):
self._struct_unpack(big_endian, "Q", value)
def write_bin(self, value):
self.buffer += value
self.offset += len(value)
def write_string(self, value, encoding="UTF-8"):
self.write_bin(value.encode(encoding))

View File

View File

@@ -14,6 +14,18 @@ import re
import json import json
import urllib.parse import urllib.parse
def hex_dump(data, column_size=16):
printables = (string.ascii_letters + string.digits + string.punctuation).encode()
for i in range(0, len(data), column_size):
row = data[i:i+column_size]
as_string = "".join("." if bytes([b]) not in printables else chr(b) for b in row)
as_hex = " ".join("%02x" % b for b in row)
if len(row) < column_size:
as_hex += " " * 3 * (column_size - len(row))
print("%08x" % (i * column_size), "|", as_hex, "|", as_string)
def is_port_in_use(port): def is_port_in_use(port):
import socket import socket
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
@@ -158,12 +170,11 @@ def assert_regex_match(pattern, data, err=None):
err = f"[-] Data does not match pattern '{pattern}': '{data}'" if err is None else err err = f"[-] Data does not match pattern '{pattern}': '{data}'" if err is None else err
exit_with_error(None, err) exit_with_error(None, err)
def open_server(address, ports=None, retry=True): def open_server(address, ports=None, retry=False):
listen_port = None listen_port = None
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
while retry: while True:
if isinstance(ports, int): if isinstance(ports, int):
listen_port = ports listen_port = ports
retry = False retry = False
@@ -173,13 +184,16 @@ def open_server(address, ports=None, retry=True):
listen_port = random.randint(10000,65535) listen_port = random.randint(10000,65535)
try: try:
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind((address, listen_port)) sock.bind((address, listen_port))
sock.listen(1) sock.listen(1)
return sock return sock
except Exception as e: except Exception as e:
if not retry: if retry:
print("[-] Unable to listen on port %d: %s" % (listenPort, str(e))) print("[-] Unable to listen on port %d: %s, Retrying…" % (listen_port, str(e)))
raise e time.sleep(1.0)
else:
raise e
class Stack: class Stack:
def __init__(self, start_address, word_size=8): def __init__(self, start_address, word_size=8):

View File

@@ -1,273 +0,0 @@
#!/usr/bin/env python
import re
import sys
import json
import argparse
import requests
import urllib.parse
import util
from bs4 import BeautifulSoup
from crawl_urls import Crawler
requests.packages.urllib3.disable_warnings(requests.packages.urllib3.exceptions.InsecureRequestWarning)
class WebServiceFinder:
def __init__(self, args):
self.parseUrl(args.url)
self.parseCookies(args.cookie)
self.headers = { }
self.session = requests.Session()
self.verbose = args.verbose
if args.user_agent:
self.headers["User-Agent"] = args.user_agent
def parseUrl(self, url):
parts = urllib.parse.urlparse(url)
if parts.scheme == '':
self.url = "http://" + url
self.scheme = "http"
elif parts.scheme not in ["http","https"]:
print("[-] Unsupported URL scheme:", parts.scheme)
exit(1)
else:
self.url = url
self.scheme = parts.scheme
def resolve(self, uri):
if uri is None or uri.strip() == "":
return self.url
elif urllib.parse.urlparse(uri).scheme != "":
return uri
target = self.url
if not target.endswith("/"):
target += "/"
if uri.startswith("/"):
uri = uri[1:]
return target + uri
def do_get(self, uri, **args):
uri = self.resolve(uri)
if self.verbose:
sys.stdout.write("GET %s: " % uri)
res = self.session.get(uri, headers=self.headers, cookies=self.cookies, verify=False, **args)
if self.verbose:
sys.stdout.write("%d %s\n" % (res.status_code, res.reason))
return res
def parseCookies(self, cookie_list):
self.cookies = { }
if cookie_list:
for cookie in cookie_list:
cookie = cookie.strip()
if "=" in cookie:
index = cookie.find("=")
key, val = cookie[0:index], cookie[index+1:]
self.cookies[key] = val
else:
self.cookies[cookie] = ""
def scan(self):
print("[ ] Retrieving:", self.url)
uri = "/"
while True:
startPage = self.do_get(uri, allow_redirects=False)
if startPage.status_code in [301, 302, 397, 308]:
uri = startPage.headers["Location"]
if urllib.parse.urlparse(uri).scheme == "https" and self.scheme == "http":
self.url = self.url.replace("http","https",1)
self.scheme = "https"
print("[+] Server redirecting to:", uri)
else:
break
self.analyseHeaders(startPage)
if "text/html" in startPage.headers["Content-Type"]:
self.analyseHtml(startPage)
elif "text/xml" in startPage.headers["Content-Type"]:
self.analyseXml(startPage)
self.analyseRobots()
self.analyseSitemap()
self.analyseChangelog()
self.checkJoomlaVersion()
self.checkManifest()
def checkManifest(self):
url = "/static/manifest.json"
res = self.do_get(url)
if res.status_code == 200:
try:
manifest = json.loads(res.text)
if "name" in manifest:
print("[+] Found manifest name:", manifest["name"])
except:
pass
def checkJoomlaVersion(self):
url = "/administrator/manifests/files/joomla.xml"
res = self.do_get(url)
if res.status_code == 200:
soup = BeautifulSoup(res.text, "lxml")
extension = soup.find("extension")
if extension and extension.has_attr("version"):
print("[+] Found Joomla version:", extension["version"])
def analyseHeaders(self, res):
phpFound = False
banner_headers = ["Server", "X-Powered-By", "X-Runtime", "X-Version"]
for banner in banner_headers:
if banner in res.headers:
phpFound = phpFound or ("PHP" in res.headers[banner])
print("[+] %s Header: %s" % (banner, res.headers[banner]))
if not phpFound and "PHPSESSID" in self.session.cookies:
print("[+] PHP detected, unknown version")
def printMatch(self, title, match, group=1, version_func=str):
if match:
version = "Unknown version" if group is None or len(match.groups()) <= group else version_func(match.group(group))
print("[+] Found %s: %s" % (title, version))
return True
return False
def retrieveMoodleVersion(self, v):
res = requests.get("https://docs.moodle.org/dev/Releases")
soup = BeautifulSoup(res.text, "html.parser")
versionStr = "Unknown"
for tr in soup.find_all("tr"):
tds = tr.find_all("td")
th = tr.find("th")
if len(tds) == 4 and th and int(tds[1].text.strip()) == v:
versionStr = th.text.strip()
if versionStr.startswith("Moodle "):
versionStr = versionStr[len("Moodle"):].strip()
break
return "%s (%d)" % (versionStr, v)
def analyseXml(self,res):
soup = BeautifulSoup(res.text, "lxml")
title = soup.find("title")
if title:
print("[+] Found XML title:", title.text.strip())
generator = soup.find("generator")
if generator:
if generator.has_attr("version"):
print("[+] Found XML Generator version:", generator["version"])
def analyseHtml(self, res):
soup = BeautifulSoup(res.text, "html.parser")
meta_generator = soup.find("meta", {"name":"generator"})
if meta_generator:
banner = meta_generator["content"].strip()
print("[+] Meta Generator:", banner)
body = soup.find("body")
if body:
gitea_pattern = re.compile(r"Gitea Version: ([0-9\.]*)")
self.printMatch("Gitea", gitea_pattern.search(body.text))
footer = soup.find("footer")
if footer:
content = footer.text.strip()
gogs_pattern = re.compile(r"(^|\s)Gogs Version: ([a-zA-Z0-9.-]+)($|\s)")
go_pattern = re.compile(r"(^|\s)Go([0-9.]+)($|\s+)")
self.printMatch("Gogs", gogs_pattern.search(content), 2)
self.printMatch("Go", go_pattern.search(content), 2)
versionInfo = soup.find("div", {"class": "versionInfo"})
if versionInfo:
content = versionInfo.text.strip()
cacti_pattern = re.compile(r"Version ([0-9.]*) .* The Cacti Group")
self.printMatch("Cacti", cacti_pattern.search(content), 1)
poweredBy = soup.find(id="poweredBy")
if poweredBy:
content = poweredBy.text.strip()
osticket_pattern = re.compile(r"powered by osTicket")
self.printMatch("OsTicket", osticket_pattern.search(content))
moodle_pattern_1 = re.compile(r"^https://download.moodle.org/mobile\?version=(\d+)(&|$)")
moodle_pattern_2 = re.compile(r"^https://docs.moodle.org/(\d+)/")
litecart_pattern = re.compile(r"^https://www.litecart.net")
wordpress_pattern = re.compile(r"/wp-(admin|includes|content)/(([^/]+)/)*(wp-emoji-release.min.js|style.min.css)\?ver=([0-9.]+)(&|$)")
urls = Crawler(self.url).collect_urls(soup)
for url in urls:
self.printMatch("Moodle", moodle_pattern_1.search(url), version_func=lambda v: self.retrieveMoodleVersion(int(v)))
self.printMatch("Moodle", moodle_pattern_2.search(url), version_func=lambda v: "%d.%d" % (int(v)//10,int(v)%10))
self.printMatch("Litecart", litecart_pattern.search(url), group=None)
if self.printMatch("Wordpress", wordpress_pattern.search(url), group=5):
print("[ ] You should consider using 'wpscan' for further investigations and more accurate results")
def analyseRobots(self):
res = self.do_get("/robots.txt", allow_redirects=False)
if res.status_code != 200:
print("[-] robots.txt not found or inaccessible")
return False
def analyseSitemap(self):
res = self.do_get("/sitemap.xml", allow_redirects=False)
if res.status_code != 200:
print("[-] sitemap.xml not found or inaccessible")
return False
def analyseChangelog(self):
drupal_pattern = re.compile("^Drupal ([0-9.]+),")
drupal_found = False
changelog_files = ["CHANGELOG", "CHANGELOG.txt"]
for file in changelog_files:
res = self.do_get(file, allow_redirects=False)
if res.status_code != 200:
continue
print("[+] Found:", file)
for line in res.text.split("\n"):
line = line.strip()
if not drupal_found and self.printMatch("Drupal", drupal_pattern.search(line)):
drupal_found = True
def banner():
print("""
,--------. ,--. ,--------. ,--. ,--. ,--.
'--. .--',---. ,---.,-' '-.'--. .--',---. ,---. | | ,--. ,--. / | / \\
| | | .-. :( .-''-. .-' | | | .-. || .-. || | \ `' / `| | | () |
| | \ --..-' `) | | | | ' '-' '' '-' '| | \ / | |.--.\ /
`--' `----'`----' `--' `--' `---' `---' `--' `--' `--''--' `--'
""")
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("url", help="The target URI to scan to, e.g. http://example.com:8080/dir/")
parser.add_argument("--proxy", help="Proxy to connect through") # TODO
parser.add_argument("--user-agent", help="User-Agent to use")
parser.add_argument("--cookie", help="Cookies to send", action='append')
parser.add_argument('--verbose', '-v', help="Verbose otuput", action='store_true')
args = parser.parse_args()
banner()
client = WebServiceFinder(args)
client.scan()