From 37614c04562015839f9620a1aed1e9cb4b87a36f Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Fri, 12 Jan 2024 23:58:26 +0000 Subject: [PATCH 01/62] [s0mbra] Fix vhosts enumeration --- s0mbra.sh | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/s0mbra.sh b/s0mbra.sh index 9b5baaa..569c8f4 100755 --- a/s0mbra.sh +++ b/s0mbra.sh @@ -295,7 +295,6 @@ recon() { NMAP="1" NIKTO="1" FFUF="1" - FEROXBUSTER="1" SUBDOMANIZER="1" SELECTED_OPTIONS="nmap, nikto, ffuf, subdomanizer" else @@ -341,9 +340,7 @@ recon() { if [[ $VHOSTS -eq "1" ]]; then # vhosts enumeration - ffuf -ac -c -w $DICT_HOME/vhosts -u $PROTO://$HOSTNAME/FUZZ -mc=200,206,301,302,422,429 -H "User-Agent: wearehackerone" -H "X-Hackerone: bl4de" -H "Host: FUZZ.$HOSTNAME" -o $TMPDIR/ffuf_vhosts_fullnames_$HOSTNAME.log - - ffuf -ac -c -w $DICT_HOME/vhosts -u $PROTO://$HOSTNAME/FUZZ -mc=200,206,301,302,422,429 -H "User-Agent: wearehackerone" -H "X-Hackerone: bl4de" -H "Host: FUZZ" -o $TMPDIR/ffuf_vhosts_$HOSTNAME.log + ffuf -ac -c -w $DICT_HOME/vhosts -u $PROTO://FUZZ.$HOSTNAME -mc=200,206,301,302,422,429 -H "User-Agent: wearehackerone" -H "X-Hackerone: bl4de" -H "Host: FUZZ.$HOSTNAME" -o $TMPDIR/ffuf_vhosts_fullnames_$HOSTNAME.log fi # ffuf @@ -390,8 +387,6 @@ fu() { # if $3 arg passed to fu equals / - add at the end of the path (for dir enumerations where sometimes # dir path has to end with / to be identified ffuf -ac -c -w /Users/bl4de/hacking/dictionaries/$SELECTED_DICT.txt -u $1/FUZZ/ -mc $HTTP_RESP_CODES -H "User-Agent: wearehackerone" -H "X-Hackerone: bl4de" - elif [[ $3 == "-" ]]; then - ffuf -ac -c -w /Users/bl4de/hacking/dictionaries/$SELECTED_DICT.txt -u $1/FUZZ -mc $HTTP_RESP_CODES -H "User-Agent: wearehackerone" -H "X-Hackerone: bl4de" else if [[ $3 == "-" ]]; then # if $3 equals - (dash) that means we should ignore it at all From 573bb80efb06fbe46c6a615162370700d3fb24be Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Fri, 9 Feb 2024 11:53:02 +0000 Subject: [PATCH 02/62] [s0mbra] Added photon to recon --- s0mbra.sh | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/s0mbra.sh b/s0mbra.sh index 569c8f4..aecac6c 100755 --- a/s0mbra.sh +++ b/s0mbra.sh @@ -242,6 +242,20 @@ scope() { echo -e "\n$BLUE[s0mbra] Done.$CLR" } +# OSINT +photon() { + URL=$1 + OUTPUT_DIR=$2 + TMPDIR=$(pwd)/photon/$OUTPUT_DIR + if [[ ! -d $TMPDIR ]]; then + mkdir -p $TMPDIR + fi + echo -e "$BLUE[s0mbra] Let's do some OSINT stuff around $URL...$CLR\n" + /usr/local/homebrew/bin/python3 /Users/bl4de/hacking/tools/Photon/photon.py -u "$URL" -l 5 -t 10 -o "$TMPDIR" + ls -lRA "$TMPDIR" + echo -e "\n$BLUE[s0mbra] Done.$CLR" +} + # quick scope, but for single domain - no need to create scope file peek() { TMPDIR=$(pwd)/$1 @@ -736,6 +750,9 @@ case "$cmd" in peek) peek "$2" ;; + photon) + photon "$2" "$3" + ;; recon) recon "$2" "$3" "$4" ;; @@ -854,7 +871,7 @@ case "$cmd" in clear echo -e "$BLUE_BG:: RECON ::\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t$CLR" echo -e "$CYAN scope $GRAY[SCOPE_FILE]$CLR\t\t\t\t$CYAN recon $GRAY[HOST] [OPTIONS:nmap,nikto,vhosts,ffuf,subdomanizer] [PROTO http/https]$CLR" - echo -e "$CYAN peek $GRAY[DOMAIN]$CLR" + echo -e "$CYAN peek $GRAY[DOMAIN]$CLR\t\t\t\t\t$CYAN photon $GRAY[HOST] [OUTPUT_DIR]$CLR" echo -e "$BLUE_BG:: WEB ::\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t$CLR" echo -e "$CYAN fu $GRAY[URL] [DICT] [*EXT,/ or -] [HTTP RESP.]$CLR\t$CYAN apifuzz $GRAY[BASE_URL] [ENDPOINTS]$CLR\t$YELLOW(REST)$CLR" From 1b0d1c8d29263d79eee25f8ca0a3bec7c300fce1 Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Fri, 16 Feb 2024 22:06:58 +0000 Subject: [PATCH 03/62] [s0mbra] arjun for url parameters discovery --- s0mbra.sh | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/s0mbra.sh b/s0mbra.sh index aecac6c..cd7f01f 100755 --- a/s0mbra.sh +++ b/s0mbra.sh @@ -377,6 +377,20 @@ recon() { echo -e "\n$BLUE[s0mbra] Done.$CLR" } +# runs GET parameter(s) discovery +_arjun() { + clear + DICT_PATH="/Users/bl4de/hacking/dictionaries" + if [[ -z $2 ]]; then + SELECTED_DICT=urlparams_medium.txt + else + SELECTED_DICT=$2 + fi + echo -e "$BLUE[s0mbra] Trying to discover GET params on $1 using $SELECTED_DICT...$GRAY" + arjun -u "$1" -w "$DICT_PATH/$SELECTED_DICT" + echo -e "$BLUE\n[s0mbra] Done! $CLR" +} + fu() { clear @@ -753,6 +767,9 @@ case "$cmd" in photon) photon "$2" "$3" ;; + arjun) + _arjun "$2" "$3" + ;; recon) recon "$2" "$3" "$4" ;; @@ -876,8 +893,7 @@ case "$cmd" in echo -e "$BLUE_BG:: WEB ::\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t$CLR" echo -e "$CYAN fu $GRAY[URL] [DICT] [*EXT,/ or -] [HTTP RESP.]$CLR\t$CYAN apifuzz $GRAY[BASE_URL] [ENDPOINTS]$CLR\t$YELLOW(REST)$CLR" echo -e "$CYAN graphw00f $GRAY[HOST]$CLR\t\t$YELLOW(GraphQl)$CLR\t$CYAN gql $GRAY[TARGET_URL]$CLR\t\t$YELLOW(GraphQL)$CLR" - echo -e "$CYAN kiterunner $GRAY[HOST] (*apis)$CLR\t$YELLOW(REST)$CLR" - + echo -e "$CYAN kiterunner $GRAY[HOST] (*apis)$CLR\t$YELLOW(REST)$CRL\t\t$CYAN arjun $GRAY[HOST] [DICT]$CLR" echo -e "$BLUE_BG:: CLOUD ::\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t$CLR" echo -e "$CYAN discloS3 $GRAY[URL]$CLR\t\t\t$YELLOW(AWS)$CLR\t\t$CYAN s3 $GRAY[BUCKET]$CLR\t\t\t$YELLOW(AWS)$CLR" echo -e "$CYAN s3get $GRAY[BUCKET] [key]$CLR\t\t$YELLOW(AWS)$CLR\t\t$CYAN s3ls $GRAY[BUCKET] [folder]$CLR\t\t$YELLOW(AWS)$CLR" From d5a985269e254a32d0200d1129b690ed9129c6ba Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Sun, 25 Feb 2024 11:02:37 +0000 Subject: [PATCH 04/62] [s0mbra] arjun fix --- s0mbra.sh | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/s0mbra.sh b/s0mbra.sh index cd7f01f..59e9768 100755 --- a/s0mbra.sh +++ b/s0mbra.sh @@ -380,14 +380,13 @@ recon() { # runs GET parameter(s) discovery _arjun() { clear - DICT_PATH="/Users/bl4de/hacking/dictionaries" if [[ -z $2 ]]; then - SELECTED_DICT=urlparams_medium.txt + SELECTED_DICT=/Users/bl4de/hacking/dictionaries/urlparams_medium.txt else - SELECTED_DICT=$2 + SELECTED_DICT="$2" fi echo -e "$BLUE[s0mbra] Trying to discover GET params on $1 using $SELECTED_DICT...$GRAY" - arjun -u "$1" -w "$DICT_PATH/$SELECTED_DICT" + arjun -u "$1" -w $SELECTED_DICT echo -e "$BLUE\n[s0mbra] Done! $CLR" } From 59115096ab5a02d1fca7978d11b3165f9d450610 Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Mon, 26 Feb 2024 07:55:02 +0000 Subject: [PATCH 05/62] [s0mbra] missing space --- s0mbra.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/s0mbra.sh b/s0mbra.sh index 59e9768..31933ca 100755 --- a/s0mbra.sh +++ b/s0mbra.sh @@ -905,7 +905,7 @@ case "$cmd" in echo -e "$CYAN smb_umount $CLR" echo -e "$BLUE_BG:: PASSWORDS CRACKIN' ::\t\t\t\t\t\t\t\t\t\t\t\t\t\t$CLR" - echo -e "$CYAN rockyou_john $GRAY[HASHES][FORMAT]$CLR\t\t\t$CYAN ssh_to_john $GRAY[ID_RSA]$CLR" + echo -e "$CYAN rockyou_john $GRAY[HASHES] [FORMAT]$CLR\t\t\t$CYAN ssh_to_john $GRAY[ID_RSA]$CLR" echo -e "$CYAN rockyou_zip $GRAY[ZIP file]$CLR\t\t\t\t$CYAN defcreds $GRAY[DEVICE/SYSTEM]$CLR" echo -e "$CYAN john_pot$CLR" From 01e7be5db84a131591d6d4488ed7a2d95aaadf1f Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Mon, 26 Feb 2024 15:52:42 +0000 Subject: [PATCH 06/62] [s0mbra] Update peek() --- s0mbra.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/s0mbra.sh b/s0mbra.sh index 31933ca..6a68539 100755 --- a/s0mbra.sh +++ b/s0mbra.sh @@ -230,7 +230,7 @@ scope() { # httpx echo -e "\n$GREEN--> httpx$CLR\n" - httpx -H "User-Agent: wearehackerone" -H "X-Hackerone: bl4de" -silent -status-code -web-server -tech-detect -ip -cname -cdn -l $TMPDIR/subdomains_final.log -o $TMPDIR/httpx.log + httpx -H "User-Agent: wearehackerone" -H "X-Hackerone: bl4de" -silent -status-code -web-server -tech-detect -ip -cname -cdn -rl 20 -exclude-cdn -l $TMPDIR/subdomains_final.log -o $TMPDIR/httpx.log END_TIME=$(date) echo -e "$GREEN\nstarted at: $RED $START_TIME $GREEN" From b5fd2150dd3ffa10103b3230fa5c5272457ac0f6 Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Sun, 31 Mar 2024 20:55:42 +0100 Subject: [PATCH 07/62] [s0mbra] Added 401 to default HTTP response codes in fu() --- s0mbra.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/s0mbra.sh b/s0mbra.sh index 6a68539..2e357df 100755 --- a/s0mbra.sh +++ b/s0mbra.sh @@ -402,7 +402,7 @@ fu() { # set response status code(s) to match on: if [[ -z $4 ]]; then - HTTP_RESP_CODES=200,206,301,302,500 + HTTP_RESP_CODES=200,206,301,302,401,500 else HTTP_RESP_CODES=$4 fi From b729f576c6b914d218b1f8f7a965786f51320ab5 Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Sun, 14 Apr 2024 21:31:35 +0100 Subject: [PATCH 08/62] [s0mbra] do not clear the screen when fu() is called --- s0mbra.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/s0mbra.sh b/s0mbra.sh index 2e357df..73d42db 100755 --- a/s0mbra.sh +++ b/s0mbra.sh @@ -391,8 +391,6 @@ _arjun() { } fu() { - clear - # use starter.txt as default dictionary if [[ -z $2 ]]; then SELECTED_DICT=starter From d7567d8b19604a1a44571c3eee7886f8ba34ccee Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Sun, 12 May 2024 19:37:59 +0100 Subject: [PATCH 09/62] [s0mbra] remove unused tool --- s0mbra.sh | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/s0mbra.sh b/s0mbra.sh index 73d42db..4dc2304 100755 --- a/s0mbra.sh +++ b/s0mbra.sh @@ -727,13 +727,6 @@ shells() { echo -e "$BLUE\n[s0mbra] Done! $CLR" } -# looks for default credentials in service/software/hardware -defcreds() { - echo -e "$BLUE[s0mbra] Looking for default credentials for $1...$CLR" - creds search $1 - echo -e "$BLUE\n[s0mbra] Done! $CLR" -} - # decodes Base64 string b64() { echo -e "$BLUE[s0mbra] Decoding Base64 string...$CLR" @@ -797,9 +790,6 @@ case "$cmd" in ssh_to_john) ssh_to_john "$2" ;; - defcreds) - defcreds "$2" - ;; unmin) unmin "$2" ;; @@ -904,8 +894,7 @@ case "$cmd" in echo -e "$BLUE_BG:: PASSWORDS CRACKIN' ::\t\t\t\t\t\t\t\t\t\t\t\t\t\t$CLR" echo -e "$CYAN rockyou_john $GRAY[HASHES] [FORMAT]$CLR\t\t\t$CYAN ssh_to_john $GRAY[ID_RSA]$CLR" - echo -e "$CYAN rockyou_zip $GRAY[ZIP file]$CLR\t\t\t\t$CYAN defcreds $GRAY[DEVICE/SYSTEM]$CLR" - echo -e "$CYAN john_pot$CLR" + echo -e "$CYAN rockyou_zip $GRAY[ZIP file]$CLR\t\t\t\t$CYAN john_pot$CLR" echo -e "$BLUE_BG:: STATIC CODE ANALYSIS ::\t\t\t\t\t\t\t\t\t\t\t\t\t\t$CLR" echo -e "$CYAN unmin $GRAY[FILE]\t\t\t$YELLOW(JavaScript)$CLR\t$CYAN snyktest $GRAY[DIR]\t\t\t$YELLOW(JavaScript)$CLR" From 299771d09d71b3e2b37a8552a243bd41bbff7632 Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Sat, 15 Jun 2024 16:54:55 +0100 Subject: [PATCH 10/62] [pef] Refactoring; bugfixing; added -f/--function to search for sinlge function only --- pef/pef.py | 54 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 24 deletions(-) diff --git a/pef/pef.py b/pef/pef.py index 6860357..136ae84 100755 --- a/pef/pef.py +++ b/pef/pef.py @@ -171,20 +171,20 @@ class PefEngine: implements pef engine """ - def __init__(self, level, source_or_sink, filename, dirs_to_scan, skip_vendor=False): + def __init__(self, level, source_or_sink, filename, skip_vendor, phpfunction): """ constructor """ - self.level = level # scan only for level set of functions + self.level = level # scan only for level set of functions self.source_or_sink = source_or_sink # show only sinks or sources - self.filename = filename # name of file/folder to scan - self.dirs_to_scan = dirs_to_scan # name(s) of dirs to scan + self.filename = filename # name of file/folder to scan self.skip_vendor = skip_vendor + self.phpfunction = '' if phpfunction is None else phpfunction - self.scanned_files = 0 # number of scanned files in total - self.found_entries = 0 # total number of findings + self.scanned_files = 0 # number of scanned files in total + self.found_entries = 0 # total number of findings - self.severity = { # severity scale + self.severity = { # severity scale "high": 0, "medium": 0, "low": 0 @@ -227,18 +227,24 @@ def print_code_line(self, file_name, _line, i, fn, severity="", level='ALL', sou found = 0 # print legend only if there i sentry in pefdocs.py + if fn and fn.strip() in pefdocs.exploitableFunctionsDesc.keys(): doc = pefdocs.exploitableFunctionsDesc.get(fn.strip()) impact = doc[3] if (impact.upper() in level.upper()) or level == 'ALL': - if (len(doc) == 5 and source_or_sink == doc[4]) or source_or_sink == 'ALL': - if len(_line) > 255: - _line = _line[:120] + \ - f" (...truncated -> line is {len(_line)} characters long)" - print("{}{}:{}\t{}{}{}{}".format(beautyConsole.getColor("white"), file_name, i, beautyConsole.getColor( - impact_color[impact]), beautyConsole.getColor(impact_color[impact]), _line.strip()[:255], beautyConsole.getColor("grey"))) - found += 1 + if self.phpfunction == '' or self.phpfunction in fn: + if (len(doc) == 5 and source_or_sink == doc[4]) or source_or_sink == 'ALL': + if len(_line) > 255: + _line = _line[:120] + \ + f" (...truncated -> line is {len(_line)} characters long)" + print("{}{}:{}\t{}{}{}{}".format(beautyConsole.getColor("white"), file_name, i, + beautyConsole.getColor( + impact_color[impact]), + beautyConsole.getColor(impact_color[impact]), + _line.strip()[:255], + beautyConsole.getColor("grey"))) + found += 1 if impact not in severity.keys(): severity[impact] = 1 else: @@ -271,6 +277,7 @@ def run(self): """ total_found = 0 os.system('clear') + print( f"{beautyConsole.getColor('green')}>>> RESULTS <<<{beautyConsole.getColor('gray')}\n") @@ -278,15 +285,13 @@ def run(self): for root, _, files in os.walk(self.filename): if self.skip_vendor is True and "vendor" in root: continue - # if self.dirs_to_scan and self.not_in_dirs_to_scan(root): - # continue prev_filename = "" for f in files: extension = f.split('.')[-1:][0] if extension in ['php', 'inc', 'php3', 'php4', 'php5', 'phtml']: self.scanned_files = self.scanned_files + 1 (res, file_found) = self.main(os.path.join(root, f)) - if res is not None and f != prev_filename: + if self.phpfunction == '' and res is not None and f != prev_filename: print(f">>> {f} <<<\t{'-' * (115 - len(f))}\n\n") prev_filename = f total_found += file_found @@ -309,7 +314,7 @@ def print_summary(self, total_found: int) -> None: """ print(f"{beautyConsole.getColor('white')}Total issues found: {total_found}") print( - f"{beautyConsole.getColor('white')}Cmd arguments: {' '.join(sys.argv[1:])}\n") + f"\n{beautyConsole.getColor('grey')}Cmd arguments: {' '.join(sys.argv[1:])}\n") # main program @@ -320,6 +325,7 @@ def print_summary(self, total_found: int) -> None: add_help=True ) filename = '.' # initial value for file/dir to scan is current directory + phpfunction = '' parser.add_argument( "-s", "--skip-vendor", help="exclude ./vendor folder", action="store_true") @@ -331,14 +337,15 @@ def print_summary(self, total_found: int) -> None: "-K", "--sink", help="show only sinks", action="store_true") parser.add_argument( "-f", - "--file", - help="File or directory name to scan", + "--function", + help="Search for particular PHP function (eg. unserialize)", ) parser.add_argument( "-d", "--dir", - help="List of directories to scan (mutually exclusive with -f flag)", + help="Directory to scan (or sinlge file, optionally)", ) + args = parser.parse_args() level = args.level.upper() if args.level else 'ALL' @@ -349,10 +356,9 @@ def print_summary(self, total_found: int) -> None: if args.sink: source_or_sink = 'sink' - dirs_to_scan = args.dir - filename = args.file + filename = args.dir # main orutine starts here engine = PefEngine(level, source_or_sink, - filename, dirs_to_scan, args.skip_vendor) + filename, args.skip_vendor, args.function) engine.run() From aa7b5a0b022f68fb9ce97565487a794b80dd53b5 Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Sun, 23 Jun 2024 23:50:27 +0100 Subject: [PATCH 11/62] [s0mbra] notification after fu, peek, nmap scans --- pef/imports/pefdocs.py | 12 ++++++------ s0mbra.sh | 5 +++++ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/pef/imports/pefdocs.py b/pef/imports/pefdocs.py index 1863d39..f405130 100644 --- a/pef/imports/pefdocs.py +++ b/pef/imports/pefdocs.py @@ -85,14 +85,14 @@ "Opens process file pointer. Opens a pipe to a process executed by forking the command given by command.", "popen ( string $command , string $mode ) : resource", "Code Injection", - "medium", + "high", "sink" ], "proc_open()": [ "Execute a command and open file pointers for input/output. proc_open() is similar to popen() but provides a much greater degree of control over the program execution.", "proc_open ( string $cmd , array $descriptorspec , array &$pipes [, string $cwd = NULL [, array $env = NULL [, array $other_options = NULL ]]] ) : resource", "Code Injection", - "medium", + "high", "sink" ], "pcntl_exec()": [ @@ -538,28 +538,28 @@ "$_POST reference found", "", "", - "critical", + "high", "source" ], "$_GET": [ "$_GET reference found", "", "", - "critical", + "high", "source" ], "$_REQUEST": [ "$_REQUEST reference found", "", "", - "critical", + "high", "source" ], "$_COOKIES": [ "$_COOKIES reference found", "", "", - "critical", + "high", "source" ] } diff --git a/s0mbra.sh b/s0mbra.sh index 4dc2304..c2478f4 100755 --- a/s0mbra.sh +++ b/s0mbra.sh @@ -32,6 +32,7 @@ full_nmap_scan() { fi echo -e "$BLUE\n[s0mbra] Done! $CLR" + osascript -e 'display notification "nmap finished, choomba!" with title "s0mbra says:"' } # runs --top-ports $2 against IP @@ -45,6 +46,7 @@ quick_nmap_scan() { fi echo -e "$BLUE\n[s0mbra] Done! $CLR" + osascript -e 'display notification "nmap finished, choomba!" with title "s0mbra says:"' } # runs Python 3 built-in HTTP server on [PORT] @@ -84,6 +86,7 @@ rockyou_john() { fi cat "$HACKING_HOME"/tools/jtr/run/john.pot echo -e "\n$BLUE[s0mbra] Done." + osascript -e 'display notification "our choom John has left the house..." with title "s0mbra says:"' } # show JTR's pot file @@ -296,6 +299,7 @@ peek() { echo -e "$GRAY sublister+subfinder found \t $YELLOW $(echo `wc -l $TMPDIR/subdomains_final.log` | cut -d" " -f 1) $GRAY subdomains" echo -e "$GRAY httpx found \t\t\t $YELLOW $(echo `wc -l $TMPDIR/httpx.log` | cut -d" " -f 1) $GRAY active web servers $GREEN" echo -e "\n$BLUE[s0mbra] Done.$CLR" + osascript -e 'display notification "peek finished, choomba!" with title "s0mbra says:"' } # does recon on URL: nmap, ffuf, other smaller tools, ...? @@ -425,6 +429,7 @@ fu() { ffuf -ac -c -w /Users/bl4de/hacking/dictionaries/$SELECTED_DICT.txt -u $1/FUZZ -mc $HTTP_RESP_CODES -H "User-Agent: wearehackerone" -H "X-Hackerone: bl4de" fi echo -e "$BLUE\n[s0mbra] Done! $CLR" + osascript -e 'display notification "ffuf finished, choomba!" with title "s0mbra says:"' } api_fuzz() { From 40421fdd5df10082e01704b024fabe937f838019 Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Sun, 30 Jun 2024 10:55:15 +0100 Subject: [PATCH 12/62] [pef] added verbose output --- pef/pef.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/pef/pef.py b/pef/pef.py index 136ae84..6c8180d 100755 --- a/pef/pef.py +++ b/pef/pef.py @@ -171,7 +171,7 @@ class PefEngine: implements pef engine """ - def __init__(self, level, source_or_sink, filename, skip_vendor, phpfunction): + def __init__(self, level, source_or_sink, filename, skip_vendor, phpfunction, verbose): """ constructor """ @@ -180,7 +180,7 @@ def __init__(self, level, source_or_sink, filename, skip_vendor, phpfunction): self.filename = filename # name of file/folder to scan self.skip_vendor = skip_vendor self.phpfunction = '' if phpfunction is None else phpfunction - + self.verbose = verbose self.scanned_files = 0 # number of scanned files in total self.found_entries = 0 # total number of findings @@ -214,7 +214,7 @@ def analyse_line(self, l, i, fn, f, line): f.name, l, i, fn + (')' if '(' in fn else ''), self.severity, self.level, self.source_or_sink) return res - def print_code_line(self, file_name, _line, i, fn, severity="", level='ALL', source_or_sink='ALL'): + def print_code_line(self, file_name, _line, i, fn, severity="", level='ALL', source_or_sink='ALL', verbose=False): """ prints formatted code line """ @@ -244,6 +244,8 @@ def print_code_line(self, file_name, _line, i, fn, severity="", level='ALL', sou beautyConsole.getColor(impact_color[impact]), _line.strip()[:255], beautyConsole.getColor("grey"))) + if self.verbose: + print(f"\t{doc[1]}\n\t{doc[0]}\n") found += 1 if impact not in severity.keys(): severity[impact] = 1 @@ -329,6 +331,8 @@ def print_summary(self, total_found: int) -> None: parser.add_argument( "-s", "--skip-vendor", help="exclude ./vendor folder", action="store_true") + parser.add_argument( + "-v", "--verbose", help="show documentation", action="store_true") parser.add_argument( "-l", "--level", help="severity level: ALL, LOW, MEDIUM, HIGH or CRITICAL; default: ALL") parser.add_argument( @@ -360,5 +364,5 @@ def print_summary(self, total_found: int) -> None: # main orutine starts here engine = PefEngine(level, source_or_sink, - filename, args.skip_vendor, args.function) + filename, args.skip_vendor, args.function, args.verbose) engine.run() From c1413e9b84296fa407a24aa57806863acbb39cfa Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Tue, 2 Jul 2024 01:04:18 +0100 Subject: [PATCH 13/62] [pef] added some functions --- pef/imports/pefdocs.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/pef/imports/pefdocs.py b/pef/imports/pefdocs.py index f405130..e6fa9ab 100644 --- a/pef/imports/pefdocs.py +++ b/pef/imports/pefdocs.py @@ -479,6 +479,20 @@ "medium", "sink" ], + "__serialize()": [ + "checks if the class has a function with the magic name __serialize(). If so, that function is executed prior to any serialization. It must construct and return an associative array of key/value pairs that represent the serialized form of the object. If no array is returned a TypeError will be thrown.", + "public __sleep ( void ) : array", + "Object Injection; RCE via unserialize() + POP gadget chain", + "medium", + "sink" + ], + "__unserialize()": [ + "checks for the presence of a function with the magic name __unserialize(). If present, this function will be passed the restored array that was returned from __serialize(). It may then restore the properties of the object from that array as appropriate.", + "public __sleep ( void ) : array", + "Object Injection; RCE via unserialize() + POP gadget chain", + "medium", + "sink" + ], "__call()": [ "Triggered when invoking inaccessible methods in an object context", "public __call ( string $name , array $arguments ) : mixed", @@ -486,6 +500,20 @@ "medium", "sink" ], + "__get()": [ + "Is utilized for reading data from inaccessible (protected or private) or non-existing properties.", + "public __get ( string $name ) : mixed", + "Object Injection; RCE via unserialize() + POP gadget chain", + "medium", + "sink" + ], + "__set()": [ + "Is run when writing data to inaccessible (protected or private) or non-existing properties.", + "public __set ( string $name, mixed $value ) : void", + "Object Injection; RCE via unserialize() + POP gadget chain", + "medium", + "sink" + ], "__callStatic()": [ "Triggered when invoking inaccessible methods in a static context.", "public static __callStatic ( string $name , array $arguments ) : mixed", From a0783e43651421a530847963769321a6116f125f Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Tue, 23 Jul 2024 20:26:16 +0100 Subject: [PATCH 14/62] [s0mbra] notification message --- s0mbra.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/s0mbra.sh b/s0mbra.sh index c2478f4..924c6e3 100755 --- a/s0mbra.sh +++ b/s0mbra.sh @@ -299,7 +299,7 @@ peek() { echo -e "$GRAY sublister+subfinder found \t $YELLOW $(echo `wc -l $TMPDIR/subdomains_final.log` | cut -d" " -f 1) $GRAY subdomains" echo -e "$GRAY httpx found \t\t\t $YELLOW $(echo `wc -l $TMPDIR/httpx.log` | cut -d" " -f 1) $GRAY active web servers $GREEN" echo -e "\n$BLUE[s0mbra] Done.$CLR" - osascript -e 'display notification "peek finished, choomba!" with title "s0mbra says:"' + osascript -e 'display notification "Hey choomba, peek finished!" with title "s0mbra says:"' } # does recon on URL: nmap, ffuf, other smaller tools, ...? From ea00bf374874c7e5596f960242abe89e2531d7d3 Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Tue, 23 Jul 2024 20:34:14 +0100 Subject: [PATCH 15/62] [denumerator] refactoring --- denumerator/denumerator.py | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/denumerator/denumerator.py b/denumerator/denumerator.py index dad6987..da41757 100755 --- a/denumerator/denumerator.py +++ b/denumerator/denumerator.py @@ -1,11 +1,10 @@ -#!/usr/bin/env python3 +#!/usr/bin/env python # pylint: disable=invalid-name """ @TODO - results summary """ - """ --- dENUMerator --- @@ -20,14 +19,15 @@ $ ./denumerator.py [domain_list_file] """ - import argparse +import json import os import subprocess import time -import requests -import json from datetime import datetime + +import requests + welcome = """ --- dENUMerator --- usage: @@ -288,8 +288,8 @@ def append_to_output(html_output, url, http_status_code, response_headers, nmap_ b"\n") if port.find(b"open") > 0] for port in open_ports: nmap_html = nmap_html + \ - "

{}

".format( - port.decode("utf-8")) + "

{}

".format( + port.decode("utf-8")) nmap_html = nmap_html + "" # HTTP response headers @@ -331,13 +331,13 @@ def append_to_output(html_output, url, http_status_code, response_headers, nmap_ """.format( - (http_status_code//100), + (http_status_code // 100), http_status_code_color, element_class_name, http_status_code, url, url, - (http_status_code//100), + (http_status_code // 100), element_class_name, screenshot_name, screenshot_name, @@ -392,7 +392,8 @@ def send_request(proto, domain, output_file, html_output, allowed_http_responses return resp.status_code -def enumerate_domains(domains, output_file, html_output, allowed_http_responses, nmap_top_ports, output_directory, show=False): +def enumerate_domains(domains, output_file, html_output, allowed_http_responses, nmap_top_ports, output_directory, + show=False): """ enumerates domain from domains """ @@ -414,7 +415,8 @@ def enumerate_domains(domains, output_file, html_output, allowed_http_responses, nmap_output = subprocess.run( ["nmap", "--top-ports", str(nmap_top_ports), "-n", d], capture_output=True) print('{} nmap: '.format(colors['grey']), [port.decode("utf-8") - for port in nmap_output.stdout.split(b"\n") if port.find(b"open") > 0], '{}'.format(colors['white'])) + for port in nmap_output.stdout.split(b"\n") if + port.find(b"open") > 0], '{}'.format(colors['white'])) send_request('http', d, output_file, html_output, allowed_http_responses, nmap_output, ip, output_directory) @@ -473,14 +475,14 @@ def enumerate_from_crt_sh(domain): def main(): - parser = argparse.ArgumentParser() allowed_http_responses = [] parser.add_argument( "-f", "--file", help="File with list of hostnames to check (-t/--target will be ignored)") parser.add_argument( - "-t", "--target", help="Target domain - will use crt.sh to perform subdomain enumeration (-f/--file will be ignored)") + "-t", "--target", + help="Target domain - will use crt.sh to perform subdomain enumeration (-f/--file will be ignored)") parser.add_argument( "-s", "--success", help="Show all responses, including exceptions", action='store_true') parser.add_argument( @@ -488,10 +490,12 @@ def main(): parser.add_argument( "-d", "--dir", help="Output directory name (default: report/)") parser.add_argument( - "-c", "--code", help="Show only selected HTTP response status codes, comma separated", default='200,206,301,302,403,422,500' + "-c", "--code", help="Show only selected HTTP response status codes, comma separated", + default='200,206,301,302,403,422,500' ) parser.add_argument( - "-n", "--nmap", help="use nmap for port scanning (slows down the whole enumeration A LOT, so be warned!)", action='store_true' + "-n", "--nmap", help="use nmap for port scanning (slows down the whole enumeration A LOT, so be warned!)", + action='store_true' ) parser.add_argument( "-p", "--ports", help="--top-ports option for nmap (default = 100)", default=100 From a73834660df5f7131b56f2c303c2a3a3079eefef Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Wed, 24 Jul 2024 02:22:02 +0100 Subject: [PATCH 16/62] [pef] bugfixes --- pef/pef.py | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/pef/pef.py b/pef/pef.py index 6c8180d..ae0d5b2 100755 --- a/pef/pef.py +++ b/pef/pef.py @@ -32,10 +32,10 @@ # - repeat until the source # -import sys +import argparse import os import re -import argparse +import sys from imports import pefdocs from imports.beautyConsole import beautyConsole @@ -200,6 +200,7 @@ def analyse_line(self, l, i, fn, f, line): if occurence found, output is printed """ res = None + number_of_isses = 0 # there has to be space before function call; prevents from false-positives strings contains PHP function names atfn = f"@{fn}" fn = f"{fn}" @@ -211,8 +212,10 @@ def analyse_line(self, l, i, fn, f, line): f.name, l, i, fn, self.severity, self.level, self.source_or_sink) else: res = self.print_code_line( - f.name, l, i, fn + (')' if '(' in fn else ''), self.severity, self.level, self.source_or_sink) - return res + f.name, l, i, fn + (')' if '(' in fn else ''), self.severity, self.level, + self.source_or_sink) + number_of_isses = number_of_isses + 1 if res is not None else number_of_isses + return number_of_isses def print_code_line(self, file_name, _line, i, fn, severity="", level='ALL', source_or_sink='ALL', verbose=False): """ @@ -251,7 +254,7 @@ def print_code_line(self, file_name, _line, i, fn, severity="", level='ALL', sou severity[impact] = 1 else: severity[impact] = severity[impact] + 1 - return found > 0 + return found def main(self, src): """ @@ -268,9 +271,10 @@ def main(self, src): if self.level: if not self.is_comment(line): for fn in exploitableFunctions: - if self.analyse_line(l, i, fn, f, line) == True: + number_of_issues = self.analyse_line(l, i, fn, f, line) + if number_of_issues > 0: res = True - file_found += 1 + file_found += number_of_issues return (res, file_found) # return how many findings in current file def run(self): @@ -299,7 +303,7 @@ def run(self): total_found += file_found else: self.scanned_files = self.scanned_files + 1 - (res, self.found_entries) = self.main(self.filename) + (res, total_found) = self.main(self.filename) # print summary self.print_summary(total_found) @@ -315,8 +319,8 @@ def print_summary(self, total_found: int) -> None: prints summary at the bottom of search results """ print(f"{beautyConsole.getColor('white')}Total issues found: {total_found}") - print( - f"\n{beautyConsole.getColor('grey')}Cmd arguments: {' '.join(sys.argv[1:])}\n") + print(f"\n{beautyConsole.getColor('grey')}Cmd arguments: {' '.join(sys.argv[1:])}") + print(f"{beautyConsole.getColor('grey')}Level: {self.level}\n") # main program @@ -336,9 +340,9 @@ def print_summary(self, total_found: int) -> None: parser.add_argument( "-l", "--level", help="severity level: ALL, LOW, MEDIUM, HIGH or CRITICAL; default: ALL") parser.add_argument( - "-S", "--source", help="show only sources", action="store_true") + "-S", "--sources", help="show only sources", action="store_true") parser.add_argument( - "-K", "--sink", help="show only sinks", action="store_true") + "-K", "--sinks", help="show only sinks", action="store_true") parser.add_argument( "-f", "--function", @@ -352,12 +356,12 @@ def print_summary(self, total_found: int) -> None: args = parser.parse_args() - level = args.level.upper() if args.level else 'ALL' + level = args.level.upper() if args.level else 'MEDIUM,HIGH,CRITICAL' source_or_sink = 'ALL' - if args.source: + if args.sources: source_or_sink = 'source' - if args.sink: + if args.sinks: source_or_sink = 'sink' filename = args.dir From 69337abd0b351eaed21a64ab671456a8d840dfd4 Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Wed, 24 Jul 2024 07:41:47 +0100 Subject: [PATCH 17/62] [pef] bugfixes --- pef/pef.py | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/pef/pef.py b/pef/pef.py index ae0d5b2..94c0c43 100755 --- a/pef/pef.py +++ b/pef/pef.py @@ -199,8 +199,8 @@ def analyse_line(self, l, i, fn, f, line): if occurence found, output is printed """ - res = None - number_of_isses = 0 + total_number_of_isses = None + meets_criteria = 0 # there has to be space before function call; prevents from false-positives strings contains PHP function names atfn = f"@{fn}" fn = f"{fn}" @@ -208,16 +208,16 @@ def analyse_line(self, l, i, fn, f, line): # @ prevents from output being echoed if fn in line or atfn in line: if fn == "`": - res = self.print_code_line( + total_number_of_isses = self.print_code_line( f.name, l, i, fn, self.severity, self.level, self.source_or_sink) else: - res = self.print_code_line( + total_number_of_isses = self.print_code_line( f.name, l, i, fn + (')' if '(' in fn else ''), self.severity, self.level, self.source_or_sink) - number_of_isses = number_of_isses + 1 if res is not None else number_of_isses - return number_of_isses + meets_criteria = meets_criteria + 1 if total_number_of_isses is not None else meets_criteria + return (meets_criteria, total_number_of_isses) - def print_code_line(self, file_name, _line, i, fn, severity="", level='ALL', source_or_sink='ALL', verbose=False): + def print_code_line(self, file_name, _line, i, fn, severity="", level='ALL', source_or_sink='ALL'): """ prints formatted code line """ @@ -228,7 +228,7 @@ def print_code_line(self, file_name, _line, i, fn, severity="", level='ALL', sou "critical": "red" } - found = 0 + meets_criteria = 0 # print legend only if there i sentry in pefdocs.py if fn and fn.strip() in pefdocs.exploitableFunctionsDesc.keys(): @@ -249,12 +249,12 @@ def print_code_line(self, file_name, _line, i, fn, severity="", level='ALL', sou beautyConsole.getColor("grey"))) if self.verbose: print(f"\t{doc[1]}\n\t{doc[0]}\n") - found += 1 + meets_criteria += 1 if impact not in severity.keys(): severity[impact] = 1 else: severity[impact] = severity[impact] + 1 - return found + return meets_criteria def main(self, src): """ @@ -271,8 +271,8 @@ def main(self, src): if self.level: if not self.is_comment(line): for fn in exploitableFunctions: - number_of_issues = self.analyse_line(l, i, fn, f, line) - if number_of_issues > 0: + (meets_criteria, number_of_issues) = self.analyse_line(l, i, fn, f, line) + if number_of_issues is not None: res = True file_found += number_of_issues return (res, file_found) # return how many findings in current file @@ -291,16 +291,14 @@ def run(self): for root, _, files in os.walk(self.filename): if self.skip_vendor is True and "vendor" in root: continue - prev_filename = "" for f in files: extension = f.split('.')[-1:][0] if extension in ['php', 'inc', 'php3', 'php4', 'php5', 'phtml']: self.scanned_files = self.scanned_files + 1 (res, file_found) = self.main(os.path.join(root, f)) - if self.phpfunction == '' and res is not None and f != prev_filename: + if file_found > 0: print(f">>> {f} <<<\t{'-' * (115 - len(f))}\n\n") - prev_filename = f - total_found += file_found + total_found += file_found else: self.scanned_files = self.scanned_files + 1 (res, total_found) = self.main(self.filename) @@ -318,7 +316,7 @@ def print_summary(self, total_found: int) -> None: """ prints summary at the bottom of search results """ - print(f"{beautyConsole.getColor('white')}Total issues found: {total_found}") + print(f"{beautyConsole.getColor('white')}Issues found: {total_found}") print(f"\n{beautyConsole.getColor('grey')}Cmd arguments: {' '.join(sys.argv[1:])}") print(f"{beautyConsole.getColor('grey')}Level: {self.level}\n") @@ -338,7 +336,8 @@ def print_summary(self, total_found: int) -> None: parser.add_argument( "-v", "--verbose", help="show documentation", action="store_true") parser.add_argument( - "-l", "--level", help="severity level: ALL, LOW, MEDIUM, HIGH or CRITICAL; default: ALL") + "-l", "--level", + help="severity: ALL, LOW, MEDIUM, HIGH or CRITICAL; default: ALL\nif -f is set, this setting is ignored") parser.add_argument( "-S", "--sources", help="show only sources", action="store_true") parser.add_argument( @@ -357,6 +356,10 @@ def print_summary(self, total_found: int) -> None: args = parser.parse_args() level = args.level.upper() if args.level else 'MEDIUM,HIGH,CRITICAL' + + # if we are looking for a specific function, level is not taken into account + if args.function is not None: + level = 'ALL' source_or_sink = 'ALL' if args.sources: From 7732955239e7103a803011a90c60046e2673a8c9 Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Wed, 24 Jul 2024 11:51:07 +0100 Subject: [PATCH 18/62] [s0mbra] LinkFinder by Gerben_Javado added --- s0mbra.sh | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/s0mbra.sh b/s0mbra.sh index 924c6e3..a1acd0a 100755 --- a/s0mbra.sh +++ b/s0mbra.sh @@ -746,6 +746,13 @@ hshr() { echo -e "$BLUE\n[s0mbra] Done! $CLR" } +# extract links and API endpoints from JavaScript file +links() { + echo -e "$BLUE[s0mbra] Extracting links and API endpoints from $1...$CLR" + python /Users/bl4de/hacking/tools/LinkFinder/linkfinder.py -i $1 -o cli + echo -e "$BLUE\n[s0mbra] Done! $CLR" +} + ### menu cmd=$1 @@ -876,6 +883,9 @@ case "$cmd" in rubysast) ruby_sast "$2" ;; + links) + links "$2" + ;; *) clear echo -e "$BLUE_BG:: RECON ::\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t$CLR" @@ -905,7 +915,7 @@ case "$cmd" in echo -e "$CYAN unmin $GRAY[FILE]\t\t\t$YELLOW(JavaScript)$CLR\t$CYAN snyktest $GRAY[DIR]\t\t\t$YELLOW(JavaScript)$CLR" echo -e "$CYAN pysast $GRAY[DIR]\t\t\t$YELLOW(Python)$CLR\t$CYAN phpsast $GRAY[DIR]\t\t\t$YELLOW(PHP)$CLR" echo -e "$CYAN rubysast $GRAY[DIR]\t\t\t$YELLOW(Ruby)$CLR\t\t$CYAN disass $GRAY[BINARY]\t\t$YELLOW(asm)$CLR" - echo -e "$CYAN unjar $GRAY[.jar FILE]\t\t$YELLOW(Java)$CLR" + echo -e "$CYAN unjar $GRAY[.jar FILE]\t\t$YELLOW(Java)$CLR\t\t$CYAN links $GRAY[FILE|DIR|URL]\t\t$YELLOW(JavaScript)$CLR" echo -e "$BLUE_BG:: ANDROID ::\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t$CLR" echo -e "$CYAN jadx $GRAY[.apk FILE]\t\t$YELLOW(Java)$CLR\t\t$CYAN dex_to_jar $GRAY[.dex file]$CLR\t\t$YELLOW(Java)$CLR" echo -e "$CYAN apk $GRAY[.apk FILE]$CLR\t\t$YELLOW(Java)$CLR\t\t$CYAN abe $GRAY[.ab FILE]$CLR\t\t\t$YELLOW(Java)$CLR" From eb80f832f21ed709a842298c2a4c9e2a1f083306 Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Wed, 24 Jul 2024 12:12:44 +0100 Subject: [PATCH 19/62] [s0mbra] added SecretFinder --- s0mbra.sh | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/s0mbra.sh b/s0mbra.sh index a1acd0a..bf38b10 100755 --- a/s0mbra.sh +++ b/s0mbra.sh @@ -742,14 +742,27 @@ b64() { # hash/encode string hshr() { echo -e "$BLUE[s0mbra] Hash/encoode $1...$CLR" - hasher $1 + hasher "$1" echo -e "$BLUE\n[s0mbra] Done! $CLR" } # extract links and API endpoints from JavaScript file -links() { - echo -e "$BLUE[s0mbra] Extracting links and API endpoints from $1...$CLR" - python /Users/bl4de/hacking/tools/LinkFinder/linkfinder.py -i $1 -o cli +urls() { + echo -e "$BLUE[s0mbra] Extracting URLs from $1...$CLR" + python /Users/bl4de/hacking/tools/LinkFinder/linkfinder.py -i "$1" -o cli | rg http | sort -u + echo -e "$BLUE\n[s0mbra] Done! $CLR" +} + +endpoints() { + echo -e "$BLUE[s0mbra] Extracting URLs from $1...$CLR" + python /Users/bl4de/hacking/tools/LinkFinder/linkfinder.py -i "$1" -o cli | rg -v http | sort -u + echo -e "$BLUE\n[s0mbra] Done! $CLR" +} + +# extract secrets from JavaScript file +secrets() { + echo -e "$BLUE[s0mbra] Extracting secrets from $1...$CLR" + python /Users/bl4de/hacking/tools/SecretFinder/SecretFinder.py -i "$1" -o cli | sort -u echo -e "$BLUE\n[s0mbra] Done! $CLR" } @@ -883,8 +896,14 @@ case "$cmd" in rubysast) ruby_sast "$2" ;; - links) - links "$2" + urls) + urls "$2" + ;; + endpoints) + endpoints "$2" + ;; + secrets) + secrets "$2" ;; *) clear @@ -915,7 +934,8 @@ case "$cmd" in echo -e "$CYAN unmin $GRAY[FILE]\t\t\t$YELLOW(JavaScript)$CLR\t$CYAN snyktest $GRAY[DIR]\t\t\t$YELLOW(JavaScript)$CLR" echo -e "$CYAN pysast $GRAY[DIR]\t\t\t$YELLOW(Python)$CLR\t$CYAN phpsast $GRAY[DIR]\t\t\t$YELLOW(PHP)$CLR" echo -e "$CYAN rubysast $GRAY[DIR]\t\t\t$YELLOW(Ruby)$CLR\t\t$CYAN disass $GRAY[BINARY]\t\t$YELLOW(asm)$CLR" - echo -e "$CYAN unjar $GRAY[.jar FILE]\t\t$YELLOW(Java)$CLR\t\t$CYAN links $GRAY[FILE|DIR|URL]\t\t$YELLOW(JavaScript)$CLR" + echo -e "$CYAN unjar $GRAY[.jar FILE]\t\t$YELLOW(Java)$CLR\t\t$CYAN urls $GRAY[FILE|DIR|URL]\t\t$YELLOW(JavaScript)$CLR" + echo -e "$CYAN secrets $GRAY[FILE|DIR|URL]\t\t$YELLOW(JavaScript)$CLR\t$CYAN endpoints $GRAY[FILE|DIR|URL]\t$YELLOW(JavaScript)$CLR" echo -e "$BLUE_BG:: ANDROID ::\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t$CLR" echo -e "$CYAN jadx $GRAY[.apk FILE]\t\t$YELLOW(Java)$CLR\t\t$CYAN dex_to_jar $GRAY[.dex file]$CLR\t\t$YELLOW(Java)$CLR" echo -e "$CYAN apk $GRAY[.apk FILE]$CLR\t\t$YELLOW(Java)$CLR\t\t$CYAN abe $GRAY[.ab FILE]$CLR\t\t\t$YELLOW(Java)$CLR" From f48eb0ca891290398f73d4ef266f83d15c431574 Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Wed, 24 Jul 2024 12:38:33 +0100 Subject: [PATCH 20/62] [s0mbra] cleanup; remove broken tools; update menu; --- s0mbra.sh | 69 +++++++++++++++---------------------------------------- 1 file changed, 18 insertions(+), 51 deletions(-) diff --git a/s0mbra.sh b/s0mbra.sh index bf38b10..fc39a73 100755 --- a/s0mbra.sh +++ b/s0mbra.sh @@ -50,7 +50,7 @@ quick_nmap_scan() { } # runs Python 3 built-in HTTP server on [PORT] -http() { +http_server() { STACK=$2 echo -e "$BLUE[s0mbra] Running $STACK HTTP Server in current directory on port $1$CLR" echo -e "$GRAY\navailable network interfaces:$YELLOW" @@ -78,37 +78,37 @@ http() { # runs john with rockyou.txt against hash type [FORMAT] and file [HASHES] rockyou_john() { echo -e "$BLUE[s0mbra] Running john with rockyou dictionary against $1 of type $2$CLR" - echo > "$HACKING_HOME"/tools/jtr/run/john.pot + echo > "$HACKING_HOME"/tools/JohnTheRipper/run/john.pot if [[ -n $2 ]]; then - "$HACKING_HOME"/tools/jtr/run/john --wordlist="$HACKING_HOME"/dictionaries/rockyou.txt --format="$2" "$1" + "$HACKING_HOME"/tools/JohnTheRipper/run/john --wordlist="$HACKING_HOME"/dictionaries/rockyou.txt --format="$2" "$1" elif [[ -z $2 ]]; then - "$HACKING_HOME"/tools/jtr/run/john --wordlist="$HACKING_HOME"/dictionaries/rockyou.txt "$1" + "$HACKING_HOME"/tools/JohnTheRipper/run/john --wordlist="$HACKING_HOME"/dictionaries/rockyou.txt "$1" fi - cat "$HACKING_HOME"/tools/jtr/run/john.pot + cat "$HACKING_HOME"/tools/JohnTheRipper/run/john.pot echo -e "\n$BLUE[s0mbra] Done." osascript -e 'display notification "our choom John has left the house..." with title "s0mbra says:"' } -# show JTR's pot file +# show JohnTheRipper's pot file john_pot() { echo -e "$BLUE[s0mbra] Joghn The Ripper pot file:$GRAY" - cat "$HACKING_HOME"/tools/jtr/run/john.pot + cat "$HACKING_HOME"/tools/JohnTheRipper/run/john.pot echo -e "\n$BLUE[s0mbra] Done." } # ZIP password cracking with rockyou.txt rockyou_zip() { echo -e "$BLUE[s0mbra] Running $MAGENTA zip2john $BLUE and prepare hash for hashcat..." - "$HACKING_HOME"/tools/jtr/run/zip2john "$1" | cut -d ':' -f 2 > ./hashes.txt + "$HACKING_HOME"/tools/JohnTheRipper/run/zip2john "$1" | cut -d ':' -f 2 > ./hashes.txt echo -e "$BLUE[s0mbra] Starting $MAGENTA hashcat $BLUE (using $YELLOW rockyou.txt $BLUE dictionary against $YELLOW hashes.txt $BLUE file)...$CLR" hashcat -m 13600 ./hashes.txt ~/hacking/dictionaries/rockyou.txt echo -e "\n$BLUE[s0mbra] Done." } -# converts id_rsa to JTR format for cracking SSH key +# converts id_rsa to JohnTheRipper format for cracking SSH key ssh_to_john() { - echo -e "$BLUE[s0mbra] Converting SSH id_rsa key to JTR format to crack it$CLR" - python "$HACKING_HOME"/tools/jtr/run/sshng2john.py "$1" > "$1".hash + echo -e "$BLUE[s0mbra] Converting SSH id_rsa key to JohnTheRipper format to crack it$CLR" + python "$HACKING_HOME"/tools/JohnTheRipper/run/sshng2john.py "$1" > "$1".hash echo -e "$BLUE[s0mbra] We have a hash.\n" echo -e "$BLUE[s0mbra] Let's now crack it!" rockyou_john "$1".hash @@ -245,20 +245,6 @@ scope() { echo -e "\n$BLUE[s0mbra] Done.$CLR" } -# OSINT -photon() { - URL=$1 - OUTPUT_DIR=$2 - TMPDIR=$(pwd)/photon/$OUTPUT_DIR - if [[ ! -d $TMPDIR ]]; then - mkdir -p $TMPDIR - fi - echo -e "$BLUE[s0mbra] Let's do some OSINT stuff around $URL...$CLR\n" - /usr/local/homebrew/bin/python3 /Users/bl4de/hacking/tools/Photon/photon.py -u "$URL" -l 5 -t 10 -o "$TMPDIR" - ls -lRA "$TMPDIR" - echo -e "\n$BLUE[s0mbra] Done.$CLR" -} - # quick scope, but for single domain - no need to create scope file peek() { TMPDIR=$(pwd)/$1 @@ -381,19 +367,6 @@ recon() { echo -e "\n$BLUE[s0mbra] Done.$CLR" } -# runs GET parameter(s) discovery -_arjun() { - clear - if [[ -z $2 ]]; then - SELECTED_DICT=/Users/bl4de/hacking/dictionaries/urlparams_medium.txt - else - SELECTED_DICT="$2" - fi - echo -e "$BLUE[s0mbra] Trying to discover GET params on $1 using $SELECTED_DICT...$GRAY" - arjun -u "$1" -w $SELECTED_DICT - echo -e "$BLUE\n[s0mbra] Done! $CLR" -} - fu() { # use starter.txt as default dictionary if [[ -z $2 ]]; then @@ -779,12 +752,6 @@ case "$cmd" in peek) peek "$2" ;; - photon) - photon "$2" "$3" - ;; - arjun) - _arjun "$2" "$3" - ;; recon) recon "$2" "$3" "$4" ;; @@ -800,8 +767,8 @@ case "$cmd" in quick_nmap_scan) quick_nmap_scan "$2" "$3" ;; - http) - http "$2" "$3" + http_server) + http_server "$2" "$3" ;; rockyou_john) rockyou_john "$2" "$3" @@ -909,26 +876,26 @@ case "$cmd" in clear echo -e "$BLUE_BG:: RECON ::\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t$CLR" echo -e "$CYAN scope $GRAY[SCOPE_FILE]$CLR\t\t\t\t$CYAN recon $GRAY[HOST] [OPTIONS:nmap,nikto,vhosts,ffuf,subdomanizer] [PROTO http/https]$CLR" - echo -e "$CYAN peek $GRAY[DOMAIN]$CLR\t\t\t\t\t$CYAN photon $GRAY[HOST] [OUTPUT_DIR]$CLR" + echo -e "$CYAN peek $GRAY[DOMAIN]$CLR" echo -e "$BLUE_BG:: WEB ::\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t$CLR" echo -e "$CYAN fu $GRAY[URL] [DICT] [*EXT,/ or -] [HTTP RESP.]$CLR\t$CYAN apifuzz $GRAY[BASE_URL] [ENDPOINTS]$CLR\t$YELLOW(REST)$CLR" echo -e "$CYAN graphw00f $GRAY[HOST]$CLR\t\t$YELLOW(GraphQl)$CLR\t$CYAN gql $GRAY[TARGET_URL]$CLR\t\t$YELLOW(GraphQL)$CLR" - echo -e "$CYAN kiterunner $GRAY[HOST] (*apis)$CLR\t$YELLOW(REST)$CRL\t\t$CYAN arjun $GRAY[HOST] [DICT]$CLR" + echo -e "$CYAN kiterunner $GRAY[HOST] (*apis)$CLR\t$YELLOW(REST)$CRL" echo -e "$BLUE_BG:: CLOUD ::\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t$CLR" echo -e "$CYAN discloS3 $GRAY[URL]$CLR\t\t\t$YELLOW(AWS)$CLR\t\t$CYAN s3 $GRAY[BUCKET]$CLR\t\t\t$YELLOW(AWS)$CLR" echo -e "$CYAN s3get $GRAY[BUCKET] [key]$CLR\t\t$YELLOW(AWS)$CLR\t\t$CYAN s3ls $GRAY[BUCKET] [folder]$CLR\t\t$YELLOW(AWS)$CLR" echo -e "$BLUE_BG:: PENTEST TOOLS ::\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t$CLR" echo -e "$CYAN quick_nmap_scan $GRAY[IP] [*PORTS]\t$LIGHTGREEN(nmap)$CLR\t\t$CYAN full_nmap_scan $GRAY[IP] [*PORTS]\t$LIGHTGREEN(nmap)$CLR" - echo -e "$CYAN http $GRAY[PORT] [STACK]$CLR\t\t\t\t$CYAN shells $GRAY[IP] [PORT] $CLR" + echo -e "$CYAN http_server $GRAY[PORT] [STACK]$CLR\t\t\t$CYAN shells $GRAY[IP] [PORT] $CLR" echo -e "$CYAN nfs_enum $GRAY[IP]$CLR\t\t\t\t\t$CYAN smb_enum $GRAY[IP] [USER] [PASSWORD]$CLR" echo -e "$CYAN smb_get_file $GRAY[IP] [PATH] [user] [*password] $CLR\t$CYAN smb_mount $GRAY[IP] [SHARE] [USER]$CLR" echo -e "$CYAN smb_umount $CLR" echo -e "$BLUE_BG:: PASSWORDS CRACKIN' ::\t\t\t\t\t\t\t\t\t\t\t\t\t\t$CLR" - echo -e "$CYAN rockyou_john $GRAY[HASHES] [FORMAT]$CLR\t\t\t$CYAN ssh_to_john $GRAY[ID_RSA]$CLR" - echo -e "$CYAN rockyou_zip $GRAY[ZIP file]$CLR\t\t\t\t$CYAN john_pot$CLR" + echo -e "$CYAN rockyou_john $GRAY[HASHES] [FORMAT]\t$LIGHTGREEN(JohnTheRipper)$CLR\t$CYAN ssh_to_john $GRAY[ID_RSA]\t\t$LIGHTGREEN(JohnTheRipper)$CLR" + echo -e "$CYAN rockyou_zip $GRAY[ZIP file]\t\t$LIGHTGREEN(JohnTheRipper)$CLR\t$CYAN john_pot\t\t\t$LIGHTGREEN(JohnTheRipper)$CLR" echo -e "$BLUE_BG:: STATIC CODE ANALYSIS ::\t\t\t\t\t\t\t\t\t\t\t\t\t\t$CLR" echo -e "$CYAN unmin $GRAY[FILE]\t\t\t$YELLOW(JavaScript)$CLR\t$CYAN snyktest $GRAY[DIR]\t\t\t$YELLOW(JavaScript)$CLR" From 6f2bd813c03a9b6050de6abecdc3231bb70b855f Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Thu, 25 Jul 2024 01:05:24 +0100 Subject: [PATCH 21/62] [pef] Fix duplicates if function name was a part of another function name --- pef/pef.py | 26 ++++++++++++++------------ s0mbra.sh | 8 ++++---- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/pef/pef.py b/pef/pef.py index 94c0c43..a38fcbe 100755 --- a/pef/pef.py +++ b/pef/pef.py @@ -201,20 +201,22 @@ def analyse_line(self, l, i, fn, f, line): """ total_number_of_isses = None meets_criteria = 0 - # there has to be space before function call; prevents from false-positives strings contains PHP function names + tokens = [token for token in line.split(' ') if token is not '\n'] + + # check agains @ at the beginning of the function name atfn = f"@{fn}" fn = f"{fn}" - # also, it has to checked agains @ at the beginning of the function name - # @ prevents from output being echoed - if fn in line or atfn in line: - if fn == "`": - total_number_of_isses = self.print_code_line( - f.name, l, i, fn, self.severity, self.level, self.source_or_sink) - else: - total_number_of_isses = self.print_code_line( - f.name, l, i, fn + (')' if '(' in fn else ''), self.severity, self.level, - self.source_or_sink) - meets_criteria = meets_criteria + 1 if total_number_of_isses is not None else meets_criteria + + for token in tokens: + if token.startswith(fn) or token.startswith(atfn): + if fn == "`": + total_number_of_isses = self.print_code_line( + f.name, l, i, fn, self.severity, self.level, self.source_or_sink) + else: + total_number_of_isses = self.print_code_line( + f.name, l, i, fn + (')' if '(' in fn else ''), self.severity, self.level, + self.source_or_sink) + meets_criteria = meets_criteria + 1 if total_number_of_isses is not None else meets_criteria return (meets_criteria, total_number_of_isses) def print_code_line(self, file_name, _line, i, fn, severity="", level='ALL', source_or_sink='ALL'): diff --git a/s0mbra.sh b/s0mbra.sh index fc39a73..11b9a8c 100755 --- a/s0mbra.sh +++ b/s0mbra.sh @@ -32,7 +32,7 @@ full_nmap_scan() { fi echo -e "$BLUE\n[s0mbra] Done! $CLR" - osascript -e 'display notification "nmap finished, choomba!" with title "s0mbra says:"' + osascript -e 'display notification "Full nmap finished, choom!" with title "s0mbra says:"' } # runs --top-ports $2 against IP @@ -46,7 +46,7 @@ quick_nmap_scan() { fi echo -e "$BLUE\n[s0mbra] Done! $CLR" - osascript -e 'display notification "nmap finished, choomba!" with title "s0mbra says:"' + osascript -e 'display notification "Quick nmap finished, choom!" with title "s0mbra says:"' } # runs Python 3 built-in HTTP server on [PORT] @@ -285,7 +285,7 @@ peek() { echo -e "$GRAY sublister+subfinder found \t $YELLOW $(echo `wc -l $TMPDIR/subdomains_final.log` | cut -d" " -f 1) $GRAY subdomains" echo -e "$GRAY httpx found \t\t\t $YELLOW $(echo `wc -l $TMPDIR/httpx.log` | cut -d" " -f 1) $GRAY active web servers $GREEN" echo -e "\n$BLUE[s0mbra] Done.$CLR" - osascript -e 'display notification "Hey choomba, peek finished!" with title "s0mbra says:"' + osascript -e 'display notification "Hey choom, peek finished!" with title "s0mbra says:"' } # does recon on URL: nmap, ffuf, other smaller tools, ...? @@ -402,7 +402,7 @@ fu() { ffuf -ac -c -w /Users/bl4de/hacking/dictionaries/$SELECTED_DICT.txt -u $1/FUZZ -mc $HTTP_RESP_CODES -H "User-Agent: wearehackerone" -H "X-Hackerone: bl4de" fi echo -e "$BLUE\n[s0mbra] Done! $CLR" - osascript -e 'display notification "ffuf finished, choomba!" with title "s0mbra says:"' + osascript -e 'display notification "ffuf finished, choom!" with title "s0mbra says:"' } api_fuzz() { From e60d034ea7a9c771b28de5b109a03f7c24020cf4 Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Thu, 25 Jul 2024 22:16:29 +0100 Subject: [PATCH 22/62] [pef] fix condition --- pef/pef.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pef/pef.py b/pef/pef.py index a38fcbe..df18390 100755 --- a/pef/pef.py +++ b/pef/pef.py @@ -201,7 +201,7 @@ def analyse_line(self, l, i, fn, f, line): """ total_number_of_isses = None meets_criteria = 0 - tokens = [token for token in line.split(' ') if token is not '\n'] + tokens = [token for token in line.split(' ') if token != "\n"] # check agains @ at the beginning of the function name atfn = f"@{fn}" From 6d7d6fa5205981ffb340cc73d6dacf73e566f6ea Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Wed, 31 Jul 2024 08:20:32 +0100 Subject: [PATCH 23/62] [s0mbra] remove redundant scope recon --- s0mbra.sh | 43 +------------------------------------------ 1 file changed, 1 insertion(+), 42 deletions(-) diff --git a/s0mbra.sh b/s0mbra.sh index 11b9a8c..e4f15d2 100755 --- a/s0mbra.sh +++ b/s0mbra.sh @@ -208,43 +208,6 @@ nfs_enum() { echo -e "\n$BLUE[s0mbra] Done." } -# quick subdomain enum + available HTTP server(s) - to find out if a program is -# actually worth to look into :D -scope() { - TMPDIR=$(pwd) - START_TIME=$(date) - echo -e "$BLUE[s0mbra] Let's see what we've got here...$CLR\n" - - # sublister - echo -e "\n$GREEN--> sublister$CLR\n" - for domain in $(cat scope); do - sublister -v -d $domain -o "$TMPDIR/sublister_$domain.log" - done - - # subfinder - echo -e "\n$GREEN--> subfinder$CLR\n" - subfinder -nW -all -v -dL $1 -o $TMPDIR/subfinder.log - - # prepare list of uniqe subdomains - cat sub* > step1 - sed 's/
/#/g' step1 | tr '#' '\n' > step2 - sort -u -k 1 step2 > subdomains_final.log - rm -f step* - - # httpx - echo -e "\n$GREEN--> httpx$CLR\n" - httpx -H "User-Agent: wearehackerone" -H "X-Hackerone: bl4de" -silent -status-code -web-server -tech-detect -ip -cname -cdn -rl 20 -exclude-cdn -l $TMPDIR/subdomains_final.log -o $TMPDIR/httpx.log - - END_TIME=$(date) - echo -e "$GREEN\nstarted at: $RED $START_TIME $GREEN" - echo -e "finished at: $RED $END_TIME $GREEN\n" - echo -e " $GRAY sublister+subfinder found \t $YELLOW $(echo `wc -l $TMPDIR/subdomains_final.log` | cut -d" " -f 1) $GRAY subdomains" - echo -e " $GRAY httpx found \t\t $YELLOW $(echo `wc -l $TMPDIR/httpx.log` | cut -d" " -f 1) $GRAY active web servers $GREEN" - echo -e " $GRAY HTTP servers responding 200 OK: $CLR\n" - grep 200 $TMPDIR/httpx.log - echo -e "\n$BLUE[s0mbra] Done.$CLR" -} - # quick scope, but for single domain - no need to create scope file peek() { TMPDIR=$(pwd)/$1 @@ -746,9 +709,6 @@ case "$cmd" in set_ip) set_ip "$2" ;; - scope) - scope "$2" - ;; peek) peek "$2" ;; @@ -875,8 +835,7 @@ case "$cmd" in *) clear echo -e "$BLUE_BG:: RECON ::\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t$CLR" - echo -e "$CYAN scope $GRAY[SCOPE_FILE]$CLR\t\t\t\t$CYAN recon $GRAY[HOST] [OPTIONS:nmap,nikto,vhosts,ffuf,subdomanizer] [PROTO http/https]$CLR" - echo -e "$CYAN peek $GRAY[DOMAIN]$CLR" + echo -e "$CYAN peek $GRAY[DOMAIN]$CLR\t\t\t\t\t$CYAN recon $GRAY[HOST] [OPTIONS:nmap,nikto,vhosts,ffuf,subdomanizer] [PROTO http/https]$CLR" echo -e "$BLUE_BG:: WEB ::\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t$CLR" echo -e "$CYAN fu $GRAY[URL] [DICT] [*EXT,/ or -] [HTTP RESP.]$CLR\t$CYAN apifuzz $GRAY[BASE_URL] [ENDPOINTS]$CLR\t$YELLOW(REST)$CLR" From 4b60093bf8b40b4bc232be162a552b3888d895e5 Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Sun, 4 Aug 2024 12:39:14 +0100 Subject: [PATCH 24/62] [s0mbra] Show only 200 OK in httpx output log --- s0mbra.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/s0mbra.sh b/s0mbra.sh index e4f15d2..d9689de 100755 --- a/s0mbra.sh +++ b/s0mbra.sh @@ -234,7 +234,7 @@ peek() { # httpx echo -e "\n$GREEN--> httpx$CLR\n" - httpx -H "User-Agent: wearehackerone" -H "X-Hackerone: bl4de" -silent -status-code -web-server -tech-detect -ip -cname -cdn -l $TMPDIR/subdomains_final.log -o $TMPDIR/httpx.log + httpx -H "User-Agent: wearehackerone" -H "X-Hackerone: bl4de" -fcdn cloudfront -v -stats -status-code -web-server -tech-detect -mc 200 -ip -cname -cdn -l $TMPDIR/subdomains_final.log -o $TMPDIR/httpx.log # cleanup echo -e "\n$BLUE[s0mbra] Remove temporary files...\n" From ee5cc1a548143d9d656afaaad217cd81cdd35e09 Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Sun, 4 Aug 2024 13:39:18 +0100 Subject: [PATCH 25/62] [s0mbra] webservers to enumerate existing subdomains file to find 200 OK --- s0mbra.sh | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/s0mbra.sh b/s0mbra.sh index d9689de..a915a8a 100755 --- a/s0mbra.sh +++ b/s0mbra.sh @@ -251,6 +251,26 @@ peek() { osascript -e 'display notification "Hey choom, peek finished!" with title "s0mbra says:"' } + +# httpx only list +webservers() { + START_TIME=$(date) + # httpx + echo -e "\n$GREEN--> httpx$CLR\n" + httpx -H "User-Agent: wearehackerone" -H "X-Hackerone: bl4de" -fcdn cloudfront -v -stats -status-code -web-server -tech-detect -mc 200 -ip -cname -cdn -l subdomains_final.log -o httpx.log + + # cleanup + echo -e "\n$BLUE[s0mbra] Remove temporary files...\n" + rm -rf httpx* + + END_TIME=$(date) + echo -e "$GREEN\nstarted at: $RED $START_TIME $GREEN" + echo -e "finished at: $RED $END_TIME $GREEN\n" + echo -e "$GRAY httpx found \t\t\t $YELLOW $(echo `wc -l $TMPDIR/httpx.log` | cut -d" " -f 1) $GRAY 200 OKs web servers $GREEN" + echo -e "\n$BLUE[s0mbra] Done.$CLR" + osascript -e 'display notification "Hey choom, we have some webservers to hack!" with title "s0mbra says:"' +} + # does recon on URL: nmap, ffuf, other smaller tools, ...? # pass ONLY hostname (without protocol prefix) recon() { @@ -712,6 +732,9 @@ case "$cmd" in peek) peek "$2" ;; + webservers) + webservers + ;; recon) recon "$2" "$3" "$4" ;; @@ -836,6 +859,7 @@ case "$cmd" in clear echo -e "$BLUE_BG:: RECON ::\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t$CLR" echo -e "$CYAN peek $GRAY[DOMAIN]$CLR\t\t\t\t\t$CYAN recon $GRAY[HOST] [OPTIONS:nmap,nikto,vhosts,ffuf,subdomanizer] [PROTO http/https]$CLR" + echo -e "$CYAN webservers $GRAY(uses subdomains_final.log in cwd)$CLR" echo -e "$BLUE_BG:: WEB ::\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t$CLR" echo -e "$CYAN fu $GRAY[URL] [DICT] [*EXT,/ or -] [HTTP RESP.]$CLR\t$CYAN apifuzz $GRAY[BASE_URL] [ENDPOINTS]$CLR\t$YELLOW(REST)$CLR" From ec984bd137d62267789f049990259d6d275795c0 Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Mon, 5 Aug 2024 02:08:12 +0100 Subject: [PATCH 26/62] [s0mbra] webservers to enumerate existing subdomains file to find 200 OK --- s0mbra.sh | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/s0mbra.sh b/s0mbra.sh index a915a8a..f9bfaec 100755 --- a/s0mbra.sh +++ b/s0mbra.sh @@ -254,19 +254,20 @@ peek() { # httpx only list webservers() { + if [[ -z $1 ]]; then + SUBDOMAINS="subdomains_final.log" + elif [[ -n $1 ]]; then + SUBDOMAINS="$1" + fi START_TIME=$(date) # httpx echo -e "\n$GREEN--> httpx$CLR\n" - httpx -H "User-Agent: wearehackerone" -H "X-Hackerone: bl4de" -fcdn cloudfront -v -stats -status-code -web-server -tech-detect -mc 200 -ip -cname -cdn -l subdomains_final.log -o httpx.log - - # cleanup - echo -e "\n$BLUE[s0mbra] Remove temporary files...\n" - rm -rf httpx* + httpx -H "User-Agent: wearehackerone" -H "X-Hackerone: bl4de" -fcdn cloudfront -v -stats -status-code -web-server -tech-detect -mc 200 -ip -cname -cdn -l $(pwd)/$SUBDOMAINS -o $(pwd)/httpx.log END_TIME=$(date) echo -e "$GREEN\nstarted at: $RED $START_TIME $GREEN" echo -e "finished at: $RED $END_TIME $GREEN\n" - echo -e "$GRAY httpx found \t\t\t $YELLOW $(echo `wc -l $TMPDIR/httpx.log` | cut -d" " -f 1) $GRAY 200 OKs web servers $GREEN" + echo -e "$GRAY httpx found \t\t\t $YELLOW $(echo `wc -l $(pwd)/httpx.log` | cut -d" " -f 1) $GRAY 200 OKs web servers $GREEN" echo -e "\n$BLUE[s0mbra] Done.$CLR" osascript -e 'display notification "Hey choom, we have some webservers to hack!" with title "s0mbra says:"' } @@ -733,7 +734,7 @@ case "$cmd" in peek "$2" ;; webservers) - webservers + webservers "$2" ;; recon) recon "$2" "$3" "$4" @@ -859,7 +860,7 @@ case "$cmd" in clear echo -e "$BLUE_BG:: RECON ::\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t$CLR" echo -e "$CYAN peek $GRAY[DOMAIN]$CLR\t\t\t\t\t$CYAN recon $GRAY[HOST] [OPTIONS:nmap,nikto,vhosts,ffuf,subdomanizer] [PROTO http/https]$CLR" - echo -e "$CYAN webservers $GRAY(uses subdomains_final.log in cwd)$CLR" + echo -e "$CYAN webservers $GRAY[SUBDOMAINS FILE]$CLR" echo -e "$BLUE_BG:: WEB ::\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t$CLR" echo -e "$CYAN fu $GRAY[URL] [DICT] [*EXT,/ or -] [HTTP RESP.]$CLR\t$CYAN apifuzz $GRAY[BASE_URL] [ENDPOINTS]$CLR\t$YELLOW(REST)$CLR" From ecf8d5b78526e668a489a98786d2cfd2ecb375b5 Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Wed, 7 Aug 2024 17:41:32 +0100 Subject: [PATCH 27/62] [diggit] Refactor to Python 3 syntax --- .pylintrc | 407 --------------------------------- .vscode/.ropeproject/config.py | 100 -------- .vscode/.ropeproject/objectdb | Bin 1646 -> 0 bytes diggit/{src => }/diggit.py | 34 ++- 4 files changed, 16 insertions(+), 525 deletions(-) delete mode 100644 .pylintrc delete mode 100644 .vscode/.ropeproject/config.py delete mode 100644 .vscode/.ropeproject/objectdb rename diggit/{src => }/diggit.py (82%) diff --git a/.pylintrc b/.pylintrc deleted file mode 100644 index 7b7a555..0000000 --- a/.pylintrc +++ /dev/null @@ -1,407 +0,0 @@ -[MASTER] - -# Specify a configuration file. -#rcfile= - -# Python code to execute, usually for sys.path manipulation such as -# pygtk.require(). -#init-hook= - -# Add files or directories to the blacklist. They should be base names, not -# paths. -ignore=CVS - -# Add files or directories matching the regex patterns to the blacklist. The -# regex matches against base names, not paths. -ignore-patterns= - -# Pickle collected data for later comparisons. -persistent=yes - -# List of plugins (as comma separated values of python modules names) to load, -# usually to register additional checkers. -load-plugins= - -# Use multiple processes to speed up Pylint. -jobs=1 - -# Allow loading of arbitrary C extensions. Extensions are imported into the -# active Python interpreter and may run arbitrary code. -unsafe-load-any-extension=no - -# A comma-separated list of package or module names from where C extensions may -# be loaded. Extensions are loading into the active Python interpreter and may -# run arbitrary code -extension-pkg-whitelist= - -# Allow optimization of some AST trees. This will activate a peephole AST -# optimizer, which will apply various small optimizations. For instance, it can -# be used to obtain the result of joining multiple strings with the addition -# operator. Joining a lot of strings can lead to a maximum recursion error in -# Pylint and this flag can prevent that. It has one side effect, the resulting -# AST will be different than the one from reality. This option is deprecated -# and it will be removed in Pylint 2.0. -optimize-ast=no - - -[MESSAGES CONTROL] - -# Only show warnings with the listed confidence levels. Leave empty to show -# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED -confidence= - -# Enable the message, report, category or checker with the given id(s). You can -# either give multiple identifier separated by comma (,) or put this option -# multiple time (only on the command line, not in the configuration file where -# it should appear only once). See also the "--disable" option for examples. -#enable= - -# Disable the message, report, category or checker with the given id(s). You -# can either give multiple identifiers separated by comma (,) or put this -# option multiple times (only on the command line, not in the configuration -# file where it should appear only once).You can also use "--disable=all" to -# disable everything first and then reenable specific checks. For example, if -# you want to run only the similarities checker, you can use "--disable=all -# --enable=similarities". If you want to run only the classes checker, but have -# no Warning level messages displayed, use"--disable=all --enable=classes -# --disable=W" -disable=import-star-module-level,old-octal-literal,oct-method,print-statement,unpacking-in-except,parameter-unpacking,backtick,old-raise-syntax,old-ne-operator,long-suffix,dict-view-method,dict-iter-method,metaclass-assignment,next-method-called,raising-string,indexing-exception,raw_input-builtin,long-builtin,file-builtin,execfile-builtin,coerce-builtin,cmp-builtin,buffer-builtin,basestring-builtin,apply-builtin,filter-builtin-not-iterating,using-cmp-argument,useless-suppression,range-builtin-not-iterating,suppressed-message,no-absolute-import,old-division,cmp-method,reload-builtin,zip-builtin-not-iterating,intern-builtin,unichr-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,input-builtin,round-builtin,hex-method,nonzero-method,map-builtin-not-iterating - - -[REPORTS] - -# Set the output format. Available formats are text, parseable, colorized, msvs -# (visual studio) and html. You can also give a reporter class, eg -# mypackage.mymodule.MyReporterClass. -output-format=text - -# Put messages in a separate file for each module / package specified on the -# command line instead of printing them on stdout. Reports (if any) will be -# written in a file name "pylint_global.[txt|html]". This option is deprecated -# and it will be removed in Pylint 2.0. -files-output=no - -# Tells whether to display a full report or only the messages -reports=yes - -# Python expression which should return a note less than 10 (10 is the highest -# note). You have access to the variables errors warning, statement which -# respectively contain the number of errors / warnings messages and the total -# number of statements analyzed. This is used by the global evaluation report -# (RP0004). -evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) - -# Template used to display messages. This is a python new-style format string -# used to format the message information. See doc for all details -#msg-template= - - -[BASIC] - -# Good variable names which should always be accepted, separated by a comma -good-names=i,j,k,ex,Run,_ - -# Bad variable names which should always be refused, separated by a comma -bad-names=foo,bar,baz,toto,tutu,tata - -# Colon-delimited sets of names that determine each other's naming style when -# the name regexes allow several styles. -name-group= - -# Include a hint for the correct naming format with invalid-name -include-naming-hint=no - -# List of decorators that produce properties, such as abc.abstractproperty. Add -# to this list to register other decorators that produce valid properties. -property-classes=abc.abstractproperty - -# Regular expression matching correct function names -function-rgx=[a-z_][a-z0-9_]{2,30}$ - -# Naming hint for function names -function-name-hint=[a-z_][a-z0-9_]{2,30}$ - -# Regular expression matching correct variable names -variable-rgx=[a-z_][a-z0-9_]{2,30}$ - -# Naming hint for variable names -variable-name-hint=[a-z_][a-z0-9_]{2,30}$ - -# Regular expression matching correct constant names -const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$ - -# Naming hint for constant names -const-name-hint=(([A-Z_][A-Z0-9_]*)|(__.*__))$ - -# Regular expression matching correct attribute names -attr-rgx=[a-z_][a-z0-9_]{2,30}$ - -# Naming hint for attribute names -attr-name-hint=[a-z_][a-z0-9_]{2,30}$ - -# Regular expression matching correct argument names -argument-rgx=[a-z_][a-z0-9_]{2,30}$ - -# Naming hint for argument names -argument-name-hint=[a-z_][a-z0-9_]{2,30}$ - -# Regular expression matching correct class attribute names -class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$ - -# Naming hint for class attribute names -class-attribute-name-hint=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$ - -# Regular expression matching correct inline iteration names -inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$ - -# Naming hint for inline iteration names -inlinevar-name-hint=[A-Za-z_][A-Za-z0-9_]*$ - -# Regular expression matching correct class names -class-rgx=[A-Z_][a-zA-Z0-9]+$ - -# Naming hint for class names -class-name-hint=[A-Z_][a-zA-Z0-9]+$ - -# Regular expression matching correct module names -module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ - -# Naming hint for module names -module-name-hint=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$ - -# Regular expression matching correct method names -method-rgx=[a-z_][a-z0-9_]{2,30}$ - -# Naming hint for method names -method-name-hint=[a-z_][a-z0-9_]{2,30}$ - -# Regular expression which should only match function or class names that do -# not require a docstring. -no-docstring-rgx=^_ - -# Minimum line length for functions/classes that require docstrings, shorter -# ones are exempt. -docstring-min-length=-1 - - -[ELIF] - -# Maximum number of nested blocks for function / method body -max-nested-blocks=5 - - -[FORMAT] - -# Maximum number of characters on a single line. -max-line-length=100 - -# Regexp for a line that is allowed to be longer than the limit. -ignore-long-lines=^\s*(# )??$ - -# Allow the body of an if to be on the same line as the test if there is no -# else. -single-line-if-stmt=no - -# List of optional constructs for which whitespace checking is disabled. `dict- -# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}. -# `trailing-comma` allows a space between comma and closing bracket: (a, ). -# `empty-line` allows space-only lines. -no-space-check=trailing-comma,dict-separator - -# Maximum number of lines in a module -max-module-lines=1000 - -# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 -# tab). -indent-string=' ' - -# Number of spaces of indent required inside a hanging or continued line. -indent-after-paren=4 - -# Expected format of line ending, e.g. empty (any line ending), LF or CRLF. -expected-line-ending-format= - - -[LOGGING] - -# Logging modules to check that the string format arguments are in logging -# function parameter format -logging-modules=logging - - -[MISCELLANEOUS] - -# List of note tags to take in consideration, separated by a comma. -notes=FIXME,XXX,TODO - - -[SIMILARITIES] - -# Minimum lines number of a similarity. -min-similarity-lines=4 - -# Ignore comments when computing similarities. -ignore-comments=yes - -# Ignore docstrings when computing similarities. -ignore-docstrings=yes - -# Ignore imports when computing similarities. -ignore-imports=no - - -[SPELLING] - -# Spelling dictionary name. Available dictionaries: none. To make it working -# install python-enchant package. -spelling-dict= - -# List of comma separated words that should not be checked. -spelling-ignore-words= - -# A path to a file that contains private dictionary; one word per line. -spelling-private-dict-file= - -# Tells whether to store unknown words to indicated private dictionary in -# --spelling-private-dict-file option instead of raising a message. -spelling-store-unknown-words=no - - -[TYPECHECK] - -# Tells whether missing members accessed in mixin class should be ignored. A -# mixin class is detected if its name ends with "mixin" (case insensitive). -ignore-mixin-members=yes - -# List of module names for which member attributes should not be checked -# (useful for modules/projects where namespaces are manipulated during runtime -# and thus existing member attributes cannot be deduced by static analysis. It -# supports qualified module names, as well as Unix pattern matching. -ignored-modules= - -# List of class names for which member attributes should not be checked (useful -# for classes with dynamically set attributes). This supports the use of -# qualified names. -ignored-classes=optparse.Values,thread._local,_thread._local - -# List of members which are set dynamically and missed by pylint inference -# system, and so shouldn't trigger E1101 when accessed. Python regular -# expressions are accepted. -generated-members= - -# List of decorators that produce context managers, such as -# contextlib.contextmanager. Add to this list to register other decorators that -# produce valid context managers. -contextmanager-decorators=contextlib.contextmanager - - -[VARIABLES] - -# Tells whether we should check for unused import in __init__ files. -init-import=no - -# A regular expression matching the name of dummy variables (i.e. expectedly -# not used). -dummy-variables-rgx=(_+[a-zA-Z0-9]*?$)|dummy - -# List of additional names supposed to be defined in builtins. Remember that -# you should avoid to define new builtins when possible. -additional-builtins= - -# List of strings which can identify a callback function by name. A callback -# name must start or end with one of those strings. -callbacks=cb_,_cb - -# List of qualified module names which can have objects that can redefine -# builtins. -redefining-builtins-modules=six.moves,future.builtins - - -[CLASSES] - -# List of method names used to declare (i.e. assign) instance attributes. -defining-attr-methods=__init__,__new__,setUp - -# List of valid names for the first argument in a class method. -valid-classmethod-first-arg=cls - -# List of valid names for the first argument in a metaclass class method. -valid-metaclass-classmethod-first-arg=mcs - -# List of member names, which should be excluded from the protected access -# warning. -exclude-protected=_asdict,_fields,_replace,_source,_make - - -[DESIGN] - -# Maximum number of arguments for function / method -max-args=5 - -# Argument names that match this expression will be ignored. Default to name -# with leading underscore -ignored-argument-names=_.* - -# Maximum number of locals for function / method body -max-locals=15 - -# Maximum number of return / yield for function / method body -max-returns=6 - -# Maximum number of branch for function / method body -max-branches=12 - -# Maximum number of statements in function / method body -max-statements=50 - -# Maximum number of parents for a class (see R0901). -max-parents=7 - -# Maximum number of attributes for a class (see R0902). -max-attributes=7 - -# Minimum number of public methods for a class (see R0903). -min-public-methods=2 - -# Maximum number of public methods for a class (see R0904). -max-public-methods=20 - -# Maximum number of boolean expressions in a if statement -max-bool-expr=5 - - -[IMPORTS] - -# Deprecated modules which should not be used, separated by a comma -deprecated-modules=regsub,TERMIOS,Bastion,rexec - -# Create a graph of every (i.e. internal and external) dependencies in the -# given file (report RP0402 must not be disabled) -import-graph= - -# Create a graph of external dependencies in the given file (report RP0402 must -# not be disabled) -ext-import-graph= - -# Create a graph of internal dependencies in the given file (report RP0402 must -# not be disabled) -int-import-graph= - -# Force import order to recognize a module as part of the standard -# compatibility libraries. -known-standard-library= - -# Force import order to recognize a module as part of a third party library. -known-third-party=enchant - -# Analyse import fallback blocks. This can be used to support both Python 2 and -# 3 compatible code, which means that the block might have code that exists -# only in one or another interpreter, leading to false positives when analysed. -analyse-fallback-blocks=no - - -[EXCEPTIONS] - -# Exceptions that will emit a warning when being caught. Defaults to -# "Exception" -overgeneral-exceptions=Exception diff --git a/.vscode/.ropeproject/config.py b/.vscode/.ropeproject/config.py deleted file mode 100644 index d1e8f3d..0000000 --- a/.vscode/.ropeproject/config.py +++ /dev/null @@ -1,100 +0,0 @@ -# The default ``config.py`` -# flake8: noqa - - -def set_prefs(prefs): - """This function is called before opening the project""" - - # Specify which files and folders to ignore in the project. - # Changes to ignored resources are not added to the history and - # VCSs. Also they are not returned in `Project.get_files()`. - # Note that ``?`` and ``*`` match all characters but slashes. - # '*.pyc': matches 'test.pyc' and 'pkg/test.pyc' - # 'mod*.pyc': matches 'test/mod1.pyc' but not 'mod/1.pyc' - # '.svn': matches 'pkg/.svn' and all of its children - # 'build/*.o': matches 'build/lib.o' but not 'build/sub/lib.o' - # 'build//*.o': matches 'build/lib.o' and 'build/sub/lib.o' - prefs['ignored_resources'] = ['*.pyc', '*~', '.ropeproject', - '.hg', '.svn', '_svn', '.git', '.tox'] - - # Specifies which files should be considered python files. It is - # useful when you have scripts inside your project. Only files - # ending with ``.py`` are considered to be python files by - # default. - #prefs['python_files'] = ['*.py'] - - # Custom source folders: By default rope searches the project - # for finding source folders (folders that should be searched - # for finding modules). You can add paths to that list. Note - # that rope guesses project source folders correctly most of the - # time; use this if you have any problems. - # The folders should be relative to project root and use '/' for - # separating folders regardless of the platform rope is running on. - # 'src/my_source_folder' for instance. - #prefs.add('source_folders', 'src') - - # You can extend python path for looking up modules - #prefs.add('python_path', '~/python/') - - # Should rope save object information or not. - prefs['save_objectdb'] = True - prefs['compress_objectdb'] = False - - # If `True`, rope analyzes each module when it is being saved. - prefs['automatic_soa'] = True - # The depth of calls to follow in static object analysis - prefs['soa_followed_calls'] = 0 - - # If `False` when running modules or unit tests "dynamic object - # analysis" is turned off. This makes them much faster. - prefs['perform_doa'] = True - - # Rope can check the validity of its object DB when running. - prefs['validate_objectdb'] = True - - # How many undos to hold? - prefs['max_history_items'] = 32 - - # Shows whether to save history across sessions. - prefs['save_history'] = True - prefs['compress_history'] = False - - # Set the number spaces used for indenting. According to - # :PEP:`8`, it is best to use 4 spaces. Since most of rope's - # unit-tests use 4 spaces it is more reliable, too. - prefs['indent_size'] = 4 - - # Builtin and c-extension modules that are allowed to be imported - # and inspected by rope. - prefs['extension_modules'] = [] - - # Add all standard c-extensions to extension_modules list. - prefs['import_dynload_stdmods'] = True - - # If `True` modules with syntax errors are considered to be empty. - # The default value is `False`; When `False` syntax errors raise - # `rope.base.exceptions.ModuleSyntaxError` exception. - prefs['ignore_syntax_errors'] = False - - # If `True`, rope ignores unresolvable imports. Otherwise, they - # appear in the importing namespace. - prefs['ignore_bad_imports'] = False - - # If `True`, rope will insert new module imports as - # `from import ` by default. - prefs['prefer_module_from_imports'] = False - - # If `True`, rope will transform a comma list of imports into - # multiple separate import statements when organizing - # imports. - prefs['split_imports'] = False - - # If `True`, rope will sort imports alphabetically by module name - # instead of alphabetically by import statement, with from imports - # after normal imports. - prefs['sort_imports_alphabetically'] = False - - -def project_opened(project): - """This function is called after opening the project""" - # Do whatever you like here! diff --git a/.vscode/.ropeproject/objectdb b/.vscode/.ropeproject/objectdb deleted file mode 100644 index a1fd398f255f2fc48df49c99917d2a41fba552db..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1646 zcmb`HNq5sQ0ED3lI0=+cwz9TBSzMqtl%?!tErha^1hIp$9iy=$dhmO2i2S#) zv%K`eseZc6K{NAd>^~C;cIafqWI>mjk=?O9EC^z z#&)B3gEsXspio-0AeI&uO&a#lKn&K#%WQ7Jf z#xnck3Ma;7P7cVNQkY>g`dFVOlD zo;svH>N(o`vwq9x30Cyt{a@t%FBKa3dWYZps~%R_e~-lLq6hRQAJAKccNv5=h4&7b z9zh5r8rl)HMlhOv7_9^!if2J`79SNp72WSM(VBz*G`^(xs_;$Wd(kF8NPTSpt35LN QnZi=|l~J`794C&Ae`AYL#Q*>R diff --git a/diggit/src/diggit.py b/diggit/diggit.py similarity index 82% rename from diggit/src/diggit.py rename to diggit/diggit.py index ea52f3a..d682b06 100755 --- a/diggit/src/diggit.py +++ b/diggit/diggit.py @@ -1,7 +1,5 @@ #!/usr/bin/python -# -# bl4de | | https://twitter.com/_bl4de -# +## # diggit - gets .git repository import argparse import os @@ -32,29 +30,28 @@ def print_banner(): def print_object_details(objtype, objcontent, objhash, objfilename): """Prints and saves object details/content""" - print "\n" + term["cyan"] + "#" * 12 + " " + objhash \ - + " information " + "#" * 12 + term["endl"] - print "\n{0}[*] Object type: {3}{2}{1}{3}".format( - term["green"], objtype, term["red"], term["endl"]) - + print("\n" + term["cyan"] + "#" * 12 + " " + objhash + + " information " + "#" * 12 + term["endl"]) + print("\n{0}[*] Object type: {3}{2}{1}{3}".format( + term["green"], objtype, term["red"], term["endl"])) if objfilename != "": global localgitrepo tmpfp = localgitrepo + "/" + objfilename - print "{0}[*] Object filename: {3}{2}{1}{3}".format( - term["green"], objfilename, term["red"], term["endl"]) - print "{0}[*] Object saved in {2}:{1}".format( - term["green"], term["endl"], tmpfp) + print("{0}[*] Object filename: {3}{2}{1}{3}".format( + term["green"], objfilename, term["red"], term["endl"])) + print("{0}[*] Object saved in {2}:{1}".format( + term["green"], term["endl"], tmpfp)) tmpfile = open(tmpfp, "w") tmpfile.write("// diggit.py by @bl4de | {} content\n".format(objhash)) tmpfile.writelines(objcontent) tmpfile.close() - print "{0}[*] Object content:{1}\n".format(term["green"], term["endl"]) + print("{0}[*] Object content:{1}\n".format(term["green"], term["endl"])) if len(objcontent) < 2048: - print "{0}{1}{2}".format(term["yellow"], objcontent, term["endl"]) + print("{0}{1}{2}".format(term["yellow"], objcontent, term["endl"])) else: - print "{}[!] file too big to preview - {} kB{}".format( - term["red"], len(objcontent)/1024, term["endl"]) + print("{}[!] file too big to preview - {} kB{}".format( + term["red"], len(objcontent)/1024, term["endl"])) def get_object_url(objhash): @@ -115,7 +112,8 @@ def save_git_object(baseurl, objhash, berecursive, objfilename=""): parser.add_argument('-t', help='path to temporary Git folder on local machine') parser.add_argument('-o', help='object hash (SHA-1, all 40 characters)') - parser.add_argument('-r', default=False, + parser.add_argument('-r', + action="store_true", help='be recursive (if commit or tree hash ' 'found get all blobs too). Default is \'False\'') @@ -136,4 +134,4 @@ def save_git_object(baseurl, objhash, berecursive, objfilename=""): if baseurl and objecthash: print_banner() save_git_object(args.u, args.o, berecursive, "") - print "\n" + term["cyan"] + "#" * 78 + term["endl"] + print("\n" + term["cyan"] + "#" * 78 + term["endl"]) From 07cd00cc32c9731ac687716d5eb4883e0d5c1209 Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Wed, 7 Aug 2024 17:47:17 +0100 Subject: [PATCH 28/62] [nodestructor] Fix Python 3.12 related errors --- nodestructor/nodestructor.py | 270 +++++++++++++++++------------------ 1 file changed, 135 insertions(+), 135 deletions(-) diff --git a/nodestructor/nodestructor.py b/nodestructor/nodestructor.py index 1a4d9cd..19438b2 100755 --- a/nodestructor/nodestructor.py +++ b/nodestructor/nodestructor.py @@ -46,144 +46,144 @@ """ nodejs_patterns = [ - ".*url.parse\(", - ".*[pP]ath.normalize\(", - ".*fs.*File.*\(", - ".*fs.*Read.*\(", - ".*pipe\(res", - ".*bodyParser\(", - ".*eval\(", - ".*exec\(", - ".*execSync\(", - ".*execFile\(", - ".*execFileSync\(", - ".*res.write\(", - ".*child_process", - ".*child_process.exec\(", - ".*\sFunction\(", - ".*spawn\(", - ".*fork\(", - "\.shell", - "\.env", - "\.exitCode", - "\.pid", - ".*newBuffer\(", - ".*\.constructor\(", - ".*mysql\.createConnection\(", - ".*\.query\(", - ".*serialize\(", - ".*unserialize\(", - ".*__proto__" + r".*url.parse\(", + r".*[pP]ath.normalize\(", + r".*fs.*File.*\(", + r".*fs.*Read.*\(", + r".*pipe\(res", + r".*bodyParser\(", + r".*eval\(", + r".*exec\(", + r".*execSync\(", + r".*execFile\(", + r".*execFileSync\(", + r".*res.write\(", + r".*child_process", + r".*child_process.exec\(", + r".*\sFunction\(", + r".*spawn\(", + r".*fork\(", + r"\.shell", + r"\.env", + r"\.exitCode", + r"\.pid", + r".*newBuffer\(", + r".*\.constructor\(", + r".*mysql\.createConnection\(", + r".*\.query\(", + r".*serialize\(", + r".*unserialize\(", + r".*__proto__" ] -browser_patterns = [ - ".*urlsearchParams\(", - ".*innerHTML", - ".*innerText", - ".*textContent", - ".*outerHTML", - ".*appendChild\(", - ".*document.write\(", - ".*document.writeln\(", - ".*document.location", - ".*document.URL", - ".*document.documentURI", - ".*document.URLUnencoded", - ".*document.baseURI", - ".*document.referrer", - ".*location.href", - ".*location.search", - ".*location.hash", - ".*location.host", - ".*location.pathname", - ".*document.cookie", - ".*history.pushState\(", - ".*history.replaceState\(", - ".*navigator.userAgent", - ".*window.open\(", - ".*postMessage\(", - ".*.addEventListener\(['\"]message['\"]", - ".*.ajax\(", - ".*.getJSON\(", - ".*\$http\(", - ".*navigator.sendBeacon\(", - ".*\.add\(", - ".*\.append\(", - ".*\.after\(", - ".*\.before\(", - ".*\.html\(", - ".*\.prepend\(", - ".*\.replaceWith\(", - ".*\.wrap\(", - ".*\.wrapAll\(", - ".*\.dangerouslySetInnerHTML", - ".*\.bypassSecurityTrust.*", - ".*localStorage\.", - ".*sessionStorage\.", - ".*\$sce\.trustAsHtml\(", - ".*\.load\(", - ".*jQuery\.ajax\(", - ".*parseHTML", - ".*wrap.*\(", - ".*html\(", - ".*before\(", - ".*after\(", - ".*insertBefore\(", - ".*insertAfter\(", - ".*prepend", - ".*setContent\(", - ".*setHTML\(", - ".*\.SafeString\(", - ".*globalEval", - ".*execScript", - ".*insertAdjacentHTML\(", - ".*setAttribute.on", - ".*xhr.open", - ".*xhr.send", - "fetch", - ".*xhr.setRequestHeader.name", - ".*xhr.setRequestHeader.value", - ".*attr.href", - ".*attr.src", - ".*attr.data", - ".*attr.action", - ".*attr.formaction", - ".*prop.href", - ".*prop.src", - ".*prop.data", - ".*prop.action", - ".*prop.formaction", - "form.action", - ".*input.formaction", - ".*button.formaction", - ".*button.value", - ".*setAttribute.href", - ".*setAttribute.src", - ".*setAttribute.data", - ".*setAttribute.action", - ".*setAttribute.formaction", - "webdatabase.executeSql", - ".*document.domain", - ".*history.pushState", - ".*history.replaceState", - ".*setRequestHeader", - ".*websocket", - ".*anchor.href", - ".*anchor.target", - ".*JSON.parse", - ".*document.cookie", - ".*localStorage.setItem.name", - ".*localStorage.setItem.value", - ".*sessionStorage.setItem.name", - ".*sessionStorage.setItem.value", - ".*outerText", - ".*innerText", - ".*textContent", - ".*style.cssText", - ".*RegExp" +browrser_patterns = [ + r".*urlsearchParams\(", + r".*innerHTML", + r".*innerText", + r".*textContent", + r".*outerHTML", + r".*appendChild\(", + r".*document.write\(", + r".*document.writeln\(", + r".*document.location", + r".*document.URL", + r".*document.documentURI", + r".*document.URLUnencoded", + r".*document.baseURI", + r".*document.referrer", + r".*location.href", + r".*location.search", + r".*location.hash", + r".*location.host", + r".*location.pathname", + r".*document.cookie", + r".*history.pushState\(", + r".*history.replaceState\(", + r".*navigator.userAgent", + r".*window.open\(", + r".*postMessage\(", + r".*.addEventListener\(['\"]message['\"]", + r".*.ajax\(", + r".*.getJSON\(", + r".*\$http\(", + r".*navigator.sendBeacon\(", + r".*\.add\(", + r".*\.append\(", + r".*\.after\(", + r".*\.before\(", + r".*\.html\(", + r".*\.prepend\(", + r".*\.replaceWith\(", + r".*\.wrap\(", + r".*\.wrapAll\(", + r".*\.dangerouslySetInnerHTML", + r".*\.bypassSecurityTrust.*", + r".*localStorage\.", + r".*sessionStorage\.", + r".*\$sce\.trustAsHtml\(", + r".*\.load\(", + r".*jQuery\.ajax\(", + r".*parseHTML", + r".*wrap.*\(", + r".*html\(", + r".*before\(", + r".*after\(", + r".*insertBefore\(", + r".*insertAfter\(", + r".*prepend", + r".*setContent\(", + r".*setHTML\(", + r".*\.SafeString\(", + r".*globalEval", + r".*execScript", + r".*insertAdjacentHTML\(", + r".*setAttribute.on", + r".*xhr.open", + r".*xhr.send", + r"fetch", + r".*xhr.setRequestHeader.name", + r".*xhr.setRequestHeader.value", + r".*attr.href", + r".*attr.src", + r".*attr.data", + r".*attr.action", + r".*attr.formaction", + r".*prop.href", + r".*prop.src", + r".*prop.data", + r".*prop.action", + r".*prop.formaction", + r"form.action", + r".*input.formaction", + r".*button.formaction", + r".*button.value", + r".*setAttribute.href", + r".*setAttribute.src", + r".*setAttribute.data", + r".*setAttribute.action", + r".*setAttribute.formaction", + r"webdatabase.executeSql", + r".*document.domain", + r".*history.pushState", + r".*history.replaceState", + r".*setRequestHeader", + r".*websocket", + r".*anchor.href", + r".*anchor.target", + r".*JSON.parse", + r".*document.cookie", + r".*localStorage.setItem.name", + r".*localStorage.setItem.value", + r".*sessionStorage.setItem.name", + r".*sessionStorage.setItem.value", + r".*outerText", + r".*innerText", + r".*textContent", + r".*style.cssText", + r".*RegExp" ] -url_regex = re.compile("(https|http):\/\/[a-zA-Z0-9#=\-\?\&\/\.]+") +url_regex = re.compile(r"(https|http):\/\/[a-zA-Z0-9#=\-\?\&\/\.]+") urls = [] patterns = nodejs_patterns @@ -341,7 +341,7 @@ def perform_code_analysis(src, pattern="", verbose=False): parser.add_argument( "-u", "--include-urls", help="identify URLs", action="store_true") parser.add_argument( - "-p", "--pattern", help="define your own pattern to look for. Pattern has to be a RegEx, like '.*fork\('. nodestructor removes whiitespaces, so if you want to look for 'new fn()', your pattern should look like this: '.*newfn\(\)' (all special characters for RegEx have to be escaped with \ )") + "-p", "--pattern", help="define your own pattern to look for. Pattern has to be a RegEx") args = parser.parse_args() From e203c37e4bb5b55befb13483a24fa9863c4990c1 Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Wed, 7 Aug 2024 17:49:59 +0100 Subject: [PATCH 29/62] [s0mbra] remove unused phpsast --- s0mbra.sh | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/s0mbra.sh b/s0mbra.sh index f9bfaec..e25c7cd 100755 --- a/s0mbra.sh +++ b/s0mbra.sh @@ -587,14 +587,6 @@ graphw00f() { echo -e "$BLUE\n[s0mbra] Done! $CLR" } -# runs PHP SAST tools against PHP application -php_sast() { - clear - echo -e "$BLUE[s0mbra] Running static code analysis...$CYAN" - semgrep scan --config=auto --severity ERROR --dataflow-traces --sarif -o ./$1.sarif $1 - echo -e "$BLUE\n[s0mbra] Done! $CLR" -} - # runs Ruby SAST tools against Ruby application ruby_sast() { clear @@ -772,9 +764,6 @@ case "$cmd" in snyktest) snyktest ;; - phpsast) - php_sast "$2" - ;; gql) gql "$2" ;; @@ -883,7 +872,7 @@ case "$cmd" in echo -e "$BLUE_BG:: STATIC CODE ANALYSIS ::\t\t\t\t\t\t\t\t\t\t\t\t\t\t$CLR" echo -e "$CYAN unmin $GRAY[FILE]\t\t\t$YELLOW(JavaScript)$CLR\t$CYAN snyktest $GRAY[DIR]\t\t\t$YELLOW(JavaScript)$CLR" - echo -e "$CYAN pysast $GRAY[DIR]\t\t\t$YELLOW(Python)$CLR\t$CYAN phpsast $GRAY[DIR]\t\t\t$YELLOW(PHP)$CLR" + echo -e "$CYAN pysast $GRAY[DIR]\t\t\t$YELLOW(Python)$CLR" echo -e "$CYAN rubysast $GRAY[DIR]\t\t\t$YELLOW(Ruby)$CLR\t\t$CYAN disass $GRAY[BINARY]\t\t$YELLOW(asm)$CLR" echo -e "$CYAN unjar $GRAY[.jar FILE]\t\t$YELLOW(Java)$CLR\t\t$CYAN urls $GRAY[FILE|DIR|URL]\t\t$YELLOW(JavaScript)$CLR" echo -e "$CYAN secrets $GRAY[FILE|DIR|URL]\t\t$YELLOW(JavaScript)$CLR\t$CYAN endpoints $GRAY[FILE|DIR|URL]\t$YELLOW(JavaScript)$CLR" From 3105223760f1852aafdf4323e8db468482e762df Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Wed, 7 Aug 2024 18:04:44 +0100 Subject: [PATCH 30/62] cleanup --- vi.py => Vi/vi.py | 2 + chromium | 37 ----------------- composer.json | 5 --- composer.lock | 78 ------------------------------------ crawl.py | 35 ---------------- dec0der.sh | 18 --------- endpoints.txt | 1 - enumeratescope.sh | 100 ---------------------------------------------- ip_generator.py | 8 ++-- jgc.py | 19 ++++----- subdomain_enum.sh | 0 11 files changed, 16 insertions(+), 287 deletions(-) rename vi.py => Vi/vi.py (98%) delete mode 100755 chromium delete mode 100644 composer.json delete mode 100644 composer.lock delete mode 100644 crawl.py delete mode 100755 dec0der.sh delete mode 100644 endpoints.txt delete mode 100755 enumeratescope.sh mode change 100755 => 100644 subdomain_enum.sh diff --git a/vi.py b/Vi/vi.py similarity index 98% rename from vi.py rename to Vi/vi.py index 096e41f..6ff26c7 100644 --- a/vi.py +++ b/Vi/vi.py @@ -119,6 +119,8 @@ def recon(emails: set, javascript_files: set): for mail in emails: print(mail) + for url in urls: + print(url) for js_file in javascript_files: print(js_file) diff --git a/chromium b/chromium deleted file mode 100755 index 5e907ef..0000000 --- a/chromium +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/bash -# -# see available options: -# http://peter.sh/experiments/chromium-command-line-switches/ -# -# 8080 - is a standard port for Burp - -# To disable XSS Auditor in Chromium simply put 0 as second argument, 1 leaves XSS Auditor enabled -# to enable auto opening DevTools, set 1 as a third argument - -echo -echo "Usage: chromium [port] [enable xss Auditor] [open DevTools for new tabs]" -echo " example:" -echo " $ chromium 8080 1 1 - runs Chromium listening on 8080, XSS Auditor enabled and DevTools open in new tab(s)" - -# default settings -xss_auditor="" -port="" -devtools="" - -if [ $1 -ne 80 ]; then - port="--proxy-server=127.0.0.1:$1" -fi - -if [ $2 == 0 ]; then - xss_auditor="--disable-xss-auditor" -fi - -if [ $3 == 1 ]; then - devtools="--auto-open-devtools-for-tabs" -fi - -# update those lines to your system specific path: -cd /Applications/Chromium.app/Contents/MacOS -echo "[+] running ./Chromium $port $xss_auditor $devtools" - -./Chromium $port $xss_auditor $devtools diff --git a/composer.json b/composer.json deleted file mode 100644 index 5575f14..0000000 --- a/composer.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "require-dev": { - "phpstan/phpstan": "^1.8" - } -} \ No newline at end of file diff --git a/composer.lock b/composer.lock deleted file mode 100644 index 51bd5e0..0000000 --- a/composer.lock +++ /dev/null @@ -1,78 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", - "This file is @generated automatically" - ], - "content-hash": "911267b8ad1b1bb25c74a4db8118c301", - "packages": [], - "packages-dev": [ - { - "name": "phpstan/phpstan", - "version": "1.8.2", - "source": { - "type": "git", - "url": "https://github.com/phpstan/phpstan.git", - "reference": "c53312ecc575caf07b0e90dee43883fdf90ca67c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/c53312ecc575caf07b0e90dee43883fdf90ca67c", - "reference": "c53312ecc575caf07b0e90dee43883fdf90ca67c", - "shasum": "" - }, - "require": { - "php": "^7.2|^8.0" - }, - "conflict": { - "phpstan/phpstan-shim": "*" - }, - "bin": [ - "phpstan", - "phpstan.phar" - ], - "type": "library", - "autoload": { - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "PHPStan - PHP Static Analysis Tool", - "support": { - "issues": "https://github.com/phpstan/phpstan/issues", - "source": "https://github.com/phpstan/phpstan/tree/1.8.2" - }, - "funding": [ - { - "url": "https://github.com/ondrejmirtes", - "type": "github" - }, - { - "url": "https://github.com/phpstan", - "type": "github" - }, - { - "url": "https://www.patreon.com/phpstan", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan", - "type": "tidelift" - } - ], - "time": "2022-07-20T09:57:31+00:00" - } - ], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": [], - "prefer-stable": false, - "prefer-lowest": false, - "platform": [], - "platform-dev": [], - "plugin-api-version": "2.1.0" -} diff --git a/crawl.py b/crawl.py deleted file mode 100644 index 1b4fc55..0000000 --- a/crawl.py +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/python -import sys -import json -import requests -import argparse -from bs4 import BeautifulSoup - - -def results(file): - content = open(file, 'r').readlines() - for line in content: - data = json.loads(line.strip()) - urls = [] - for url in data['results']: - urls.append(url['url']) - return urls - - -def crawl(url): - r = requests.get(url) - soup = BeautifulSoup(r.text, 'lxml') - links = soup.findAll('a', href=True) - for link in links: - link = link['href'] - if link and link != '#': - print '[+] {} : {}'.format(url, link) - -if __name__ == "__main__": - parser = argparse.ArgumentParser() - parser.add_argument("file", help="ffuf results") - args = parser.parse_args() - urls = results(args.file) - - for url in urls: - crawl(url) diff --git a/dec0der.sh b/dec0der.sh deleted file mode 100755 index bd914db..0000000 --- a/dec0der.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash - -# simple command line decoder/enmcoder -# by bl4de -# -# invoke: -# dec0der [FROM] [string] - -FROM=$1 -STRING=$2 - -if [[ $FROM == 'ascii' ]]; then - echo $STRING | xxd -r -p -fi - -if [[ $FROM == 'base64' ]]; then - echo $STRING | base64 -D -fi diff --git a/endpoints.txt b/endpoints.txt deleted file mode 100644 index ff772e2..0000000 --- a/endpoints.txt +++ /dev/null @@ -1 +0,0 @@ -/api/v1/user diff --git a/enumeratescope.sh b/enumeratescope.sh deleted file mode 100755 index 46c4e8b..0000000 --- a/enumeratescope.sh +++ /dev/null @@ -1,100 +0,0 @@ -#!/bin/bash -# Subdomain enumeration and web server discovery + screenshot tools -# -# @author: bl4de -# @licence: MIT -# - -HOME=/Users/bl4de - -## create domains/ folder -create_domains_folder() { - if [ ! -d domains ]; then - mkdir domains - echo -e "$(date) domains/ folder created" >> subdomain_enum.log - fi -} - - -## perform sublist3r, subfinder and amass enumeration on each domain passed as an argument -enumerate_domain() { - local DOMAIN=$1 - echo -e "$(date) started enumerate $DOMAIN" >> subdomain_enum.log - sublister -d $DOMAIN -o domains/$DOMAIN.sublister - subfinder -d $DOMAIN -o domains/$DOMAIN.subfinder - # amass enum -active -norecursive -noalts -d $DOMAIN -o domains/$DOMAIN.amass - - if [ -s domains/$DOMAIN.sublister ] || [ -s domains/$DOMAIN.amass ] || [ -s domains/$DOMAIN.subfinder ]; then - cat domains/$DOMAIN.* > domains/$DOMAIN.all - sort -u -k 1 domains/$DOMAIN.all > domains/$DOMAIN - fi - rm -f domains/$DOMAIN.* - echo -e "$(date) finished enumerate $DOMAIN, total number of unique domains found: $(cat domains/$DOMAIN|wc -l)" >> subdomain_enum.log -} - -## creates list of uniqe, sorted domains obtained from subdomain enum tools: -create_list_of_domains() { - echo -e "$(date) create final list of domains found..." >> subdomain_enum.log - # concatenate and sort all domains from the target - cat domains/*.* > domains/all - # remove
left from DNS records into unsorted list with dups: - sed 's/
/#/g' domains/all | tr '#' '\n' > domains/unsorted - # remove dups and create final list of domains: - sort -u -k 1 domains/unsorted > domains/final - # remove temporary files - rm -f domains/all domains/unsorted - # show how many uniq domains were found: - echo -e "$(date) ... Done! $(cat domains/final|wc -l) unique domains gathered \o/" >> subdomain_enum.log -} - - -## runs denumerator -run_denumerator() { - echo $1 - echo -e "$(date) denumerator started" >> subdomain_enum.log - # denumerator -f domains/final -c 200,403,500,301,302,304,404,206,405,411,415,422 --dir $1 --output __$1.log - denumerator -f domains/final -c 200,403,500,206,405,411,415,422 --dir $1 --output __$1.log - echo -e "$(date) denumerator finished" >> subdomain_enum.log - echo -e "$(date) total webservers enumerated and saved to report: $(ls -l reports/$1 | wc -l)" >> subdomain_enum.log -} - - - -## ----------------------------------------------------------------------------- - -# list of domains - text file, one domain per line -DOMAINS=$1 - -# output directory for denumerator -if [ -z $2 ]; then - OUTPUT_DIR="report" -else - OUTPUT_DIR=$2 -fi - - -# IP address range -CIDR=$3 - -echo -e "$(date) subdomain_enum.sh started" > subdomain_enum.log - -# enusre that domains/ folder exists, if not create one -create_domains_folder - -cat $DOMAINS | while read DOMAIN -do - enumerate_domain $DOMAIN -done - -# concatenate and sort all domains from the target -create_list_of_domains -echo -e "\n[+} DONE. Found $(wc -l domains/final) unique subdomains" - -# run denumerator on the domains/domains.final output file -run_denumerator $OUTPUT_DIR - -echo -e "\n[+} DONE." - -## ----------------------------------------------------------------------------- - - diff --git a/ip_generator.py b/ip_generator.py index 75330a1..9952cbd 100755 --- a/ip_generator.py +++ b/ip_generator.py @@ -18,7 +18,7 @@ def help(): - print usage + print(usage) def generate(start, stop, logfile): @@ -31,6 +31,7 @@ def generate(start, stop, logfile): logfile.writelines("{}\n".format(res)) return + if __name__ == "__main__": f = open("ip_list.log", "w+") @@ -41,7 +42,6 @@ def generate(start, stop, logfile): start = sys.argv[1].split(".") stop = sys.argv[2].split(".") - print "\n[+] generating IP addresses in range from {} to {}...".format(sys.argv[1], sys.argv[2]) + print("\n[+] generating IP addresses in range from {} to {}...".format(sys.argv[1], sys.argv[2])) generate(start, stop, f) - print "[+] addresses generated...\n" - \ No newline at end of file + print("[+] addresses generated...\n") diff --git a/jgc.py b/jgc.py index 71a8504..2511599 100755 --- a/jgc.py +++ b/jgc.py @@ -2,27 +2,28 @@ import requests import sys -print """ -Jenkins Groovy Console cmd runner. +print(""" + Jenkins Groovy Console cmd runner. -usage: ./jgc.py [HOST] + usage: ./jgc.py [HOST] + + Then type any command and wait for STDOUT output from remote machine. + Type 'exit' to exit :) +""") -Then type any command and wait for STDOUT output from remote machine. -Type 'exit' to exit :) -""" URL = sys.argv[1] + '/scriptText' HEADERS = { 'User-Agent': 'jgc' } while 1: - CMD = raw_input(">> Enter command to execute (or type 'exit' to exit): ") + CMD = input(">> Enter command to execute (or type 'exit' to exit): ") if CMD == 'exit': - print "exiting...\n" + print("exiting...\n") exit(0) DATA = { 'script': 'println "{}".execute().text'.format(CMD) } result = requests.post(URL, headers=HEADERS, data=DATA) - print result.text + print(result.text) diff --git a/subdomain_enum.sh b/subdomain_enum.sh old mode 100755 new mode 100644 From a5cbfbec76e7757913b3eab757ecd7fbd9e8226e Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Wed, 7 Aug 2024 18:07:29 +0100 Subject: [PATCH 31/62] cleanup --- Vi/vi.py | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/Vi/vi.py b/Vi/vi.py index 6ff26c7..af5d33c 100644 --- a/Vi/vi.py +++ b/Vi/vi.py @@ -1,9 +1,10 @@ -from bs4 import BeautifulSoup -import requests -import requests.exceptions +import re import urllib.parse from collections import deque -import re + +import requests +import requests.exceptions +from bs4 import BeautifulSoup ''' Vi.py - an automated script to extract all inteersting information from website @@ -19,9 +20,6 @@ - parse HTML for stuff - harvest useful information from any comment found (in HTML and JS alike) - other? (TBA) - -- add as a submodule (enabled by cmd option) to denumerator.py - and perform full recon of every website found in scope ''' @@ -92,7 +90,7 @@ def recon(emails: set, javascript_files: set): parts = urllib.parse.urlsplit(url) base_url = '{0.scheme}://{0.netloc}'.format(parts) - path = url[:url.rfind('/')+1] if '/' in parts.path else url + path = url[:url.rfind('/') + 1] if '/' in parts.path else url print('[%d] Processing %s' % (count, url)) try: @@ -126,7 +124,6 @@ def recon(emails: set, javascript_files: set): if __name__ == "__main__": - emails = set() javascript_files = set() From 03fcd59a461886e1cc7f227825b6626b9a8d5334 Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Thu, 15 Aug 2024 12:38:15 +0100 Subject: [PATCH 32/62] updates --- Vi/vi.py | 1 + s0mbra.sh | 2 ++ 2 files changed, 3 insertions(+) mode change 100644 => 100755 Vi/vi.py diff --git a/Vi/vi.py b/Vi/vi.py old mode 100644 new mode 100755 index af5d33c..7e4fddc --- a/Vi/vi.py +++ b/Vi/vi.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python import re import urllib.parse from collections import deque diff --git a/s0mbra.sh b/s0mbra.sh index e25c7cd..3be341d 100755 --- a/s0mbra.sh +++ b/s0mbra.sh @@ -847,6 +847,7 @@ case "$cmd" in ;; *) clear + echo -e "$CLR" echo -e "$BLUE_BG:: RECON ::\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t$CLR" echo -e "$CYAN peek $GRAY[DOMAIN]$CLR\t\t\t\t\t$CYAN recon $GRAY[HOST] [OPTIONS:nmap,nikto,vhosts,ffuf,subdomanizer] [PROTO http/https]$CLR" echo -e "$CYAN webservers $GRAY[SUBDOMAINS FILE]$CLR" @@ -883,5 +884,6 @@ case "$cmd" in echo -e "$BLUE_BG:: UTILS ::\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t$CLR" echo -e "$CYAN b64 $GRAY[STRING]$CLR\t\t\t\t\t$CYAN hashme $GRAY[STRING]$CLR" echo -e "$CLR" + echo -e "$CLR" ;; esac From 6b0ce6b47f9f5cfd41e2e04516beb9a86b9cb81f Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Sun, 18 Aug 2024 12:31:51 +0100 Subject: [PATCH 33/62] small updates --- pef/pef.py | 2 +- s0mbra.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pef/pef.py b/pef/pef.py index df18390..89510f0 100755 --- a/pef/pef.py +++ b/pef/pef.py @@ -299,7 +299,7 @@ def run(self): self.scanned_files = self.scanned_files + 1 (res, file_found) = self.main(os.path.join(root, f)) if file_found > 0: - print(f">>> {f} <<<\t{'-' * (115 - len(f))}\n\n") + print(f">>> {f} <<<\t{'-' * (115 - len(f))}\n") total_found += file_found else: self.scanned_files = self.scanned_files + 1 diff --git a/s0mbra.sh b/s0mbra.sh index 3be341d..c66111f 100755 --- a/s0mbra.sh +++ b/s0mbra.sh @@ -262,7 +262,7 @@ webservers() { START_TIME=$(date) # httpx echo -e "\n$GREEN--> httpx$CLR\n" - httpx -H "User-Agent: wearehackerone" -H "X-Hackerone: bl4de" -fcdn cloudfront -v -stats -status-code -web-server -tech-detect -mc 200 -ip -cname -cdn -l $(pwd)/$SUBDOMAINS -o $(pwd)/httpx.log + httpx -H "User-Agent: wearehackerone" -H "X-Hackerone: bl4de" -fcdn cloudfront -v -stats -status-code -web-server -tech-detect -mc 200,403,500 -ip -cname -cdn -l $(pwd)/$SUBDOMAINS -o $(pwd)/httpx.log END_TIME=$(date) echo -e "$GREEN\nstarted at: $RED $START_TIME $GREEN" From 82ef16e2b7ae9a0cb3c879f2efb018743890f89a Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Sun, 18 Aug 2024 12:32:16 +0100 Subject: [PATCH 34/62] small updates --- pef/pef.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pef/pef.py b/pef/pef.py index 89510f0..407e036 100755 --- a/pef/pef.py +++ b/pef/pef.py @@ -318,7 +318,7 @@ def print_summary(self, total_found: int) -> None: """ prints summary at the bottom of search results """ - print(f"{beautyConsole.getColor('white')}Issues found: {total_found}") + print(f"{beautyConsole.getColor('white')}Patterns found: {total_found}") print(f"\n{beautyConsole.getColor('grey')}Cmd arguments: {' '.join(sys.argv[1:])}") print(f"{beautyConsole.getColor('grey')}Level: {self.level}\n") From 159045b3185435ed65318a2a2fd1f4830faf778b Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Mon, 19 Aug 2024 09:59:02 +0100 Subject: [PATCH 35/62] pefdocs update --- pef/imports/pefdocs.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pef/imports/pefdocs.py b/pef/imports/pefdocs.py index e6fa9ab..d17844c 100644 --- a/pef/imports/pefdocs.py +++ b/pef/imports/pefdocs.py @@ -85,7 +85,7 @@ "Opens process file pointer. Opens a pipe to a process executed by forking the command given by command.", "popen ( string $command , string $mode ) : resource", "Code Injection", - "high", + "critical", "sink" ], "proc_open()": [ @@ -145,7 +145,7 @@ "Calls the callback given by the first parameter and passes the remaining parameters as arguments.", "call_user_func ( callable $callback [, mixed $... ] ) : mixed", "Code Injection", - "medium", + "high", "sink" ], "ereg_replace()": [ @@ -531,7 +531,7 @@ "Write data to a file", "file_put_contents ( string $filename , mixed $data [, int $flags = 0 [, resource $context ]] ) : int", "Arbitrary file write", - "medium", + "high", "source" ], "SELECT.*FROM": [ From 3927893f85cd5e4982f27af75380fc7328e52e65 Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Sun, 8 Sep 2024 20:14:56 +0100 Subject: [PATCH 36/62] [s0mbra] menu update --- s0mbra.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/s0mbra.sh b/s0mbra.sh index c66111f..4ff49e3 100755 --- a/s0mbra.sh +++ b/s0mbra.sh @@ -873,10 +873,10 @@ case "$cmd" in echo -e "$BLUE_BG:: STATIC CODE ANALYSIS ::\t\t\t\t\t\t\t\t\t\t\t\t\t\t$CLR" echo -e "$CYAN unmin $GRAY[FILE]\t\t\t$YELLOW(JavaScript)$CLR\t$CYAN snyktest $GRAY[DIR]\t\t\t$YELLOW(JavaScript)$CLR" - echo -e "$CYAN pysast $GRAY[DIR]\t\t\t$YELLOW(Python)$CLR" echo -e "$CYAN rubysast $GRAY[DIR]\t\t\t$YELLOW(Ruby)$CLR\t\t$CYAN disass $GRAY[BINARY]\t\t$YELLOW(asm)$CLR" echo -e "$CYAN unjar $GRAY[.jar FILE]\t\t$YELLOW(Java)$CLR\t\t$CYAN urls $GRAY[FILE|DIR|URL]\t\t$YELLOW(JavaScript)$CLR" echo -e "$CYAN secrets $GRAY[FILE|DIR|URL]\t\t$YELLOW(JavaScript)$CLR\t$CYAN endpoints $GRAY[FILE|DIR|URL]\t$YELLOW(JavaScript)$CLR" + echo -e "$CYAN pysast $GRAY[DIR]\t\t\t$YELLOW(Python)$CLR" echo -e "$BLUE_BG:: ANDROID ::\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t$CLR" echo -e "$CYAN jadx $GRAY[.apk FILE]\t\t$YELLOW(Java)$CLR\t\t$CYAN dex_to_jar $GRAY[.dex file]$CLR\t\t$YELLOW(Java)$CLR" echo -e "$CYAN apk $GRAY[.apk FILE]$CLR\t\t$YELLOW(Java)$CLR\t\t$CYAN abe $GRAY[.ab FILE]$CLR\t\t\t$YELLOW(Java)$CLR" From 2c82ccbdb909bc08cbf1381735f661060cdea9da Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Tue, 1 Oct 2024 12:37:03 +0100 Subject: [PATCH 37/62] [s0mbra] remove Subfinder --- s0mbra.sh | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/s0mbra.sh b/s0mbra.sh index 4ff49e3..62939ac 100755 --- a/s0mbra.sh +++ b/s0mbra.sh @@ -217,11 +217,11 @@ peek() { START_TIME=$(date) DOMAIN=$1 echo -e "$BLUE[s0mbra] Let's see what have we got here...$CLR\n" - - # sublister - echo -e "\n$GREEN--> sublister$CLR\n" - sublister -v -d $DOMAIN -o "$TMPDIR/sublister_$DOMAIN.log" + ## + ## other subdomain enumeration tool(s) goes here... + ## + # subfinder echo -e "\n$GREEN--> subfinder$CLR\n" subfinder -nW -all -v -d $DOMAIN -o $TMPDIR/subfinder.log @@ -234,18 +234,17 @@ peek() { # httpx echo -e "\n$GREEN--> httpx$CLR\n" - httpx -H "User-Agent: wearehackerone" -H "X-Hackerone: bl4de" -fcdn cloudfront -v -stats -status-code -web-server -tech-detect -mc 200 -ip -cname -cdn -l $TMPDIR/subdomains_final.log -o $TMPDIR/httpx.log + httpx -H "User-Agent: wearehackerone" -H "X-Hackerone: bl4de" -fcdn cloudfront -v -stats -status-code -web-server -tech-detect -mc 200,301,302,403,500 -ip -cname -cdn -l $TMPDIR/subdomains_final.log -o $TMPDIR/httpx.log # cleanup echo -e "\n$BLUE[s0mbra] Remove temporary files...\n" - rm -f $TMPDIR/sublister_$DOMAIN.log rm -f $TMPDIR/subfinder.log rm -rf httpx* END_TIME=$(date) echo -e "$GREEN\nstarted at: $RED $START_TIME $GREEN" echo -e "finished at: $RED $END_TIME $GREEN\n" - echo -e "$GRAY sublister+subfinder found \t $YELLOW $(echo `wc -l $TMPDIR/subdomains_final.log` | cut -d" " -f 1) $GRAY subdomains" + echo -e "$GRAY subfinder found \t $YELLOW $(echo `wc -l $TMPDIR/subdomains_final.log` | cut -d" " -f 1) $GRAY subdomains" echo -e "$GRAY httpx found \t\t\t $YELLOW $(echo `wc -l $TMPDIR/httpx.log` | cut -d" " -f 1) $GRAY active web servers $GREEN" echo -e "\n$BLUE[s0mbra] Done.$CLR" osascript -e 'display notification "Hey choom, peek finished!" with title "s0mbra says:"' @@ -262,7 +261,7 @@ webservers() { START_TIME=$(date) # httpx echo -e "\n$GREEN--> httpx$CLR\n" - httpx -H "User-Agent: wearehackerone" -H "X-Hackerone: bl4de" -fcdn cloudfront -v -stats -status-code -web-server -tech-detect -mc 200,403,500 -ip -cname -cdn -l $(pwd)/$SUBDOMAINS -o $(pwd)/httpx.log + httpx -H "User-Agent: wearehackerone" -H "X-Hackerone: bl4de" -fcdn cloudfront -v -stats -status-code -web-server -tech-detect -mc 200,301,302,304,403,500 -ip -cname -cdn -l $(pwd)/$SUBDOMAINS -o $(pwd)/httpx.log END_TIME=$(date) echo -e "$GREEN\nstarted at: $RED $START_TIME $GREEN" From 15cbf80a3adbc1389eebd2e262ad2031da8a6ff8 Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Tue, 1 Oct 2024 18:32:01 +0100 Subject: [PATCH 38/62] [s0mbra] revert changes --- s0mbra.sh | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/s0mbra.sh b/s0mbra.sh index 62939ac..804f4b3 100755 --- a/s0mbra.sh +++ b/s0mbra.sh @@ -217,11 +217,11 @@ peek() { START_TIME=$(date) DOMAIN=$1 echo -e "$BLUE[s0mbra] Let's see what have we got here...$CLR\n" - - ## - ## other subdomain enumeration tool(s) goes here... - ## + # sublister + echo -e "\n$GREEN--> sublister$CLR\n" + sublister -v -d $DOMAIN -o "$TMPDIR/sublister_$DOMAIN.log" + # subfinder echo -e "\n$GREEN--> subfinder$CLR\n" subfinder -nW -all -v -d $DOMAIN -o $TMPDIR/subfinder.log @@ -238,13 +238,14 @@ peek() { # cleanup echo -e "\n$BLUE[s0mbra] Remove temporary files...\n" + rm -f $TMPDIR/sublister_$DOMAIN.log rm -f $TMPDIR/subfinder.log rm -rf httpx* END_TIME=$(date) echo -e "$GREEN\nstarted at: $RED $START_TIME $GREEN" echo -e "finished at: $RED $END_TIME $GREEN\n" - echo -e "$GRAY subfinder found \t $YELLOW $(echo `wc -l $TMPDIR/subdomains_final.log` | cut -d" " -f 1) $GRAY subdomains" + echo -e "$GRAY sublister+subfinder found \t $YELLOW $(echo `wc -l $TMPDIR/subdomains_final.log` | cut -d" " -f 1) $GRAY subdomains" echo -e "$GRAY httpx found \t\t\t $YELLOW $(echo `wc -l $TMPDIR/httpx.log` | cut -d" " -f 1) $GRAY active web servers $GREEN" echo -e "\n$BLUE[s0mbra] Done.$CLR" osascript -e 'display notification "Hey choom, peek finished!" with title "s0mbra says:"' From 33aec79d82d91efde0cae8670637dac918d44379 Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Tue, 1 Oct 2024 18:48:17 +0100 Subject: [PATCH 39/62] [s0mbra] Split peek into enum+webservers --- s0mbra.sh | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/s0mbra.sh b/s0mbra.sh index 804f4b3..bcc9f7b 100755 --- a/s0mbra.sh +++ b/s0mbra.sh @@ -209,7 +209,7 @@ nfs_enum() { } # quick scope, but for single domain - no need to create scope file -peek() { +enum() { TMPDIR=$(pwd)/$1 if [[ ! -d $TMPDIR ]]; then mkdir -p $TMPDIR @@ -232,23 +232,17 @@ peek() { sort -u -k 1 $TMPDIR/step2 > $TMPDIR/subdomains_final.log rm -f $TMPDIR/step* - # httpx - echo -e "\n$GREEN--> httpx$CLR\n" - httpx -H "User-Agent: wearehackerone" -H "X-Hackerone: bl4de" -fcdn cloudfront -v -stats -status-code -web-server -tech-detect -mc 200,301,302,403,500 -ip -cname -cdn -l $TMPDIR/subdomains_final.log -o $TMPDIR/httpx.log - # cleanup echo -e "\n$BLUE[s0mbra] Remove temporary files...\n" rm -f $TMPDIR/sublister_$DOMAIN.log rm -f $TMPDIR/subfinder.log - rm -rf httpx* END_TIME=$(date) echo -e "$GREEN\nstarted at: $RED $START_TIME $GREEN" echo -e "finished at: $RED $END_TIME $GREEN\n" echo -e "$GRAY sublister+subfinder found \t $YELLOW $(echo `wc -l $TMPDIR/subdomains_final.log` | cut -d" " -f 1) $GRAY subdomains" - echo -e "$GRAY httpx found \t\t\t $YELLOW $(echo `wc -l $TMPDIR/httpx.log` | cut -d" " -f 1) $GRAY active web servers $GREEN" echo -e "\n$BLUE[s0mbra] Done.$CLR" - osascript -e 'display notification "Hey choom, peek finished!" with title "s0mbra says:"' + osascript -e 'display notification "Hey choom, enum finished!" with title "s0mbra says:"' } @@ -722,8 +716,8 @@ case "$cmd" in set_ip) set_ip "$2" ;; - peek) - peek "$2" + enum) + enum "$2" ;; webservers) webservers "$2" @@ -849,7 +843,7 @@ case "$cmd" in clear echo -e "$CLR" echo -e "$BLUE_BG:: RECON ::\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t$CLR" - echo -e "$CYAN peek $GRAY[DOMAIN]$CLR\t\t\t\t\t$CYAN recon $GRAY[HOST] [OPTIONS:nmap,nikto,vhosts,ffuf,subdomanizer] [PROTO http/https]$CLR" + echo -e "$CYAN enum $GRAY[DOMAIN]$CLR\t\t\t\t\t$CYAN recon $GRAY[HOST] [OPTIONS:nmap,nikto,vhosts,ffuf,subdomanizer] [PROTO http/https]$CLR" echo -e "$CYAN webservers $GRAY[SUBDOMAINS FILE]$CLR" echo -e "$BLUE_BG:: WEB ::\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t$CLR" From 48d109b04f5b194dda615e43beafd8f7ee665dd2 Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Sat, 7 Dec 2024 11:48:29 +0000 Subject: [PATCH 40/62] [pef] check level param; default levels --- Vi/vi.py | 2 +- pef/pef.py | 20 ++++++++++++-------- s0mbra.sh | 29 +++++------------------------ 3 files changed, 18 insertions(+), 33 deletions(-) diff --git a/Vi/vi.py b/Vi/vi.py index 7e4fddc..43408b9 100755 --- a/Vi/vi.py +++ b/Vi/vi.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import re import urllib.parse from collections import deque diff --git a/pef/pef.py b/pef/pef.py index 407e036..2953b73 100755 --- a/pef/pef.py +++ b/pef/pef.py @@ -153,6 +153,10 @@ "DELETE.*FROM" ] +# allowed scan levels +ALLOWED_LEVELS = ['ALL', 'LOW', 'MEDIUM', 'HIGH', 'CRITICAL'] +DEFAULT_LEVELS = 'MEDIUM,HIGH,CRITICAL' + def banner(): """ @@ -334,30 +338,30 @@ def print_summary(self, total_found: int) -> None: phpfunction = '' parser.add_argument( - "-s", "--skip-vendor", help="exclude ./vendor folder", action="store_true") + "-s", "--skip-vendor", help=f"exclude ./vendor folder", action="store_true") parser.add_argument( - "-v", "--verbose", help="show documentation", action="store_true") + "-v", "--verbose", help=f"show documentation", action="store_true") parser.add_argument( "-l", "--level", - help="severity: ALL, LOW, MEDIUM, HIGH or CRITICAL; default: ALL\nif -f is set, this setting is ignored") + help=f"severity: ALL, LOW, MEDIUM, HIGH or CRITICAL; default: {DEFAULT_LEVELS} if -f is set, this setting is ignored") parser.add_argument( - "-S", "--sources", help="show only sources", action="store_true") + "-S", "--sources", help=f"show only sources", action="store_true") parser.add_argument( - "-K", "--sinks", help="show only sinks", action="store_true") + "-K", "--sinks", help=f"show only sinks", action="store_true") parser.add_argument( "-f", "--function", - help="Search for particular PHP function (eg. unserialize)", + help=f"Search for particular PHP function (eg. unserialize)", ) parser.add_argument( "-d", "--dir", - help="Directory to scan (or sinlge file, optionally)", + help=f"Directory to scan (or sinlge file, optionally)", ) args = parser.parse_args() - level = args.level.upper() if args.level else 'MEDIUM,HIGH,CRITICAL' + level = args.level.upper() if args.level in ALLOWED_LEVELS else 'MEDIUM,HIGH,CRITICAL' # if we are looking for a specific function, level is not taken into account if args.function is not None: diff --git a/s0mbra.sh b/s0mbra.sh index bcc9f7b..34b3f86 100755 --- a/s0mbra.sh +++ b/s0mbra.sh @@ -237,33 +237,18 @@ enum() { rm -f $TMPDIR/sublister_$DOMAIN.log rm -f $TMPDIR/subfinder.log - END_TIME=$(date) - echo -e "$GREEN\nstarted at: $RED $START_TIME $GREEN" - echo -e "finished at: $RED $END_TIME $GREEN\n" - echo -e "$GRAY sublister+subfinder found \t $YELLOW $(echo `wc -l $TMPDIR/subdomains_final.log` | cut -d" " -f 1) $GRAY subdomains" - echo -e "\n$BLUE[s0mbra] Done.$CLR" - osascript -e 'display notification "Hey choom, enum finished!" with title "s0mbra says:"' -} - - -# httpx only list -webservers() { - if [[ -z $1 ]]; then - SUBDOMAINS="subdomains_final.log" - elif [[ -n $1 ]]; then - SUBDOMAINS="$1" - fi - START_TIME=$(date) # httpx echo -e "\n$GREEN--> httpx$CLR\n" - httpx -H "User-Agent: wearehackerone" -H "X-Hackerone: bl4de" -fcdn cloudfront -v -stats -status-code -web-server -tech-detect -mc 200,301,302,304,403,500 -ip -cname -cdn -l $(pwd)/$SUBDOMAINS -o $(pwd)/httpx.log + httpx -H "User-Agent: wearehackerone" -H "X-Hackerone: bl4de" -fcdn cloudfront -v -stats -status-code -web-server -tech-detect -mc 200,301,302,304,403,500 -ip -cname -cdn -l $TMPDIR/subdomains_final.log -o $TMPDIR/httpx.log END_TIME=$(date) echo -e "$GREEN\nstarted at: $RED $START_TIME $GREEN" echo -e "finished at: $RED $END_TIME $GREEN\n" - echo -e "$GRAY httpx found \t\t\t $YELLOW $(echo `wc -l $(pwd)/httpx.log` | cut -d" " -f 1) $GRAY 200 OKs web servers $GREEN" + echo -e "$GRAY sublister+subfinder found \t $YELLOW $(echo `wc -l $TMPDIR/subdomains_final.log` | cut -d" " -f 1) $GRAY subdomains" + echo -e "$GRAY httpx found \t\t\t $YELLOW $(echo `wc -l $TMPDIR/httpx.log` | cut -d" " -f 1) $GRAY 200 OKs web servers $GREEN" + echo -e "\n$BLUE[s0mbra] Done.$CLR" - osascript -e 'display notification "Hey choom, we have some webservers to hack!" with title "s0mbra says:"' + osascript -e 'display notification "Hey choom, enum finished!" with title "s0mbra says:"' } # does recon on URL: nmap, ffuf, other smaller tools, ...? @@ -719,9 +704,6 @@ case "$cmd" in enum) enum "$2" ;; - webservers) - webservers "$2" - ;; recon) recon "$2" "$3" "$4" ;; @@ -844,7 +826,6 @@ case "$cmd" in echo -e "$CLR" echo -e "$BLUE_BG:: RECON ::\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t$CLR" echo -e "$CYAN enum $GRAY[DOMAIN]$CLR\t\t\t\t\t$CYAN recon $GRAY[HOST] [OPTIONS:nmap,nikto,vhosts,ffuf,subdomanizer] [PROTO http/https]$CLR" - echo -e "$CYAN webservers $GRAY[SUBDOMAINS FILE]$CLR" echo -e "$BLUE_BG:: WEB ::\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t$CLR" echo -e "$CYAN fu $GRAY[URL] [DICT] [*EXT,/ or -] [HTTP RESP.]$CLR\t$CYAN apifuzz $GRAY[BASE_URL] [ENDPOINTS]$CLR\t$YELLOW(REST)$CLR" From 17d3f99b9cb453fd0efc0e02578647879d47b198 Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Sat, 7 Dec 2024 11:54:09 +0000 Subject: [PATCH 41/62] [pef] exit when no dir/file provided for scan --- pef/pef.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pef/pef.py b/pef/pef.py index 2953b73..92d4be2 100755 --- a/pef/pef.py +++ b/pef/pef.py @@ -373,6 +373,10 @@ def print_summary(self, total_found: int) -> None: if args.sinks: source_or_sink = 'sink' + if args.dir is None: + print(f"{beautyConsole.getColor('red')}No directory or file(s) to scan provided...") + exit(0) + filename = args.dir # main orutine starts here From 2093050e422e6189a3f8f0e44164941d0635b9ad Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Thu, 20 Feb 2025 16:03:35 +0000 Subject: [PATCH 42/62] [s0mbra] remove sublister; added amass --- pef/pef.py | 2 +- s0mbra.sh | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/pef/pef.py b/pef/pef.py index 92d4be2..e0a8e12 100755 --- a/pef/pef.py +++ b/pef/pef.py @@ -376,7 +376,7 @@ def print_summary(self, total_found: int) -> None: if args.dir is None: print(f"{beautyConsole.getColor('red')}No directory or file(s) to scan provided...") exit(0) - + filename = args.dir # main orutine starts here diff --git a/s0mbra.sh b/s0mbra.sh index 34b3f86..d4e4b83 100755 --- a/s0mbra.sh +++ b/s0mbra.sh @@ -218,16 +218,17 @@ enum() { DOMAIN=$1 echo -e "$BLUE[s0mbra] Let's see what have we got here...$CLR\n" - # sublister - echo -e "\n$GREEN--> sublister$CLR\n" - sublister -v -d $DOMAIN -o "$TMPDIR/sublister_$DOMAIN.log" - + # amass passive enum + echo -e "\n$GREEN--> amass (takes some time, so sit tight, Choom...)$CLR\n" + amass enum -passive -d $DOMAIN -o "$TMPDIR/amass.tmp" + cut -d' ' -f 1 "$TMPDIR/amass.tmp" | grep -e '[a-z]' | sort -u | sed "s,\x1B\[[0-9;]*[a-zA-Z],,g" | grep $DOMAIN > "$TMPDIR/enum_amass.log" + # subfinder echo -e "\n$GREEN--> subfinder$CLR\n" - subfinder -nW -all -v -d $DOMAIN -o $TMPDIR/subfinder.log + subfinder -nW -all -v -d $DOMAIN -o $TMPDIR/enum_subfinder.log # prepare list of uniqe subdomains - cat $TMPDIR/sub* > $TMPDIR/step1 + cat $TMPDIR/enum* > $TMPDIR/step1 sed 's/
/#/g' $TMPDIR/step1 | tr '#' '\n' > $TMPDIR/step2 sort -u -k 1 $TMPDIR/step2 > $TMPDIR/subdomains_final.log rm -f $TMPDIR/step* From 53a7fcc4094613ed6148df5ad59602444470860c Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Fri, 21 Feb 2025 16:59:11 +0000 Subject: [PATCH 43/62] [pef] fix for multiple levels passed --- pef/pef.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pef/pef.py b/pef/pef.py index e0a8e12..a3f4b3e 100755 --- a/pef/pef.py +++ b/pef/pef.py @@ -361,7 +361,7 @@ def print_summary(self, total_found: int) -> None: args = parser.parse_args() - level = args.level.upper() if args.level in ALLOWED_LEVELS else 'MEDIUM,HIGH,CRITICAL' + level = args.level.upper() if args.level else 'HIGH,CRITICAL' # if we are looking for a specific function, level is not taken into account if args.function is not None: From ca76b87a368a62072ba0f4c38a46dce2fa2ad634 Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Fri, 21 Feb 2025 17:03:42 +0000 Subject: [PATCH 44/62] [pef] do not clear screen between calls --- pef/pef.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pef/pef.py b/pef/pef.py index a3f4b3e..aa9daa2 100755 --- a/pef/pef.py +++ b/pef/pef.py @@ -288,7 +288,6 @@ def run(self): runs scanning """ total_found = 0 - os.system('clear') print( f"{beautyConsole.getColor('green')}>>> RESULTS <<<{beautyConsole.getColor('gray')}\n") From 2541ea6d34e1b3df96c7f6397b8cab1b6dd8700d Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Mon, 10 Mar 2025 09:13:48 +0000 Subject: [PATCH 45/62] [pef] update severity level for . variables --- pef/imports/pefdocs.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/pef/imports/pefdocs.py b/pef/imports/pefdocs.py index d17844c..e422511 100644 --- a/pef/imports/pefdocs.py +++ b/pef/imports/pefdocs.py @@ -566,21 +566,21 @@ "$_POST reference found", "", "", - "high", + "critical", "source" ], "$_GET": [ "$_GET reference found", "", "", - "high", + "critical", "source" ], "$_REQUEST": [ "$_REQUEST reference found", "", "", - "high", + "critical", "source" ], "$_COOKIES": [ @@ -589,5 +589,12 @@ "", "high", "source" + ], + "$_SESSION": [ + "$_SESSION reference found", + "", + "", + "high", + "source" ] } From c2cd5a721e50765cb6d4959697780a82266f3c3b Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Thu, 13 Mar 2025 13:40:54 +0000 Subject: [PATCH 46/62] [pef] updates --- pef/imports/pefdocs.py | 14 ++++++++++++++ pef/pef.py | 8 ++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/pef/imports/pefdocs.py b/pef/imports/pefdocs.py index e422511..2952215 100644 --- a/pef/imports/pefdocs.py +++ b/pef/imports/pefdocs.py @@ -583,6 +583,20 @@ "critical", "source" ], + "$_FILES": [ + "$_FILES reference found", + "", + "", + "high", + "source" + ], + "$_ENV": [ + "$_ENV reference found", + "", + "", + "medium", + "source" + ], "$_COOKIES": [ "$_COOKIES reference found", "", diff --git a/pef/pef.py b/pef/pef.py index aa9daa2..3ccf16f 100755 --- a/pef/pef.py +++ b/pef/pef.py @@ -163,9 +163,9 @@ def banner(): Prints welcome banner with contact info """ print(beautyConsole.getColor("green") + "\n\n", "-" * 100) - print("-" * 6, " PEF | PHP Exploitable Functions source code advanced grep utility", + print("-" * 6, " PEF | PHP Source Code grep tool", " " * 35, "-" * 16) - print("-" * 6, " GitHub: bl4de | Twitter: @_bl4de | bloorq@gmail.com ", + print("-" * 6, " https://github.com/bl4de ", " " * 22, "-" * 16) print("-" * 100, "\33[0m\n") @@ -235,7 +235,7 @@ def print_code_line(self, file_name, _line, i, fn, severity="", level='ALL', sou } meets_criteria = 0 - # print legend only if there i sentry in pefdocs.py + # print legend only if there is entry in pefdocs.py if fn and fn.strip() in pefdocs.exploitableFunctionsDesc.keys(): doc = pefdocs.exploitableFunctionsDesc.get(fn.strip()) @@ -323,7 +323,7 @@ def print_summary(self, total_found: int) -> None: """ print(f"{beautyConsole.getColor('white')}Patterns found: {total_found}") print(f"\n{beautyConsole.getColor('grey')}Cmd arguments: {' '.join(sys.argv[1:])}") - print(f"{beautyConsole.getColor('grey')}Level: {self.level}\n") + print(f"{beautyConsole.getColor('grey')}Level: {beautyConsole.getColor('green')}LOW,{beautyConsole.getColor('yellow')}MEDIUM,HIGH,{beautyConsole.getColor('red')}CRITICAL{beautyConsole.getColor('grey')}\n") # main program From e375e73ab0ab613b915172bbb97c2556f58291fe Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Sun, 6 Apr 2025 12:44:20 +0100 Subject: [PATCH 47/62] [s0mbra] update enum message --- s0mbra.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/s0mbra.sh b/s0mbra.sh index d4e4b83..cfae07f 100755 --- a/s0mbra.sh +++ b/s0mbra.sh @@ -245,7 +245,7 @@ enum() { END_TIME=$(date) echo -e "$GREEN\nstarted at: $RED $START_TIME $GREEN" echo -e "finished at: $RED $END_TIME $GREEN\n" - echo -e "$GRAY sublister+subfinder found \t $YELLOW $(echo `wc -l $TMPDIR/subdomains_final.log` | cut -d" " -f 1) $GRAY subdomains" + echo -e "$GRAY amass+subfinder found \t $YELLOW $(echo `wc -l $TMPDIR/subdomains_final.log` | cut -d" " -f 1) $GRAY subdomains" echo -e "$GRAY httpx found \t\t\t $YELLOW $(echo `wc -l $TMPDIR/httpx.log` | cut -d" " -f 1) $GRAY 200 OKs web servers $GREEN" echo -e "\n$BLUE[s0mbra] Done.$CLR" From 99116cf4b8e883990a001cb65a17addcdf85287d Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Wed, 23 Apr 2025 16:45:15 +0100 Subject: [PATCH 48/62] [pef] added _SESSION --- pef/imports/pefdocs.py | 2 +- pef/pef.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/pef/imports/pefdocs.py b/pef/imports/pefdocs.py index 2952215..ed8f95b 100644 --- a/pef/imports/pefdocs.py +++ b/pef/imports/pefdocs.py @@ -608,7 +608,7 @@ "$_SESSION reference found", "", "", - "high", + "medium", "source" ] } diff --git a/pef/pef.py b/pef/pef.py index 3ccf16f..b4f9a94 100755 --- a/pef/pef.py +++ b/pef/pef.py @@ -132,6 +132,7 @@ "$_COOKIE", "$_REQUEST", "$_SERVER", + "$_SESSION", "include($_GET", "require($_GET", "include_once($_GET", From a37c78c82231cc969ba0b86acdb4e4ac8fd4e494 Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Thu, 24 Apr 2025 18:03:14 +0100 Subject: [PATCH 49/62] [pef] added extractTo() --- pef/imports/pefdocs.py | 7 +++++++ pef/pef.py | 1 + 2 files changed, 8 insertions(+) diff --git a/pef/imports/pefdocs.py b/pef/imports/pefdocs.py index ed8f95b..bf153e7 100644 --- a/pef/imports/pefdocs.py +++ b/pef/imports/pefdocs.py @@ -534,6 +534,13 @@ "high", "source" ], + "extractTo(": [ + "Extract the complete archive or the given files to the specified destination. The default permissions for extracted files and directories give the widest possible access.", + "public ZipArchive::extractTo(string $pathto, array|string|null $files = null): bool", + "Arbitrary file write", + "medium", + "source" + ], "SELECT.*FROM": [ "SQL syntax found.", "This is likely a raw SQL query, which can be filled with user provided input or not implemented as prepared statement", diff --git a/pef/pef.py b/pef/pef.py index b4f9a94..a59b2e8 100755 --- a/pef/pef.py +++ b/pef/pef.py @@ -127,6 +127,7 @@ "__sleep(", "filter_var(", "file_put_contents(", + "extractTo(", "$_POST", "$_GET", "$_COOKIE", From 3bd5ec1e97f1668b28eb6ecf309b9a9842e7e70e Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Fri, 25 Apr 2025 08:01:10 +0100 Subject: [PATCH 50/62] [pef] changes --- pef/imports/pefdocs.py | 7 +++++++ pef/pef.py | 41 ++++++++++++++--------------------------- pef/test.php | 3 +++ 3 files changed, 24 insertions(+), 27 deletions(-) diff --git a/pef/imports/pefdocs.py b/pef/imports/pefdocs.py index bf153e7..c05b10c 100644 --- a/pef/imports/pefdocs.py +++ b/pef/imports/pefdocs.py @@ -617,5 +617,12 @@ "", "medium", "source" + ], + "$_SERVER": [ + "$_SERVER reference found", + "", + "", + "medium", + "source" ] } diff --git a/pef/pef.py b/pef/pef.py index a59b2e8..4e1329f 100755 --- a/pef/pef.py +++ b/pef/pef.py @@ -130,7 +130,7 @@ "extractTo(", "$_POST", "$_GET", - "$_COOKIE", + "$_COOKIES", "$_REQUEST", "$_SERVER", "$_SESSION", @@ -142,13 +142,6 @@ "require($_REQUEST", "include_once($_REQUEST", "require_once($_REQUEST", - "$_SERVER[\"PHP_SELF\"]", - "$_SERVER[\"SERVER_ADDR\"]", - "$_SERVER[\"SERVER_NAME\"]", - "$_SERVER[\"REMOTE_ADDR\"]", - "$_SERVER[\"REMOTE_HOST\"]", - "$_SERVER[\"REQUEST_URI\"]", - "$_SERVER[\"HTTP_USER_AGENT\"]", "SELECT.*FROM", "INSERT.*INTO", "UPDATE.*", @@ -207,22 +200,16 @@ def analyse_line(self, l, i, fn, f, line): """ total_number_of_isses = None meets_criteria = 0 - tokens = [token for token in line.split(' ') if token != "\n"] - - # check agains @ at the beginning of the function name - atfn = f"@{fn}" - fn = f"{fn}" - - for token in tokens: - if token.startswith(fn) or token.startswith(atfn): - if fn == "`": - total_number_of_isses = self.print_code_line( - f.name, l, i, fn, self.severity, self.level, self.source_or_sink) - else: - total_number_of_isses = self.print_code_line( - f.name, l, i, fn + (')' if '(' in fn else ''), self.severity, self.level, - self.source_or_sink) - meets_criteria = meets_criteria + 1 if total_number_of_isses is not None else meets_criteria + + if fn in line: + if fn == "`": + total_number_of_isses = self.print_code_line( + f.name, l, i, fn, self.severity, self.level, self.source_or_sink) + else: + total_number_of_isses = self.print_code_line( + f.name, l, i, fn + (')' if '(' in fn else ''), self.severity, self.level, + self.source_or_sink) + meets_criteria = meets_criteria + 1 if total_number_of_isses is not None else meets_criteria return (meets_criteria, total_number_of_isses) def print_code_line(self, file_name, _line, i, fn, severity="", level='ALL', source_or_sink='ALL'): @@ -230,8 +217,8 @@ def print_code_line(self, file_name, _line, i, fn, severity="", level='ALL', sou prints formatted code line """ impact_color = { - "low": "green", - "medium": "yellow", + "low": "grey", + "medium": "green", "high": "yellow", "critical": "red" } @@ -325,7 +312,7 @@ def print_summary(self, total_found: int) -> None: """ print(f"{beautyConsole.getColor('white')}Patterns found: {total_found}") print(f"\n{beautyConsole.getColor('grey')}Cmd arguments: {' '.join(sys.argv[1:])}") - print(f"{beautyConsole.getColor('grey')}Level: {beautyConsole.getColor('green')}LOW,{beautyConsole.getColor('yellow')}MEDIUM,HIGH,{beautyConsole.getColor('red')}CRITICAL{beautyConsole.getColor('grey')}\n") + print(f"{beautyConsole.getColor('grey')}Severity levels: {beautyConsole.getColor('grey')} LOW {beautyConsole.getColor('green')} MEDIUM {beautyConsole.getColor('yellow')} HIGH {beautyConsole.getColor('red')} CRITICAL{beautyConsole.getColor('grey')}\n") # main program diff --git a/pef/test.php b/pef/test.php index 3bb1f9e..2008858 100644 --- a/pef/test.php +++ b/pef/test.php @@ -4,6 +4,9 @@ echo $_GET['cmd']; } +$_SERVER['x']; + `ls -lA`; []; +$test = $_COOKIES['x']; From 77f45c7689f54777560d246c26274ec24a7d18af Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Mon, 28 Apr 2025 18:57:14 +0100 Subject: [PATCH 51/62] [s0mbra] update jadx version --- s0mbra.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/s0mbra.sh b/s0mbra.sh index cfae07f..bf782b0 100755 --- a/s0mbra.sh +++ b/s0mbra.sh @@ -531,7 +531,7 @@ dex_to_jar() { unjar() { clear echo -e "$BLUE[s0mbra] Opening $1 in JD-Gui...$CLR" - /Users/bl4de/hacking/tools/Java_Decompilers/jadx/bin/jadx-gui $1 + /Users/bl4de/hacking/tools/Java_Decompilers/jadx-1.5.1/bin/jadx-gui $1 } # runs disassembly agains binary From 79b67f3b8975fd356b3e93b6665cc8e168aeb6d5 Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Wed, 11 Jun 2025 13:32:58 +0100 Subject: [PATCH 52/62] [s0mbra] remove amass tmp file --- s0mbra.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/s0mbra.sh b/s0mbra.sh index bf782b0..a779562 100755 --- a/s0mbra.sh +++ b/s0mbra.sh @@ -14,7 +14,6 @@ MAGENTA='\033[1;35m' CYAN='\033[36m' CLR='\033[0m' -NEWLINE='\n' # runs $2 port(s) against IP; then -sV -sC -A against every open port found full_nmap_scan() { @@ -237,6 +236,7 @@ enum() { echo -e "\n$BLUE[s0mbra] Remove temporary files...\n" rm -f $TMPDIR/sublister_$DOMAIN.log rm -f $TMPDIR/subfinder.log + rm -f $TMPDIR/amass.tmp # httpx echo -e "\n$GREEN--> httpx$CLR\n" @@ -246,7 +246,7 @@ enum() { echo -e "$GREEN\nstarted at: $RED $START_TIME $GREEN" echo -e "finished at: $RED $END_TIME $GREEN\n" echo -e "$GRAY amass+subfinder found \t $YELLOW $(echo `wc -l $TMPDIR/subdomains_final.log` | cut -d" " -f 1) $GRAY subdomains" - echo -e "$GRAY httpx found \t\t\t $YELLOW $(echo `wc -l $TMPDIR/httpx.log` | cut -d" " -f 1) $GRAY 200 OKs web servers $GREEN" + echo -e "$GRAY httpx found \t $YELLOW $(echo `wc -l $TMPDIR/httpx.log` | cut -d" " -f 1) $GRAY 200 OKs web servers $GREEN" echo -e "\n$BLUE[s0mbra] Done.$CLR" osascript -e 'display notification "Hey choom, enum finished!" with title "s0mbra says:"' From e03ccc55ac015123a2fd4985d01e1e8b826a2f76 Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Mon, 23 Jun 2025 05:30:57 +0100 Subject: [PATCH 53/62] [s0mbra] refactoring --- s0mbra.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/s0mbra.sh b/s0mbra.sh index a779562..a932357 100755 --- a/s0mbra.sh +++ b/s0mbra.sh @@ -38,10 +38,10 @@ full_nmap_scan() { quick_nmap_scan() { if [[ -z "$2" ]]; then echo -e "$BLUE[s0mbra] Running nmap scan against all ports on $1 ...$CYAN" - nmap -p- --min-rate=1000 -T4 $1 + nmap -p- --min-rate=1000 -T4 "$1" else echo -e "$BLUE[s0mbra] Running nmap scan against top $2 ports on $1 ...$CYAN" - nmap --top-ports $2 --min-rate=1000 -T4 $1 + nmap --top-ports "$2" --min-rate=1000 -T4 "$1" fi echo -e "$BLUE\n[s0mbra] Done! $CLR" From 7379f5103843eb6702111d42861d056242c30829 Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Wed, 9 Jul 2025 18:53:39 +0100 Subject: [PATCH 54/62] [pef] add support for different languages --- pef/imports/pefdocs.py | 1364 ++++++++++++++++++++++------------------ pef/pef.py | 192 ++---- pef/test.js | 5 + 3 files changed, 800 insertions(+), 761 deletions(-) create mode 100644 pef/test.js diff --git a/pef/imports/pefdocs.py b/pef/imports/pefdocs.py index c05b10c..b48edf9 100644 --- a/pef/imports/pefdocs.py +++ b/pef/imports/pefdocs.py @@ -1,628 +1,752 @@ # Reference(S) for pef.py +# exploitable functions +exploitableFunctions = { + "javascript": [ + "eval(", + ], + "php": [ + "`", + "system(", + "exec(", + "popen(", + "pcntl_exec(", + "eval(", + "arse_str(", + "parse_url(", + "preg_replace(", + "create_function(", + "passthru(", + "shell_exec(", + "popen(", + "proc_open(", + "pcntl_exec(", + "extract(", + "putenv(", + "ini_set(", + "mail(", + "unserialize(", + "assert(", + "call_user_func(", + "call_user_func_array(", + "ereg_replace(", + "eregi_replace(", + "mb_ereg_replace(", + "mb_eregi_replace(", + "virtual", + "readfile(", + "file_get_contents(", + "show_source(", + "highlight_file(", + "fopen(", + "file(", + "fpassthru(", + "fsockopen(", + "gzopen(", + "gzread(", + "gzfile(", + "gzpassthru(", + "readgzfile(", + "mssql_query(", + "odbc_exec(", + "sqlsrv_query(", + "PDO::query(", + "move_uploaded_file(", + "echo", + "print(", + "printf(", + "ldap_search(", + "sqlite_", + "sqlite_query(", + "pg_", + "pg_query(", + "mysql_", + "mysql_query(", + "mysqli::query(", + "mysqli_", + "mysqli_query(", + "apache_setenv(", + "dl(", + "escapeshellarg(", + "escapeshellcmd(", + "extract(", + "get_cfg_var(", + "get_current_user(", + "getcwd(", + "getenv(", + "ini_restore(", + "ini_set(", + "passthru(", + "pcntl_exec(", + "php_uname(", + "phpinfo(", + "popen(", + "proc_open(", + "putenv(", + "symlink(", + "syslog(", + "curl_exec(", + "__wakeup(", + "__destruct(", + "__sleep(", + "filter_var(", + "file_put_contents(", + "extractTo(", + "$_POST", + "$_GET", + "$_COOKIES", + "$_REQUEST", + "$_SERVER", + "$_SESSION", + "include($_GET", + "require($_GET", + "include_once($_GET", + "require_once($_GET", + "include($_REQUEST", + "require($_REQUEST", + "include_once($_REQUEST", + "require_once($_REQUEST", + "SELECT.*FROM", + "INSERT.*INTO", + "UPDATE.*", + "DELETE.*FROM" + ] +} + # doc dipslayed: # 1st element - description # 2nd element - syntax # 3rd element - possible vulnerability classes exploitableFunctionsDesc = { - "`": [ - "Allows to execute system command", - "`$command`", - "RCE", - "critical", - "sink" - ], - "system()": [ - "Allows to execute system command passed as an argument", - "system ( string $command [, int &$return_var ] ) : string", - "RCE", - "critical", - "sink" - ], - "exec()": [ - "exec - Execute an external program", - "exec ( string $command [, array &$output [, int &$return_var ]] ) : string", - "RCE", - "critical", - "sink" - ], - "call_user_func_array()": [ - "Call a callback with an array of parameters", - "call_user_func_array ( callable $callback , array $param_arr ) : mixed", - "RCE", - "high", - "sink" - ], - "parse_url()": [ - "parse_url — Parse a URL and return its components", - "parse_url(string $url, int $component = -1): mixed", - "SSRF, Filter Bypass", - "medium", - "sink" - ], - "parse_str()": [ - "when parse_str(arg, [target]) parses URL-like string, it sets variables in current scope WITHOUT initializing it", - "parse_str ( string $encoded_string [, array &$result ] ) : void" - "Code Injection", - "high", - "sink" - ], - "eval()": [ - "Evaluate a string as PHP code", - "eval ( string $code ) : mixed", - "RCE", - "critical", - "sink" - ], - "preg_replace()": [ - "Perform a regular expression search and replace. Searches subject for matches to pattern and replaces them with replacement", - "preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] ) : mixed", - "RCE (in certain conditions)", - "medium" - ], - "create_function()": [ - "DEPRECATED as of PHP 7.2.0 - Create an anonymous (lambda-style) function. Creates an anonymous function from the parameters passed, and returns a unique name for it.", - "create_function ( string $args , string $code ) : string", - "Code Injection, RCE", - "medium", - "sink" - ], - "passthru()": [ - "Execute an external program and display raw output", - "passthru ( string $command [, int &$return_var ] ) : void", - "RCE", - "critical", - "sink" - ], - "shell_exec()": [ - "Execute command via shell and return the complete output as a string. This function is identical to the backtick operator.", - "shell_exec ( string $cmd ) : string", - "RCE", - "critical", - "sink" - ], - "popen()": [ - "Opens process file pointer. Opens a pipe to a process executed by forking the command given by command.", - "popen ( string $command , string $mode ) : resource", - "Code Injection", - "critical", - "sink" - ], - "proc_open()": [ - "Execute a command and open file pointers for input/output. proc_open() is similar to popen() but provides a much greater degree of control over the program execution.", - "proc_open ( string $cmd , array $descriptorspec , array &$pipes [, string $cwd = NULL [, array $env = NULL [, array $other_options = NULL ]]] ) : resource", - "Code Injection", - "high", - "sink" - ], - "pcntl_exec()": [ - "Executes the program with the given arguments.", - "pcntl_exec ( string $path [, array $args [, array $envs ]] ) : void", - "RCE", - "critical", - "sink" - ], - "extract()": [ - "Import variables into the current symbol table from an array", - "extract ( array &$array [, int $flags = EXTR_OVERWRITE [, string $prefix = NULL ]] ) : int", - "Code Injection", - "high", - "sink" - ], - "ini_set()": [ - "Sets the value of the given configuration option. The configuration option will keep this new value during the script's execution, and will be restored at the script's ending.", - "ini_set ( string $varname , string $newvalue ) : string", - "PHP Interpreter behavior change; application settings overwrite", - "low" - ], - "mail()": [ - "Sends an email.", - "mail ( string $to , string $subject , string $message [, mixed $additional_headers [, string $additional_parameters ]] ) : bool", - "Arbitrary mail sending", - "low", - "sink" - ], - "echo": [ - "Outputs all parameters. No additional newline is appended.", - "echo ( string $arg1 [, string $... ] ) : void", - "XSS, HTML Injection, Content Injection etc.", - "low" - ], - "unserialize()": [ - "unserialize() takes a single serialized variable and converts it back into a PHP value.", - "unserialize ( string $str [, array $options ] ) : mixed", - "Code Injection, RCE (in certain conditions)", - "high", - "sink" - ], - "assert()": [ - "assert() will check the given assertion and take appropriate action if its result is FALSE. If the assertion is given as a string it will be evaluated as PHP code by assert() - ONLY PNP <7.2.0", - "assert ( mixed $assertion [, string $description ] ) : bool (PHP 5,7) assert ( mixed $assertion [, Throwable $exception ] ) : bool (PHP 7)", - "RCE, Code Injection (in certain conditions)", - "low" - ], - "call_user_func()": [ - "Calls the callback given by the first parameter and passes the remaining parameters as arguments.", - "call_user_func ( callable $callback [, mixed $... ] ) : mixed", - "Code Injection", - "high", - "sink" - ], - "ereg_replace()": [ - "This function scans string for matches to pattern, then replaces the matched text with replacement (DEPRECATED in PHP 5.3.0, and REMOVED in PHP 7.0.0.)", - "ereg_replace ( string $pattern , string $replacement , string $string ) : string", - "Code Injection", - "low", - "sink" - ], - "eregi_replace()": [ - "This function is identical to ereg_replace() except that this ignores case distinction when matching alphabetic characters. (DEPRECATED in PHP 5.3.0, and REMOVED in PHP 7.0.0)", - "eregi_replace ( string $pattern , string $replacement , string $string ) : string", - "Code Injection", - "low", - "sink" - ], - "mb_ereg_replace()": [ - "Scans string for matches to pattern, then replaces the matched text with replacement. Never use the e modifier when working on untrusted input. No automatic escaping will happen (as known from preg_replace()).", - "mb_ereg_replace ( string $pattern , string $replacement , string $string [, string $option = \"msr\" ] ) : string", - "Code Injection", - "low", - "sink" - ], - "mb_eregi_replace()": [ - "Scans string for matches to pattern, then replaces the matched text with replacement. Never use the e modifier when working on untrusted input. No automatic escaping will happen (as known from preg_replace()).", - "mb_eregi_replace ( string $pattern , string $replace , string $string [, string $option = \"msri\" ] ) : string", - "Code Injection", - "low", - "sink" - ], - "virtual()": [ - "Perform an Apache sub-request (calls url passed as an argument). This function is supported when PHP is installed as an Apache module or by the NSAPI server module", - "virtual ( string $filename ) : bool", - "Local File Include, Remote File Include", - "low", - "sink" - ], - "readfile()": [ - "Reads a file and writes it to the output buffer.", - "readfile ( string $filename [, bool $use_include_path = FALSE [, resource $context ]] ) : int", - "Code Injection, LFI, RFI", - "high", - "source" - ], - "file_get_contents()": [ - "This function is similar to file(), except that file_get_contents() returns the file in a string, starting at the specified offset up to maxlen bytes. On failure, file_get_contents() will return FALSE.", - "file_get_contents ( string $filename [, bool $use_include_path = FALSE [, resource $context [, int $offset = 0 [, int $maxlen ]]]] ) : string", - "Code Injection, LFI, RFI", - "high", - "source" - ], - "show_source()": [ - "(Alias for highlight_file()) Prints out or returns a syntax highlighted version of the code contained in filename using the colors defined in the built-in syntax highlighter for PHP.", - "show_source ( string $filename [, bool $return = FALSE ] ) : mixed", - "Information Disclosure", - "low", - "source" - ], - "highlight_file()": [ - "Prints out or returns a syntax highlighted version of the code contained in filename using the colors defined in the built-in syntax highlighter for PHP.", - "highlight_file ( string $filename [, bool $return = FALSE ] ) : mixed", - "Information Disclosure", - "low", - "source" - ], - "fopen()": [ - "fopen() binds a named resource, specified by filename, to a stream.", - "fopen ( string $filename , string $mode [, bool $use_include_path = FALSE [, resource $context ]] ) : resource", - "Code Injection, LFI, RFI", - "low", - "source" - ], - "file()": [ - "Reads an entire file into an array.", - "ile ( string $filename [, int $flags = 0 [, resource $context ]] ) : array", - "Code Injection, LFI, RFI", - "low", - "source" - ], - "fpassthru()": [ - "Reads to EOF on the given file pointer from the current position and writes the results to the output buffer.", - "fpassthru ( resource $handle ) : int", - "Code Injection, LFI, RFI, RCE (depending on the context)", - "low", - "sink" - ], - "fsockopen()": [ - "Initiates a socket connection to the resource specified by hostname.", - "fsockopen ( string $hostname [, int $port = -1 [, int &$errno [, string &$errstr [, float $timeout = ini_get(\"default_socket_timeout\") ]]]] ) : resource", - "RCE (depends on context)", - "low", - "sink" - ], - "gzopen()": [ - "Opens a gzip (.gz) file for reading or writing.", - "gzopen ( string $filename , string $mode [, int $use_include_path = 0 ] ) : resource", - "Code Injection, LFI (depends on context)", - "low", - "sink" - ], - "gzread()": [ - "gzread() reads up to length bytes from the given gz-file pointer. Reading stops when length (uncompressed) bytes have been read or EOF is reached, whichever comes first.", - "gzread ( resource $zp , int $length ) : string", - "Code Injection, LFI", - "low", - "sink" - ], - "gzfile()": [ - "Read entire gz-file into an array. This function is identical to readgzfile(), except that it returns the file in an array.", - "gzfile ( string $filename [, int $use_include_path = 0 ] ) : array", - "Code Injection, LFI", - "low", - "sink" - ], - "gzpassthru()": [ - "Output all remaining data on a gz-file pointer. Reads to EOF on the given gz-file pointer from the current position and writes the (uncompressed) results to standard output.", - "gzpassthru ( resource $zp ) : int", - "Code Injection, LFI", - "low", - "sink" - ], - "readgzfile()": [ - "Output a gz-file. Reads a file, decompresses it and writes it to standard output.", - "readgzfile ( string $filename [, int $use_include_path = 0 ] ) : int", - "Code Injection, LFI, RCE", - "medium", - "sink" - ], - "mssql_query()": [ - "Send MS SQL query to the currently active database on the server that's associated with the specified link identifier. This function was REMOVED in PHP 7.0.0.", - "mssql_query ( string $query [, resource $link_identifier [, int $batch_size = 0 ]] ) : mixed", - "SQL Injection", - "high" - ], - "odbc_exec()": [ - "Sends an SQL statement to the database server.", - "odbc_exec ( resource $connection_id , string $query_string [, int $flags ] ) : resource", - "SQL Injection", - "high", - "sink" - ], - "sqlsrv_query()": [ - "Prepares and executes a query", - "sqlsrv_query ( resource $conn , string $sql [, array $params [, array $options ]] ) : mixed", - "SQL Injection", - "medium", - "sink" - ], - "PDO::query()": [ - "PDO::query() executes an SQL statement in a single function call, returning the result set (if any) returned by the statement as a PDOStatement object.", - "public PDO::query ( string $statement , int $PDO::FETCH_CLASS , string $classname , array $ctorargs ) : PDOStatement", - "SQL Injection", - "medium", - "sink" - ], - "move_uploaded_file()": [ - "This function checks to ensure that the file designated by filename is a valid upload file (meaning that it was uploaded via PHP's HTTP POST upload mechanism). If the file is valid, it will be moved to the filename given by destination.", - "move_uploaded_file ( string $filename , string $destination ) : bool", - "File Include", - "low", - "sink" - ], - "print()": [ - "Outputs arg. print is not actually a real function (it is a language construct) so you are not required to use parentheses with its argument list.", - "print ( string $arg ) : int", - "XSS, Content/HTML Injection", - "low", - "sink" - ], - "printf()": [ - "Produces output according to format.", - "printf ( string $format [, mixed $... ] ) : int", - "XSS, Content/HTML Injection", - "low", - "sink" - ], - "ldap_search()": [ - "Performs the search for a specified filter on the directory with the scope of LDAP_SCOPE_SUBTREE. This is equivalent to searching the entire directory.", - "ldap_search ( resource $link_identifier , string $base_dn , string $filter [, array $attributes = array() [, int $attrsonly = 0 [, int $sizelimit = -1 [, int $timelimit = -1 [, int $deref = LDAP_DEREF_NEVER [, array $serverctrls = array() ]]]]]] ) : resource", - "unknown?", - "low" - ], - "header()": [ - "Send a raw HTTP header", - "header ( string $header [, bool $replace = TRUE [, int $http_response_code ]] ) : void", - "Header Injection, Open Redirect", - "low", - "sink" - ], - "sqlite_query()": [ - "SQLiteDatabase::query - Executes a query against a given database and returns a result handle", - "sqlite_query ( string $query , resource $dbhandle [, int $result_type = SQLITE_BOTH [, string &$error_msg ]] ) : resource", - "SQL Injection", - "medium", - "sink" - ], - "pg_query()": [ - "pg_query() executes the query on the specified database connection. pg_query_params() should be preferred in most cases.", - "pg_query ([ resource $connection ], string $query ) : resource", - "SQL Injection", - "medium", - "sink" - ], - "mysql_query()": [ - "mysql_query() sends a unique query (multiple queries are not supported) to the currently active database on the server that's associated with the specified link_identifier.(deprecated in PHP 5.5.0, and it was removed in PHP 7.0.0)", - "mysql_query ( string $query [, resource $link_identifier = NULL ] ) : mixed", - "SQL Injection", - "high", - "sink" - ], - "mysqli_query()": [ - "Performs a query against the database.", - "mysqli_query ( mysqli $link , string $query [, int $resultmode = MYSQLI_STORE_RESULT ] ) : mixed", - "SQL Injection", - "medium", - "sink" - ], - "mysqli::query()": [ - "Performs a query against the database.", - "mysqli::query ( string $query [, int $resultmode = MYSQLI_STORE_RESULT ] ) : mixed", - "SQL Injection", - "medium", - "sink" - ], - "apache_setenv()": [ - "Sets the value of the Apache environment variable specified by variable.", - "apache_setenv ( string $variable , string $value [, bool $walk_to_top = FALSE ] ) : bool", - "ENV server variables overwrite", - "low", - "sink" - ], - "dl()": [ - "Loads a PHP extension at runtime", - "dl ( string $library ) : bool", - "Code Injection, RCE (in certain conditions)", - "low", - "sink" - ], - "escapeshellarg()": [ - "Escape a string to be used as a shell argument", - "escapeshellarg ( string $arg ) : string", - "", - "low" - ], - "escapeshellcmd()": [ - "Escapes any characters in a string that might be used to trick a shell command into executing arbitrary commands", - "escapeshellcmd ( string $command ) : string", - "", - "low" - ], - "get_cfg_var()": [ - "Gets the value of a PHP configuration option", - "get_cfg_var ( string $option ) : mixed", - "Information Disclosure", - "low" - ], - "get_current_user()": [ - "Gets the name of the owner of the current PHP script", - "get_current_user ( void ) : string", - "Information Disclosure", - "low" - ], - "getcwd()": [ - "Gets the current working directory", - "getcwd ( void ) : string", - "Information Disclosure", - "low" - ], - "getenv()": [ - " Gets the value of an environment variable", - "getenv ( string $varname [, bool $local_only = FALSE ] ) : string", - "Information Disclosure", - "low" - ], - "php_uname()": [ - "Returns information about the operating system PHP is running on", - "php_uname ([ string $mode = \"a\" ] ) : string", - "Information Disclosure", - "low" - ], - "phpinfo()": [ - "Outputs information about PHP's configuration", - "phpinfo ([ int $what = INFO_ALL ] ) : bool", - "Information Disclosure", - "medium" - ], - "putenv()": [ - "Adds setting to the server environment. The environment variable will only exist for the duration of the current request. At the end of the request the environment is restored to its original state.", - "putenv ( string $setting ) : bool", - "ENV variable create/owerwrite", - "low", - "sink" - ], - "symlink()": [ - "Creates a symbolic link to the existing target with the specified name link.", - "symlink ( string $target , string $link ) : bool", - "LFI (in certain conditions)", - "low" - ], - "syslog()": [ - "Generate a system log message", - "syslog ( int $priority , string $message ) : bool", - "Log poisoning", - "low" - ], - "curl_exec()": [ - "Execute the given cURL session. This function should be called after initializing a cURL session and all the options for the session are set.", - "curl_exec ( resource $ch ) : mixed", - "SSRF", - "medium", - "sink" - ], - "__destruct()": [ - "unserialize() checks if your class has a function with the magic name __destruct(). If so, that function is executed after unserialization", - "__destruct ( void ) : void", - "Object Injection; RCE via unserialize() + POP gadget chain", - "high", - "sink" - ], - "__wakeup()": [ - "serialize() checks if your class has a function with the magic name __wakeup(). If so, that function is executed prior to any serialization", - "__wakeup ( void ) : void", - "Object Injection; RCE via unserialize() + POP gadget chain", - "medium", - "sink" - ], - "__sleep()": [ - "serialize() checks if your class has a function with the magic name __sleep(). If so, that function is executed prior to any serialization", - "public __sleep ( void ) : array", - "Object Injection; RCE via unserialize() + POP gadget chain", - "medium", - "sink" - ], - "__serialize()": [ - "checks if the class has a function with the magic name __serialize(). If so, that function is executed prior to any serialization. It must construct and return an associative array of key/value pairs that represent the serialized form of the object. If no array is returned a TypeError will be thrown.", - "public __sleep ( void ) : array", - "Object Injection; RCE via unserialize() + POP gadget chain", - "medium", - "sink" - ], - "__unserialize()": [ - "checks for the presence of a function with the magic name __unserialize(). If present, this function will be passed the restored array that was returned from __serialize(). It may then restore the properties of the object from that array as appropriate.", - "public __sleep ( void ) : array", - "Object Injection; RCE via unserialize() + POP gadget chain", - "medium", - "sink" - ], - "__call()": [ - "Triggered when invoking inaccessible methods in an object context", - "public __call ( string $name , array $arguments ) : mixed", - "Object Injection; RCE via unserialize() + POP gadget chain", - "medium", - "sink" - ], - "__get()": [ - "Is utilized for reading data from inaccessible (protected or private) or non-existing properties.", - "public __get ( string $name ) : mixed", - "Object Injection; RCE via unserialize() + POP gadget chain", - "medium", - "sink" - ], - "__set()": [ - "Is run when writing data to inaccessible (protected or private) or non-existing properties.", - "public __set ( string $name, mixed $value ) : void", - "Object Injection; RCE via unserialize() + POP gadget chain", - "medium", - "sink" - ], - "__callStatic()": [ - "Triggered when invoking inaccessible methods in a static context.", - "public static __callStatic ( string $name , array $arguments ) : mixed", - "Object Injection; RCE via unserialize() + POP gadget chain", - "medium", - "sink" - ], - "filter_var()": [ - "Filters a variable with a specified filter", - "filter_var ( mixed $variable [, int $filter = FILTER_DEFAULT [, mixed $options ]] ) : mixed", - "Validation bypass (in certain conditions)", - "low" - ], - "file_put_contents()": [ - "Write data to a file", - "file_put_contents ( string $filename , mixed $data [, int $flags = 0 [, resource $context ]] ) : int", - "Arbitrary file write", - "high", - "source" - ], - "extractTo(": [ - "Extract the complete archive or the given files to the specified destination. The default permissions for extracted files and directories give the widest possible access.", - "public ZipArchive::extractTo(string $pathto, array|string|null $files = null): bool", - "Arbitrary file write", - "medium", - "source" - ], - "SELECT.*FROM": [ - "SQL syntax found.", - "This is likely a raw SQL query, which can be filled with user provided input or not implemented as prepared statement", - "SQL Injection", - "medium", - "source" - ], - "INSERT.*INTO": [ - "SQL syntax found.", - "This is likely a raw SQL query, which can be filled with user provided input or not implemented as prepared statement", - "SQL Injection", - "medium", - "source" - ], - "UPDATE.*": [ - "SQL syntax found.", - "This is likely a raw SQL query, which can be filled with user provided input or not implemented as prepared statement", - "SQL Injection", - "medium", - "source" - ], - "DELETE.*FROM": [ - "SQL syntax found.", - "This is likely a raw SQL query, which can be filled with user provided input or not implemented as prepared statement", - "SQL Injection", - "medium", - "source" - ], - "$_POST": [ - "$_POST reference found", - "", - "", - "critical", - "source" - ], - "$_GET": [ - "$_GET reference found", - "", - "", - "critical", - "source" - ], - "$_REQUEST": [ - "$_REQUEST reference found", - "", - "", - "critical", - "source" - ], - "$_FILES": [ - "$_FILES reference found", - "", - "", - "high", - "source" - ], - "$_ENV": [ - "$_ENV reference found", - "", - "", - "medium", - "source" - ], - "$_COOKIES": [ - "$_COOKIES reference found", - "", - "", - "high", - "source" - ], - "$_SESSION": [ - "$_SESSION reference found", - "", - "", - "medium", - "source" - ], - "$_SERVER": [ - "$_SERVER reference found", - "", - "", - "medium", - "source" - ] + "javascript": { + "eval()": [ + "The eval() function evaluates JavaScript code represented as a string and returns its completion value. The source is parsed as a script.", + "eval(script)", + "RCE", + "critical", + "sink" + ] + }, + "php": { + "`": [ + "Allows to execute system command", + "`$command`", + "RCE", + "critical", + "sink" + ], + "system()": [ + "Allows to execute system command passed as an argument", + "system ( string $command [, int &$return_var ] ) : string", + "RCE", + "critical", + "sink" + ], + "exec()": [ + "exec - Execute an external program", + "exec ( string $command [, array &$output [, int &$return_var ]] ) : string", + "RCE", + "critical", + "sink" + ], + "call_user_func_array()": [ + "Call a callback with an array of parameters", + "call_user_func_array ( callable $callback , array $param_arr ) : mixed", + "RCE", + "high", + "sink" + ], + "parse_url()": [ + "parse_url — Parse a URL and return its components", + "parse_url(string $url, int $component = -1): mixed", + "SSRF, Filter Bypass", + "medium", + "sink" + ], + "parse_str()": [ + "when parse_str(arg, [target]) parses URL-like string, it sets variables in current scope WITHOUT initializing it", + "parse_str ( string $encoded_string [, array &$result ] ) : void" + "Code Injection", + "high", + "sink" + ], + "eval()": [ + "Evaluate a string as PHP code", + "eval ( string $code ) : mixed", + "RCE", + "critical", + "sink" + ], + "preg_replace()": [ + "Perform a regular expression search and replace. Searches subject for matches to pattern and replaces them with replacement", + "preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] ) : mixed", + "RCE (in certain conditions)", + "medium" + ], + "create_function()": [ + "DEPRECATED as of PHP 7.2.0 - Create an anonymous (lambda-style) function. Creates an anonymous function from the parameters passed, and returns a unique name for it.", + "create_function ( string $args , string $code ) : string", + "Code Injection, RCE", + "medium", + "sink" + ], + "passthru()": [ + "Execute an external program and display raw output", + "passthru ( string $command [, int &$return_var ] ) : void", + "RCE", + "critical", + "sink" + ], + "shell_exec()": [ + "Execute command via shell and return the complete output as a string. This function is identical to the backtick operator.", + "shell_exec ( string $cmd ) : string", + "RCE", + "critical", + "sink" + ], + "popen()": [ + "Opens process file pointer. Opens a pipe to a process executed by forking the command given by command.", + "popen ( string $command , string $mode ) : resource", + "Code Injection", + "critical", + "sink" + ], + "proc_open()": [ + "Execute a command and open file pointers for input/output. proc_open() is similar to popen() but provides a much greater degree of control over the program execution.", + "proc_open ( string $cmd , array $descriptorspec , array &$pipes [, string $cwd = NULL [, array $env = NULL [, array $other_options = NULL ]]] ) : resource", + "Code Injection", + "high", + "sink" + ], + "pcntl_exec()": [ + "Executes the program with the given arguments.", + "pcntl_exec ( string $path [, array $args [, array $envs ]] ) : void", + "RCE", + "critical", + "sink" + ], + "extract()": [ + "Import variables into the current symbol table from an array", + "extract ( array &$array [, int $flags = EXTR_OVERWRITE [, string $prefix = NULL ]] ) : int", + "Code Injection", + "high", + "sink" + ], + "ini_set()": [ + "Sets the value of the given configuration option. The configuration option will keep this new value during the script's execution, and will be restored at the script's ending.", + "ini_set ( string $varname , string $newvalue ) : string", + "PHP Interpreter behavior change; application settings overwrite", + "low" + ], + "mail()": [ + "Sends an email.", + "mail ( string $to , string $subject , string $message [, mixed $additional_headers [, string $additional_parameters ]] ) : bool", + "Arbitrary mail sending", + "low", + "sink" + ], + "echo": [ + "Outputs all parameters. No additional newline is appended.", + "echo ( string $arg1 [, string $... ] ) : void", + "XSS, HTML Injection, Content Injection etc.", + "low" + ], + "unserialize()": [ + "unserialize() takes a single serialized variable and converts it back into a PHP value.", + "unserialize ( string $str [, array $options ] ) : mixed", + "Code Injection, RCE (in certain conditions)", + "high", + "sink" + ], + "assert()": [ + "assert() will check the given assertion and take appropriate action if its result is FALSE. If the assertion is given as a string it will be evaluated as PHP code by assert() - ONLY PNP <7.2.0", + "assert ( mixed $assertion [, string $description ] ) : bool (PHP 5,7) assert ( mixed $assertion [, Throwable $exception ] ) : bool (PHP 7)", + "RCE, Code Injection (in certain conditions)", + "low" + ], + "call_user_func()": [ + "Calls the callback given by the first parameter and passes the remaining parameters as arguments.", + "call_user_func ( callable $callback [, mixed $... ] ) : mixed", + "Code Injection", + "high", + "sink" + ], + "ereg_replace()": [ + "This function scans string for matches to pattern, then replaces the matched text with replacement (DEPRECATED in PHP 5.3.0, and REMOVED in PHP 7.0.0.)", + "ereg_replace ( string $pattern , string $replacement , string $string ) : string", + "Code Injection", + "low", + "sink" + ], + "eregi_replace()": [ + "This function is identical to ereg_replace() except that this ignores case distinction when matching alphabetic characters. (DEPRECATED in PHP 5.3.0, and REMOVED in PHP 7.0.0)", + "eregi_replace ( string $pattern , string $replacement , string $string ) : string", + "Code Injection", + "low", + "sink" + ], + "mb_ereg_replace()": [ + "Scans string for matches to pattern, then replaces the matched text with replacement. Never use the e modifier when working on untrusted input. No automatic escaping will happen (as known from preg_replace()).", + "mb_ereg_replace ( string $pattern , string $replacement , string $string [, string $option = \"msr\" ] ) : string", + "Code Injection", + "low", + "sink" + ], + "mb_eregi_replace()": [ + "Scans string for matches to pattern, then replaces the matched text with replacement. Never use the e modifier when working on untrusted input. No automatic escaping will happen (as known from preg_replace()).", + "mb_eregi_replace ( string $pattern , string $replace , string $string [, string $option = \"msri\" ] ) : string", + "Code Injection", + "low", + "sink" + ], + "virtual()": [ + "Perform an Apache sub-request (calls url passed as an argument). This function is supported when PHP is installed as an Apache module or by the NSAPI server module", + "virtual ( string $filename ) : bool", + "Local File Include, Remote File Include", + "low", + "sink" + ], + "readfile()": [ + "Reads a file and writes it to the output buffer.", + "readfile ( string $filename [, bool $use_include_path = FALSE [, resource $context ]] ) : int", + "Code Injection, LFI, RFI", + "high", + "source" + ], + "file_get_contents()": [ + "This function is similar to file(), except that file_get_contents() returns the file in a string, starting at the specified offset up to maxlen bytes. On failure, file_get_contents() will return FALSE.", + "file_get_contents ( string $filename [, bool $use_include_path = FALSE [, resource $context [, int $offset = 0 [, int $maxlen ]]]] ) : string", + "Code Injection, LFI, RFI", + "high", + "source" + ], + "show_source()": [ + "(Alias for highlight_file()) Prints out or returns a syntax highlighted version of the code contained in filename using the colors defined in the built-in syntax highlighter for PHP.", + "show_source ( string $filename [, bool $return = FALSE ] ) : mixed", + "Information Disclosure", + "low", + "source" + ], + "highlight_file()": [ + "Prints out or returns a syntax highlighted version of the code contained in filename using the colors defined in the built-in syntax highlighter for PHP.", + "highlight_file ( string $filename [, bool $return = FALSE ] ) : mixed", + "Information Disclosure", + "low", + "source" + ], + "fopen()": [ + "fopen() binds a named resource, specified by filename, to a stream.", + "fopen ( string $filename , string $mode [, bool $use_include_path = FALSE [, resource $context ]] ) : resource", + "Code Injection, LFI, RFI", + "low", + "source" + ], + "file()": [ + "Reads an entire file into an array.", + "ile ( string $filename [, int $flags = 0 [, resource $context ]] ) : array", + "Code Injection, LFI, RFI", + "low", + "source" + ], + "fpassthru()": [ + "Reads to EOF on the given file pointer from the current position and writes the results to the output buffer.", + "fpassthru ( resource $handle ) : int", + "Code Injection, LFI, RFI, RCE (depending on the context)", + "low", + "sink" + ], + "fsockopen()": [ + "Initiates a socket connection to the resource specified by hostname.", + "fsockopen ( string $hostname [, int $port = -1 [, int &$errno [, string &$errstr [, float $timeout = ini_get(\"default_socket_timeout\") ]]]] ) : resource", + "RCE (depends on context)", + "low", + "sink" + ], + "gzopen()": [ + "Opens a gzip (.gz) file for reading or writing.", + "gzopen ( string $filename , string $mode [, int $use_include_path = 0 ] ) : resource", + "Code Injection, LFI (depends on context)", + "low", + "sink" + ], + "gzread()": [ + "gzread() reads up to length bytes from the given gz-file pointer. Reading stops when length (uncompressed) bytes have been read or EOF is reached, whichever comes first.", + "gzread ( resource $zp , int $length ) : string", + "Code Injection, LFI", + "low", + "sink" + ], + "gzfile()": [ + "Read entire gz-file into an array. This function is identical to readgzfile(), except that it returns the file in an array.", + "gzfile ( string $filename [, int $use_include_path = 0 ] ) : array", + "Code Injection, LFI", + "low", + "sink" + ], + "gzpassthru()": [ + "Output all remaining data on a gz-file pointer. Reads to EOF on the given gz-file pointer from the current position and writes the (uncompressed) results to standard output.", + "gzpassthru ( resource $zp ) : int", + "Code Injection, LFI", + "low", + "sink" + ], + "readgzfile()": [ + "Output a gz-file. Reads a file, decompresses it and writes it to standard output.", + "readgzfile ( string $filename [, int $use_include_path = 0 ] ) : int", + "Code Injection, LFI, RCE", + "medium", + "sink" + ], + "mssql_query()": [ + "Send MS SQL query to the currently active database on the server that's associated with the specified link identifier. This function was REMOVED in PHP 7.0.0.", + "mssql_query ( string $query [, resource $link_identifier [, int $batch_size = 0 ]] ) : mixed", + "SQL Injection", + "high" + ], + "odbc_exec()": [ + "Sends an SQL statement to the database server.", + "odbc_exec ( resource $connection_id , string $query_string [, int $flags ] ) : resource", + "SQL Injection", + "high", + "sink" + ], + "sqlsrv_query()": [ + "Prepares and executes a query", + "sqlsrv_query ( resource $conn , string $sql [, array $params [, array $options ]] ) : mixed", + "SQL Injection", + "medium", + "sink" + ], + "PDO::query()": [ + "PDO::query() executes an SQL statement in a single function call, returning the result set (if any) returned by the statement as a PDOStatement object.", + "public PDO::query ( string $statement , int $PDO::FETCH_CLASS , string $classname , array $ctorargs ) : PDOStatement", + "SQL Injection", + "medium", + "sink" + ], + "move_uploaded_file()": [ + "This function checks to ensure that the file designated by filename is a valid upload file (meaning that it was uploaded via PHP's HTTP POST upload mechanism). If the file is valid, it will be moved to the filename given by destination.", + "move_uploaded_file ( string $filename , string $destination ) : bool", + "File Include", + "low", + "sink" + ], + "print()": [ + "Outputs arg. print is not actually a real function (it is a language construct) so you are not required to use parentheses with its argument list.", + "print ( string $arg ) : int", + "XSS, Content/HTML Injection", + "low", + "sink" + ], + "printf()": [ + "Produces output according to format.", + "printf ( string $format [, mixed $... ] ) : int", + "XSS, Content/HTML Injection", + "low", + "sink" + ], + "ldap_search()": [ + "Performs the search for a specified filter on the directory with the scope of LDAP_SCOPE_SUBTREE. This is equivalent to searching the entire directory.", + "ldap_search ( resource $link_identifier , string $base_dn , string $filter [, array $attributes = array() [, int $attrsonly = 0 [, int $sizelimit = -1 [, int $timelimit = -1 [, int $deref = LDAP_DEREF_NEVER [, array $serverctrls = array() ]]]]]] ) : resource", + "unknown?", + "low" + ], + "header()": [ + "Send a raw HTTP header", + "header ( string $header [, bool $replace = TRUE [, int $http_response_code ]] ) : void", + "Header Injection, Open Redirect", + "low", + "sink" + ], + "sqlite_query()": [ + "SQLiteDatabase::query - Executes a query against a given database and returns a result handle", + "sqlite_query ( string $query , resource $dbhandle [, int $result_type = SQLITE_BOTH [, string &$error_msg ]] ) : resource", + "SQL Injection", + "medium", + "sink" + ], + "pg_query()": [ + "pg_query() executes the query on the specified database connection. pg_query_params() should be preferred in most cases.", + "pg_query ([ resource $connection ], string $query ) : resource", + "SQL Injection", + "medium", + "sink" + ], + "mysql_query()": [ + "mysql_query() sends a unique query (multiple queries are not supported) to the currently active database on the server that's associated with the specified link_identifier.(deprecated in PHP 5.5.0, and it was removed in PHP 7.0.0)", + "mysql_query ( string $query [, resource $link_identifier = NULL ] ) : mixed", + "SQL Injection", + "high", + "sink" + ], + "mysqli_query()": [ + "Performs a query against the database.", + "mysqli_query ( mysqli $link , string $query [, int $resultmode = MYSQLI_STORE_RESULT ] ) : mixed", + "SQL Injection", + "medium", + "sink" + ], + "mysqli::query()": [ + "Performs a query against the database.", + "mysqli::query ( string $query [, int $resultmode = MYSQLI_STORE_RESULT ] ) : mixed", + "SQL Injection", + "medium", + "sink" + ], + "apache_setenv()": [ + "Sets the value of the Apache environment variable specified by variable.", + "apache_setenv ( string $variable , string $value [, bool $walk_to_top = FALSE ] ) : bool", + "ENV server variables overwrite", + "low", + "sink" + ], + "dl()": [ + "Loads a PHP extension at runtime", + "dl ( string $library ) : bool", + "Code Injection, RCE (in certain conditions)", + "low", + "sink" + ], + "escapeshellarg()": [ + "Escape a string to be used as a shell argument", + "escapeshellarg ( string $arg ) : string", + "", + "low" + ], + "escapeshellcmd()": [ + "Escapes any characters in a string that might be used to trick a shell command into executing arbitrary commands", + "escapeshellcmd ( string $command ) : string", + "", + "low" + ], + "get_cfg_var()": [ + "Gets the value of a PHP configuration option", + "get_cfg_var ( string $option ) : mixed", + "Information Disclosure", + "low" + ], + "get_current_user()": [ + "Gets the name of the owner of the current PHP script", + "get_current_user ( void ) : string", + "Information Disclosure", + "low" + ], + "getcwd()": [ + "Gets the current working directory", + "getcwd ( void ) : string", + "Information Disclosure", + "low" + ], + "getenv()": [ + " Gets the value of an environment variable", + "getenv ( string $varname [, bool $local_only = FALSE ] ) : string", + "Information Disclosure", + "low" + ], + "php_uname()": [ + "Returns information about the operating system PHP is running on", + "php_uname ([ string $mode = \"a\" ] ) : string", + "Information Disclosure", + "low" + ], + "phpinfo()": [ + "Outputs information about PHP's configuration", + "phpinfo ([ int $what = INFO_ALL ] ) : bool", + "Information Disclosure", + "medium" + ], + "putenv()": [ + "Adds setting to the server environment. The environment variable will only exist for the duration of the current request. At the end of the request the environment is restored to its original state.", + "putenv ( string $setting ) : bool", + "ENV variable create/owerwrite", + "low", + "sink" + ], + "symlink()": [ + "Creates a symbolic link to the existing target with the specified name link.", + "symlink ( string $target , string $link ) : bool", + "LFI (in certain conditions)", + "low" + ], + "syslog()": [ + "Generate a system log message", + "syslog ( int $priority , string $message ) : bool", + "Log poisoning", + "low" + ], + "curl_exec()": [ + "Execute the given cURL session. This function should be called after initializing a cURL session and all the options for the session are set.", + "curl_exec ( resource $ch ) : mixed", + "SSRF", + "medium", + "sink" + ], + "__destruct()": [ + "unserialize() checks if your class has a function with the magic name __destruct(). If so, that function is executed after unserialization", + "__destruct ( void ) : void", + "Object Injection; RCE via unserialize() + POP gadget chain", + "high", + "sink" + ], + "__wakeup()": [ + "serialize() checks if your class has a function with the magic name __wakeup(). If so, that function is executed prior to any serialization", + "__wakeup ( void ) : void", + "Object Injection; RCE via unserialize() + POP gadget chain", + "medium", + "sink" + ], + "__sleep()": [ + "serialize() checks if your class has a function with the magic name __sleep(). If so, that function is executed prior to any serialization", + "public __sleep ( void ) : array", + "Object Injection; RCE via unserialize() + POP gadget chain", + "medium", + "sink" + ], + "__serialize()": [ + "checks if the class has a function with the magic name __serialize(). If so, that function is executed prior to any serialization. It must construct and return an associative array of key/value pairs that represent the serialized form of the object. If no array is returned a TypeError will be thrown.", + "public __sleep ( void ) : array", + "Object Injection; RCE via unserialize() + POP gadget chain", + "medium", + "sink" + ], + "__unserialize()": [ + "checks for the presence of a function with the magic name __unserialize(). If present, this function will be passed the restored array that was returned from __serialize(). It may then restore the properties of the object from that array as appropriate.", + "public __sleep ( void ) : array", + "Object Injection; RCE via unserialize() + POP gadget chain", + "medium", + "sink" + ], + "__call()": [ + "Triggered when invoking inaccessible methods in an object context", + "public __call ( string $name , array $arguments ) : mixed", + "Object Injection; RCE via unserialize() + POP gadget chain", + "medium", + "sink" + ], + "__get()": [ + "Is utilized for reading data from inaccessible (protected or private) or non-existing properties.", + "public __get ( string $name ) : mixed", + "Object Injection; RCE via unserialize() + POP gadget chain", + "medium", + "sink" + ], + "__set()": [ + "Is run when writing data to inaccessible (protected or private) or non-existing properties.", + "public __set ( string $name, mixed $value ) : void", + "Object Injection; RCE via unserialize() + POP gadget chain", + "medium", + "sink" + ], + "__callStatic()": [ + "Triggered when invoking inaccessible methods in a static context.", + "public static __callStatic ( string $name , array $arguments ) : mixed", + "Object Injection; RCE via unserialize() + POP gadget chain", + "medium", + "sink" + ], + "filter_var()": [ + "Filters a variable with a specified filter", + "filter_var ( mixed $variable [, int $filter = FILTER_DEFAULT [, mixed $options ]] ) : mixed", + "Validation bypass (in certain conditions)", + "low" + ], + "file_put_contents()": [ + "Write data to a file", + "file_put_contents ( string $filename , mixed $data [, int $flags = 0 [, resource $context ]] ) : int", + "Arbitrary file write", + "high", + "source" + ], + "extractTo(": [ + "Extract the complete archive or the given files to the specified destination. The default permissions for extracted files and directories give the widest possible access.", + "public ZipArchive::extractTo(string $pathto, array|string|null $files = null): bool", + "Arbitrary file write", + "medium", + "source" + ], + "SELECT.*FROM": [ + "SQL syntax found.", + "This is likely a raw SQL query, which can be filled with user provided input or not implemented as prepared statement", + "SQL Injection", + "medium", + "source" + ], + "INSERT.*INTO": [ + "SQL syntax found.", + "This is likely a raw SQL query, which can be filled with user provided input or not implemented as prepared statement", + "SQL Injection", + "medium", + "source" + ], + "UPDATE.*": [ + "SQL syntax found.", + "This is likely a raw SQL query, which can be filled with user provided input or not implemented as prepared statement", + "SQL Injection", + "medium", + "source" + ], + "DELETE.*FROM": [ + "SQL syntax found.", + "This is likely a raw SQL query, which can be filled with user provided input or not implemented as prepared statement", + "SQL Injection", + "medium", + "source" + ], + "$_POST": [ + "$_POST reference found", + "", + "", + "critical", + "source" + ], + "$_GET": [ + "$_GET reference found", + "", + "", + "critical", + "source" + ], + "$_REQUEST": [ + "$_REQUEST reference found", + "", + "", + "critical", + "source" + ], + "$_FILES": [ + "$_FILES reference found", + "", + "", + "high", + "source" + ], + "$_ENV": [ + "$_ENV reference found", + "", + "", + "medium", + "source" + ], + "$_COOKIES": [ + "$_COOKIES reference found", + "", + "", + "high", + "source" + ], + "$_SESSION": [ + "$_SESSION reference found", + "", + "", + "medium", + "source" + ], + "$_SERVER": [ + "$_SERVER reference found", + "", + "", + "medium", + "source" + ] + } } diff --git a/pef/pef.py b/pef/pef.py index 4e1329f..80cb34a 100755 --- a/pef/pef.py +++ b/pef/pef.py @@ -37,143 +37,26 @@ import re import sys -from imports import pefdocs +from imports.pefdocs import exploitableFunctions, exploitableFunctionsDesc from imports.beautyConsole import beautyConsole -# exploitable functions -exploitableFunctions = [ - "`", - "system(", - "exec(", - "popen(", - "pcntl_exec(", - "eval(", - "arse_str(", - "parse_url(", - "preg_replace(", - "create_function(", - "passthru(", - "shell_exec(", - "popen(", - "proc_open(", - "pcntl_exec(", - "extract(", - "putenv(", - "ini_set(", - "mail(", - "unserialize(", - "assert(", - "call_user_func(", - "call_user_func_array(", - "ereg_replace(", - "eregi_replace(", - "mb_ereg_replace(", - "mb_eregi_replace(", - "virtual", - "readfile(", - "file_get_contents(", - "show_source(", - "highlight_file(", - "fopen(", - "file(", - "fpassthru(", - "fsockopen(", - "gzopen(", - "gzread(", - "gzfile(", - "gzpassthru(", - "readgzfile(", - "mssql_query(", - "odbc_exec(", - "sqlsrv_query(", - "PDO::query(", - "move_uploaded_file(", - "echo", - "print(", - "printf(", - "ldap_search(", - "sqlite_", - "sqlite_query(", - "pg_", - "pg_query(", - "mysql_", - "mysql_query(", - "mysqli::query(", - "mysqli_", - "mysqli_query(", - "apache_setenv(", - "dl(", - "escapeshellarg(", - "escapeshellcmd(", - "extract(", - "get_cfg_var(", - "get_current_user(", - "getcwd(", - "getenv(", - "ini_restore(", - "ini_set(", - "passthru(", - "pcntl_exec(", - "php_uname(", - "phpinfo(", - "popen(", - "proc_open(", - "putenv(", - "symlink(", - "syslog(", - "curl_exec(", - "__wakeup(", - "__destruct(", - "__sleep(", - "filter_var(", - "file_put_contents(", - "extractTo(", - "$_POST", - "$_GET", - "$_COOKIES", - "$_REQUEST", - "$_SERVER", - "$_SESSION", - "include($_GET", - "require($_GET", - "include_once($_GET", - "require_once($_GET", - "include($_REQUEST", - "require($_REQUEST", - "include_once($_REQUEST", - "require_once($_REQUEST", - "SELECT.*FROM", - "INSERT.*INTO", - "UPDATE.*", - "DELETE.*FROM" -] - # allowed scan levels ALLOWED_LEVELS = ['ALL', 'LOW', 'MEDIUM', 'HIGH', 'CRITICAL'] DEFAULT_LEVELS = 'MEDIUM,HIGH,CRITICAL' - -def banner(): - """ - Prints welcome banner with contact info - """ - print(beautyConsole.getColor("green") + "\n\n", "-" * 100) - print("-" * 6, " PEF | PHP Source Code grep tool", - " " * 35, "-" * 16) - print("-" * 6, " https://github.com/bl4de ", - " " * 22, "-" * 16) - print("-" * 100, "\33[0m\n") - +ALLOWED_LANG = ['PHP', 'JavaScript'] +DEFAULT_LANG = 'PHP' class PefEngine: """ implements pef engine """ - def __init__(self, level, source_or_sink, filename, skip_vendor, phpfunction, verbose): + def __init__(self, lang, level, source_or_sink, filename, skip_vendor, phpfunction, verbose): """ constructor """ + self.lang = lang # selected language self.level = level # scan only for level set of functions self.source_or_sink = source_or_sink # show only sinks or sources self.filename = filename # name of file/folder to scan @@ -226,8 +109,8 @@ def print_code_line(self, file_name, _line, i, fn, severity="", level='ALL', sou meets_criteria = 0 # print legend only if there is entry in pefdocs.py - if fn and fn.strip() in pefdocs.exploitableFunctionsDesc.keys(): - doc = pefdocs.exploitableFunctionsDesc.get(fn.strip()) + if fn and fn.strip() in exploitableFunctionsDesc[self.lang].keys(): + doc = exploitableFunctionsDesc[self.lang].get(fn.strip()) impact = doc[3] if (impact.upper() in level.upper()) or level == 'ALL': @@ -265,7 +148,7 @@ def main(self, src): line = l.rstrip() if self.level: if not self.is_comment(line): - for fn in exploitableFunctions: + for fn in exploitableFunctions[self.lang]: (meets_criteria, number_of_issues) = self.analyse_line(l, i, fn, f, line) if number_of_issues is not None: res = True @@ -315,40 +198,61 @@ def print_summary(self, total_found: int) -> None: print(f"{beautyConsole.getColor('grey')}Severity levels: {beautyConsole.getColor('grey')} LOW {beautyConsole.getColor('green')} MEDIUM {beautyConsole.getColor('yellow')} HIGH {beautyConsole.getColor('red')} CRITICAL{beautyConsole.getColor('grey')}\n") -# main program -if __name__ == "__main__": +def banner(): + """ + Prints welcome banner with contact info + """ + print(beautyConsole.getColor("green") + "\n\n", "-" * 100) + print("-" * 6, " PEF | PHP Source Code grep tool", + " " * 35, "-" * 16) + print("-" * 6, " https://github.com/bl4de ", + " " * 22, "-" * 16) + print("-" * 100, "\33[0m\n") +def parse_arguments(): + """ + Parses command line arguments + """ parser = argparse.ArgumentParser( - description=sys.modules[__name__].__doc__, + description="PHP Source Code grep tool", add_help=True ) - filename = '.' # initial value for file/dir to scan is current directory - phpfunction = '' - parser.add_argument( - "-s", "--skip-vendor", help=f"exclude ./vendor folder", action="store_true") + "-s", "--skip-vendor", help="exclude ./vendor folder", action="store_true") parser.add_argument( - "-v", "--verbose", help=f"show documentation", action="store_true") + "-v", "--verbose", help="show documentation", action="store_true") parser.add_argument( "-l", "--level", - help=f"severity: ALL, LOW, MEDIUM, HIGH or CRITICAL; default: {DEFAULT_LEVELS} if -f is set, this setting is ignored") + help=f"severity: ALL, LOW, MEDIUM, HIGH or CRITICAL; default: {DEFAULT_LEVELS}") parser.add_argument( - "-S", "--sources", help=f"show only sources", action="store_true") + "-L", "--lang", + help=f"language: PHP, JavaScript; default: {DEFAULT_LANG}") parser.add_argument( - "-K", "--sinks", help=f"show only sinks", action="store_true") + "-S", "--sources", help="show only sources", action="store_true") + parser.add_argument( + "-K", "--sinks", help="show only sinks", action="store_true") parser.add_argument( "-f", "--function", - help=f"Search for particular PHP function (eg. unserialize)", + help="Search for particular PHP function (eg. unserialize)", ) parser.add_argument( "-d", "--dir", - help=f"Directory to scan (or sinlge file, optionally)", + help="Directory to scan (or single file, optionally)", ) + return parser.parse_args() + +# main program +if __name__ == "__main__": - args = parser.parse_args() + if len(sys.argv) == 1: + print(f"{beautyConsole.getColor('red')}No arguments provided, use -h for help") + exit(1) + args = parse_arguments() + + lang = args.lang.lower() if args.lang else DEFAULT_LANG.lower() level = args.level.upper() if args.level else 'HIGH,CRITICAL' # if we are looking for a specific function, level is not taken into account @@ -361,13 +265,19 @@ def print_summary(self, total_found: int) -> None: if args.sinks: source_or_sink = 'sink' + # if no directory or file is provided, exit if args.dir is None: print(f"{beautyConsole.getColor('red')}No directory or file(s) to scan provided...") - exit(0) + exit(1) + + # check if the langauge selected is available + if lang not in [l.lower() for l in ALLOWED_LANG]: + print(f"{beautyConsole.getColor('red')}Language {args.lang} is not supported, use one of: {', '.join(ALLOWED_LANG)}") + exit(1) filename = args.dir # main orutine starts here - engine = PefEngine(level, source_or_sink, + engine = PefEngine(lang, level, source_or_sink, filename, args.skip_vendor, args.function, args.verbose) engine.run() diff --git a/pef/test.js b/pef/test.js new file mode 100644 index 0000000..a9711a6 --- /dev/null +++ b/pef/test.js @@ -0,0 +1,5 @@ +'use strict'; +const cmd = 'console.log("Hello, World!");'; +eval(cmd); + + From b7bf0ec80922ef9339049574ed22819381328fb8 Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Wed, 16 Jul 2025 20:16:37 +0100 Subject: [PATCH 55/62] [s0mbra] fix paths for John The Ripper --- s0mbra.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/s0mbra.sh b/s0mbra.sh index a932357..9a48152 100755 --- a/s0mbra.sh +++ b/s0mbra.sh @@ -77,13 +77,13 @@ http_server() { # runs john with rockyou.txt against hash type [FORMAT] and file [HASHES] rockyou_john() { echo -e "$BLUE[s0mbra] Running john with rockyou dictionary against $1 of type $2$CLR" - echo > "$HACKING_HOME"/tools/JohnTheRipper/run/john.pot + echo > "$HACKING_HOME"/tools/jtr/run/john.pot if [[ -n $2 ]]; then - "$HACKING_HOME"/tools/JohnTheRipper/run/john --wordlist="$HACKING_HOME"/dictionaries/rockyou.txt --format="$2" "$1" + "$HACKING_HOME"/tools/jtr/run/john --wordlist="$HACKING_HOME"/dictionaries/rockyou.txt --format="$2" "$1" elif [[ -z $2 ]]; then - "$HACKING_HOME"/tools/JohnTheRipper/run/john --wordlist="$HACKING_HOME"/dictionaries/rockyou.txt "$1" + "$HACKING_HOME"/tools/jtr/run/john --wordlist="$HACKING_HOME"/dictionaries/rockyou.txt "$1" fi - cat "$HACKING_HOME"/tools/JohnTheRipper/run/john.pot + cat "$HACKING_HOME"/tools/jtr/run/john.pot echo -e "\n$BLUE[s0mbra] Done." osascript -e 'display notification "our choom John has left the house..." with title "s0mbra says:"' } @@ -91,14 +91,14 @@ rockyou_john() { # show JohnTheRipper's pot file john_pot() { echo -e "$BLUE[s0mbra] Joghn The Ripper pot file:$GRAY" - cat "$HACKING_HOME"/tools/JohnTheRipper/run/john.pot + cat "$HACKING_HOME"/tools/jtr/run/john.pot echo -e "\n$BLUE[s0mbra] Done." } # ZIP password cracking with rockyou.txt rockyou_zip() { echo -e "$BLUE[s0mbra] Running $MAGENTA zip2john $BLUE and prepare hash for hashcat..." - "$HACKING_HOME"/tools/JohnTheRipper/run/zip2john "$1" | cut -d ':' -f 2 > ./hashes.txt + "$HACKING_HOME"/tools/jtr/run/zip2john "$1" | cut -d ':' -f 2 > ./hashes.txt echo -e "$BLUE[s0mbra] Starting $MAGENTA hashcat $BLUE (using $YELLOW rockyou.txt $BLUE dictionary against $YELLOW hashes.txt $BLUE file)...$CLR" hashcat -m 13600 ./hashes.txt ~/hacking/dictionaries/rockyou.txt echo -e "\n$BLUE[s0mbra] Done." @@ -107,7 +107,7 @@ rockyou_zip() { # converts id_rsa to JohnTheRipper format for cracking SSH key ssh_to_john() { echo -e "$BLUE[s0mbra] Converting SSH id_rsa key to JohnTheRipper format to crack it$CLR" - python "$HACKING_HOME"/tools/JohnTheRipper/run/sshng2john.py "$1" > "$1".hash + python "$HACKING_HOME"/tools/jtr/run/sshng2john.py "$1" > "$1".hash echo -e "$BLUE[s0mbra] We have a hash.\n" echo -e "$BLUE[s0mbra] Let's now crack it!" rockyou_john "$1".hash From 4ed6384b5f2c24ebce8c401511206f5c8adcfd7e Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Thu, 17 Jul 2025 16:56:21 +0100 Subject: [PATCH 56/62] [pef] add JavaScript sources and sinks --- pef/imports/pefdocs.py | 128 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) diff --git a/pef/imports/pefdocs.py b/pef/imports/pefdocs.py index b48edf9..79b74a9 100644 --- a/pef/imports/pefdocs.py +++ b/pef/imports/pefdocs.py @@ -4,6 +4,22 @@ exploitableFunctions = { "javascript": [ "eval(", + "document.URL", + "document.documentURI", + "document.baseURI", + "location", + "document.cookie", + "document.referrer", + "document.write(", + "innerHTML", + "outerHTML", + "insertAdjacentHTML(", + "location.host", + "location.href", + "location.search", + "Function(", + "textContent", + "innerText", ], "php": [ "`", @@ -125,6 +141,118 @@ "RCE", "critical", "sink" + ], + "document.URL": [ + "The URL of the document", + "document.URL", + "SSRF, Filter Bypass", + "medium", + "source" + ], + "document.documentURI": [ + "The documentURI property returns the URI of the document", + "document.documentURI", + "SSRF, Filter Bypass", + "medium", + "source" + ], + "document.baseURI": [ + "The baseURI property returns the absolute base URI of the document", + "document.baseURI", + "SSRF, Filter Bypass", + "medium", + "source" + ], + "location": [ + "The location property of the Window interface is a Location object, which represents the location (URL) of the object to which it is applied.", + "location", + "SSRF, Filter Bypass", + "medium", + "source" + ], + "document.cookie": [ + "The cookie property of the Document interface represents the cookies of the current document.", + "document.cookie", + "XSS, CSRF, Cookie Injection", + "medium", + "source" + ], + "document.referrer": [ + "The referrer property of the Document interface returns the address of the previous document from which the current document was accessed.", + "document.referrer", + "SSRF, Filter Bypass", + "medium", + "source" + ], + "document.write()": [ + "The write() method of the Document interface writes a string of text to a document stream opened by document.open().", + "document.write(text)", + "XSS, HTML Injection, Content Injection etc.", + "high", + "sink" + ], + "innerHTML": [ + "The innerHTML property of the Element interface gets or sets the HTML or XML markup contained within the element.", + "element.innerHTML", + "XSS, HTML Injection, Content Injection etc.", + "high", + "sink" + ], + "outerHTML": [ + "The outerHTML property of the Element interface gets or sets the HTML or XML markup contained within the element, including the element itself.", + "element.outerHTML", + "XSS, HTML Injection, Content Injection etc.", + "high", + "sink" + ], + "insertAdjacentHTML": [ + "The insertAdjacentHTML() method of the Element interface parses the specified text as HTML or XML and inserts the resulting nodes into the DOM tree at a specified position.", + "element.insertAdjacentHTML(position, text)", + "XSS, HTML Injection, Content Injection etc.", + "high", + "sink" + ], + "location.host": [ + "The host property of the Location interface returns the host and port of the URL.", + "location.host", + "SSRF, Filter Bypass, Open Redirect", + "medium", + "sink" + ], + "location.href": [ + "The href property of the Location interface gets or sets the entire URL.", + "location.href", + "SSRF, Filter Bypass, Open Redirect", + "medium", + "sink" + ], + "location.search": [ + "The search property of the Location interface gets or sets the query string part of the URL.", + "location.search", + "SSRF, Filter Bypass", + "medium", + "sink" + ], + "Function()": [ + "The Function() constructor creates a new Function object. Calling the constructor directly can create functions dynamically, but it is not recommended due to security and performance reasons.", + "new Function([arg1[, arg2[, ...argN]],] functionBody)", + "RCE", + "critical", + "sink" + ], + "textContent": [ + "The textContent property of the Node interface represents the text content of the node and its descendants.", + "element.textContent", + "XSS, HTML Injection, Content Injection etc.", + "medium", + "sink" + ], + "innerText": [ + "The innerText property of the Element interface represents the rendered text content of an element and its descendants.", + "element.innerText", + "XSS, HTML Injection, Content Injection etc.", + "medium", + "sink" ] }, "php": { From b12141fa673dd618da7c7a1289037152cdf1b31b Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Sat, 19 Jul 2025 23:42:05 +0100 Subject: [PATCH 57/62] [s0mbra] remove unused commands --- s0mbra.sh | 33 +-------------------------------- 1 file changed, 1 insertion(+), 32 deletions(-) diff --git a/s0mbra.sh b/s0mbra.sh index 9a48152..08d5a55 100755 --- a/s0mbra.sh +++ b/s0mbra.sh @@ -675,26 +675,6 @@ hshr() { echo -e "$BLUE\n[s0mbra] Done! $CLR" } -# extract links and API endpoints from JavaScript file -urls() { - echo -e "$BLUE[s0mbra] Extracting URLs from $1...$CLR" - python /Users/bl4de/hacking/tools/LinkFinder/linkfinder.py -i "$1" -o cli | rg http | sort -u - echo -e "$BLUE\n[s0mbra] Done! $CLR" -} - -endpoints() { - echo -e "$BLUE[s0mbra] Extracting URLs from $1...$CLR" - python /Users/bl4de/hacking/tools/LinkFinder/linkfinder.py -i "$1" -o cli | rg -v http | sort -u - echo -e "$BLUE\n[s0mbra] Done! $CLR" -} - -# extract secrets from JavaScript file -secrets() { - echo -e "$BLUE[s0mbra] Extracting secrets from $1...$CLR" - python /Users/bl4de/hacking/tools/SecretFinder/SecretFinder.py -i "$1" -o cli | sort -u - echo -e "$BLUE\n[s0mbra] Done! $CLR" -} - ### menu cmd=$1 @@ -813,15 +793,6 @@ case "$cmd" in rubysast) ruby_sast "$2" ;; - urls) - urls "$2" - ;; - endpoints) - endpoints "$2" - ;; - secrets) - secrets "$2" - ;; *) clear echo -e "$CLR" @@ -850,9 +821,7 @@ case "$cmd" in echo -e "$BLUE_BG:: STATIC CODE ANALYSIS ::\t\t\t\t\t\t\t\t\t\t\t\t\t\t$CLR" echo -e "$CYAN unmin $GRAY[FILE]\t\t\t$YELLOW(JavaScript)$CLR\t$CYAN snyktest $GRAY[DIR]\t\t\t$YELLOW(JavaScript)$CLR" echo -e "$CYAN rubysast $GRAY[DIR]\t\t\t$YELLOW(Ruby)$CLR\t\t$CYAN disass $GRAY[BINARY]\t\t$YELLOW(asm)$CLR" - echo -e "$CYAN unjar $GRAY[.jar FILE]\t\t$YELLOW(Java)$CLR\t\t$CYAN urls $GRAY[FILE|DIR|URL]\t\t$YELLOW(JavaScript)$CLR" - echo -e "$CYAN secrets $GRAY[FILE|DIR|URL]\t\t$YELLOW(JavaScript)$CLR\t$CYAN endpoints $GRAY[FILE|DIR|URL]\t$YELLOW(JavaScript)$CLR" - echo -e "$CYAN pysast $GRAY[DIR]\t\t\t$YELLOW(Python)$CLR" + echo -e "$CYAN unjar $GRAY[.jar FILE]\t\t$YELLOW(Java)$CLR\t\t$CYAN pysast $GRAY[DIR]\t\t\t$YELLOW(Python)$CLR" echo -e "$BLUE_BG:: ANDROID ::\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t$CLR" echo -e "$CYAN jadx $GRAY[.apk FILE]\t\t$YELLOW(Java)$CLR\t\t$CYAN dex_to_jar $GRAY[.dex file]$CLR\t\t$YELLOW(Java)$CLR" echo -e "$CYAN apk $GRAY[.apk FILE]$CLR\t\t$YELLOW(Java)$CLR\t\t$CYAN abe $GRAY[.ab FILE]$CLR\t\t\t$YELLOW(Java)$CLR" From 5cde940a6391a4d15d8934466ca7ab85afae6531 Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Wed, 17 Sep 2025 08:17:51 +0100 Subject: [PATCH 58/62] [s0mbra] update --- Vi/vi.py | 135 ---------------------------------------------- s0mbra.sh | 8 +++ subdomain_enum.sh | 98 --------------------------------- 3 files changed, 8 insertions(+), 233 deletions(-) delete mode 100755 Vi/vi.py delete mode 100644 subdomain_enum.sh diff --git a/Vi/vi.py b/Vi/vi.py deleted file mode 100755 index 43408b9..0000000 --- a/Vi/vi.py +++ /dev/null @@ -1,135 +0,0 @@ -#!/usr/bin/env python3 -import re -import urllib.parse -from collections import deque - -import requests -import requests.exceptions -from bs4 import BeautifulSoup - -''' -Vi.py - an automated script to extract all inteersting information from website - -@author: bl4de - -@TBD: -- refactor scafolding code [In progress] -- add argparser - -- extract JavaScript files -> scan them for stuff - (API endpoints, secrets, hardcoded information etc.) -- parse HTML for stuff -- harvest useful information from any comment found (in HTML and JS alike) -- other? (TBA) -''' - - -def extract_emails(emails: set, http_response: requests.Response) -> set: - ''' - Extracts emails from provided HTTP response body and append them - to already found set of emails - ''' - emails.update(set(re.findall( - r"[a-z0-9\.\-+_]+@[a-z0-9\.\-+_]+\.[a-z]+", http_response.text, re.IGNORECASE))) - return emails - - -def extract_javascript_files(javascript_files: set, http_response: requests.Response) -> set: - ''' - Extracts JavaScript files urls from provided HTTP response body and append them - to already found set of javascript_files - ''' - javascript_files.update(set(re.findall( - r"[a-z0-9\.\-_]+\.js", http_response.text, re.IGNORECASE - ))) - return javascript_files - - -def parse_javascript_file(js_filename: str): - ''' - Parse JavaScript file for interesting stuff - ''' - TYPE = 'DEBUG' - print(f"[{TYPE}] parsing {js_filename} for interesting stuff...") - pass - - -def tear_off(): - ''' - Performs data extraction stage - ''' - for js_filename in javascript_files: - parse_javascript_file(js_filename) - - pass - - -def recon(emails: set, javascript_files: set): - ''' - Creates list of resources; some will be proceeded later in next - steps - ''' - user_url = str(input('[+] Enter Target URL To Scan: ')) - urls = deque([user_url]) - MAX_COUNT = 2 - - scraped_urls = set() - - count = 0 - - try: - ''' - main execution loop - ''' - while len(urls): - count += 1 - if count == MAX_COUNT: - break - url = urls.popleft() - scraped_urls.add(url) - - parts = urllib.parse.urlsplit(url) - base_url = '{0.scheme}://{0.netloc}'.format(parts) - - path = url[:url.rfind('/') + 1] if '/' in parts.path else url - - print('[%d] Processing %s' % (count, url)) - try: - response = requests.get(url) - except (requests.exceptions.MissingSchema, requests.exceptions.ConnectionError): - continue - - emails = extract_emails(emails, response) - javascript_files = extract_javascript_files( - javascript_files, response) - - soup = BeautifulSoup(response.text, features="lxml") - - for anchor in soup.find_all("a"): - link = anchor.attrs['href'] if 'href' in anchor.attrs else '' - if link.startswith('/'): - link = base_url + link - elif not link.startswith('http'): - link = path + link - if not link in urls and not link in scraped_urls: - urls.append(link) - except KeyboardInterrupt: - print('[-] Closing!') - - for mail in emails: - print(mail) - for url in urls: - print(url) - for js_file in javascript_files: - print(js_file) - - -if __name__ == "__main__": - emails = set() - javascript_files = set() - - # go through provided url; find emails, javascript files etc. - recon(emails, javascript_files) - - # extract sensitive and interesting information from what was found - tear_off() diff --git a/s0mbra.sh b/s0mbra.sh index 08d5a55..c10bbdb 100755 --- a/s0mbra.sh +++ b/s0mbra.sh @@ -675,6 +675,14 @@ hshr() { echo -e "$BLUE\n[s0mbra] Done! $CLR" } +# cat <<'-md-' +# # s0mbra.sh - Recon and pentest tool + +# This script is a collection of various tools and functions for reconnaissance, pentesting, and code analysis +# It provides functionalities for network scanning, web application testing, cloud storage enumeration, and more. + +# -md- + ### menu cmd=$1 diff --git a/subdomain_enum.sh b/subdomain_enum.sh deleted file mode 100644 index daea6b3..0000000 --- a/subdomain_enum.sh +++ /dev/null @@ -1,98 +0,0 @@ -#!/bin/bash -# Subdomain enumeration and web server discovery + screenshot tools -# -# @author: bl4de -# @licence: MIT -# - - -## create domains/ folder -create_domains_folder() { - if [ ! -d domains ]; then - mkdir domains - echo -e "$(date) domains/ folder created" >> subdomain_enum.log - fi -} - - -## perform sublist3r and amass enumeration on each domain passed as an argument -enumerate_domain() { - local DOMAIN=$1 - echo -e "$(date) started enumerate $DOMAIN" >> subdomain_enum.log - sublister -d $DOMAIN -o domains/$DOMAIN.sublister - amass enum -brute -min-for-recursive 1 -d $DOMAIN -o domains/$DOMAIN.amass - - if [ -s domains/$DOMAIN.sublister ] || [ -s domains/$DOMAIN.amass ]; then - cat domains/$DOMAIN.* > domains/$DOMAIN.all - sort -u -k 1 domains/$DOMAIN.all > domains/$DOMAIN - fi - rm -f domains/$DOMAIN.* - echo -e "$(date) finished enumerate $DOMAIN, total number of unique domains found: $(cat domains/$DOMAIN|wc -l)" >> subdomain_enum.log -} - -## processing all outputed list of domains into one, removing dups -## and sorting -create_list_of_domains() { - echo -e "$(date) create final list of domains found..." >> subdomain_enum.log - # concatenate and sort all domains from the target - cat domains/*.* > domains/domains.all - sort -u -k 1 domains/domains.all > domains/__domains - # remove odd
left by Sublist3r or amass :P - sed 's/
/#/g' __domains | tr '#' '\n' > __domains.final - rm -f domains/domains.all - echo -e "$(date) ... Done! $(cat domains/__domains.final|wc -l) unique domains gathered \o/" >> subdomain_enum.log -} - - -## runs denumerator -run_denumerator() { - echo -e "$(date) denumerator started" >> subdomain_enum.log - denumerator -f domains/__domains.final -c 200,302,403,500 - echo -e "$(date) denumerator finished" >> subdomain_enum.log - echo -e "$(date) total webservers enumerated and saved to report: $(ls -l report/ | wc -l)" >> subdomain_enum.log -} - - -## performs nmap scan -run_virustotal_enum() { - echo -e "$(date) virustotal $CIDR enumeration started" >> subdomain_enum.log - # run virustotal.py reverse domain search - virustotal --cidr $CIDR --output domains/virustotal.domains - echo -e "$(date) virustotal $CIDR enumeration finished, $(cat domains/virustotal.domains|wc -l) domains found" >> subdomain_enum.log -} - - -## ----------------------------------------------------------------------------- - -# list of domains - text file, one domain in single line -DOMAINS=$1 - -# IP address range -CIDR=$2 - -echo -e "$(date) subdomain_enum.sh started" >> subdomain_enum.log - -# enusre that domains/ folder exists, if not create one -create_domains_folder - -if [[ -n $CIDR ]]; then - run_virustotal_enum -fi - -cat $DOMAINS | while read DOMAIN -do - enumerate_domain $DOMAIN -done - -# concatenate and sort all domains from the target -create_list_of_domains -echo -e "\n[+} DONE. Found $(wc -l domains/__domains.final) unique subdomains" - -# run denumerator on the domains/domains.final output file -run_denumerator - -echo -e "\n[+} DONE." - -## ----------------------------------------------------------------------------- - - From 128236f5078a140352a24d277febdcf0ee5e2035 Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Thu, 25 Sep 2025 19:03:08 +0100 Subject: [PATCH 59/62] [s0mbra] proper temp filenames to remove after scan is done --- s0mbra.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/s0mbra.sh b/s0mbra.sh index c10bbdb..def71a4 100755 --- a/s0mbra.sh +++ b/s0mbra.sh @@ -234,8 +234,8 @@ enum() { # cleanup echo -e "\n$BLUE[s0mbra] Remove temporary files...\n" - rm -f $TMPDIR/sublister_$DOMAIN.log - rm -f $TMPDIR/subfinder.log + rm -f $TMPDIR/enum_amass.log + rm -f $TMPDIR/enum_subfinder.log rm -f $TMPDIR/amass.tmp # httpx From 94152adbd020988862e5156ca8113fc7a8329ffc Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Tue, 10 Feb 2026 18:22:44 +0000 Subject: [PATCH 60/62] commented backticks --- pef/imports/pefdocs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pef/imports/pefdocs.py b/pef/imports/pefdocs.py index 79b74a9..8395d59 100644 --- a/pef/imports/pefdocs.py +++ b/pef/imports/pefdocs.py @@ -22,7 +22,7 @@ "innerText", ], "php": [ - "`", + # "`", "system(", "exec(", "popen(", From 0a18ad474e2546b40c7d8df9e47f0353ffd7e077 Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Tue, 14 Apr 2026 21:20:18 +0100 Subject: [PATCH 61/62] updates --- pef/imports/pefdocs.py | 11 ++++++++++- s0mbra.sh | 6 +++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/pef/imports/pefdocs.py b/pef/imports/pefdocs.py index 8395d59..a0efbfd 100644 --- a/pef/imports/pefdocs.py +++ b/pef/imports/pefdocs.py @@ -20,6 +20,7 @@ "Function(", "textContent", "innerText", + "URLSearchParams(", ], "php": [ # "`", @@ -253,7 +254,15 @@ "XSS, HTML Injection, Content Injection etc.", "medium", "sink" - ] + ], + "URLSearchParams": [ + "The URLSearchParams interface defines utility methods to work with the query string of a URL.", + "URLSearchParams()", + "XSS, HTML Injection, Content Injection etc.", + "medium", + "source" + ], + }, "php": { "`": [ diff --git a/s0mbra.sh b/s0mbra.sh index def71a4..c42f9ce 100755 --- a/s0mbra.sh +++ b/s0mbra.sh @@ -218,9 +218,9 @@ enum() { echo -e "$BLUE[s0mbra] Let's see what have we got here...$CLR\n" # amass passive enum - echo -e "\n$GREEN--> amass (takes some time, so sit tight, Choom...)$CLR\n" - amass enum -passive -d $DOMAIN -o "$TMPDIR/amass.tmp" - cut -d' ' -f 1 "$TMPDIR/amass.tmp" | grep -e '[a-z]' | sort -u | sed "s,\x1B\[[0-9;]*[a-zA-Z],,g" | grep $DOMAIN > "$TMPDIR/enum_amass.log" + # echo -e "\n$GREEN--> amass (takes some time, so sit tight, Choom...)$CLR\n" + # amass enum -passive -d $DOMAIN -o "$TMPDIR/amass.tmp" + # cut -d' ' -f 1 "$TMPDIR/amass.tmp" | grep -e '[a-z]' | sort -u | sed "s,\x1B\[[0-9;]*[a-zA-Z],,g" | grep $DOMAIN > "$TMPDIR/enum_amass.log" # subfinder echo -e "\n$GREEN--> subfinder$CLR\n" From 4d3b58f491114ebae0a387eba58926b24d5fbe29 Mon Sep 17 00:00:00 2001 From: Rafal Janicki Date: Wed, 22 Apr 2026 15:10:17 +0100 Subject: [PATCH 62/62] [s0mbra] update --- s0mbra.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/s0mbra.sh b/s0mbra.sh index c42f9ce..17d618a 100755 --- a/s0mbra.sh +++ b/s0mbra.sh @@ -217,10 +217,10 @@ enum() { DOMAIN=$1 echo -e "$BLUE[s0mbra] Let's see what have we got here...$CLR\n" - # amass passive enum - # echo -e "\n$GREEN--> amass (takes some time, so sit tight, Choom...)$CLR\n" - # amass enum -passive -d $DOMAIN -o "$TMPDIR/amass.tmp" - # cut -d' ' -f 1 "$TMPDIR/amass.tmp" | grep -e '[a-z]' | sort -u | sed "s,\x1B\[[0-9;]*[a-zA-Z],,g" | grep $DOMAIN > "$TMPDIR/enum_amass.log" + amass passive enum + echo -e "\n$GREEN--> amass (takes some time, so sit tight, Choom...)$CLR\n" + amass enum -passive -d $DOMAIN -o "$TMPDIR/amass.tmp" + cut -d' ' -f 1 "$TMPDIR/amass.tmp" | grep -e '[a-z]' | sort -u | sed "s,\x1B\[[0-9;]*[a-zA-Z],,g" | grep $DOMAIN > "$TMPDIR/enum_amass.log" # subfinder echo -e "\n$GREEN--> subfinder$CLR\n"