Created
January 7, 2019 14:59
-
-
Save decal/198399fde5858857b0d8a4930c8c5330 to your computer and use it in GitHub Desktop.
Enumerate sub-domains with Google's site: search operator
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# | |
# goodoms: Enumerate sub-domains with Google's site: search operator | |
# | |
# Admittedly, general-purpose search engines aren't the best enumerators of DNS | |
# records. However, they are good at extracting host names that may have been | |
# otherwise inaccessible as a result of cached web pages in the search indices. | |
# This script was created to automate the process in a semi-predictable manner. | |
# | |
# Written by: Derek Callaway [derek.callaway (AT) ioactive {D0T} com] | |
# Created on: Mon Jul 23 21:03:33 PDT 2018 | |
# Tested via: macOS High Sierra and WSL Ubuntu | |
# Final edit: Sun Jan 6 01:08:33 PST 2019 | |
# | |
# *Pseudo-code:* | |
# | |
# 0. Parse arguments passed as command-line options | |
# | |
# 1. Perform an initial search of given parent domain | |
# i.e. `site:host.dom` | |
# | |
# 2. Iteratively negate the site operator for known sub-domain names | |
# i.e. `site:host.dom -site:www.host.dom -site:mail.host.dom` | |
# | |
# 3. Continue this behavior until no new sub-domains are discovered | |
# | |
# 4. Write the final accumulated sub-domain name list to standard output | |
# | |
# 5. Exit gracefully | |
# | |
if [ ! "$1" ]; then | |
# Show usage if no domain has been provided | |
echo | |
echo -e "\033[41;30musage:\033[m \033[43;32;3;1m$0\033[m \033[44;31mDOMAIN\033[m" | |
echo | |
echo -e ' \033[44;31mDOMAIN\033[m \033[42;33mdomain to enumerate hosts of with the Google \033[3;1msite:\033[m\033[42;33m operator\033[m' | |
echo | |
exit 1 | |
fi | |
# Detect if the googler script has been installed | |
which googler >/dev/null | |
if [ $? -ne 0 ]; then | |
# Print installation instructions and error out if unable to run googler | |
echo -e '\n\033[41;30mgoogler:\033[m \033[31mUnknown command\033[m' | |
echo | |
echo -e ' \033[31;42m1\033[1m.\033[m \033[34;43;3;1mbrew install googler\033[m \033[4;1mor\033[m \033[34;43;3;1mpip install googler\033[m' | |
echo | |
echo -e ' \033[31;42m2\033[1m.\033[m \033[34;43mcheck your \033[3;1m$PATH\033[m\033[34;43m environment variable\033[m' | |
echo | |
exit 2 | |
fi | |
# Initialization syntax of variables required to perform auxiliary storage | |
declare gargs="site:*.${1}" | |
declare -i count=0 | |
declare -a hosts=() hostz=() | |
while true; do | |
# Pause execution occassionally to prevent Google from getting overwhelmed | |
[ $count -ne 0 ] && sleep $(( 4 + $[ RANDOM % 8 ] )) | |
# Extract DNS domain names from JSON syntax that comprises Google response | |
declare hosts=$(googler --json -- "$gargs" | grep '"url"' | cut -d: -f2- | cut -d\" -f2 | egrep "[.]${1}" | awk -F".${1}" '{print$1}' | awk -F'//' '{print$2}' | sort -u) | |
if [ ${#hosts} -eq 0 ]; then | |
if [ $count -eq 0 ]; then | |
# Show error message and exit if there are no result items | |
echo -e "\n\033[41;30mgoodoms:\033[m \033[31mNo search results detected!\033[m\n" | |
exit 3 | |
fi | |
# Escape from loop if this is not the first iteration and it lacks results | |
break | |
fi | |
# Show the operator that the process is keeping busy | |
echo -ne '.' >/dev/stderr | |
# Ensure new host names are unique | |
hostz=$(echo ${hostz[@]} ${hosts[@]} | tr ' ' '\n' | sort -u | tr '\n' ' ') | |
# Increment the loop counter | |
count+=1 | |
# Show activity by periodically outputting a dot to the process error stream | |
echo -ne '.' >/dev/stderr | |
# Wait at least two seconds with a possibility of up to four more | |
sleep $(( 2 + $[ RANDOM % 4 ] )) | |
# Iteratively append negated site operators to new search request | |
for h in ${hosts[*]}; do | |
# Craft query string based on discovered sub-domain names | |
gargs+=" -site:${h}.${1}" | |
done | |
# Continuously alert the operator to ongoing business | |
echo -ne '.' >/dev/stderr | |
# Avoid getting flagged as a bot by trying not to startle Google | |
sleep $(( 4 + $[ RANDOM % 8 ] )) | |
# Display another period via the standard error device | |
echo -ne '.' >/dev/stderr | |
done | |
# End dot sequence by dropping down onto the next terminal row via a newline | |
echo >/dev/stderr | |
# Output results array | |
for h in ${hostz[*]}; do | |
echo "${h}.${1}" | |
done | |
# Finished! | |
exit 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment