The below code fails to exit after 3/3 even though the stderr text
[ERROR] ssh target does not support password auth
fprintf(stderr, "[ERROR] ssh target..
if len(sys.argv) != 3:
print "Usage: sshrecon.py <ip address> <port>"
ip_address = sys.argv.strip()
port = sys.argv.strip()
print "INFO: Performing <<TEST>> hydra ssh scan against " + ip_address
#3 steps for test phase:
#1 Run Hydra
#2 Gather std_err std_out output into a var
#3 analyze for String. Exit if found, else continue with full scan.
#[1/3] TEST if target allows PW auth
HYDRA_TEST_COMMAND = "hydra -l test -p test -f -o /var/www/html/recon_scan/results/labs/%s_test.txt -u %s -s %s ssh" % (ip_address, ip_address, port)
results_Test = subprocess.Popen(HYDRA_TEST_COMMAND, stdout=subprocess.PIPE, shell=True)
#[2/3]Gather stderr, stdout output into var
output = results_Test.stdout.read()
#[3/3]analyze std_out for string. Exit if found.
if "ssh target does not support password auth" in output:
This does not capture the result of
results_Test = subprocess.Popen( HYDRA_TEST_COMMAND, stdout=subprocess.PIPE, shell=True)
stderr is not redirected, only
stdout, your program will not be able to read it. Your two choices are to mix
stdout into one single stream, or to capture them separately.
If you want to combine both
stdout into one stream,
results_Test = subprocess.Popen( HYDRA_TEST_COMMAND, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
If you want separate streams,
results_Test = subprocess.Popen( HYDRA_TEST_COMMAND, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
shell=True is not recommended in general, because it can lead to potential unexpected behavior or attack vectors. Alternatively, you can pass the arguments as a list instead of a string, and then you can use the default (safer, faster)
HYDRA_TEST_COMMAND = [ 'hydra', '-l', 'test', '-p', 'test', '-f', '-o', '/var/www/html/recon_scan/results/labs/%s_test.txt' % ip_address, '-u', ip_address, '-s', port, 'ssh']
port is an
int you will need to use
There are cases where
shell=True is more convenient but they are rare in practice.
This might not affect how your program works, but it eliminates problems with quoting or weird characters in filenames. If you don't like how verbose it is you can make it a bit shorter with
# instead of results_Test.stdout.read() stdout, stderr = results_Test.communicate()
If you used
PIPE for both
stderr, this gives you the contents of both in separate variables. If you use
.stdout.read() instead, the process can become blocked waiting for you to read from
.stderr.read(). That's the primary job of
.communicate() -- it reads from both
stdout at the same time so the process doesn't block.
If you use
stderr will be
None because the contents are mixed into
In either case, it is recommended to use