[No audio]
We looked at the basics of bash shell scripting.
But we just looked at the absolute basics, there's
a lot more to it, and we're not going to cover
everything here, we're just going to cover a tiny
bit more. We're covering bash in a little bit
more depth, because the concepts are the same for
all languages. But we have to start somewhere. So
let's continue our exploration of bash shell
scripting, and how it can help us automate tasks
and ultimately do a whole lot less tedious work,
because that's the goal. It may seem a little
tedious upfront to learn all this stuff. But
again, the goal is to make the production process
much, much faster and more reliable. So let's
continue looking at bash. In order to make a
successful and helpful shell script, we're going
to have to interact with the outside world. So
we're going to have to input from an output to
files, terminals, and maybe even the network. If
your script needs to input from a terminal, we
use the read command, read -p and you give a
little label and you tell bash where to put the
results. So if you run this, you're going to be
asked to Enter your name. When you type in a
value, it'll be stored in the variable name, then
we have a semicolon, which means here's a new
comment or excuse me a new statement, and in that
statement, we're going to say echo Hi, whatever
the value is that you typed in. If you want to
input from a file, we would say input is equal to
the file's PathName, just give the entire
path name to where the file is located, and then
you would use a different type of loop to say
where IFS equals read -r function or
token one, token two, and we use the variables f1, f2,
f3, and f4, and it'll read from a file. So if you
have multiple tokens in a file, it'll put them
in these different variables, and of course, if
you want to reference the variables, we use the
dollar sign just like, just as always, and we can
do the same thing to read from a network. While
read -r inline, and inline will be the
variable where the whatever we read is going to be
stored, and we're going to import from or input
from /dev/ttyS1. So this is a
device. So we're actually reading from a network
port or network device and storing the results in
inline. Again, it's not important to pick these
apart. These are just samples of how we can
interact with the outside world. Sometimes bad
things happen, you need to handle errors. The
dollar sign question mark is the exit status of a
script that we just ran. So it's very common that
our script will run another script or
another command, and when that script or command
returns, remember, we talked about the exit, and
we could pass a value back, well, if the called
program or script or command sends an exit code
back, we can trap it and compare it. In this case,
we're saying that if the exit status of whatever
we just ran is equal to zero, then do something.
Otherwise, if it's not zero, it probably means
there's an error and we want to do something else.
Bash can also handle arrays. As a quick side note,
many people confuse bash and the original shell
or /bin/sh. If you try to use things
such as a raise, bash will handle them. But if you
interpret that with an old shell, it may get an
error message. Bottom line is make sure you put
that shebang, /bin/bash at the top of
your scripts, that way, it'll avoid any
difficulties going back and forth between the
different shells. The way we declare an array is we simply
give it a name, I'm calling this bashArray, it could be Fred
or Mary, it doesn't matter, and I'm gonna give it values, the value
list is comma delimited, separated by commas and put into
parentheses. So my bashArray is val1, val2, val3.
Remember I talked about arrays being like a column in a spreadsheet,
so we can look at this is val1 would be in the first cell,
val2 would be in the second cell, and val3 would
be in the third cell. Alternatively, we could say
declare -a bashArray equals val1, val2, val3, same syntax or same
result. The way we access this would be in a loop.
So we go into a loop for i in 1 2 3. That means the
first time through the loop, i will add the value
of 1, the second time through the loop, it'll
add the value of 2. So we see inside the body of
the loop in between the do and done, we're going
to echo the value of bashArray sub one,
bashArray sub two, and bashArray sub three, so we're
replacing i with each iteration, every time we
go around, we're referencing a different cell in
that array, and we're incrementing i each time.
So this is actually a fairly complex structure.
We've got several things going on here. We've got
an array, we've got navigation through the array,
and we've got a looping structure. So this puts it
all in perspective, but again, it's pretty simple
code, and lastly, let's take a look at encoding
and decoding. locale shows the local related
environment variables, so if you type in locale,
you're going to end up with a lot of character set
and location based information. You can change the
assignment of the LANG environment variable for
local character encoding. For example, I can say
LANG is equal to da_DK.UTF-8.
This allows bash to accept special
characters. This is the Danish character set in
this particular case. So if I set my environment
variable, it'll allows the interpreter, the shell
interpreter to handle different characters beyond
just the standard ones in our base character set.
Additionally, we may need to encode strings or
decode them using base64. That's a very common
encoding and decoding mechanism that's used to
store obfuscated data. The data sometimes a binary
data cannot always be transferred, especially
across text links. So it's fairly common to take
binary data, use a base64 encoding to translate
it into text data, transmit, and then the other
side, you have to decode. So you may run into that
from time to time in pentesting. So if you do,
here's how you do it, take your string, and you
simply say echo my string, the pipe means echo
that into the standard input of the base64
command, or you could say base64 less than less
than less than the value of my string. Either way,
we ended up getting the string encoded using base64,
and then to decode it, we turn it around the other way.
We say echo the encoded string to base64
with the option decode and that'll actually turn
it around and decode back to a plain text string.
Let's look again at our port scanner. This is the
same script we looked at a little bit earlier. But
now we have a little bit more bash under our
belts. So let's dig a little bit deeper. We know
the first line, we know how to get our input
parameters in. But now here's a function, we
really haven't talked about functions. But a
function is a sub procedure. They're handy to use
if you want to use them, not going to be tested on
the exam. The idea behind this one is we create a
function called scanports, it does some cool
things, then at the bottom of the program, which is
our main area, we just simply call scanports. All
this does is it runs the function scanports. So
let's look in the function. What it does is we go
into a for block, the for loop basically says
counter is going to start off at the value of minport,
and while it is less than or equal to the
value of maxport, I'm just going to increment
counter. So basically, we type in the first port
and the last port we want when we run the program,
and this loop takes us through all the ports, and
what we do basically is we attempt to echo out to
/dev/tcp/target, which is our IP
address slash port number. That is a link
basically to a network connection to a port on
another machine. If we get an error back, it means
there's the port is closed, if we don't get an
error, then the port is open, and that's where
redirecting to dev/null basically doesn't really
send anything out, any messages out, but the 2
greater than &1 is a little trick where
you're outputting standard out and standard error.
It basically says, 'I want to grab all my errors and
all my output and put it to the same place', and
what it does is it simply says if something came
back, then the counter or the port is open.
Otherwise, it's not. So that's the idea behind it.
Either error is out or I get something back, and
that's all I'm doing. It's a very, very simple
port scanner. So let's go see what it looks like
in real life. So here it is again, this is the
actual shell script. We're back in Kali Linux, I
just opened up a shell, and by the way, the shell
I've opened is a bash shell. So that's exactly
what we're using here, and the way I run this, the
shells name is portscan.sh. So I'm going to type
bash portscan.sh, the first parameter is my IP
address I want to scan and I want to scan from port 21 to 80.
That didn't take very long, did it? That's actually
what it does. He found out that these ports
21, 22, 23, 25, and 53 are open, or at least they didn't
say they were closed and then 80 was open as well.
All right. So that pretty much shows you the power
of bash, simple scripts, all I need to do to scan
any IP address in any port range is just type in
bash portscan.sh, and it'll do all the work for
me. I can even redirect this out to a file and
save it for later if I want to and run lots of
scans without me having to type stuff over and
over again. That's the power of using shell
scripting. Let's touch on the other environments,
the other shell script languages, and then we're
going to compare all these. We've already seen the
basic ideas behind shell scripting, but we want to
get you to the point of being able to recognize
the differences for the PenTest+ exam.
[No audio]