#! /usr/bin/env bash # # ssht # Copyright (C) 2018 salt # # Distributed under terms of the MIT license. # name="$(basename $0 .sh)" # $1: Message function log() { [ -z ${1+x} ] && return 1 printf "\e[94m$name\e[0m: $*\n" } # $1: Binary in $PATH function check_program_exists() { if ! which $1 > /dev/null 2>&1; then return 1 fi return 0 } function get_tor_port() { for port in 9050 9051 9150 9151; do if netstat -ntl | grep 127.0.0.1:"$port" > /dev/null 2>&1; then export return="$port" return 0 fi done return 1 } # $1: Tor Port # $2: Host # $*: Command function ssh_through_tor() { [ -z ${3+x} ] && return 1 ssh -o ProxyCommand="nc -x 127.0.0.1:$1 \%h \%p" $2 ${*:3} } # $1: Tor Port # $2: Host function get_ssh_ip() { # Yes, this is bad and you could totally run it through an SSH tunnel # to avoid the curl requirement on the remote host # Yes, that would avoid an extraneous connection # TODO: That, also add curl to the list of critical requirements log "Checking if host $2 has curl" if ssh_through_tor "$1" "$2" which curl > /dev/null 2>&1; then log "Finding out host's IP through curl" export return="$(ssh_through_tor $1 $2 curl -s http://whatismyip.akamai.com)" return 0 fi # TODO: Add more identification methods return 1 } # $1: Host # $*: Arguments to ssh function main() { if ! [[ "$1" == *.onion ]]; then log "First argument must be a .onion address" exit 1 fi for dep in ssh tor netstat nc; do if ! check_program_exists "$dep"; then log "Could not find critical dependency \"$dep\"" exit 50 fi done if ! get_tor_port; then log "Tor is not running" exit 51 fi torport="$return" log "Found Tor listening on local port $torport" if ! get_ssh_ip $torport $1; then log "Failed to determine target's public IP" exit 52 fi ssh_ip="$return" log "Found public IP: $ssh_ip" unset return torport exec ssh $ssh_ip ${*:2} } main "$@"