1 00:00:00,000 --> 00:00:01,014 [No audio] 2 00:00:01,040 --> 00:00:04,490 We looked at the basics of bash shell scripting. 3 00:00:04,560 --> 00:00:07,230 But we just looked at the absolute basics, there's 4 00:00:07,230 --> 00:00:08,940 a lot more to it, and we're not going to cover 5 00:00:08,940 --> 00:00:11,220 everything here, we're just going to cover a tiny 6 00:00:11,220 --> 00:00:14,400 bit more. We're covering bash in a little bit 7 00:00:14,400 --> 00:00:16,800 more depth, because the concepts are the same for 8 00:00:16,800 --> 00:00:19,980 all languages. But we have to start somewhere. So 9 00:00:19,980 --> 00:00:23,430 let's continue our exploration of bash shell 10 00:00:23,430 --> 00:00:26,010 scripting, and how it can help us automate tasks 11 00:00:26,100 --> 00:00:28,860 and ultimately do a whole lot less tedious work, 12 00:00:28,920 --> 00:00:30,990 because that's the goal. It may seem a little 13 00:00:30,990 --> 00:00:33,180 tedious upfront to learn all this stuff. But 14 00:00:33,180 --> 00:00:36,600 again, the goal is to make the production process 15 00:00:36,600 --> 00:00:39,270 much, much faster and more reliable. So let's 16 00:00:39,270 --> 00:00:41,850 continue looking at bash. In order to make a 17 00:00:41,880 --> 00:00:44,280 successful and helpful shell script, we're going 18 00:00:44,280 --> 00:00:47,130 to have to interact with the outside world. So 19 00:00:47,130 --> 00:00:49,350 we're going to have to input from an output to 20 00:00:49,470 --> 00:00:52,860 files, terminals, and maybe even the network. If 21 00:00:52,860 --> 00:00:55,500 your script needs to input from a terminal, we 22 00:00:55,500 --> 00:00:58,560 use the read command, read -p and you give a 23 00:00:58,560 --> 00:01:00,900 little label and you tell bash where to put the 24 00:01:00,900 --> 00:01:03,960 results. So if you run this, you're going to be 25 00:01:03,960 --> 00:01:06,180 asked to Enter your name. When you type in a 26 00:01:06,180 --> 00:01:08,940 value, it'll be stored in the variable name, then 27 00:01:08,940 --> 00:01:10,800 we have a semicolon, which means here's a new 28 00:01:10,800 --> 00:01:13,350 comment or excuse me a new statement, and in that 29 00:01:13,350 --> 00:01:16,080 statement, we're going to say echo Hi, whatever 30 00:01:16,080 --> 00:01:19,530 the value is that you typed in. If you want to 31 00:01:19,530 --> 00:01:23,670 input from a file, we would say input is equal to 32 00:01:23,670 --> 00:01:26,610 the file's PathName, just give the entire 33 00:01:26,610 --> 00:01:29,010 path name to where the file is located, and then 34 00:01:29,010 --> 00:01:31,650 you would use a different type of loop to say 35 00:01:31,650 --> 00:01:35,820 where IFS equals read -r function or 36 00:01:35,970 --> 00:01:39,180 token one, token two, and we use the variables f1, f2, 37 00:01:39,180 --> 00:01:42,210 f3, and f4, and it'll read from a file. So if you 38 00:01:42,210 --> 00:01:44,670 have multiple tokens in a file, it'll put them 39 00:01:44,670 --> 00:01:46,560 in these different variables, and of course, if 40 00:01:46,560 --> 00:01:48,120 you want to reference the variables, we use the 41 00:01:48,120 --> 00:01:50,850 dollar sign just like, just as always, and we can 42 00:01:50,850 --> 00:01:53,460 do the same thing to read from a network. While 43 00:01:53,460 --> 00:01:57,240 read -r inline, and inline will be the 44 00:01:57,240 --> 00:02:00,060 variable where the whatever we read is going to be 45 00:02:00,060 --> 00:02:02,700 stored, and we're going to import from or input 46 00:02:02,700 --> 00:02:06,540 from /dev/ttyS1. So this is a 47 00:02:06,540 --> 00:02:09,150 device. So we're actually reading from a network 48 00:02:09,150 --> 00:02:12,330 port or network device and storing the results in 49 00:02:12,330 --> 00:02:14,730 inline. Again, it's not important to pick these 50 00:02:14,730 --> 00:02:18,210 apart. These are just samples of how we can 51 00:02:18,210 --> 00:02:20,640 interact with the outside world. Sometimes bad 52 00:02:20,640 --> 00:02:23,370 things happen, you need to handle errors. The 53 00:02:23,370 --> 00:02:26,190 dollar sign question mark is the exit status of a 54 00:02:26,190 --> 00:02:28,830 script that we just ran. So it's very common that 55 00:02:28,830 --> 00:02:31,320 our script will run another script or 56 00:02:31,320 --> 00:02:34,110 another command, and when that script or command 57 00:02:34,110 --> 00:02:37,170 returns, remember, we talked about the exit, and 58 00:02:37,170 --> 00:02:40,800 we could pass a value back, well, if the called 59 00:02:40,830 --> 00:02:44,280 program or script or command sends an exit code 60 00:02:44,280 --> 00:02:47,190 back, we can trap it and compare it. In this case, 61 00:02:47,190 --> 00:02:49,740 we're saying that if the exit status of whatever 62 00:02:49,740 --> 00:02:52,590 we just ran is equal to zero, then do something. 63 00:02:53,070 --> 00:02:55,620 Otherwise, if it's not zero, it probably means 64 00:02:55,620 --> 00:02:57,630 there's an error and we want to do something else. 65 00:02:57,750 --> 00:03:01,410 Bash can also handle arrays. As a quick side note, 66 00:03:01,410 --> 00:03:05,340 many people confuse bash and the original shell 67 00:03:05,340 --> 00:03:08,910 or /bin/sh. If you try to use things 68 00:03:08,910 --> 00:03:11,670 such as a raise, bash will handle them. But if you 69 00:03:11,790 --> 00:03:14,730 interpret that with an old shell, it may get an 70 00:03:14,730 --> 00:03:16,830 error message. Bottom line is make sure you put 71 00:03:16,830 --> 00:03:20,430 that shebang, /bin/bash at the top of 72 00:03:20,430 --> 00:03:23,100 your scripts, that way, it'll avoid any 73 00:03:23,580 --> 00:03:26,100 difficulties going back and forth between the 74 00:03:26,100 --> 00:03:29,680 different shells. The way we declare an array is we simply 75 00:03:29,704 --> 00:03:32,534 give it a name, I'm calling this bashArray, it could be Fred 76 00:03:32,558 --> 00:03:36,300 or Mary, it doesn't matter, and I'm gonna give it values, the value 77 00:03:36,300 --> 00:03:40,341 list is comma delimited, separated by commas and put into 78 00:03:40,366 --> 00:03:44,080 parentheses. So my bashArray is val1, val2, val3. 79 00:03:44,183 --> 00:03:47,782 Remember I talked about arrays being like a column in a spreadsheet, 80 00:03:47,806 --> 00:03:52,031 so we can look at this is val1 would be in the first cell, 81 00:03:52,055 --> 00:03:54,689 val2 would be in the second cell, and val3 would 82 00:03:54,713 --> 00:03:57,285 be in the third cell. Alternatively, we could say 83 00:03:57,309 --> 00:04:03,120 declare -a bashArray equals val1, val2, val3, same syntax or same 84 00:04:03,145 --> 00:04:06,745 result. The way we access this would be in a loop. 85 00:04:07,080 --> 00:04:11,160 So we go into a loop for i in 1 2 3. That means the 86 00:04:11,160 --> 00:04:13,230 first time through the loop, i will add the value 87 00:04:13,230 --> 00:04:15,450 of 1, the second time through the loop, it'll 88 00:04:15,450 --> 00:04:18,810 add the value of 2. So we see inside the body of 89 00:04:18,810 --> 00:04:21,240 the loop in between the do and done, we're going 90 00:04:21,240 --> 00:04:26,454 to echo the value of bashArray sub one, 91 00:04:26,872 --> 00:04:30,090 bashArray sub two, and bashArray sub three, so we're 92 00:04:30,090 --> 00:04:34,020 replacing i with each iteration, every time we 93 00:04:34,020 --> 00:04:36,300 go around, we're referencing a different cell in 94 00:04:36,332 --> 00:04:39,332 that array, and we're incrementing i each time. 95 00:04:40,560 --> 00:04:42,720 So this is actually a fairly complex structure. 96 00:04:42,720 --> 00:04:44,520 We've got several things going on here. We've got 97 00:04:44,520 --> 00:04:46,890 an array, we've got navigation through the array, 98 00:04:46,890 --> 00:04:49,560 and we've got a looping structure. So this puts it 99 00:04:49,560 --> 00:04:51,360 all in perspective, but again, it's pretty simple 100 00:04:51,360 --> 00:04:53,850 code, and lastly, let's take a look at encoding 101 00:04:53,850 --> 00:04:57,210 and decoding. locale shows the local related 102 00:04:57,210 --> 00:04:59,790 environment variables, so if you type in locale, 103 00:04:59,790 --> 00:05:02,370 you're going to end up with a lot of character set 104 00:05:02,370 --> 00:05:05,250 and location based information. You can change the 105 00:05:05,250 --> 00:05:08,880 assignment of the LANG environment variable for 106 00:05:08,880 --> 00:05:11,940 local character encoding. For example, I can say 107 00:05:11,940 --> 00:05:16,829 LANG is equal to da_DK.UTF-8. 108 00:05:17,102 --> 00:05:19,710 This allows bash to accept special 109 00:05:19,710 --> 00:05:22,800 characters. This is the Danish character set in 110 00:05:22,800 --> 00:05:25,410 this particular case. So if I set my environment 111 00:05:25,410 --> 00:05:28,950 variable, it'll allows the interpreter, the shell 112 00:05:28,950 --> 00:05:31,530 interpreter to handle different characters beyond 113 00:05:31,530 --> 00:05:34,440 just the standard ones in our base character set. 114 00:05:34,835 --> 00:05:38,765 Additionally, we may need to encode strings or 115 00:05:38,790 --> 00:05:41,910 decode them using base64. That's a very common 116 00:05:41,910 --> 00:05:44,190 encoding and decoding mechanism that's used to 117 00:05:44,190 --> 00:05:48,930 store obfuscated data. The data sometimes a binary 118 00:05:48,930 --> 00:05:51,660 data cannot always be transferred, especially 119 00:05:51,660 --> 00:05:55,290 across text links. So it's fairly common to take 120 00:05:55,290 --> 00:05:59,760 binary data, use a base64 encoding to translate 121 00:05:59,760 --> 00:06:02,880 it into text data, transmit, and then the other 122 00:06:02,880 --> 00:06:05,280 side, you have to decode. So you may run into that 123 00:06:05,280 --> 00:06:07,980 from time to time in pentesting. So if you do, 124 00:06:08,010 --> 00:06:10,590 here's how you do it, take your string, and you 125 00:06:10,590 --> 00:06:14,490 simply say echo my string, the pipe means echo 126 00:06:14,490 --> 00:06:17,910 that into the standard input of the base64 127 00:06:17,910 --> 00:06:21,420 command, or you could say base64 less than less 128 00:06:21,420 --> 00:06:23,910 than less than the value of my string. Either way, 129 00:06:23,935 --> 00:06:27,464 we ended up getting the string encoded using base64, 130 00:06:27,532 --> 00:06:29,740 and then to decode it, we turn it around the other way. 131 00:06:29,980 --> 00:06:33,450 We say echo the encoded string to base64 132 00:06:33,450 --> 00:06:35,700 with the option decode and that'll actually turn 133 00:06:35,700 --> 00:06:38,160 it around and decode back to a plain text string. 134 00:06:38,695 --> 00:06:40,655 Let's look again at our port scanner. This is the 135 00:06:40,680 --> 00:06:42,720 same script we looked at a little bit earlier. But 136 00:06:42,720 --> 00:06:45,300 now we have a little bit more bash under our 137 00:06:45,300 --> 00:06:48,210 belts. So let's dig a little bit deeper. We know 138 00:06:48,210 --> 00:06:50,370 the first line, we know how to get our input 139 00:06:50,370 --> 00:06:52,710 parameters in. But now here's a function, we 140 00:06:52,710 --> 00:06:54,870 really haven't talked about functions. But a 141 00:06:54,870 --> 00:06:57,630 function is a sub procedure. They're handy to use 142 00:06:57,630 --> 00:07:00,330 if you want to use them, not going to be tested on 143 00:07:00,330 --> 00:07:03,210 the exam. The idea behind this one is we create a 144 00:07:03,210 --> 00:07:05,790 function called scanports, it does some cool 145 00:07:05,790 --> 00:07:08,370 things, then at the bottom of the program, which is 146 00:07:08,370 --> 00:07:12,270 our main area, we just simply call scanports. All 147 00:07:12,270 --> 00:07:15,600 this does is it runs the function scanports. So 148 00:07:15,600 --> 00:07:18,120 let's look in the function. What it does is we go 149 00:07:18,145 --> 00:07:22,765 into a for block, the for loop basically says 150 00:07:22,860 --> 00:07:25,633 counter is going to start off at the value of minport, 151 00:07:26,233 --> 00:07:28,440 and while it is less than or equal to the 152 00:07:28,440 --> 00:07:30,780 value of maxport, I'm just going to increment 153 00:07:30,780 --> 00:07:33,150 counter. So basically, we type in the first port 154 00:07:33,150 --> 00:07:35,670 and the last port we want when we run the program, 155 00:07:35,880 --> 00:07:39,390 and this loop takes us through all the ports, and 156 00:07:39,390 --> 00:07:43,050 what we do basically is we attempt to echo out to 157 00:07:43,050 --> 00:07:47,220 /dev/tcp/target, which is our IP 158 00:07:47,220 --> 00:07:52,050 address slash port number. That is a link 159 00:07:52,050 --> 00:07:55,410 basically to a network connection to a port on 160 00:07:55,410 --> 00:07:58,650 another machine. If we get an error back, it means 161 00:07:58,650 --> 00:08:01,530 there's the port is closed, if we don't get an 162 00:08:01,530 --> 00:08:03,900 error, then the port is open, and that's where 163 00:08:03,930 --> 00:08:07,050 redirecting to dev/null basically doesn't really 164 00:08:07,050 --> 00:08:10,050 send anything out, any messages out, but the 2 165 00:08:10,050 --> 00:08:12,690 greater than &1 is a little trick where 166 00:08:12,690 --> 00:08:15,870 you're outputting standard out and standard error. 167 00:08:16,080 --> 00:08:18,210 It basically says, 'I want to grab all my errors and 168 00:08:18,210 --> 00:08:21,060 all my output and put it to the same place', and 169 00:08:21,390 --> 00:08:24,330 what it does is it simply says if something came 170 00:08:24,330 --> 00:08:29,130 back, then the counter or the port is open. 171 00:08:29,130 --> 00:08:31,170 Otherwise, it's not. So that's the idea behind it. 172 00:08:31,170 --> 00:08:33,630 Either error is out or I get something back, and 173 00:08:33,630 --> 00:08:35,940 that's all I'm doing. It's a very, very simple 174 00:08:35,940 --> 00:08:37,980 port scanner. So let's go see what it looks like 175 00:08:37,980 --> 00:08:40,440 in real life. So here it is again, this is the 176 00:08:40,440 --> 00:08:43,200 actual shell script. We're back in Kali Linux, I 177 00:08:43,200 --> 00:08:46,470 just opened up a shell, and by the way, the shell 178 00:08:46,470 --> 00:08:49,110 I've opened is a bash shell. So that's exactly 179 00:08:49,320 --> 00:08:52,620 what we're using here, and the way I run this, the 180 00:08:52,684 --> 00:08:56,794 shells name is portscan.sh. So I'm going to type 181 00:08:56,820 --> 00:09:01,170 bash portscan.sh, the first parameter is my IP 182 00:09:01,170 --> 00:09:04,779 address I want to scan and I want to scan from port 21 to 80. 183 00:09:06,412 --> 00:09:08,669 That didn't take very long, did it? That's actually 184 00:09:08,669 --> 00:09:11,159 what it does. He found out that these ports 185 00:09:11,159 --> 00:09:15,389 21, 22, 23, 25, and 53 are open, or at least they didn't 186 00:09:15,389 --> 00:09:18,029 say they were closed and then 80 was open as well. 187 00:09:18,479 --> 00:09:21,209 All right. So that pretty much shows you the power 188 00:09:21,209 --> 00:09:25,229 of bash, simple scripts, all I need to do to scan 189 00:09:25,266 --> 00:09:28,416 any IP address in any port range is just type in 190 00:09:28,619 --> 00:09:31,319 bash portscan.sh, and it'll do all the work for 191 00:09:31,319 --> 00:09:33,779 me. I can even redirect this out to a file and 192 00:09:33,779 --> 00:09:36,209 save it for later if I want to and run lots of 193 00:09:36,209 --> 00:09:38,579 scans without me having to type stuff over and 194 00:09:38,579 --> 00:09:41,489 over again. That's the power of using shell 195 00:09:41,489 --> 00:09:43,889 scripting. Let's touch on the other environments, 196 00:09:43,889 --> 00:09:45,719 the other shell script languages, and then we're 197 00:09:45,719 --> 00:09:48,749 going to compare all these. We've already seen the 198 00:09:48,749 --> 00:09:51,899 basic ideas behind shell scripting, but we want to 199 00:09:51,899 --> 00:09:54,089 get you to the point of being able to recognize 200 00:09:54,089 --> 00:09:56,489 the differences for the PenTest+ exam. 201 00:09:56,513 --> 00:10:11,353 [No audio]