Bash Port Scanning (SSH) as a Python Script [TryHackMe]

5/5 - (2 votes)
Bash Port Scanning (SSH) as a Python Script [TryHackMe]

Background

I’ve been working on the Alice in Wonderland series of free hacking CTF (Capture the Flag) challenges on TryHackMe.

🚩 Recommended Tutorial: Capture the Flag – Alice in Wonderland – TryHackMe Walkthrough

While working on the second box in the series, Looking Glass, I stumbled upon a bash script written by Tay1or, another user on TryHackMe.

The opening challenge involves finding the correct port which hides an encrypted poem, Jabberwocky by Lewis Caroll.

Using a script here is a more efficient solution because it is quite time-consuming to manually attempt connecting to different ssh ports over and over until the correct port can be found.

The box also resets the mystery port after each login, so unless you solve the box on your first attempt, the script will come in handy multiple times.

Bash Script

Here is Tay1or’s bash script with a few slight modifications in bold to make it run on my machine:

#!/usr/bin/bash

low=9000
high=13000

while true
do
        mid=$(echo "($high+$low)/2" | bc)
        echo -n "Low: $low, High: $high, Trying port: $mid – "
        msg=$(ssh -o "HostKeyAlgorithms=+ssh-rsa" -p $mid $targetIP | tr -d '\r')
        echo "$msg"

        if [[ "$msg" == "Lower" ]]
        then
                low=$mid
        elif [[ "$msg" == "Higher" ]]
        then
                high=$mid
        fi
done

I’m still new to bash scripting, but because I already understand the context of the problem being faced, I can more or less guess what the script is doing.

At the top, under the shebang line, it first sets low and high values for the ports to be searched. Then we see a while true loop.

The first command in the loop calculates the midpoint between the low and the high port values in the given range.

The echo command prints the low/high/and midpoint port that is currently being tested.

Then we have if/elif commands to respond appropriately to the output of the $msg to set the mid to either the lower or higher range variables. By resetting the range after each attempted connection, the search will take a minimal amount of time by eliminating the largest number of ports possible on each attempt.

When the output msg is neither “Higher” or “Lower” it will end the loop because we will have hit our secret encrypted message on the correct port.

Conversion into a Python script

I started wondering how it might be possible to translate the bash script to a Python script and decided to try my hand at converting the functionality of the code.

I’m more comfortable scripting in Python, and I think it will probably come in handy later in future challenges to be able to quickly write up a script during CTF challenges to save time. 

The inputs of the code are the targetIP and high and low values of the target SSH port range.

Outputs are the response from the targetIP on each attempted connection until the secret port is found. Once the secret port is found, the program will reiterate that you have found the port.

I posted the final version of the python script here on GitHub. For your convenience, I’ll include it here too:

#!/usr/bin/env python3
# These sites were used as references: https://stackabuse.com/executing-shell-commands-wi>
# https://stackoverflow.com/questions/4760215/running-shell-command-and-capturing-the->

#set up initial conditions for the target port search
import subprocess
low_port=9000
high_port=13790
targetIP = "10.10.252.52"
print(targetIP)
#initialize loop_key variable:
loop_key="higher"

while loop_key=="Higher" or "Lower":
    print('low = '  + str(low_port) + ', high = ' + str(high_port))
#a good place to use floor division to cut off the extra digit
    mid_port=(high_port+low_port)//2
    print('Trying port ' + str(mid_port))
    #attempt to connect to the mid port
    result = subprocess.run(['ssh', 'root@' + str(targetIP), '-oHostKeyAlgorithms=+ssh-rsa', '-p', str(mid_port)], stdout=subprocess.PIPE)
    # prep the decoded output variable
    msg = result.stdout
    decoded_msg = msg.decode('utf-8')
    # print result of attempted ssh connection
    print(decoded_msg)

    if "Higher" in decoded_msg:
        #print("yes I see the words Higher")
        high_port=mid_port
        print(high_port)
        loop_key="Higher"
    elif "Lower" in decoded_msg:
        low_port=mid_port
        print(low_port)
        loop_key="Lower"
    else:
        print("You found the secret port - " + str(mid_port))
        exit()