Linux Up Skill - Day 20
I’m working on lesson 20 of the Linux Up Skill Challenge today. This lesson is titled “Scripting” and I’m hopeful that means I can learn something here. For a large part of my career I have been told “Forget best practices, just get it working. Now!”
The lesson begins talking about the needs for writing scripts and automating things. It then mentions you can set the execute permission the system will then look for the shebang (#!) in the first line. The lesson is having me write a script to list out who has most recently unsuccessfully trying to login to the server. Sounds good to me!
I SSH into my server and then run vim attacker
followed by the following in the script:
#! # # attacker - prints out the last failed login attempt # echo "The last failed login attempt came from IP address:" grep -i "disconneted from" /var/log/auth.log|tail -1| cut -d:
Next I make the file executable with chmod +x attacker
. Then if I test with ./attacker
I get an error cut: you must specify a list of bytes, characters, or fields
. Hmm I had some typos and didn’t even finish the script. I missed the code insert scrolled to the right. Let’s fix this. vim attacker
#! # # attacker - prints out the last failed login attempt # echo "The last failed login attempt came from IP address:" grep -i "disconnected from" /var/log/auth.log|tail -1| cut -d: -f4|cut -f7 -d" "
That looks better. Let’s test again. It outputs the first line but the second comes back empty. Oh well since my server is behind a firewall and only accessible on the LAN there would be no bad actors scanning and attempting to log on unlike where the lesson assumes you are on a cloud server open to the internet. Well then I suppose I need to make some failed attempts.
I first make some failed attempts from my desktop via Putty. But they don’t show up in the script. I try directly from the console and they fail as well. Interesting. I try to SSH in from my iPhone. Testing the script ./attacker
I get a return of:
david@linux-up-skill:~$ ./attacker The last failed login attempt came from IP address: xxx.xxx.xxx.81
That’s my phone’s IP address so the script is working. But why are my failed attempts from my desktop not working? Even if I SSH from powershell instead of Putty it still doesn’t show up in the script. When I actually look in /var/log/auth.log
it looks like the attempts from my desktop are not actually disconnecting. I could change this script to show the last failed password attempt and that should show. I play around with the command and can get it to output with:
david@linux-up-skill:~$ grep -i "failed" /var/log/auth.log|tail -1| cut -d: -f5| cut -f8 -d" " xxx.xxx.xxx.20 david@linux-up-skill:~$
Ok I feel like I have a handle on this, but I’ll have to look into why there is no disconnect showing in the log from my desktop just so I can understand the difference. Now that the script is working I can move it into my $PATH
so I run sudo mv attacker /usr/local/bin/attacker
and now I can run the script by just typing attacker
. Cool!
We’re going to make a more elaborate script. vim topattack
and I enter the following script copied from the lesson:
# ## topattack - list the most persistent attackers # if [ -z "$1" ]; then echo -e "\nUsage: `basename $0` <num> - Lists the top <num> attackers by IP" exit 0 fi echo " " echo "Persistant recent attackers" echo " " echo "Attempts IP " echo "-----------------------" grep "Disconnected from authenticating user root" /var/log/auth.log|cut -d: -f 4 | cut -d" " -f7|sort |uniq -c |sort -nr |head -$1
This is an exact copy and paste from the lesson. I’m not great at scripting but it doesn’t seem like this would work as it is. Is that part of the lesson today? I’m pretty sure an exit there is going to just stop the script and in my testing it does. I made the following modifications:
#! # # topattack - list the most persistent attackers # if [ -z "$1" ] then echo -e "\nUsage: `basename $0` <num> - Lists the top <num> attackers by IP" fi echo " " echo "Persistant recent attackers" echo " " echo "Attempts IP " echo "____________________________" grep "Disconnected from authenticating user root" /var/log/auth.log|cut -d: -f 4 | cut -d" " -f7|sort |uniq -c |sort -nr |head -$1
When I run ./topattack
like this the program runs and produces the IP for my phone and lists the number of attempts. But I’m still confused. What is the <num>
for? Is it supposed to be like a variable? I can’t find anything online referencing this in bash. And I’m still confused as to why only my phone shows up? When I do a search online to accomplish this sort of task all I can find is people using grep "Failed password"
which is what I would think it should be?
So I decided to play around a little more for this lesson and created an additional script called top-failed-passwords:
#! # # top-failed-password - list the most persistent failed passwords # if [ -z "$1" ] then echo -e "\nUsage: `basename $0` - Lists the top failed passwords by IP" fi echo " " echo "Persistant recent attackers" echo " " echo "Attempts IP " echo "____________________________" grep "Failed password" /var/log/auth.log|cut -d: -f 5| cut -d" " -f8|sort |uniq -c |sort -nr |head -$1
This allows me to check on any IP address with a failed password. This should give me information if an attacker is trying to access my server with any account instead of just with root. When I run the script ./top-failed-passwords
I get the following output:
david@linux-up-skill:~$ ./top-failed-passwords Usage: top-failed-passwords - Lists the top failed passwords by IP Persistant failed logins Attempts IP ____________________________ 5 3 xxx.xxx.xxx.20 2 xxx.xxx.xxx.81
So I’ll finish with sudo mv topattack /usr/local/bin/topattack
and sudo mv top-failed-passwords /usr/local/bin/top-failed-passwords
and now topattack
and top-failed-passwords
both work. Nice! This was a fun lesson to dig into and dedicate some time to.