1 00:00:00,000 --> 00:00:01,014 [No audio] 2 00:00:01,040 --> 00:00:03,540 Let's move on to talk about another scripting 3 00:00:03,565 --> 00:00:06,535 environment. In fact, the next environment, Ruby 4 00:00:06,570 --> 00:00:09,330 is much more than just a scripting environment. It 5 00:00:09,330 --> 00:00:12,090 is a full blown high level language. It was 6 00:00:12,090 --> 00:00:15,210 originally developed and designed in the 1990s, 7 00:00:15,335 --> 00:00:18,305 and it has gained a lot of popularity. It's object 8 00:00:18,330 --> 00:00:21,030 oriented, and it gives us way more functionality 9 00:00:21,030 --> 00:00:24,150 than we'll ever need as pen testers. But it does 10 00:00:24,150 --> 00:00:28,380 make it possible to create a very nice and elegant 11 00:00:28,380 --> 00:00:31,260 level of shell scripting that's very powerful, and 12 00:00:31,260 --> 00:00:35,580 very, very compact. As with other languages, many 13 00:00:35,580 --> 00:00:38,027 of the constructs we use are similar, and 14 00:00:38,052 --> 00:00:40,710 we'll line them up side by side to see what the 15 00:00:40,710 --> 00:00:44,160 minute differences may be. But the best way to talk 16 00:00:44,160 --> 00:00:47,340 about Ruby is to jump right in, let's take a port 17 00:00:47,340 --> 00:00:50,190 scanner written in Ruby, and see what it looks 18 00:00:50,190 --> 00:00:53,550 like. We'll run some real Ruby code. So here is our 19 00:00:53,550 --> 00:00:56,820 port scanner written in Ruby. It's very similar 20 00:00:56,820 --> 00:00:58,590 to the other port scanners that we've already 21 00:00:58,590 --> 00:01:01,080 looked at. But it's written of course, in a 22 00:01:01,080 --> 00:01:03,900 different language. The very first line is this 23 00:01:03,900 --> 00:01:07,590 shebang line, similar in some ways to the shebang 24 00:01:07,590 --> 00:01:10,020 line from bash, but this time, it tells the 25 00:01:10,051 --> 00:01:13,891 interpreter to use ruby to interpret this code. 26 00:01:13,955 --> 00:01:16,865 The next line is require socket, now this is a 27 00:01:16,890 --> 00:01:19,860 nice feature that we can just import a socket 28 00:01:19,860 --> 00:01:21,840 library. So we don't have to write all the 29 00:01:21,840 --> 00:01:24,388 functionality or assume that it's native in the 30 00:01:24,413 --> 00:01:27,480 language. We can simply import a library and 31 00:01:27,480 --> 00:01:30,030 then use whatever that library maintains. Then we 32 00:01:30,055 --> 00:01:33,052 assign three variables, TARGET, MINPORT, AND MAXPORT, 33 00:01:33,093 --> 00:01:37,110 and actually, in Ruby, any variable that 34 00:01:37,110 --> 00:01:40,530 starts with a capital is a constant. So once we 35 00:01:40,530 --> 00:01:42,090 set it, we're not going to change it. we're going 36 00:01:42,090 --> 00:01:44,880 to say that TARGET is equal to ARGV 0, that 37 00:01:44,880 --> 00:01:47,070 simply means it's the first argument that was 38 00:01:47,070 --> 00:01:50,520 passed in on the command line. Most languages are 39 00:01:50,550 --> 00:01:53,400 zero based, so when you deal with arrays, the 40 00:01:53,400 --> 00:01:56,400 first element is zero, it's the zeroth element. 41 00:01:56,675 --> 00:01:59,465 The second element is elements of one. So you have 42 00:01:59,490 --> 00:02:01,920 to be careful when you're dealing with any type of 43 00:02:01,920 --> 00:02:04,680 array whether your language is zero based, or one 44 00:02:04,680 --> 00:02:06,990 based, because you can be off by one and count 45 00:02:06,990 --> 00:02:10,347 wrong if you're not careful. But in this case, ARGV 0 46 00:02:10,442 --> 00:02:13,080 is the TARGET, is the IP address. The two 47 00:02:13,080 --> 00:02:17,070 vertical bars tell us, if ARGV 0 is blank, 48 00:02:17,100 --> 00:02:19,380 let's assign it a value, a default value of 49 00:02:19,380 --> 00:02:23,040 10.10.1.10, and the same thing, our minimum port, if 50 00:02:23,040 --> 00:02:27,210 ARGV 1 is blank, we're going to give it a seed 51 00:02:27,210 --> 00:02:30,330 value or default value of 22, and MAXPORT is 80, 52 00:02:30,360 --> 00:02:32,490 if we don't provide anything. Then we go into our 53 00:02:32,490 --> 00:02:35,550 loop. First thing we do is we sign on a variable i 54 00:02:35,585 --> 00:02:38,747 is equal to MINPORT, but what's this to_i? 55 00:02:38,916 --> 00:02:43,320 MINPORT by default becomes a character variable. Ruby 56 00:02:43,320 --> 00:02:46,050 does use data typing, so you've got to be careful 57 00:02:46,050 --> 00:02:49,090 about what data type you use. Since we assign MINPORT 58 00:02:49,114 --> 00:02:50,940 to be a character variable, because user 59 00:02:50,940 --> 00:02:53,280 typed something into the terminal, we have to 60 00:02:53,280 --> 00:02:55,770 actually convert it to an integer, and that's what 61 00:02:55,770 --> 00:03:00,180 the to_i method actually does. Also, notice that 62 00:03:00,450 --> 00:03:04,050 Ruby is an object oriented environment, that means 63 00:03:04,050 --> 00:03:06,540 that everything is pretty much an object. So 64 00:03:06,540 --> 00:03:10,350 instead of running commands to modify things, we 65 00:03:10,350 --> 00:03:14,370 actually invoke attributes or methods. So that's 66 00:03:14,370 --> 00:03:17,490 kind of a really big, deep topic. But be aware 67 00:03:17,490 --> 00:03:19,650 that when you get into languages like Ruby, you're 68 00:03:19,650 --> 00:03:23,758 going to start seeing things, such as a data item dot 69 00:03:23,782 --> 00:03:26,280 something, and most of the times the dot 70 00:03:26,280 --> 00:03:28,620 something is probably a method, which is a 71 00:03:28,620 --> 00:03:32,010 function that operates on the object. So what this 72 00:03:32,010 --> 00:03:34,770 really means is, I have an object, I have a 73 00:03:34,830 --> 00:03:38,880 variable called MINPORT. When I say '.to_i', I'm 74 00:03:38,880 --> 00:03:42,930 going to run the to_i or the to integer function 75 00:03:42,960 --> 00:03:45,480 on MINPORT, and all that does is it converts the 76 00:03:45,480 --> 00:03:48,780 value of MINPORT into an integer value and stores 77 00:03:48,780 --> 00:03:52,290 the result in the variable i, and that let's us 78 00:03:52,290 --> 00:03:56,691 loop through while i is less than or equal to MAXPORT integer 79 00:03:57,017 --> 00:03:58,830 do and so we're just looping through 80 00:03:58,830 --> 00:04:03,210 for MINPORT to MAXPORT. We grab a new socket. If 81 00:04:03,240 --> 00:04:06,300 we get a new socket, the status is open, and then 82 00:04:06,325 --> 00:04:08,605 we're going to output the fact that it is open, 83 00:04:09,155 --> 00:04:12,005 and that's what puts does. puts says or actually 84 00:04:12,030 --> 00:04:15,270 stands for put string. So we get down to line 14, 85 00:04:15,330 --> 00:04:18,120 puts string would actually output to the terminal 86 00:04:18,154 --> 00:04:22,295 Port i is status and status is open at this 87 00:04:22,320 --> 00:04:25,980 point. rescue is what happens if there's an error. 88 00:04:26,010 --> 00:04:27,720 See this is a little bit different than what we saw 89 00:04:27,720 --> 00:04:30,360 in earlier scripts. We didn't have much error 90 00:04:30,360 --> 00:04:32,400 processing. In this case, we say what if the 91 00:04:32,400 --> 00:04:34,920 connection refused? Well, the connection is refused, 92 00:04:34,950 --> 00:04:37,080 I can really just do nothing, but I'm gonna go 93 00:04:37,080 --> 00:04:40,170 ahead and assign status equals closed, and then I 94 00:04:40,170 --> 00:04:44,160 increment i and move on. Now, you'll notice that 95 00:04:44,160 --> 00:04:46,350 there's no reason to say status is closed because 96 00:04:46,350 --> 00:04:48,810 I never use it, which is true. I just did it, just 97 00:04:48,810 --> 00:04:51,690 to show you that the status is closed. All right, 98 00:04:51,720 --> 00:04:54,390 all that's left is to run this thing. So let's 99 00:04:54,390 --> 00:04:56,550 type in ruby 100 00:04:56,574 --> 00:04:58,745 [No audio] 101 00:04:58,770 --> 00:05:01,980 portscan.rb, and what do I need to pass it? 102 00:05:02,010 --> 00:05:07,770 Let's say 10.10.1.10 22 and 80. Those 103 00:05:07,795 --> 00:05:11,443 are the defaults, and we're done pretty fast, 104 00:05:12,031 --> 00:05:15,600 and we can actually change these values and 105 00:05:15,600 --> 00:05:21,030 not use the defaults. So let's try 20, and I'm 106 00:05:21,030 --> 00:05:23,130 actually going to hit another machine, and there 107 00:05:23,130 --> 00:05:27,540 we go. So for Port 10, or for IP address 10.10.1.11, 108 00:05:27,960 --> 00:05:31,200 Ports 21, 22, and 80 are open. But we didn't see 109 00:05:31,200 --> 00:05:36,480 23, 25, and 53, like we did on the .10 machine. So 110 00:05:36,480 --> 00:05:39,240 that's a high level lightning round look at Ruby. 111 00:05:39,300 --> 00:05:41,700 Ruby is a pretty cool language. I wouldn't 112 00:05:41,700 --> 00:05:44,460 recommend it to be the first language because it's 113 00:05:44,610 --> 00:05:47,670 elegant, it's object oriented, and there's a lot 114 00:05:47,670 --> 00:05:50,160 of functionality that you may not need. My 115 00:05:50,160 --> 00:05:52,980 suggestion would be pick one of the languages out 116 00:05:52,980 --> 00:05:55,320 of these four that is most comfortable for you, 117 00:05:55,350 --> 00:05:58,200 the one you like and really focus on that one is 118 00:05:58,200 --> 00:06:02,040 the language you use, and then just be aware of 119 00:06:02,040 --> 00:06:04,890 how to read scripts written in other languages. 120 00:06:04,980 --> 00:06:07,500 You always want to be able to open up a ruby 121 00:06:07,500 --> 00:06:10,290 script and understand what it's trying to do. 122 00:06:10,470 --> 00:06:12,900 That's really the whole key, not to be a Ruby 123 00:06:12,900 --> 00:06:15,480 developer, but to be able to understand what the 124 00:06:15,480 --> 00:06:18,600 ruby script developer was trying to do in the first place. 125 00:06:18,624 --> 00:06:32,513 [No audio]