Let's Code! An Ssh Bruteforcer. by Ben from 21 Aug 2016

Since this is the first Let's Code! I am going to describe my setup and why I am doing things the way I am going to do them. I am going to do most of my early coding on this site in either powershell or C#. I use PowerGUI for coding powershell in. It has excellent syntax highlighting; and I find the variables window to be indispensable when trying to figure out what my code is doing. And for C# I use Visual Studio 2015 Community, as it is industry standard, but mainly becuase I absolutely LOVE LOVE it's indentation fixing.

I am going to be using the default powershell that comes with a fully updated Windows 10 install. I have not specifically updated powershell. But why would I not download the most up to date powershell to write my code in? I want my code to be as compatible as possible. Powershell regularly releases entire functions in new versions which will not be compatible with older versions. I know that Windows 7 uses powershell 2.0 by default and that my powershell version is 5.0(Windows 10). At work, I limit my code to 2.0 compatible only functions and code as Windows 7 is heavily deployed. At home, I am fine with running 5.0 as I only have the one Windows machine and its 10. But why am I fine with this for code intended to be used in unknown environments? Well, as we all know Microsoft has sorta been dicks about shoving Windows 10 down everyone's throats! They brag about having 300 million plus installs already. So, I would say that's a decent target base and so again to maximize compatibility I limit myself to the default version.

Ok, So with that out of the way I'll get to the meat of today's Let's Code!

The first project I am going to be working on is an SSH bruteforcer. I've heard alot about bruteforce attacks in the media. I think it's fairly common knowledge that any server with an interactive login is actively scanned against within a few hours of coming online. SSH is an extremely common protocol and it's the main remote access protocol for almost all linux machines. So it presents a potentially very large attack surface. A bruteforce attack is simply an attack in which the attacker tries a combination of all possible usernames and passwords. If I wanted to do this myself how hard would it be? I don't know, let's figure it out! How should I go about doing this? Well, I want to be able to reuse my work with as little friction as possible in the future. So, I am thinking I should make this into a powershell function; that way I can use it with other scripts or from a command line. This project may possibly end up being multiple interdependent functions, I really don't know... I haven't written it yet. What features should it have to prove the concept?

  • Load a list of servers from a file.
  • Load a list of usernames from a file.
  • Load a password wordlist from a file.
  • Cycle through all username and password combinations.
  • Attempt SSH logins for each combination.
  • Output successes into a file.

So, now that I have some idea of what I am going to do and what the requirements are, I am finally going to jump into the code.

function Ssh-Bruteforcer
	 [string] $PathtoServers,
	 [string] $PathtoUsernames,
	 [string] $PathtoPasswords,
	 [string] $PathtoOutput
Import-Module PoSH-SSH

$servers = Get-Content $PathtoServers
$usernames = Get-Content $PathtoUsernames
$passwords = Get-Content $PathtoPasswords	
Foreach ($urlofserver in $servers)
	Foreach($username in $usernames)
		Foreach ($password in $passwords)
			$password2 = $password.ToString()
			$password = $password | Convertto-Securestring -AsPlainText -Force
			$creds = new-object -typename System.Management.Automation.PSCredential`
			-argumentlist $username,$password
			New-SSHSession -ComputerName $urlofserver -Credential $creds -Force
			$currentses = Get-SSHSession -SessionId 0
			If($currentses.Session.IsConnected -eq $True)
				$output = $urlofserver + ", " + $username + ", " + $password2 
				$output | Out-File -Append -FilePath $PathtoOutput
				Remove-SSHSession -SessionId 0

So I had heard a while back that Microsoft was bringing SSH to Powershell in Windows 10. Well, that didn't come in the form of built in functions as I had hoped. Instead, best I can tell it has come about in the form of modules. PoSH-SSH is one such module. I am going to use it do the heavy lifting for establishing SSH sessions. I am simply going to be directing it with my function. First you wanna make sure you have the module installed. This can be done by running the following command from a powershell window that has been opened with administrative privilege.

  • Find-Module PoSH-SSH | Install-Module

Once I had the PoSH-SSH module installed wanted to make sure that it is invoked every time I want to use the my function. Import-Module PoSH-SSH is included in the script for that purpose. Next I get the content of 3 different text files using Get-Content. First, I start with the first server in the servers.txt file. I then loop through all usernames in the usernames text file. For each username I then loop through every password in the passwords text file. So say for example admin is the first username in the list, this function will loop through all of the passwords in the list with admin as the username before it moves on to the second username in the list. After it has tried all usernames and passwords, it then moves on to the next server. PoSH-SSH does not just allow you feed it a username and password as arguments. Instead it used -Credential, which from what I can tell is meant to use the Get-Credentials module. This makes us do a couple extra lines worth of work in order to feed it usernames and passwords of our choosing. First, we have to convert the password to a secure string. While attempting this I ran into some issues which lead to me needing the -AsPlainText -Force arguments for this to work. The "$creds = new-object -typename System.Management.Automation.PSCredential -argumentlist $username,$password" line then takes the current username and password combo and creates an object which can then be fed into PoSH-SSH. I then actually attempt to log in. The output of the login attempt is parsed to see if it was successful or not. If the output indicates the session was connected successfully I then output to a textfile the successful serverurl, username, password combo for later use. I then close the sesssion and move on to the next combination.

So that's it for the proof of concept code. Lets see if it works! For this I have setup a simple ssh server on a spare Raspberry Pi with an IP on my local network of I have placed the server, output, username, and password text files in C:\Users\Cold\Documents\scripts\sshbruteforcer\ but you can put them where ever you would like. In these files I have been sure to include the correct username and password combo for the SSH server. In this instance I have left the defualt password set for the Raspberry Pi as alot of people are prone to do this with certain devices. I then tested my function by running the below command:

Ssh-Bruteforcer -PathtoUsernames "C:\Users\Cold\Documents\scripts\sshbruteforcer\usernames.txt" -PathtoPasswords "C:\Users\Cold\Documents\scripts\sshbruteforcer\passwords.txt" -PathtoServers "C:\Users\Cold\Documents\scripts\sshbruteforcer\servers.txt" -PathtoOutput "C:\Users\Cold\Documents\scripts\sshbruteforcer\output.txt"

So what was the outcome? A complete success!! I got a login!!! So what are the takeways? Well, I learned alot along the way. Got to break in Notepad++ and powerGUI a bit. And most importantly I can now bruteforce SSH servers!!!!! I think I can refine the bruteforcer some. I think I could add in some multithreading and things like that to speed everything up. But thats for another day. For now I have packaged the script and text files up into a zip which you can download here. But I have also added it to my profile so I can use it whenever I need. And last but not least check out a video of this bad boy in action.