forked from extern/SSH-Snake
Resolve all IPv4 addresses for domain names (if possible).
Return false in is_ssh_host() if an invalid IP address ([0-9\.]* which is not ^[0-9]+(\.[0-9]+){3}$) Force lowercase in is_ssh_dest() and add_ssh_dest()
This commit is contained in:
parent
3ff1879d06
commit
f9a46b8c86
@ -147,5 +147,3 @@ I am particually interested in any interesting `[line]` outputs associated with
|
|||||||
- `find ... -readable ...` is used in the script in multiple places. The `-readable` flag is not supported on all versions of `find(1)`.
|
- `find ... -readable ...` is used in the script in multiple places. The `-readable` flag is not supported on all versions of `find(1)`.
|
||||||
|
|
||||||
- The script does not currently look for SSH agent sockets.
|
- The script does not currently look for SSH agent sockets.
|
||||||
|
|
||||||
- The script does not properly resolve domains with multiple IPv4 addresses.
|
|
||||||
|
@ -994,7 +994,7 @@ local ssh_dest
|
|||||||
declare -A valid_ssh_dests
|
declare -A valid_ssh_dests
|
||||||
declare -A resolved_hosts
|
declare -A resolved_hosts
|
||||||
local res
|
local res
|
||||||
local mac
|
local use_mac
|
||||||
local to
|
local to
|
||||||
if command -v timeout >/dev/null 2>&1; then
|
if command -v timeout >/dev/null 2>&1; then
|
||||||
to="timeout 5"
|
to="timeout 5"
|
||||||
@ -1003,7 +1003,7 @@ if getent ahostsv4 -- 1.1.1.1 >/dev/null 2>&1; then
|
|||||||
res="$to getent ahostsv4 --"
|
res="$to getent ahostsv4 --"
|
||||||
elif dscacheutil -q host -a name 1.1.1.1 >/dev/null 2>&1; then
|
elif dscacheutil -q host -a name 1.1.1.1 >/dev/null 2>&1; then
|
||||||
res="$to dscacheutil -q host -a name"
|
res="$to dscacheutil -q host -a name"
|
||||||
mac="1"
|
use_mac="1"
|
||||||
else
|
else
|
||||||
printf "INTERNAL_MSG: command not found: RESOLVE (%s)\n" "$(uname -a 2>/dev/null)"
|
printf "INTERNAL_MSG: command not found: RESOLVE (%s)\n" "$(uname -a 2>/dev/null)"
|
||||||
fin
|
fin
|
||||||
@ -1027,27 +1027,32 @@ is_ssh_dest "$ssh_dest" || continue
|
|||||||
ssh_user="${ssh_dest%%@*}"
|
ssh_user="${ssh_dest%%@*}"
|
||||||
ssh_host="${ssh_dest#*@}"
|
ssh_host="${ssh_dest#*@}"
|
||||||
if [[ -v 'resolved_hosts["$ssh_host"]' || ${#resolved_hosts["$ssh_host"]} -gt 0 ]]; then
|
if [[ -v 'resolved_hosts["$ssh_host"]' || ${#resolved_hosts["$ssh_host"]} -gt 0 ]]; then
|
||||||
resolved_ssh_host="${resolved_hosts["$ssh_host"]}"
|
:
|
||||||
else
|
else
|
||||||
if [[ -n "$mac" ]]; then
|
local resolved_ssh_hosts
|
||||||
resolved_ssh_host="$($res "$ssh_host" 2>/dev/null | grep -F 'ip_address:')"
|
if [[ -n "$use_mac" ]]; then
|
||||||
resolved_ssh_host="${resolved_ssh_host#* }"
|
resolved_ssh_hosts="$($res "$ssh_host" 2>/dev/null | awk '/ip_address:/{print $NF}')"
|
||||||
else
|
else
|
||||||
resolved_ssh_host="$($res "$ssh_host" 2>/dev/null)"
|
resolved_ssh_hosts="$($res "$ssh_host" 2>/dev/null | awk '/RAW/{print $1}')"
|
||||||
resolved_ssh_host="${resolved_ssh_host%% *}"
|
|
||||||
fi
|
fi
|
||||||
|
for resolved_ssh_host in "${resolved_ssh_hosts[@]}"; do
|
||||||
if [[ "${resolved_ssh_host:0:1}" =~ [12] ]]; then
|
if [[ "${resolved_ssh_host:0:1}" =~ [12] ]]; then
|
||||||
[[ "$resolved_ssh_host" =~ ^127\. ]] && resolved_ssh_host="127.0.0.1"
|
[[ "$resolved_ssh_host" =~ ^127\. ]] && resolved_ssh_host="127.0.0.1"
|
||||||
resolved_hosts["$ssh_host"]="$resolved_ssh_host"
|
[[ -v '_ignored_hosts["$resolved_ssh_host"]' || ${#_ignored_hosts["$resolved_ssh_host"]} -gt 0 ]] && continue
|
||||||
|
resolved_hosts["$ssh_host"]+="$resolved_ssh_host "
|
||||||
else
|
else
|
||||||
_ignored_hosts["$ssh_host"]=1
|
|
||||||
[[ -n "$resolved_ssh_host" ]] && _ignored_hosts["$resolved_ssh_host"]=1
|
[[ -n "$resolved_ssh_host" ]] && _ignored_hosts["$resolved_ssh_host"]=1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
if [[ "${#resolved_hosts["$ssh_host"]}" -lt 7 ]]; then
|
||||||
|
_ignored_hosts["$ssh_host"]=1
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
fi
|
for resolved_ssh_host in ${resolved_hosts["$ssh_host"]}; do
|
||||||
[[ -v '_ignored_hosts["$resolved_ssh_host"]' || ${#_ignored_hosts["$resolved_ssh_host"]} -gt 0 ]] && _ignored_hosts["$ssh_host"]=1
|
|
||||||
valid_ssh_dests["$ssh_user@$resolved_ssh_host"]=1
|
valid_ssh_dests["$ssh_user@$resolved_ssh_host"]=1
|
||||||
done
|
done
|
||||||
|
done
|
||||||
ssh_dests=()
|
ssh_dests=()
|
||||||
for ssh_dest in "${!valid_ssh_dests[@]}"; do
|
for ssh_dest in "${!valid_ssh_dests[@]}"; do
|
||||||
add_ssh_dest "$ssh_dest"
|
add_ssh_dest "$ssh_dest"
|
||||||
@ -1088,6 +1093,9 @@ ssh_host="$1"
|
|||||||
[[ -v 'ssh_hosts["$ssh_host"]' || ${#ssh_hosts["$ssh_host"]} -gt 0 ]] && return 0
|
[[ -v 'ssh_hosts["$ssh_host"]' || ${#ssh_hosts["$ssh_host"]} -gt 0 ]] && return 0
|
||||||
[[ "$ssh_host" =~ ^$allowed_host_chars+$ ]] || return 1
|
[[ "$ssh_host" =~ ^$allowed_host_chars+$ ]] || return 1
|
||||||
[[ "${ssh_host:0:1}" == "-" || "${ssh_host:0-1}" == "-" || "${ssh_host:0:1}" == "." || "${ssh_host:0-1}" == "." || "$ssh_host" == *"-."* || "$ssh_host" == *"--"* ]] && return 1
|
[[ "${ssh_host:0:1}" == "-" || "${ssh_host:0-1}" == "-" || "${ssh_host:0:1}" == "." || "${ssh_host:0-1}" == "." || "$ssh_host" == *"-."* || "$ssh_host" == *"--"* ]] && return 1
|
||||||
|
if [[ "$ssh_host" =~ ^[0-9.]+$ ]]; then
|
||||||
|
[[ "$ssh_host" =~ ^[0-9]+(\.[0-9]+){3}$ ]] || return 1
|
||||||
|
fi
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
is_ssh_dest() {
|
is_ssh_dest() {
|
||||||
@ -1096,6 +1104,7 @@ local ssh_host
|
|||||||
local ssh_dest
|
local ssh_dest
|
||||||
ssh_dest="$1"
|
ssh_dest="$1"
|
||||||
[[ -z "$ssh_dest" ]] && return 1
|
[[ -z "$ssh_dest" ]] && return 1
|
||||||
|
ssh_dest="${ssh_dest,,}"
|
||||||
[[ -v '_ignored_dests["$ssh_dest"]' || ${#_ignored_dests["$ssh_dest"]} -gt 0 ]] && return 1
|
[[ -v '_ignored_dests["$ssh_dest"]' || ${#_ignored_dests["$ssh_dest"]} -gt 0 ]] && return 1
|
||||||
ssh_user="${ssh_dest%%@*}"
|
ssh_user="${ssh_dest%%@*}"
|
||||||
ssh_host="${ssh_dest#*@}"
|
ssh_host="${ssh_dest#*@}"
|
||||||
@ -1119,6 +1128,7 @@ local ssh_dest
|
|||||||
local ssh_host
|
local ssh_host
|
||||||
local ssh_user
|
local ssh_user
|
||||||
ssh_dest="$1"
|
ssh_dest="$1"
|
||||||
|
ssh_dest="${ssh_dest,,}"
|
||||||
ssh_user="${ssh_dest%%@*}"
|
ssh_user="${ssh_dest%%@*}"
|
||||||
ssh_host="${ssh_dest#*@}"
|
ssh_host="${ssh_dest#*@}"
|
||||||
is_ssh_dest "$ssh_dest" && ssh_dests["$ssh_dest"]=1 && ssh_hosts["$ssh_host"]=1 && ssh_users["$ssh_user"]=1 && return 0
|
is_ssh_dest "$ssh_dest" && ssh_dests["$ssh_dest"]=1 && ssh_hosts["$ssh_host"]=1 && ssh_users["$ssh_user"]=1 && return 0
|
||||||
|
51
Snake.sh
51
Snake.sh
@ -1672,13 +1672,12 @@ combinate_interesting_users_hosts() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# Deduplicate ssh_dests by resolving the hosts for each ssh_dest, checking whether the user, host, or resolved dest is ignored, then adding the destinations back to the original ssh_dests array.
|
# Deduplicate ssh_dests by resolving the hosts for each ssh_dest, checking whether the user, host, or resolved dest is ignored, then adding the destinations back to the original ssh_dests array.
|
||||||
# TODO: doesn't support hosts with multiple hosts (4 ips for 1 domain), and in fact may even break that.
|
|
||||||
deduplicate_resolved_hosts_keys() {
|
deduplicate_resolved_hosts_keys() {
|
||||||
local ssh_dest
|
local ssh_dest
|
||||||
declare -A valid_ssh_dests
|
declare -A valid_ssh_dests
|
||||||
declare -A resolved_hosts
|
declare -A resolved_hosts
|
||||||
local res
|
local res
|
||||||
local mac
|
local use_mac
|
||||||
local to
|
local to
|
||||||
|
|
||||||
# DNS timeout of 5 seconds per address (bleh, hack).
|
# DNS timeout of 5 seconds per address (bleh, hack).
|
||||||
@ -1692,7 +1691,7 @@ deduplicate_resolved_hosts_keys() {
|
|||||||
# Otherwise dscacheutils for mac.
|
# Otherwise dscacheutils for mac.
|
||||||
elif dscacheutil -q host -a name 1.1.1.1 >/dev/null 2>&1; then
|
elif dscacheutil -q host -a name 1.1.1.1 >/dev/null 2>&1; then
|
||||||
res="$to dscacheutil -q host -a name"
|
res="$to dscacheutil -q host -a name"
|
||||||
mac="1"
|
use_mac="1"
|
||||||
else
|
else
|
||||||
# If we can't use getent or dscacheutil, we're on an unknown type of system (with bash?!)
|
# If we can't use getent or dscacheutil, we're on an unknown type of system (with bash?!)
|
||||||
# Use printf instead of chained_print() to be consistent.
|
# Use printf instead of chained_print() to be consistent.
|
||||||
@ -1724,45 +1723,52 @@ deduplicate_resolved_hosts_keys() {
|
|||||||
# Make everything lower case.
|
# Make everything lower case.
|
||||||
ssh_dest="${ssh_dest,,}"
|
ssh_dest="${ssh_dest,,}"
|
||||||
|
|
||||||
is_ssh_dest "$ssh_dest" || continue
|
is_ssh_dest "$ssh_dest" || continue # Checks if the host has been ignored in this loop
|
||||||
|
|
||||||
ssh_user="${ssh_dest%%@*}"
|
ssh_user="${ssh_dest%%@*}"
|
||||||
ssh_host="${ssh_dest#*@}"
|
ssh_host="${ssh_dest#*@}"
|
||||||
|
|
||||||
# Check if the host has already been resolved. If it has, use the internally cached answer.
|
# Check if the host has already been resolved. If it has, use the internally cached answer.
|
||||||
if [[ -v 'resolved_hosts["$ssh_host"]' || ${#resolved_hosts["$ssh_host"]} -gt 0 ]]; then
|
if [[ -v 'resolved_hosts["$ssh_host"]' || ${#resolved_hosts["$ssh_host"]} -gt 0 ]]; then
|
||||||
resolved_ssh_host="${resolved_hosts["$ssh_host"]}"
|
:
|
||||||
else
|
else
|
||||||
# If the host has not already been resolved, resolve it.
|
# If the host has not already been resolved, resolve it.
|
||||||
|
# If resolution of ${resolved_hosts["$ssh_host"]} failed before, we won't hit this code path because the host will be added to _ignored_hosts (and will be skipped using is_ssh_dest().
|
||||||
# macos
|
# macos
|
||||||
if [[ -n "$mac" ]]; then
|
local resolved_ssh_hosts # list of ipv4 addresses for a host
|
||||||
resolved_ssh_host="$($res "$ssh_host" 2>/dev/null | grep -F 'ip_address:')"
|
if [[ -n "$use_mac" ]]; then
|
||||||
resolved_ssh_host="${resolved_ssh_host#* }" # format is 'ip_address: ip'
|
resolved_ssh_hosts="$($res "$ssh_host" 2>/dev/null | awk '/ip_address:/{print $NF}')"
|
||||||
else
|
else
|
||||||
resolved_ssh_host="$($res "$ssh_host" 2>/dev/null)"
|
# linux
|
||||||
resolved_ssh_host="${resolved_ssh_host%% *}" # format is 'ip\t[junk]
|
resolved_ssh_hosts="$($res "$ssh_host" 2>/dev/null | awk '/RAW/{print $1}')"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
for resolved_ssh_host in "${resolved_ssh_hosts[@]}"; do
|
||||||
# Answer must begin with 1 or 2 ($res 0.1.2.3 will respond with 0.1.2.3).
|
# Answer must begin with 1 or 2 ($res 0.1.2.3 will respond with 0.1.2.3).
|
||||||
if [[ "${resolved_ssh_host:0:1}" =~ [12] ]]; then
|
if [[ "${resolved_ssh_host:0:1}" =~ [12] ]]; then
|
||||||
[[ "$resolved_ssh_host" =~ ^127\. ]] && resolved_ssh_host="127.0.0.1" # If it's loopback, always use 127.0.0.1
|
[[ "$resolved_ssh_host" =~ ^127\. ]] && resolved_ssh_host="127.0.0.1" # If it's loopback, always use 127.0.0.1
|
||||||
|
[[ -v '_ignored_hosts["$resolved_ssh_host"]' || ${#_ignored_hosts["$resolved_ssh_host"]} -gt 0 ]] && continue
|
||||||
# Cache the host
|
# Cache the host
|
||||||
resolved_hosts["$ssh_host"]="$resolved_ssh_host"
|
resolved_hosts["$ssh_host"]+="$resolved_ssh_host "
|
||||||
else
|
else
|
||||||
# Ignore this host
|
# Ignore this RESOLVED host (might save us a few cycles).
|
||||||
_ignored_hosts["$ssh_host"]=1
|
# Don't add the ssh_host to _ignored_hosts become it may have non-ignored hosts, too.
|
||||||
# Also ignore the resolved host (which may not necessarily be the same as the host).
|
|
||||||
[[ -n "$resolved_ssh_host" ]] && _ignored_hosts["$resolved_ssh_host"]=1
|
[[ -n "$resolved_ssh_host" ]] && _ignored_hosts["$resolved_ssh_host"]=1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# No IPs resolved for the host, add the host to _ignored_host.
|
||||||
|
if [[ "${#resolved_hosts["$ssh_host"]}" -lt 7 ]]; then
|
||||||
|
_ignored_hosts["$ssh_host"]=1
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
fi
|
|
||||||
|
|
||||||
# Check whether the resolved host is ignored. If so, also add the unresolved host to _ignored_hosts.
|
|
||||||
[[ -v '_ignored_hosts["$resolved_ssh_host"]' || ${#_ignored_hosts["$resolved_ssh_host"]} -gt 0 ]] && _ignored_hosts["$ssh_host"]=1
|
|
||||||
# add_ssh_dest will check whether the $ssh_user@$resolved_ssh_host is ignored.
|
|
||||||
|
|
||||||
|
# Loop through each host (which are space-separated now), so no quotation marks.
|
||||||
|
for resolved_ssh_host in ${resolved_hosts["$ssh_host"]}; do
|
||||||
valid_ssh_dests["$ssh_user@$resolved_ssh_host"]=1
|
valid_ssh_dests["$ssh_user@$resolved_ssh_host"]=1
|
||||||
done
|
done
|
||||||
|
done
|
||||||
|
|
||||||
ssh_dests=()
|
ssh_dests=()
|
||||||
|
|
||||||
@ -1834,6 +1840,10 @@ is_ssh_host() {
|
|||||||
|
|
||||||
[[ "${ssh_host:0:1}" == "-" || "${ssh_host:0-1}" == "-" || "${ssh_host:0:1}" == "." || "${ssh_host:0-1}" == "." || "$ssh_host" == *"-."* || "$ssh_host" == *"--"* ]] && return 1
|
[[ "${ssh_host:0:1}" == "-" || "${ssh_host:0-1}" == "-" || "${ssh_host:0:1}" == "." || "${ssh_host:0-1}" == "." || "$ssh_host" == *"-."* || "$ssh_host" == *"--"* ]] && return 1
|
||||||
|
|
||||||
|
if [[ "$ssh_host" =~ ^[0-9.]+$ ]]; then
|
||||||
|
[[ "$ssh_host" =~ ^[0-9]+(\.[0-9]+){3}$ ]] || return 1
|
||||||
|
fi
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1847,6 +1857,8 @@ is_ssh_dest() {
|
|||||||
|
|
||||||
[[ -z "$ssh_dest" ]] && return 1
|
[[ -z "$ssh_dest" ]] && return 1
|
||||||
|
|
||||||
|
ssh_dest="${ssh_dest,,}"
|
||||||
|
|
||||||
# XXX: The below line is intrinsically flawed because even if $ssh_dest is already in ssh_dests, this does not mean $ssh_host has not been added to $_ignored_hosts. We keep it here to remember not to add it again.
|
# XXX: The below line is intrinsically flawed because even if $ssh_dest is already in ssh_dests, this does not mean $ssh_host has not been added to $_ignored_hosts. We keep it here to remember not to add it again.
|
||||||
# [[ -v 'ssh_dests["$ssh_dest"]' || ${#ssh_dests["$ssh_dest"]} -gt 0 ]] && return 0
|
# [[ -v 'ssh_dests["$ssh_dest"]' || ${#ssh_dests["$ssh_dest"]} -gt 0 ]] && return 0
|
||||||
|
|
||||||
@ -1888,6 +1900,7 @@ add_ssh_dest() {
|
|||||||
local ssh_user
|
local ssh_user
|
||||||
|
|
||||||
ssh_dest="$1"
|
ssh_dest="$1"
|
||||||
|
ssh_dest="${ssh_dest,,}"
|
||||||
ssh_user="${ssh_dest%%@*}"
|
ssh_user="${ssh_dest%%@*}"
|
||||||
ssh_host="${ssh_dest#*@}"
|
ssh_host="${ssh_dest#*@}"
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user