Skill Level Intermediate
- The Bash scripting environment is the first environment we're going to explore. If you do anything with any type of Linux environment, you're going to run into the Bash shell and likely run into the Bash scripts at some point. You see 'em all over the place. They're extremely common because they're available in every distribution of Linux and most distributions of Unix as well. So let's start off with what it looks like when we start opening up a Bash shell. Now, for all the shell scripting environments we're going to talk about, you can use a regular text editor.
You don't have to have a special editor, although you can get cool editors that'll highlight text and everything, we're not going to be doing that. You can just open up any Bash script or any of them in a test editor like Nano or VI, or whatever you want. The first thing you'll notice is a bunch of hash characters all over the place, or pound signs. Well, those are comments. Comments help you remember what you were thinking. It's very important when you're writing a script or anything in any language, that you document what you're doing, so that if someone else pulls up the script and they're trying to figure it out, you give 'em a little bit of a hint and you normally would document any values that you're going to assign, any values you use, and then the functionality, like what is it supposed to be doing? Any time you want to enter a comment in a Bash shell, you start off with the pound sign, that's it.
Everything after that is considered to be a comment so you can put it anywhere in the line, but remember, if you try to put a comment in the middle of a line and then you want the rest of that line to be executed, it's not going to happen. Everything after the pound sign is a comment. For example, if I were to type in pound sign, space, This is a comment, that's an actual comment. We can also assign variables. In fact, it's very unusual to see a shell script that doesn't use variables because we need to store data somewhere in order to do things.
In Bash, the way we assign variables is we say, variable name equals value. For example, name equals Michael. That means that I've created a variable called name and the value of name is Michael. So if I want to use that, let's say that I want to display that out to the terminal. I would then have to reference the value of name. All right, so name is the pneumonic that points to the place in memory and the value stored in it is Michael.
So if I want to grab whatever is in that name variable, I simply say, dollar sign name, or dollar sign variable name, for any variable name. So if I wanted output to the terminal, I would use the Echo command. So I would say echo dollar sign name, and what Bash would do is he would say, echo means I'm going to print something to the terminal, dollar sign name means go grab whatever's in the variable name, which is the string Michael, and put it out to the terminal. It's as easy as that.
It's very common to use variables as opposed to hard coding a whole lot. You want to let variables take on different values as your script progresses. And remember, though, for Bash variables, they're all untyped. What that means is that name can store a name, it can also store a number. Bash doesn't care whether it's a numeric or a character data type, or really, anything else. It's all untyped. So it makes it really easy. You don't have to worry about type conversion issues that other languages have issues with.
But that's basically comments and how to deal with variables in Bash. Once you start using variables, it's likely that you're going to want to assign different values. Remember that the dollar sign prefix refers to the contents of an identifier. Now, we've talked about variables, but it also looks at other identifiers as well. An identifier can be a variable, as we just looked at. It can also be an input parameter. So if you're going to run a shell script and you provide some input values, like let's say we're going to run a port scanner, and we type in scan port, if the name of the script is scan port, and we give it an IP address and then we give it a port number.
Well, the first input parameter would be $1. That would be the IP address. The second input parameter would be $2, and so on and so forth. Those are referred to as positional parameters. We can also reference environment variables. In your environment, in the operating system, there are many variables that are set that refer to the current environment. One is called the Path variable. That is a comma delimited, typically, it depends on the operating system, but it's a delimited list of paths that the operating system uses to go find executable code.
So the dollar sign path value would return whatever is stored in my current environment's path. Notice that environment variables are typically all uppercase. It's not absolutely required, but it is a strong standard. And then lastly, we can also reference values from utilities. The whoami utility basically returns the currently logged-in user in Linux. If we put that in parentheses and preface it with a dollar sign, that tells Bash shell to go wrong whoami, take the return value, and return it as a token.
So the bottom line is if I'm logged in as root and I say echo, dollar sign whoami, it'll come back and say root. So it's just a way of grabbing things from the outside world and using them inside the Bash shell. And sometimes, it's handy have Bash set defaults when no other value is provided. For example, if we want to assign the value JAVAPATH, we have a variable JAVAPATH I want to assign, I can use this syntax to say let's place the value of JAVAHOME and store it in the new variable JAVAPATH, unless JAVAHOME is empty.
Then let's use the string slash user slash lib slash java. So all this says is, if the first value is empty, use the second value. And that's the basic syntax, but you have to be careful if you're using positional parameters or positional arguments like the input parameters such as one, two, three and four, you have to use a slightly different syntax. Don't worry about this. Doubt if you'll ever see it, but it's important to note if you try to make assignments with input parameters, you've got to use that colon dash as opposed to the colon equals.
All right, let's get to some common operations in Bash. There's string operations. Things that we do in any environment to build our tokens that we're going to start using. One will be concatenate. Concatenate means sticking two strings together. So we have two variables, Hello, and we're going to concatenate World to the end. The one way we can do that is we can say var equals Hello. Then we're going to say var is equal to whatever var was, which is Hello, along with space World, and we end up getting Hello space World.
The semi-colon in between is a way of linking two commands together and doing it all in one line. If you need to find the length of the string, here's the syntax. Basically, take the name of the variable, slap a pound sign in front of it, wrap it up in curly braces and put a dollar sign in front of that. It's kind of difficult to remember all these different characters, but the idea for the Pentest+ exam is that you recognize and can read scripts. Not that you can write them off the top of your end, but it's very common to find the length of something.
Sometimes, you also want to grab a piece of a string. It's called a substring. That's fairly easy. It is simply, dollar sign, close the whole string name up in curly braces, and all you do is you give the name of the variable, colon, and the starting position. So if I want to grab all the characters in name starting at position three, here's the syntax. And the last thing that we typically do in most common string operations is replace the substring. So if I want to replace ch with xx, this is the syntax.
It's simply similar to extracting a substring, but a little bit different. Ad the variable name slash substring I want to replace, slash what I want to replace it with. Granted the syntax is tedious, but you're going to be using scripts all over the place, either reading them and possibly, eventually, maybe writing some, because the idea is to automate. So any time you've got this long list of either vulnerabilities you're trying to scan for or just IP addresses you're scanning for, it's not uncommon to take a bass string and then loop through a bunch of replacements and replace it with IP address 10, then 14, then 33, and so you'll be using things like this all over the place to just simply make your life easier, rather than type so much that your fingers hurt.
So that's why we're covering all this. Don't get lost in the weeds. The actual syntax and memorizing everything is not as important as simply recognizing what these scripting languages can do for you. All right, compound operations. Sometimes you need to put multiple operations together and you need to compare with, and or or. And is minus a, or is minus o. We're going to see in logic operations, where I say, well, if Port 80 is open, then I'm going to do something. Well, sometimes I want to say, if Port 80 is open or Port 43.
Those are both HTTP type of traffic. So I would use if Port 80 is open, minus o, which is or, and sometimes I want to use the minus a for and so that gives us the ability in a shell script to use either one of those. So when we do comparisons, the basic syntax is if varA is equal to varB. That's the basic syntax. We put it in square braces and we have to remember to reference the contents of variable A and the contents of variable B with that dollar sign.
We can use equal, is either minus eq or the equal equal sign. We can also say not equal, greater than, or so on and so forth. We can compare these either way. At the bottom, we can also find out or ask Bash if a particular string is not null or is null. In other words, it's empty. So these are the comparison operators that Bash supports. Additionally, let's learn a little bit about looping. In looping, there's multiple ways to loop in Bash. The most common looping structure is the for loop and it looks something like this.
For var in list. That means for variable, which is our control counter, or our control variable, is in the element in a list. If it is in that list, we're going to do something. So we have several different statements and we end it with a done statement. So in Bash, it's always for something, do statement, statement, statement, done, and that is the whole loop. Example would be for i in one, two, three, four, five, or i in a sequence of one to five.
So these would actually do the same things. And of course, underneath the for header, we would have our do and done block statements so that we put it all together. In addition to looping, we also need to control the flow of our application. For example, if something happens, then do something, otherwise, do something else. The way we do that in Bash is we say, if condition, now condition would be something like, if name equals Michael. That would be an example, then we run commands.
Elif means if the condition was not true, I have a new if statement. So if name is not equal to Michael, you can say else if, name equals Mary, then do some commands. If name is not Michael or Mary, then we drop to the else portion and at the very end, we end an if block with the fi statement. So this is the situation or this is the syntax. Notice the elif. When you see elif, that's going to be a clue this could be a Bash script.
We don't see that in all the other script languages so that's the key here. The if conditions could be minus d, could say, if a file, or given a file name, minus d file, means that is a directory. If minus e file means it exists and so on and so forth. So these are some of the basic conditions we can use. We commonly would use if stringA equals string B or if stringA is not equal to stringB. We use that all the time when we're trying to do things like port scans where it comes back as either open or closed.
We basically test for it. If it came back open, then we report. If it comes back closed, we're probably going to ignore it. So that would be an example of a conditional statement that we would use with the port scanner. So here's an example of test. We can say if test equaled name Michael, that's the same way of saying if name equals Michael. So the curl, or the square brackets are the same thing as the test command. It's just in a different order. You can use either one you want. If you decide you want to, based on a condition, get out of a current loop, you can use the break command.
If you're done and you want to just totally get out of the whole script, the exit command will do that and you can actually pass back an exit value or an exit code so we can say exit one or exit minus one would give the calling program a return value. So let's start for a second and take a look at a very simple Bash script. This Bash script is a port scanner. It's a very simple port scanner, but it's a port scanner nonetheless. Notice the very first line is the common salutation or common intro for Bash scripts.
It's called shebang, which is a pound sign followed by an exclamation point. Shebang slash bin shash bash. That tells the operating system which interpreter to use and this basically identifies the script as a Bash script. The next three lines, we're going to take input arguments so the first parameter is going to be stored in a variable target. The second parameter in minport, the first parameter in maxport. And then we go into a little for block. Now, this for block looks a little different than the previous one we saw but it's still a for block.
We say for something, do, we have a line in the middle, done, and then we're done. We're going to come back and talk about this a little bit later and dig a little bit deeper into what's going on here but that's a basic, very, very simple shell script that'll execute a port scan for us.