Hello, and welcome to this course where, we're talking about how to use Python to gain initial access to a target system. Hitting that initial access tactic of the miter attack framework. In this video, we're going to be talking about testing for the use of default account credentials. We are not aware, there are a lot of systems that have very weak default usernames and passwords. For example, routers, commonly something like 'admin' on the main portal. This makes it rather easy to gain access to and take control of these vulnerable systems like routers, IoT devices, computers with weak passwords, etc. In this video, we're going to talk about a few different ways to use Python to scan for these devices with these weak default usernames and passwords. Our file in this case, for this demo is TestDefaultCredentials.py. What we're going to be doing in this example is using SSH and Telnet to test default credentials on a system. We have Python code written here to do an SSHLogin and a TelnetLogin. If we go down to the bottom here and call it our main function, we see the code that's going to be run when we start up this program. In this case we're going to try to be logging onto local host 127.0.0.1. We're going to be using a file called defaults.text as our list or source of default credentials. You're going to iterate over that, split them based of space, and then pull username password pairs out of this file. In this case, the file structure to have just a line of username password in the same line, could also write this to have maybe our usernames file, and a passwords file, where every password is tested with every username. For each username password combination, we're going to try and log in to the local host on port 22 using SSH and on port 23 using Telnet combination on as useful because computers may be running an SSH server, while things like IoT devices often have a weak protocol like Telnet enabled, making it a good choice to scan for that as well. Looking into our SSH code here at the top, we see that we're going to be using library called Paramiko to implement SSH for us. What we can do is access it's SSHClient, and then we just need to set up and perform our request using passwords rather than host keys. What we're going to do here is if we don't have a server key enabled, Which we don't because we're scanning, we're going to say that we just ignore the fact that the server host key isn't in our list of trusted keys. Which makes perfect sense because we don't want to either require user interaction to accept a key, and we certainly don't want the connection to fail simply because we don't have a key for a server that we're currently scanning. Here in this line, we're using ssh.connect to actually try to perform the login. We say, local host as our host, so 127.0.0.1. Port is going to be 22, and then we have a username and password that we're providing from our defaults.txt file. Then we attempt to open the session now that we've tried to connect. In this statement, we're testing whether or not we have an active session. If you think about it, if you're logging in via SSH, if you have an active session after providing username and password, that means that your login was successful. That means that that username and password are valid set of credentials for that particular machine. If you don't have an active session, then those credentials weren't correct. If we get an active session, we're saying, SSH login successful on, this is host and port, with username this, and password this. Getting those parameters from over here. This way, since we're iterating potentially over many, many IP addresses, maybe many, many ports. If you're assuming that SSH isn't running on a default port and many, many usernames and passwords. Our print statement here tells us exactly how we succeeded. Then we're catching any exceptions that may occur here. If we have any exceptions, we just returned from the function and then if we've had a clean login, everything worked out. We're going to close our SSH connection cleanly. That's our test to determine can we log in via SSH. Our other option is telnet. I mentioned IoT devices often have default credentials, often have Telnet running, and so having a Telnet based test also makes good sense. In this case, we need to define our username and password as bytes. They also need to be on their own lines, so we're defining user and password here as those so we can use them later in the code. In this case, we're using Python's telnetlib library. This sets up a Telnet connection to a particular IP address, in this case local host, and a particular port, in this case, Port 23. We're then going to use the read until command of Telnet lab. What this does is it takes a particular thing to look for, and it just keeps on reading in data off of the wire until it sees that particular thing. In this case, we're looking for a login prompt. If this isn't the login prompt used by this particular system, say they've customized it in some way, this is going to fail. This only works if we have the correct login prompt. If we do, we write in our username on its own line, and then we again read until and look for the password login prompt. When we receive that, we again provide a password. Then we've got a try-except block for here as well. In this case, we're using something similar to our read until. Telnet lab in Python, expect will essentially perform read until but have a list of different things that you can trigger on. In this case, we're taking advantage of the fact that a lot of Telnet servers often will say the date of the last successful login. If we see last login and have that sent back to us, we know that we've successfully logged out on Telnet. We're then also going to set a timeout so that we don't keep listening forever. In this way, we ensure that our code runs fairly quickly. We can tune this time-out value based off of how quickly we think servers will respond, and have that balance between runtime and essentially giving them enough time to respond if they're live. How except works, is it's going to return stuff in our variable result. What will happen is it will return a tuple. The first value in that tuple is the index at which our expected value occurs. If the expected value happens, then that value is going to be at least zero. If it doesn't happen, result's going to have a negative one in the first value of that tuple because there is no index at which our expected value occurred. What we're doing is we're testing that first value of the tuple if it's greater than or equal to zero, then we got a message that included the phrase last login and so we have a successful Telnet connection. We print that, saying Telnet login successful on this IP address, this port with this username, and this password. Then we close the Telnet connection. If we get an end-of-file error before that happens, we say login failed and provide the username and password. That's our code. The goal here is to write a Python script that uses two different protocols, SSH and Telnet to determine if a target system uses a set of default credentials. In this case, our list of default credentials is saved in defaults dot text. Obviously, this isn't a large list of default credentials but we could easily set it up to be so. In this case, we're just have a simple test where we've got admin pass. This isn't the correct password but on the local host, there is a user account, User 1 and password exclamation point 123. What we should have is we should get no results for the admin pass, but we should successfully get a response on both SSH and Telnet for User 1 password exclamation point 123. We close this out, run it with Python, test default credentials dot py, and give it a moment to run. What we see here is that we get two success messages. We get SSH login successful, telling us which IP address, which port, username, password, and similar print message for our Telnet login. This is designed to demonstrate a way to scan systems for the user, either default or just weak credentials. You can easily use this script for credential stuffing attack by just listing a set of breach credentials and defaults dot text and providing IP addresses and ports for servers that are likely to accept those credentials. Or you can take the root of using those weak default passwords that may have been configured on IoT devices and left open that way. If you get any results like we do here, you know there's a way to login to those devices using the identified credentials. That provides very definitive initial access to those devices. Obviously, you can just simply open up SSH, provide the set of credentials we've discovered, and you have some level of user access on the target machine. This demonstrates a way to use Python, to use the default accounts technique to achieve the tactic of initial access in the MITRE ATT&CK framework. Thank you.