1 00:00:01,420 --> 00:00:02,280 Done. 2 00:00:02,280 --> 00:00:03,440 Okay, is that better? 3 00:00:04,500 --> 00:00:05,200 Yes. 4 00:00:05,200 --> 00:00:05,720 Nice. 5 00:00:05,880 --> 00:00:06,780 That's good. 6 00:00:06,780 --> 00:00:07,760 Nailed it. 7 00:00:08,220 --> 00:00:10,200 Thank you for hanging in there. 8 00:00:12,620 --> 00:00:15,460 Okay, so I want to ask, what isn't machine learning? 9 00:00:15,820 --> 00:00:28,320 So , as math underpins everything we do, I think you get to a point where everything is machine learning. 10 00:00:28,320 --> 00:00:45,160 So, if you think about when you're a child and you're trying to learn to walk, it doesn't look that unfamiliar to when someone has reinforcement learning algorithms that are teaching something to walk. 11 00:00:46,160 --> 00:01:04,060 So from an offensive standpoint, I think it's an important distinction because where offensive folks try to live in the realm of possibility rather than in a box that we try to define. 12 00:01:04,060 --> 00:01:15,080 So , maybe if you start thinking of everything as machine learning, you're going to find more opportunities to attack machine learning models, use them in your ops, whatever that might be. 13 00:01:15,740 --> 00:01:23,280 But for this attack in particular, we're going to do a copycat model. 14 00:01:23,280 --> 00:01:28,060 And I think this kind of concept will come out as we go through it. 15 00:01:28,840 --> 00:01:34,740 So, I'm kind of tired of the name copycat model, so I'm just going to call them Pink Panther attacks from now on. 16 00:01:35,220 --> 00:01:36,880 One, it's more fun. 17 00:01:37,040 --> 00:01:39,780 Two, it's still kind of cat-like. 18 00:01:40,120 --> 00:01:45,720 And three, I know Pink Panther involves a diamond that is always trying to be stolen. 19 00:01:46,260 --> 00:01:53,060 And preconditions for a successful attack, and these are pretty loose, are a representative data set. 20 00:01:53,380 --> 00:02:07,280 So, for example, in the case of an AMSI provider, we're looking for like PowerShell, VBA code, a big representative data set that we want to model. 21 00:02:07,620 --> 00:02:11,960 And we need the ability to get feedback from our target model. 22 00:02:11,960 --> 00:02:15,760 And this doesn't have to be direct output. 23 00:02:15,760 --> 00:02:29,000 So, if you imagine that a model doesn't give you back a score, but it keeps it in a Windows event log, you still get your hard label, hard label being a 0 or a 1. 24 00:02:29,860 --> 00:02:46,900 So, even if the model doesn't give you back output, there are still, just due to the telemetry nature of our networks, it's more likely than not that somewhere output's being recorded. 25 00:02:47,420 --> 00:03:02,760 So, rather than maybe going directly to the model, try and think of some binary test that you can perform that is potentially outside of the realm of a machine learning model. 26 00:03:03,540 --> 00:03:07,600 So, it's a pretty simple attack once you kind of get into it. 27 00:03:07,600 --> 00:03:10,960 Effectively, you grab a massive... 28 00:03:10,960 --> 00:03:15,300 in this case, we found a big PowerShell corpus. 29 00:03:15,640 --> 00:03:19,740 So , there's like 400,000 scripts. 30 00:03:20,020 --> 00:03:24,760 And the workshop, the lab piece of it, we'll talk about that. 31 00:03:25,020 --> 00:03:30,800 Effectively, the scripts get fed into an AMSI integration. 32 00:03:32,080 --> 00:03:34,980 And this just came off of the Windows sample. 33 00:03:34,980 --> 00:03:46,600 So, all it does is load AMSI.dll and instantiate the com object and we feed it every script in that corpus. 34 00:03:47,000 --> 00:03:52,940 And that gets passed to Defender or whatever AMSI provider that might be. 35 00:03:53,280 --> 00:03:56,140 And it comes back with a score. 36 00:03:57,120 --> 00:04:01,460 And then we turn around and we just collect those scores offline. 37 00:04:02,400 --> 00:04:08,420 And once we have known inputs and we know what the output... 38 00:04:08,420 --> 00:04:13,740 Defender thinks of the output, we can model our model. 39 00:04:14,560 --> 00:04:24,280 And the hardest part about, I think, adversarial machine learning isn't the machine learning piece. 40 00:04:24,720 --> 00:04:27,940 Most of us don't have to invent math. 41 00:04:27,940 --> 00:04:34,620 People much smarter than myself have already done that for me. 42 00:04:34,620 --> 00:04:37,840 But what is difficult is the engineering piece. 43 00:04:37,840 --> 00:04:40,420 It's getting access to the right data. 44 00:04:40,720 --> 00:04:51,300 It's getting data in a way that isn't going to get you caught or you're going to distribute your traffic accordingly. 45 00:04:51,760 --> 00:04:54,700 And you can kind of fly under the radar. 46 00:04:54,700 --> 00:05:02,760 In the future, currently attackers kind of have free reign and get away with quite a lot of querying and noise in the network. 47 00:05:02,760 --> 00:05:04,680 That's not always going to be the case. 48 00:05:05,120 --> 00:05:19,140 And I think it is helpful for us to start thinking about limiting our queries, thinking about information density of a command, a ping versus a process list, for example. 49 00:05:20,880 --> 00:05:24,260 Ping, you're going to get if a host is up or not. 50 00:05:24,260 --> 00:05:26,780 Or you're going to get TTL, which is going to tell the OS. 51 00:05:27,200 --> 00:05:30,360 But a process list, you're going to get that and more. 52 00:05:30,920 --> 00:05:33,040 But it probably just depends on what you're after. 53 00:05:34,840 --> 00:05:41,100 And from a machine learning perspective and an offensive perspective, anything can be modeled. 54 00:05:41,100 --> 00:05:57,320 So if defenders are using machine learning to model whatever logs they're looking for, there's nothing to say that we as offensive folks can't also use machine learning to say model CT traffic. 55 00:05:57,320 --> 00:06:05,260 Or let's say you have semantic, you have some product that is blocking you and you can't quite pinpoint it. 56 00:06:05,880 --> 00:06:11,240 Machine learning will be able to do that for you if you can set up the right experiment. 57 00:06:11,300 --> 00:06:34,820 So even though Semantic is not using machine learning necessarily to look for your CT traffic, you can still use it to find those relationships between whatever domain or whatever callback interval that you're using against whatever product it might be. 58 00:06:35,500 --> 00:06:39,340 So I guess I just come back to the question of what isn't machine learning. 59 00:06:41,840 --> 00:06:50,580 And in my mind, everything is machine learning if you kind of go back to the math, which is kind of fun. 60 00:06:50,720 --> 00:06:58,240 Okay, so in the lab, the workshop, all the code is in there for you. 61 00:06:58,240 --> 00:07:06,280 So the first half, you'll step through and it'll be very explanatory. 62 00:07:07,380 --> 00:07:12,840 And then as we go through, it'll be less and less explanation. 63 00:07:12,840 --> 00:07:18,800 So you'll be required to kind of look more, ask more questions, etc., etc. 64 00:07:19,380 --> 00:07:23,360 Break stuff, like you're not going to break it, you can always reset it. 65 00:07:23,360 --> 00:07:25,720 Google it, ask us for help. 66 00:07:25,720 --> 00:07:34,640 AI Village has easily, probably the highest concentration of some of the smartest people in the industry. 67 00:07:34,820 --> 00:07:41,600 And there's so many PhDs and super experienced people. 68 00:07:41,600 --> 00:07:44,220 So , you know, we love talking. 69 00:07:44,220 --> 00:07:55,000 I like talking offensive ops, but you know, a lot of people like talking stats and topology and homology and all this other stuff. 70 00:07:55,600 --> 00:07:59,240 The other day I learned that there is more than one algebra. 71 00:08:01,760 --> 00:08:06,000 But yeah, so this is the place to ask, so go ask for it. 72 00:08:06,640 --> 00:08:13,380 As you go through, I would challenge those of you who are more experienced to produce a better and more efficient attack. 73 00:08:14,320 --> 00:08:19,800 And in there, there is also a massive data set of VBA code that I found. 74 00:08:19,800 --> 00:08:21,980 It's like nine gigs of VBA code. 75 00:08:22,640 --> 00:08:27,580 So if you want, go through this code, it would work the same. 76 00:08:27,580 --> 00:08:35,760 And you could get your name on that leaderboard for CVs for machine learning systems. 77 00:08:37,280 --> 00:08:40,400 So if you want to do that, you can go for it. 78 00:08:42,280 --> 00:08:44,660 So feel free to ask questions in Discord. 79 00:08:44,660 --> 00:08:46,680 There are no dumb questions. 80 00:08:47,620 --> 00:08:52,440 And we have three TAs that are helping me out here. 81 00:08:52,500 --> 00:08:56,100 So if you have specific questions, we can ask for it. 82 00:08:56,260 --> 00:09:00,280 So hopefully you have the link. 83 00:09:01,000 --> 00:09:02,540 You have everything. 84 00:09:03,980 --> 00:09:09,100 So effectively, this is the... what do you call this? 85 00:09:09,100 --> 00:09:11,080 This is the workshop. 86 00:09:13,180 --> 00:09:16,440 And there are two files, two Python notebooks. 87 00:09:16,440 --> 00:09:21,100 One is the solutions, and one is the workbook. 88 00:09:21,960 --> 00:09:23,740 And you should start with the workbook. 89 00:09:23,740 --> 00:09:32,940 If you do get stuck, or you need code help, or you just want to grab it and go, the solutions one is going to work for you. 90 00:09:32,940 --> 00:09:45,220 This amsy.h file is if you do want to compile the amsy stream.exe so you can recreate the full attack path. 91 00:09:46,000 --> 00:09:48,380 You're going to need this header file. 92 00:09:48,900 --> 00:09:53,640 Collect.py is what we use to gather all the information. 93 00:09:53,640 --> 00:09:57,580 And then this insights.xlsx, this Excel file. 94 00:09:57,580 --> 00:10:03,860 This is the version 1 of the insights that we pulled out of Defender. 95 00:10:04,520 --> 00:10:09,840 So this would be like that proof point style insight. 96 00:10:10,580 --> 00:10:15,760 And it is our version 1, so this is it. 97 00:10:15,760 --> 00:10:19,400 So obviously you can see there's a lot of binary blobs in here. 98 00:10:19,480 --> 00:10:22,220 But these would be the most malicious tokens. 99 00:10:22,860 --> 00:10:25,040 And this makes sense to me. 100 00:10:26,600 --> 00:10:33,240 And at the bottom you have the least giant binary blob. 101 00:10:34,900 --> 00:10:43,180 And at the bottom you have the least malicious tokens. 102 00:10:46,080 --> 00:10:48,240 So that's free. 103 00:10:50,560 --> 00:10:54,260 So you guys can get started. 104 00:10:54,260 --> 00:10:56,400 Do you guys have any questions right away? 105 00:10:59,220 --> 00:11:01,640 I haven't seen any questions so far. 106 00:11:03,840 --> 00:11:04,880 Perfect. 107 00:11:10,490 --> 00:11:11,790 That's good. 108 00:11:15,890 --> 00:11:18,150 Is anyone else getting 403? 109 00:11:32,220 --> 00:11:34,300 I have to say I haven't used Defender. 110 00:11:35,440 --> 00:11:37,660 Is anyone else getting 403? 111 00:11:45,650 --> 00:11:49,630 We are not seeing any chat on Twitch or Discord. 112 00:11:49,630 --> 00:11:54,550 I just reopened the link and it's building the container for me. 113 00:11:54,910 --> 00:11:56,030 Yeah, me too. 114 00:11:56,030 --> 00:11:57,310 Okay, that's good. 115 00:11:59,070 --> 00:12:01,030 I have my own copy. 116 00:12:01,050 --> 00:12:03,770 I am in the Jupyter Notebook. 117 00:12:03,850 --> 00:12:04,770 Nice. 118 00:12:05,110 --> 00:12:12,630 Yeah, so the first little bit, I'll give you guys 10-15 minutes to rip through the first little bit. 119 00:12:12,630 --> 00:12:18,850 And if you guys have questions, let me know. 120 00:12:21,570 --> 00:12:23,510 Remote is always a bit weird. 121 00:12:33,570 --> 00:12:36,610 But, you know what always gets me in the mood? 122 00:12:41,760 --> 00:12:42,740 Can you guys hear that? 123 00:12:42,740 --> 00:12:44,680 What always gets you in the mood? 124 00:12:45,540 --> 00:12:46,380 Tron. 125 00:12:47,140 --> 00:12:50,980 Yeah, I don't think it's a good idea to stream copyrighted music on here. 126 00:12:50,980 --> 00:12:52,900 Oh, right, right, right. 127 00:12:54,100 --> 00:12:59,860 Twitch doesn't really have a problem with that, but the YouTube VOD at the end will be removed. 128 00:12:59,980 --> 00:13:00,920 That's fair. 129 00:13:01,960 --> 00:13:04,600 Yeah, I don't spend that much time on the internet. 130 00:13:06,380 --> 00:13:10,220 So, Will, I can send you the Notebook link again. 131 00:13:10,220 --> 00:13:13,660 The one that myself and other people are using on the chat. 132 00:13:13,820 --> 00:13:14,480 That's good. 133 00:13:14,480 --> 00:13:16,240 I have my own. 134 00:13:42,000 --> 00:13:42,740 Excellent. 135 00:13:42,740 --> 00:13:46,720 Okay, so I'm just going to talk. 136 00:13:46,840 --> 00:13:55,260 Everything is pretty self-explanatory in terms of the instructions. 137 00:13:57,820 --> 00:13:59,760 Can you zoom in a little bit? 138 00:13:59,760 --> 00:14:01,420 It's kind of hard to see on the screen. 139 00:14:05,910 --> 00:14:07,070 Is that better? 140 00:14:09,610 --> 00:14:10,830 One more. 141 00:14:14,780 --> 00:14:16,080 That should be good. 142 00:14:17,840 --> 00:14:19,800 Sorry, there's a one-year-old. 143 00:14:20,320 --> 00:14:22,180 I can see it very clearly. 144 00:14:23,980 --> 00:14:24,800 Excellent. 145 00:14:24,800 --> 00:14:26,960 So, I'm just going to talk. 146 00:14:26,960 --> 00:14:28,900 You guys feel free to run through. 147 00:14:30,240 --> 00:14:36,880 So, sort of the basis of this attack is really the AnyMalware scan interface. 148 00:14:39,340 --> 00:14:45,060 And Emsi is something they introduced in, I want to say, PowerShell 5. 149 00:14:45,940 --> 00:14:47,720 A little sooner than that. 150 00:14:47,920 --> 00:15:02,580 But effectively, it's just a DLL that gets called into PowerShell, UAC dialogs, any Jscript, VBScript, and now .NET 4.8 and beyond. 151 00:15:03,500 --> 00:15:17,380 And inside, it has a number of blacklisted functions that whenever one of those functions is called, Emsi will get called to scan content. 152 00:15:18,560 --> 00:15:21,660 And Emsi is not a security boundary. 153 00:15:21,660 --> 00:15:24,320 It's not a security product. 154 00:15:24,320 --> 00:15:26,020 It's an interface. 155 00:15:26,020 --> 00:15:40,980 And so, all it does is collect whatever content is being put into the buffer or the string, and it passes it back to an Emsi provider. 156 00:15:41,360 --> 00:15:47,920 And the Emsi provider then has an opportunity to scan the content and make some determination. 157 00:15:47,920 --> 00:15:51,820 So, obviously, this workshop is about Windows Defender. 158 00:15:53,280 --> 00:16:02,300 But there are several other providers, Emsi providers, that this attack would work against. 159 00:16:04,180 --> 00:16:11,460 And that's, I suppose, kind of the nice part about machine learning currently is there's a lot of attack surface. 160 00:16:11,460 --> 00:16:21,080 So, once an Emsi provider scans the content and decides what it is, there's a range of scores it can give. 161 00:16:21,080 --> 00:16:27,160 Currently, it only gives back 0 or 1, 32, 768. 162 00:16:27,540 --> 00:16:32,060 But in Microsoft documentation, they talk about a range of scores. 163 00:16:32,060 --> 00:16:49,080 So , if you think rather than a hard label as a 0 or a 1, eventually you'd get some sort of regression type continuous variable on the out. 164 00:16:49,080 --> 00:16:52,700 And so, you'd get some heuristic, I suppose. 165 00:16:56,520 --> 00:17:05,000 There's a great talk by, actually Microsoft, called Badly Behaving Scripts. 166 00:17:05,000 --> 00:17:08,540 It's probably like an hour long. 167 00:17:08,600 --> 00:17:13,520 But I think they gave it two years ago at Blue Hat IL. 168 00:17:13,920 --> 00:17:17,760 And it's two engineers from the machine learning team. 169 00:17:17,760 --> 00:17:33,140 And they're just discussing how Emsi works, the things that they're looking for, the kind of models that they're building, and so on. 170 00:17:33,140 --> 00:17:40,640 And so, this is kind of our first indication, at least officially, that machine learning is being pushed onto the client. 171 00:17:40,640 --> 00:17:51,460 And I think it would seem anyway that overtly malicious things get stopped on the client. 172 00:17:51,460 --> 00:17:58,860 But anything that's kind of in between seems to go to the cloud. 173 00:17:58,860 --> 00:18:03,540 One way to test this would be to have some sort of timing attack. 174 00:18:03,540 --> 00:18:10,840 You could get the response times for submission to the reception of the score. 175 00:18:11,140 --> 00:18:22,600 And you could maybe see if there's a significant difference between the worst scripts and the medium bad scripts. 176 00:18:25,310 --> 00:18:26,990 So, moving on. 177 00:18:26,990 --> 00:18:28,330 You guys can obviously read. 178 00:18:29,910 --> 00:18:37,370 So, the first thing we obviously needed to do to create a copycat is we needed a data set. 179 00:18:37,370 --> 00:18:47,130 And there's a talk by Lee Holmes and Daniel Bohannon in 2017 called Revoke Obfuscation, Powershot Obfuscation Detection Using Science. 180 00:18:48,210 --> 00:19:03,550 So, Daniel Bohannon wrote Invoke Obfuscation, which basically takes a script or any number of different languages and it puts it through an obfuscation. 181 00:19:03,950 --> 00:19:08,390 So, it breaks it up into a million different pieces. 182 00:19:08,390 --> 00:19:12,990 So, it'll break those regexes, those brittle detections. 183 00:19:12,990 --> 00:19:15,470 It's an awesome, awesome tool. 184 00:19:15,470 --> 00:19:17,690 These guys wrote it, wrote the talk. 185 00:19:17,690 --> 00:19:23,090 And part of that research, they collected like two gigs worth of PowerShell scripts. 186 00:19:23,550 --> 00:19:29,570 And they labeled them both benign and malicious for us. 187 00:19:30,310 --> 00:19:33,470 And so, they're already... you can actually... the link's here. 188 00:19:33,470 --> 00:19:36,130 So, you can go pull it down and rip through it. 189 00:19:37,790 --> 00:19:46,070 Once you have that, the rest of it is just getting target outputs from the target models. 190 00:19:46,110 --> 00:19:54,810 So , if we want to create a copycat, we want to know what Defender thinks of each script that we give it. 191 00:19:55,090 --> 00:19:58,110 And then, that is remodeling the model. 192 00:19:58,110 --> 00:20:00,030 So, we have the inputs and we have the outputs. 193 00:20:00,030 --> 00:20:01,770 We don't know what's in the middle. 194 00:20:01,830 --> 00:20:03,210 We don't know that black box. 195 00:20:03,210 --> 00:20:08,590 But we can infer it with our own model. 196 00:20:08,630 --> 00:20:11,530 And you'll never get 100% of the model. 197 00:20:11,530 --> 00:20:24,790 But you might get just enough to bypass Windows Defender for a month or just one time or whatever it might be. 198 00:20:24,790 --> 00:20:37,290 But the nice part about machine learning and the struggle that machine learning has, I think, is it does introduce a probability into what used to be a static decision. 199 00:20:40,850 --> 00:20:45,050 The large repository of something interesting is VBA. 200 00:20:45,050 --> 00:20:50,730 So, that's just 9 gigs of Excel macros that you could do the same with. 201 00:20:52,850 --> 00:20:54,610 Which would be pretty awesome. 202 00:20:58,830 --> 00:21:02,750 We have... let's see, what is this? 203 00:21:02,750 --> 00:21:07,370 This is the... you're not on Windows. 204 00:21:08,250 --> 00:21:13,150 If this were like Lab Lab, we'd have Windows VMs and we'd do this for real. 205 00:21:13,390 --> 00:21:16,310 This is just the output from the AMSI stream. 206 00:21:16,430 --> 00:21:22,270 So, InvokeWMIBackdoor looks malicious, but Defender doesn't think it's malicious. 207 00:21:22,270 --> 00:21:32,590 So, if you look down, you see ScanResult is 1, IsMalware is 0, IsMalware is the official feedback loop. 208 00:21:33,410 --> 00:21:39,730 And even in that talk that is above, they discuss the fact that you can't trust filenames. 209 00:21:39,730 --> 00:21:40,670 And that makes sense. 210 00:21:40,670 --> 00:21:43,330 You can't trust headers anymore. 211 00:21:43,970 --> 00:21:55,550 There's some research that did a number of, like 3 years ago now, against mail filters where you would null out the first 2 bytes of a .m file. 212 00:21:56,150 --> 00:22:06,430 And depending on how the mail filter decided what kind of file it was, it would either block it or let it through. 213 00:22:06,430 --> 00:22:09,550 Because it can't read the magic bytes at the top. 214 00:22:10,330 --> 00:22:14,310 And then, obviously the document is corrupt at that point. 215 00:22:14,310 --> 00:22:19,930 But what Windows does is when you open the .m file, it would ask you to repair it. 216 00:22:20,410 --> 00:22:29,790 And if the user clicked yes, I'd like to repair this document, your macro would live and you could get code execution. 217 00:22:31,790 --> 00:22:36,510 Right, but the next bit is the provider display name. 218 00:22:36,510 --> 00:22:38,990 So we have Microsoft Defender Antivirus. 219 00:22:39,850 --> 00:22:41,790 If this is... 220 00:22:47,110 --> 00:22:54,810 If Defender is turned off for whatever reason, or there is no AMZ provider, it will give you an error. 221 00:22:55,090 --> 00:22:57,730 And you will not get a score back. 222 00:22:58,430 --> 00:23:01,770 The next piece is just PowerView. 223 00:23:01,770 --> 00:23:05,450 So PowerView is pretty well known script, and it is definitely... 224 00:23:05,450 --> 00:23:12,810 Well, it's not explicitly malicious, but it is used by malicious people. 225 00:23:14,390 --> 00:23:16,190 That's not fair to say. 226 00:23:16,250 --> 00:23:18,250 It's used by attackers. 227 00:23:18,630 --> 00:23:21,710 I'm sure there are some nice attackers. 228 00:23:23,910 --> 00:23:25,980 So in this lab, there are... 229 00:23:27,290 --> 00:23:32,410 Uploading 380,000 scripts to GitHub was not popular with GitHub. 230 00:23:32,990 --> 00:23:35,610 So in this little bit, you only have 3,000. 231 00:23:35,630 --> 00:23:39,010 But the collect.py has everything you need. 232 00:23:40,090 --> 00:23:44,210 And when we were parsing, we just did... 233 00:23:44,210 --> 00:23:47,390 In your data, you have data clean and dirty. 234 00:23:47,890 --> 00:23:50,070 These would be your malicious scripts. 235 00:23:50,070 --> 00:23:56,740 And clean scripts are actually clean. 236 00:23:56,740 --> 00:23:58,120 There's like 3,000. 237 00:23:58,120 --> 00:24:04,280 There are about 1,200 malicious scripts that you can look at. 238 00:24:04,740 --> 00:24:08,640 Yeah, if you guys want to start ripping through this code. 239 00:24:11,000 --> 00:24:15,080 As we were parsing, you can look through collect.py. 240 00:24:15,300 --> 00:24:18,200 But I personally like to keep... 241 00:24:18,200 --> 00:24:21,380 So there's a lot of moving parts in machine learning. 242 00:24:21,380 --> 00:24:23,560 You kind of can't get away from it. 243 00:24:24,060 --> 00:24:28,560 So whenever possible, I like to keep at each step. 244 00:24:28,560 --> 00:24:33,060 I'll build a data structure and I'll keep the previous output. 245 00:24:33,880 --> 00:24:35,320 And I think it works nicely. 246 00:24:35,320 --> 00:24:37,360 Most of my datasets are pretty small anyway. 247 00:24:37,440 --> 00:24:39,280 So it's manageable. 248 00:24:39,620 --> 00:24:42,820 But you can kind of see the GetScreenshot. 249 00:24:42,820 --> 00:24:46,800 So this is the file name, the original file name. 250 00:24:46,800 --> 00:24:49,580 This is the hash, the MD5 hash of it. 251 00:24:49,580 --> 00:24:53,760 And then you have the result, being its malware. 252 00:24:54,000 --> 00:24:59,080 And then you have the base64 encoded text that you can look through. 253 00:24:59,080 --> 00:25:05,960 I like this because if there's any weirdness, you have everything you need right in front of you. 254 00:25:06,000 --> 00:25:09,640 You don't have to start again at a particular point. 255 00:25:09,640 --> 00:25:12,320 You don't have to go back to the beginning of the process. 256 00:25:13,500 --> 00:25:17,580 Being able to debug all the way through your pipeline is... 257 00:25:17,580 --> 00:25:20,500 It might cost you some speed. 258 00:25:22,280 --> 00:25:25,240 But at least for me, it's fine. 259 00:25:25,240 --> 00:25:27,460 I'm not dealing with billions of anything. 260 00:25:31,600 --> 00:25:34,140 We just got discussed lists. 261 00:25:34,340 --> 00:25:44,500 So if you're not familiar with a list, which I think probably most of you are, raise your hand if you're familiar with lists. 262 00:25:46,000 --> 00:25:48,420 Nice, okay, so about 20% of you. 263 00:25:52,420 --> 00:25:54,040 Can't hear any giggling. 264 00:25:54,840 --> 00:25:56,440 Alright, so you have lists. 265 00:25:56,440 --> 00:25:57,600 Lists are really nice. 266 00:25:57,600 --> 00:26:00,160 So you can just put them on any delimiter you want. 267 00:26:02,280 --> 00:26:04,860 So quick question, Will. 268 00:26:05,020 --> 00:26:09,380 This is from the Twitch chat. 269 00:26:10,200 --> 00:26:14,020 Should he be able to view the PowerShell code? 270 00:26:14,020 --> 00:26:19,620 When they click on a file with clean or dirty, get a mess of characters but not a script. 271 00:26:21,160 --> 00:26:23,760 Yes, so you... 272 00:26:23,760 --> 00:26:29,200 Yeah, so in this little code block here, you can open it. 273 00:26:29,200 --> 00:26:31,380 And it is just a... 274 00:26:31,380 --> 00:26:33,620 So we've already parsed it for you. 275 00:26:33,720 --> 00:26:35,960 It was just going to take forever otherwise. 276 00:26:36,320 --> 00:26:40,460 So what you're going to see is the script name. 277 00:26:41,080 --> 00:26:43,680 So this is the original script name. 278 00:26:43,680 --> 00:26:47,580 The MD5 hash of the script content. 279 00:26:48,550 --> 00:26:52,030 The AMSI result, or I should say the Defender result. 280 00:26:52,300 --> 00:26:54,760 So what Defender thinks of the script. 281 00:26:54,980 --> 00:26:59,900 And then the Base64 encoded version of the script. 282 00:27:03,900 --> 00:27:07,680 Can you turn lines on? 283 00:27:15,820 --> 00:27:17,940 So this is what we're doing here. 284 00:27:17,940 --> 00:27:20,380 So we're splitting a file. 285 00:27:20,380 --> 00:27:22,380 So what we're doing is we're setting up... 286 00:27:22,380 --> 00:27:28,340 Eventually we're going to rip through all these files and we're going to build a big vocab. 287 00:27:28,700 --> 00:27:30,360 So this is a... 288 00:27:30,360 --> 00:27:33,060 I just pulled one out as an example. 289 00:27:34,840 --> 00:27:35,920 So let's see. 290 00:27:36,820 --> 00:27:39,000 So for example, if we want to reference... 291 00:27:39,000 --> 00:27:40,740 This is just list stuff. 292 00:27:40,740 --> 00:27:42,080 So obviously zero index. 293 00:27:42,080 --> 00:27:45,140 So we can reference it however we want. 294 00:27:46,480 --> 00:27:49,260 You can then reference with semicolon. 295 00:27:49,300 --> 00:27:52,600 You know, from index one to the end. 296 00:27:52,600 --> 00:27:56,480 Or from index one to the third. 297 00:27:58,740 --> 00:28:01,260 Or you can even do minus. 298 00:28:01,260 --> 00:28:03,720 So you can go to the end of the list. 299 00:28:04,360 --> 00:28:06,740 And just get the script content. 300 00:28:07,560 --> 00:28:13,740 But if we're going to look at the script content, we kind of want to know... 301 00:28:15,580 --> 00:28:21,140 It's interesting that getScreenshot is counted as malicious. 302 00:28:22,120 --> 00:28:26,820 So if we decode it, we can have a look and maybe... 303 00:28:26,820 --> 00:28:33,800 Maybe there's some knowledge that we have that we can think about as to why it might be malicious. 304 00:28:37,780 --> 00:28:41,160 So we're just using split to make it a little nicer. 305 00:28:41,160 --> 00:28:42,740 And there's a typo right there. 306 00:28:44,980 --> 00:28:46,580 It's a double typo now. 307 00:28:48,780 --> 00:28:54,130 Alright, so we're just going to run through it. 308 00:28:54,190 --> 00:28:55,230 Actually, no, it's not. 309 00:28:57,770 --> 00:29:02,110 So to make it nice, actually, this isn't the solutions one, so you guys already know this. 310 00:29:04,330 --> 00:29:08,310 So if you want to make it a little nicer, we're just going to split it again. 311 00:29:09,670 --> 00:29:14,930 And we're going to get a list of the things. 312 00:29:14,930 --> 00:29:21,770 So, looking through this list, in my mind, some of the more malicious things would be the AddTypeAssembly. 313 00:29:22,590 --> 00:29:32,950 It would be ConvertToInt32, NewObjectSystemIOMemoryStream, so everything like in-memory attacks, any sort of memory streams. 314 00:29:32,950 --> 00:29:37,790 And then at the bottom, you also have two Base64 string. 315 00:29:39,370 --> 00:29:44,370 I think Base64 is typically something that gets picked up quite easily. 316 00:29:46,430 --> 00:29:50,690 But if we wanted to figure out how this was... 317 00:29:50,690 --> 00:30:00,850 why this was malicious, or why Defender thought this was malicious, does anybody have any ideas that they want to type out? 318 00:30:00,850 --> 00:30:00,990 Is 319 00:30:10,320 --> 00:30:12,780 anybody typing? 320 00:30:12,780 --> 00:30:13,620 I can't see. 321 00:30:19,720 --> 00:30:24,020 Yeah, it doesn't seem like there is anybody typing on Discord right now. 322 00:30:24,020 --> 00:30:24,740 Nice. 323 00:30:27,420 --> 00:30:29,840 Yeah, so we're just going to go through the dictionary. 324 00:30:30,560 --> 00:30:43,500 So, this is just what I came up with, and it would be to try and determine the commonality between all the malicious scripts and see if... see what tokens... 325 00:30:44,760 --> 00:30:47,180 and when I say tokens, I mean words... 326 00:30:47,720 --> 00:30:49,640 words came to the top. 327 00:30:50,100 --> 00:30:51,640 And to do this, we're going to use... 328 00:30:51,640 --> 00:30:53,040 we're just going to do a dictionary. 329 00:30:53,840 --> 00:30:57,960 And it's kept, you know, key-value pair. 330 00:30:58,600 --> 00:31:00,720 So I'll let you guys run through that. 331 00:31:11,360 --> 00:31:15,440 And if you need to play around with dictionaries, they're pretty awesome. 332 00:31:15,440 --> 00:31:25,240 I like dictionaries, but there is one other data structure that I like even more than dictionaries. 333 00:31:26,660 --> 00:31:27,640 Excellent. 334 00:31:27,640 --> 00:31:29,700 So, we know what dictionaries are now. 335 00:31:29,700 --> 00:31:35,660 And we're just going to decode the content, and we're going to add it all to a dictionary. 336 00:31:36,180 --> 00:31:38,700 We're only going to do one script. 337 00:31:39,100 --> 00:31:44,920 And does anybody know why we might just only want to do one for now? 338 00:31:53,660 --> 00:31:56,460 Because it's good practice? 339 00:31:56,460 --> 00:31:57,800 Yeah, it's good practice. 340 00:31:57,800 --> 00:32:18,280 But when you are dealing with, I don't know, thousands of scripts, like half a million scripts, if you have something that's going to mess up halfway through, or you start down that path, you're just going to waste a lot of time fixing errors. 341 00:32:18,280 --> 00:32:34,300 So, if you can get it to work with one, and then ten, and then fifty, and then a thousand, I think that's a much better way to go about processing large data, large data sets. 342 00:32:34,300 --> 00:32:45,520 So, for this one we're just going to do one, but we're going to split it twice, and then we're going to just add everything to the word index. 343 00:32:45,520 --> 00:32:49,560 So, there's a fill-in-the-blank bit here. 344 00:32:50,120 --> 00:32:55,000 So, if you guys want to go ahead and run that code, and then tell me what the issue is. 345 00:33:02,290 --> 00:33:03,430 And I'll give you clues. 346 00:33:03,430 --> 00:33:05,630 It's on the line with all the question marks. 347 00:33:07,230 --> 00:33:09,670 I didn't know that I needed to be this close to the microphone. 348 00:33:21,940 --> 00:33:24,960 Or you guys are already way, way, way past this. 349 00:33:40,850 --> 00:33:46,590 So, to get a proper count of the words as we go through them, we need to just add one. 350 00:33:47,610 --> 00:33:59,950 And you would have been able to tell after you went through it, because there's only one token listed for each. 351 00:34:02,940 --> 00:34:07,400 But the script has at least more than one. 352 00:34:07,400 --> 00:34:09,740 So, if we just fix that, 353 00:34:14,110 --> 00:34:18,550 now we get a better representation of what's out there. 354 00:34:20,030 --> 00:34:30,750 Going one at a time, I guess I've found I used to have a real issue with loops, where I wouldn't break them up properly. 355 00:34:31,670 --> 00:34:36,630 And so, doing it a little more slowly, at least one at a time, has helped me. 356 00:34:37,470 --> 00:34:41,610 And then we're just going to sort the dictionary by token. 357 00:34:42,010 --> 00:34:59,690 So now, this equals sign, there's nine of them, there's six curly brackets, there's four new objects, but nothing particularly malicious. 358 00:35:00,110 --> 00:35:08,970 So there is a lot of punctuation in there, but we can deal with that later. 359 00:35:08,970 --> 00:35:18,090 So, now, because we're impatient, and we just want to get to the machine learning bit, we're going to run through the entire... 360 00:35:19,090 --> 00:35:21,630 all of the malicious scripts. 361 00:35:26,890 --> 00:35:29,670 And it might take a little bit on Binder. 362 00:35:37,010 --> 00:35:38,890 Might even take a little bit here. 363 00:35:40,930 --> 00:35:42,250 The... yeah. 364 00:35:42,630 --> 00:35:48,130 I wish I... I tried to ship all of the scripts to you. 365 00:35:53,180 --> 00:35:55,700 Okay, so now we're just going to sort the words. 366 00:35:55,700 --> 00:36:00,900 So this is all of the tokens for all of the malicious scripts. 367 00:36:05,000 --> 00:36:07,040 And it isn't ideal. 368 00:36:13,510 --> 00:36:19,310 So there's a lot of numbers, and this is fairly common when you're tokenizing text. 369 00:36:20,070 --> 00:36:23,050 And I would generally just say go a little slow. 370 00:36:23,050 --> 00:36:25,710 But, nice bit is, we're seeing get proc address. 371 00:36:26,370 --> 00:36:29,070 Does anybody know... 372 00:36:29,690 --> 00:36:33,690 you know, in what operation get proc address might be used? 373 00:36:38,070 --> 00:36:43,190 Does anybody that works in an AV vendor know what get proc address might be used for? 374 00:36:53,010 --> 00:36:55,050 You can Google it if you want. 375 00:37:03,250 --> 00:37:03,910 No? 376 00:37:03,910 --> 00:37:04,710 Nobody? 377 00:37:05,230 --> 00:37:06,150 GT? 378 00:37:07,270 --> 00:37:10,150 Any penetration testers? 379 00:37:10,950 --> 00:37:12,350 Malware authors? 380 00:37:12,350 --> 00:37:13,450 Anybody? 381 00:37:15,640 --> 00:37:17,460 I'm a data scientist. 382 00:37:17,700 --> 00:37:19,680 That's fair. 383 00:37:20,120 --> 00:37:22,300 I'll let you look that up. 384 00:37:22,380 --> 00:37:30,080 But it's used typically when you're looking up functions in other DLLs. 385 00:37:31,320 --> 00:37:39,600 Most notably I think used in process injection. 386 00:37:40,280 --> 00:37:41,480 Anyway. 387 00:37:43,760 --> 00:37:45,620 Alright, so there's a lot of numbers. 388 00:37:45,620 --> 00:37:47,020 It's fairly classic. 389 00:37:47,780 --> 00:37:53,960 But we're seeing write bytes to memory, memory address, a lot of malware type things. 390 00:37:55,140 --> 00:37:57,160 Remote proc handle. 391 00:37:57,700 --> 00:37:59,820 Obviously this is all PowerShell. 392 00:38:00,480 --> 00:38:02,540 But the numbers are actually kind of annoying. 393 00:38:03,960 --> 00:38:04,760 So... 394 00:38:06,920 --> 00:38:09,620 Let's scroll through. 395 00:38:09,620 --> 00:38:15,780 Are there any tokens in there that are particularly interesting to anybody? 396 00:38:29,840 --> 00:38:34,040 Rob, Logistic Aggression managed to answer your question. 397 00:38:34,040 --> 00:38:35,780 Thanks, Rob. 398 00:38:35,780 --> 00:38:37,260 Rob's the man. 399 00:38:37,260 --> 00:38:41,020 What was it? 400 00:38:41,580 --> 00:38:45,400 He said you get the address of a DLL function in memory. 401 00:38:45,400 --> 00:38:47,660 Also heavily used in packers. 402 00:38:48,360 --> 00:38:49,900 Yeah, exactly. 403 00:38:52,120 --> 00:38:54,600 Okay, so the next bit. 404 00:38:54,740 --> 00:38:57,920 We're just going to continue to filter down. 405 00:38:58,320 --> 00:39:03,060 And I would say that's generally the case with most of your data. 406 00:39:03,060 --> 00:39:13,020 I think most of your time spent when you're doing machine learning isn't the math piece that you typically think of. 407 00:39:13,020 --> 00:39:30,100 It's processing data, it's filtering data, it's making sure that your data sets are balanced or have a distribution that you want or whatever it might be. 408 00:39:30,100 --> 00:39:33,860 I said earlier that we're not inventing new math. 409 00:39:33,860 --> 00:39:37,640 I'm not going to be the guy to invent new math. 410 00:39:39,920 --> 00:39:52,260 The place that I can be most effective is applying my domain knowledge to what I know of machine learning and being extra careful with my data. 411 00:39:53,300 --> 00:39:56,720 Abraham Lincoln has a saying about sharpening an ax. 412 00:39:56,720 --> 00:39:58,760 I can't remember exactly what it is. 413 00:40:00,700 --> 00:40:05,600 If I had 10 hours to cut down a tree I would spend the first 8 sharpening my ax. 414 00:40:06,160 --> 00:40:07,980 That sounds right, I could have made that up. 415 00:40:08,960 --> 00:40:13,260 The same is true for machine learning and I would say data science. 416 00:40:14,120 --> 00:40:20,780 I don't know if Comath, do you want to chime in there as a data scientist? 417 00:40:23,100 --> 00:40:24,760 It's true or not? 418 00:40:29,500 --> 00:40:42,380 I tend to try something that works and then go back and perfect it to make sure I don't get little mistakes because when you scale things up it really screws you. 419 00:40:42,380 --> 00:40:49,780 There's a bug 0.1% of the time and now you have 100,000 things the bug is guaranteed to happen. 420 00:40:51,020 --> 00:40:55,520 It's better to clean those up before you really... 421 00:40:55,520 --> 00:41:28,320 If you're a data scientist in the twitch chat what do you think the percentage of cleaning versus actual machine learning data processing versus machine learning I think that would be interesting and if you're new to machine learning I would say it's okay to be impatient and go really fast because you want to get the end result but if you want to get quality results it is better to go a little slower. 422 00:41:30,720 --> 00:41:45,580 We're just going to create a new list and the difference here is we're creating a find all so we're going to start removing some punctuation and numbers and then we're just going to add it to a new list and then we're going to print the top 100 tokens. 423 00:41:48,480 --> 00:41:56,300 So all the numbers are gone a lot of the punctuation is gone I'd say that looks quite a bit better than the other one. 424 00:41:57,080 --> 00:42:23,500 We still have a getproc address we're still seeing the malicious tokens that we would expect shellcode so we haven't completely ruined our I want to call them crispy bits but we haven't ruined our what we want to model effectively so that's also there. 425 00:42:26,400 --> 00:42:43,340 So this bit I just said pick some tokens and go google them and make sure that they're see what comes up that's kind of the fun bit I suppose if we are live I can do that let's see 426 00:42:47,760 --> 00:42:49,740 that's what pehandle does 427 00:42:53,920 --> 00:42:56,540 I'm using edge that's embarrassing 428 00:43:04,400 --> 00:43:06,700 Have you guys heard of Mimikatz? 429 00:43:08,420 --> 00:43:10,240 Do you know if that one's malicious? 430 00:43:14,600 --> 00:43:16,000 Yeah, I would say so. 431 00:43:17,100 --> 00:43:18,260 PowerShell Type Loader? 432 00:43:18,260 --> 00:43:19,680 Mimikatz is flagged as malicious, yeah. 433 00:43:19,740 --> 00:43:21,760 Yeah, yeah, definitely malicious. 434 00:43:24,780 --> 00:43:32,500 And I would say, as an operator, I think a lot of the industry uses a lot of the same scripts. 435 00:43:32,500 --> 00:43:33,780 So, 436 00:43:36,970 --> 00:43:39,910 yeah. 437 00:43:40,910 --> 00:43:45,890 In fact, the DLL injection, bookdllinjection, atgraver... 438 00:43:46,730 --> 00:43:50,710 Yeah, so these are malicious type scripts. 439 00:43:52,330 --> 00:44:01,140 Okay, so once we have that bit, you know, you could... 440 00:44:01,140 --> 00:44:02,780 We could stop here, right? 441 00:44:02,780 --> 00:44:13,200 So we have some malicious tokens that we know that, you know, these are all tokens or words that were labeled by Defender as malicious. 442 00:44:13,260 --> 00:44:21,900 So we could stop here, theoretically, and have malicious scripts that never, you know, don't use any of these words. 443 00:44:22,100 --> 00:44:30,560 Alternatively, you could do the same with the clean scripts and only use, you know, words from those clean scripts. 444 00:44:30,560 --> 00:44:32,280 Or, you know, you could do both. 445 00:44:32,280 --> 00:44:36,200 But I think that would probably work. 446 00:44:37,540 --> 00:44:42,840 But I think you would have a hard time making it repeatable. 447 00:44:42,920 --> 00:44:45,410 And you wouldn't necessarily, you know, if something... 448 00:44:45,920 --> 00:44:54,200 If it all of a sudden stopped working, I don't think you would have much recourse in being able to figure out how or why. 449 00:44:55,320 --> 00:44:59,980 And so I think this is kind of where machine learning shines for us. 450 00:44:59,980 --> 00:45:07,440 And it's just the ability to iterate through massive amounts of data extremely quickly. 451 00:45:07,940 --> 00:45:14,880 So , you know, while... I'm going to use the GPT-2 fishing analogy. 452 00:45:14,880 --> 00:45:25,000 And it's like, you can spend an hour crafting, you know, one fish for five targets. 453 00:45:25,000 --> 00:45:34,260 Or you could spend an hour correcting five unique fish generated out of GPT-2 for five targets. 454 00:45:35,580 --> 00:45:42,320 GPT-2 language models aren't perfect, but they do help scale. 455 00:45:43,200 --> 00:45:52,160 You know , so it's like you generate five of them and you can correct them, make them seem, you know, realistic and not sound terrible. 456 00:45:52,840 --> 00:45:55,740 In the same time you could to do one. 457 00:45:55,740 --> 00:46:01,620 So, you know, in terms of pulling out insights from Windows Defender, I think this is also true. 458 00:46:02,200 --> 00:46:03,060 All right. 459 00:46:03,420 --> 00:46:06,580 So we're getting to... we got to the machine learning bit. 460 00:46:07,360 --> 00:46:12,460 And in this manual, you know, we referenced 380,000 scripts. 461 00:46:12,460 --> 00:46:18,760 There are, I think, 410 in the whole piece. 462 00:46:18,760 --> 00:46:24,080 So in that PowerShell link at the top, you know, it has that many. 463 00:46:24,740 --> 00:46:28,620 We just use... I just chose the biggest folder that had them in there. 464 00:46:30,560 --> 00:46:33,780 And then introduced them to Insight. 465 00:46:35,960 --> 00:46:39,060 So we're going to get into some of the data representation. 466 00:46:39,060 --> 00:46:44,300 I think data representation is probably my favorite part of machine learning. 467 00:46:44,300 --> 00:46:54,260 It's really where you get to shape... kind of shape the output and shape... 468 00:46:54,260 --> 00:47:04,060 not the model, because the model has its own architecture, but you get to encode and embed your domain knowledge when you... 469 00:47:04,060 --> 00:47:12,240 you know, I guess it would be called... it's fine if I'm wrong, but you could call it feature engineering. 470 00:47:13,820 --> 00:47:17,720 And that piece is extremely important. 471 00:47:17,720 --> 00:47:23,580 So , you know, if you want to... 472 00:47:23,580 --> 00:47:37,260 the outputs of your model are... the accuracy of your model is a direct representation, correlation with the quality of your data representation and your feature engineering. 473 00:47:38,320 --> 00:47:40,400 And it's... yeah, it's my favorite part. 474 00:47:42,020 --> 00:47:44,880 Okay, so... 475 00:47:46,940 --> 00:48:05,240 GT went through tokenization earlier today, but we've already kind of played with tokenization, but tokenization is effectively the process of splitting, you know, the words into separate words. 476 00:48:05,240 --> 00:48:08,440 So , you know, each... 477 00:48:08,440 --> 00:48:11,420 I'm losing it. 478 00:48:11,800 --> 00:48:13,240 Not into separate words. 479 00:48:13,240 --> 00:48:16,560 You piece out sentences into a list. 480 00:48:16,560 --> 00:48:20,360 So once we have a tokenizer, rather than... 481 00:48:20,360 --> 00:48:34,860 we could write it ourself, like we did up here, but I would imagine there's probably better developers out there, and I trust them probably more than I trust my own code for some reason. 482 00:48:35,180 --> 00:48:50,820 But if you imagine it as a corpus, so if you imagine this corpus is actually just our big PowerShell list, so each line is a PowerShell script, you know, just a list of it, and we're going to fit on text, and this is just to create an index. 483 00:48:51,180 --> 00:49:01,120 So we're just creating those data structures, and you can see, you know, each word gets its own integer. 484 00:49:01,860 --> 00:49:17,680 And, you know, in terms of sequential numbers, like in a text prediction scenario, like sequences are really nice, because you can say, you know, what number comes after what, and you can go back to your index and look it up. 485 00:49:23,220 --> 00:49:26,980 Yeah, so if we can go, my cat likes mittens. 486 00:49:29,280 --> 00:49:32,820 I don't have a cat, but I assume cats like mittens. 487 00:49:34,380 --> 00:49:36,980 Or most cats are called mittens. 488 00:49:38,740 --> 00:49:42,520 But we're just taking the first index and we're tokenizing it. 489 00:49:49,920 --> 00:49:52,080 Yeah, six small cats. 490 00:49:52,540 --> 00:49:54,300 Yeah, it's a word index. 491 00:49:54,460 --> 00:49:55,900 It's fairly straightforward. 492 00:49:57,460 --> 00:50:01,460 And there are a number of ways to represent text. 493 00:50:01,580 --> 00:50:21,460 You have machine learning models that'll do it, you have frequency models, you have TF-IDF, which is Term Frequency Inverse Document Frequency, which is like a weighted frequency. 494 00:50:21,800 --> 00:50:23,200 What else do you have? 495 00:50:24,260 --> 00:50:25,740 What am I missing? 496 00:50:28,260 --> 00:50:31,600 Obviously, one-hot encoding, that's where we're going to go next. 497 00:50:33,340 --> 00:50:42,240 So one-hot encoding is, basically, it's a vector, which is the length of your vocabulary. 498 00:50:43,200 --> 00:50:49,640 And the presence of a token or a word is denoted by a 1. 499 00:50:49,640 --> 00:50:52,660 And if it doesn't exist in a document, then it's a 0. 500 00:50:53,200 --> 00:50:55,240 And so what you end up getting is... 501 00:50:55,240 --> 00:50:58,280 Let's see how long these are... 502 00:50:58,280 --> 00:50:59,400 Well, it's only 17. 503 00:50:59,400 --> 00:51:06,960 So each vector is going to be 17 integers long. 504 00:51:06,960 --> 00:51:10,660 And the array is going to look like this. 505 00:51:10,660 --> 00:51:13,580 So this is just the first sentence. 506 00:51:13,580 --> 00:51:23,480 But as we go through, you'll see as the words change, you get different... what do you call it? 507 00:51:23,560 --> 00:51:25,920 Not indications, activations? 508 00:51:25,920 --> 00:51:28,460 That's probably incorrect. 509 00:51:28,960 --> 00:51:32,020 You get different indications. 510 00:51:34,880 --> 00:51:38,260 Hopefully that makes a little bit of sense. 511 00:51:39,520 --> 00:51:41,380 And let's see... 512 00:51:41,380 --> 00:51:50,960 The nice part about one-hot encoding is that you do get every token in. 513 00:51:51,880 --> 00:51:57,420 Once they're well represented, you do get some sparsity. 514 00:51:57,420 --> 00:52:06,180 So if you have a really big corpus or vocabulary, you get some sparsity in there. 515 00:52:08,040 --> 00:52:12,060 But it's really nice if you only care about the presence of a word. 516 00:52:12,060 --> 00:52:20,160 It doesn't necessarily keep the semantics or the syntax. 517 00:52:23,060 --> 00:52:26,500 It's not very good for text prediction. 518 00:52:26,500 --> 00:52:29,760 It is good for classification. 519 00:52:30,640 --> 00:52:32,100 Which is kind of what we want to do. 520 00:52:33,120 --> 00:52:44,240 Alright, so now that we have an idea of what tokenization does and the tokenization scheme that we're going to use, we're going to get into my favorite data structure, which is named tuples. 521 00:52:44,980 --> 00:52:52,480 Named tuples are immutable... well, they're tuples, but they're like immutable classes. 522 00:52:52,480 --> 00:53:15,780 So you can kind of create them, you can set your variables to whatever you want, and it's really nice because then you can turn around and reference a tuple, or reference a variable inside of a tuple, by name, which makes your code read a lot cleaner than if you were just going to use a tuple or a list or even a dictionary. 523 00:53:15,780 --> 00:53:20,660 Dictionaries can be... actually, I don't know the speed difference between dictionaries and named tuples. 524 00:53:20,660 --> 00:53:22,120 Does anybody know? 525 00:53:23,780 --> 00:53:24,840 If there's any? 526 00:53:26,660 --> 00:53:27,740 Maybe not. 527 00:53:28,300 --> 00:53:30,140 But this is an example of a named tuple. 528 00:53:31,860 --> 00:53:36,480 It's like when you find something you like and you just use them absolutely everywhere. 529 00:53:36,780 --> 00:53:38,660 This is where I'm at with named tuples. 530 00:53:40,800 --> 00:53:42,460 Just because they're super nice. 531 00:53:44,890 --> 00:53:45,970 Alright. 532 00:53:46,390 --> 00:53:52,250 So this code, we are going to kind of create our training structure. 533 00:53:52,350 --> 00:53:57,430 So this is... you should be familiar with everything in this code block by now. 534 00:53:57,430 --> 00:54:03,370 So we are... we have our filter. 535 00:54:03,550 --> 00:54:06,430 The tokenizer has a filter attached to it. 536 00:54:07,390 --> 00:54:17,990 If you want to use that one, we're going to create a primary list to hold all of our training data, and then we're going to hold a... we're going to create a list that we're going to use for tokenizing. 537 00:54:18,630 --> 00:54:29,830 And this is kind of... eventually, when you start building these small pieces, eventually there's a point where they kind of all come together, and you can transition from processing into learning. 538 00:54:30,110 --> 00:54:33,290 And this script here is where we do that. 539 00:54:33,650 --> 00:54:38,850 So, all of a sudden we can... I shouldn't say script, but... 540 00:54:38,850 --> 00:54:44,370 So we've built all these tiny pieces out, and you can kind of see how they're coming together. 541 00:54:44,710 --> 00:54:50,510 And there's two really important things happening in this little code block. 542 00:54:51,350 --> 00:55:02,750 Obviously the tokenization is happening, and we are collecting all of the... all of the named tuples. 543 00:55:02,750 --> 00:55:03,770 So I know named tuples. 544 00:55:03,770 --> 00:55:07,050 So we're going to go through every malicious script. 545 00:55:07,050 --> 00:55:09,570 We're going to decode it as we did before. 546 00:55:09,570 --> 00:55:11,610 We're going to remove all the punctuation. 547 00:55:11,610 --> 00:55:12,770 We're going to split it. 548 00:55:12,770 --> 00:55:14,170 We're going to unique it. 549 00:55:14,790 --> 00:55:20,050 I did this because I assume it makes tokenization faster, but I don't... 550 00:55:21,010 --> 00:55:22,750 As I said, I don't have any evidence for that. 551 00:55:22,750 --> 00:55:24,530 It just seemed to make sense. 552 00:55:25,990 --> 00:55:27,870 Maybe you guys can try and let me know. 553 00:55:29,350 --> 00:55:43,350 We are going to then rejoin the unique tokens, unique words in a sentence, and we're just going to add them to a named tuple, and then add that named tuple to a list. 554 00:55:43,350 --> 00:55:47,390 So the important piece here is the label. 555 00:55:50,410 --> 00:55:58,410 For malware, the label is a 1, and then for clean, labels are a 0. 556 00:55:58,410 --> 00:56:02,110 So this is where we're kind of creating our training structure. 557 00:56:02,930 --> 00:56:16,770 The other piece you might notice is originally we had 380,000 scripts that we ran this on for this demonstration, this workshop that GitHub didn't really like it. 558 00:56:17,370 --> 00:56:23,610 So we only gave you 3,000, but that's still like a 2-to-1. 559 00:56:23,610 --> 00:56:31,630 But when you're having 380,000 scripts versus almost 1,200 scripts, your data is very unbalanced. 560 00:56:31,630 --> 00:56:47,630 So if you, for example, were to do a similar scheme as we did earlier with just the malicious scripts, we did it for both, what might end up happening is your clean script words will start to... 561 00:56:49,510 --> 00:56:51,770 The word isn't drown out. 562 00:56:54,430 --> 00:56:56,290 What's the word, Eric? 563 00:56:56,390 --> 00:56:57,190 Spin. 564 00:56:57,190 --> 00:56:58,990 What's the technical term? 565 00:57:04,400 --> 00:57:05,980 I'm going to say drown out. 566 00:57:08,220 --> 00:57:10,820 Or average out, whatever it might be. 567 00:57:10,820 --> 00:57:15,720 It's like if your GPA is really bad, eventually you just can't get it up. 568 00:57:18,420 --> 00:57:19,120 Anyway. 569 00:57:19,200 --> 00:57:20,940 Alright, so then at the end of this... 570 00:57:20,940 --> 00:57:33,840 The outcome of this is we're going to get a list that has all of our named tuples that are ready to be fed into a model, and then we're going to have all of our documents that are ready to be tokenized. 571 00:57:33,840 --> 00:57:37,780 So at the end of this, we're just going to build the vocab, and we're going to have everything. 572 00:57:38,780 --> 00:57:40,420 This is a little blurb. 573 00:57:43,060 --> 00:57:46,000 So it takes a little bit to go through all of them. 574 00:57:57,480 --> 00:57:58,940 It's because I opened this. 575 00:58:03,050 --> 00:58:04,570 I don't want to tokenize that. 576 00:58:06,130 --> 00:58:15,210 Also, you guys probably know this, but if you guys use Vim, it creates a swap file. 577 00:58:15,210 --> 00:58:30,430 So I helped debug some issues where they were opening their data files inside of a folder and running Python out of the same folder. 578 00:58:30,430 --> 00:58:36,030 And so their Python was trying to tokenize their text, and they couldn't figure out the error. 579 00:58:36,030 --> 00:58:39,070 And it was just because they were trying to read a swap file. 580 00:58:41,370 --> 00:58:43,950 So now we have our vocab. 581 00:58:50,570 --> 00:58:54,050 And we can kind of see the tokens that came out. 582 00:58:54,050 --> 00:58:58,230 These are the tokens after our filtering. 583 00:58:58,730 --> 00:59:10,810 The closer you get to training, you want to be increasingly happy with what you're seeing in terms of the words or the tokens. 584 00:59:11,230 --> 00:59:15,090 And I think that I'm more happy with this than when we started. 585 00:59:15,710 --> 00:59:16,970 But definitely play by ear. 586 00:59:16,970 --> 00:59:20,930 But it is useful to take a moment and see. 587 00:59:21,010 --> 00:59:22,050 Just take a look. 588 00:59:24,290 --> 00:59:26,110 Remote DLL handle. 589 00:59:26,110 --> 00:59:26,810 Just take a look. 590 00:59:28,050 --> 00:59:29,550 There's quite a lot of them. 591 00:59:31,110 --> 00:59:37,730 So this is something I haven't dealt with, and you can see in the insights.xls. 592 00:59:37,730 --> 00:59:41,910 But if you were going to deal with it, this is probably how you would do it. 593 00:59:42,570 --> 00:59:47,590 So you just want to do a regex for this TVQQAAMA. 594 00:59:47,590 --> 00:59:49,770 Does anybody know what that is? 595 00:59:50,450 --> 00:59:51,590 I bet Rob does. 596 01:00:05,220 --> 01:00:07,340 I see you're binging it. 597 01:00:07,340 --> 01:00:10,740 Yeah, this is embarrassing. 598 01:00:12,480 --> 01:00:14,360 Bing, the best way to Google. 599 01:00:16,360 --> 01:00:20,620 But yeah, you'd want to remove those obviously. 600 01:00:21,560 --> 01:00:23,100 I didn't. 601 01:00:23,820 --> 01:00:27,100 It indicates that it is a PE file. 602 01:00:31,770 --> 01:00:37,510 Compressed or embedded in some other medium. 603 01:00:38,190 --> 01:00:40,790 Okay, so now we're at the point where we are... 604 01:00:41,310 --> 01:00:43,770 Well, I already described this, but... 605 01:00:43,770 --> 01:00:51,750 If you're not familiar with machine learning at all, whatsoever, there's a little video series by... 606 01:00:53,010 --> 01:00:54,070 What's his name? 607 01:00:54,070 --> 01:00:54,510 I don't know. 608 01:00:54,510 --> 01:00:57,270 But his YouTube channel is 3Blue1Brown. 609 01:00:57,270 --> 01:00:59,470 It's just like 4 videos an hour. 610 01:00:59,530 --> 01:01:01,150 It is... 611 01:01:02,490 --> 01:01:03,690 It's really good. 612 01:01:03,690 --> 01:01:08,790 It's going to be way better than I will ever be able to explain machine learning to you. 613 01:01:09,430 --> 01:01:12,950 So I recommend having a look through that. 614 01:01:13,670 --> 01:01:14,630 Watch it a couple times. 615 01:01:14,630 --> 01:01:16,850 And if you're really into math, he has a lot of cool stuff. 616 01:01:18,350 --> 01:01:21,290 Yeah, his animations are really good. 617 01:01:23,290 --> 01:01:26,770 Neural networks, we've kind of all seen this picture. 618 01:01:27,550 --> 01:01:30,150 But our input layers represent our input data. 619 01:01:30,150 --> 01:01:32,610 Or our one-hot encoded text. 620 01:01:32,630 --> 01:01:36,070 Hidden layers represent an activation function. 621 01:01:36,610 --> 01:01:41,170 And the output layer or node is the result of the network. 622 01:01:41,170 --> 01:01:43,630 Or classification, prediction, whatever it might be. 623 01:01:44,910 --> 01:01:47,290 There are a lot of... 624 01:01:47,290 --> 01:01:52,670 Machine learning is more than this little picture that we see everywhere. 625 01:01:54,130 --> 01:02:02,590 And I would say this is like the tiniest little bit of machine learning. 626 01:02:02,590 --> 01:02:10,530 And even inside of this picture, the mechanics that are going on are quite extensive. 627 01:02:11,490 --> 01:02:16,590 And this is just like the most vanilla machine learning implementation. 628 01:02:16,590 --> 01:02:30,550 I think the nice part about Keras and the frameworks is they bring that kind of ability and power to non-mathematicians. 629 01:02:32,090 --> 01:02:35,510 What do you call non-mathematicians, Sven? 630 01:02:37,050 --> 01:02:38,530 I don't. 631 01:02:38,530 --> 01:02:40,730 Is there an industry word for them? 632 01:02:44,710 --> 01:02:45,590 Students? 633 01:02:46,550 --> 01:02:46,990 What ? 634 01:02:47,470 --> 01:02:48,350 Students? 635 01:02:49,450 --> 01:02:50,490 Yeah, something like that. 636 01:02:50,550 --> 01:02:51,170 Normies. 637 01:02:51,370 --> 01:02:52,750 Normies, yeah. 638 01:02:53,270 --> 01:02:57,010 Honestly, we just don't think about non... 639 01:02:57,010 --> 01:02:58,010 Yeah. 640 01:02:58,270 --> 01:03:00,450 I don't want to dig myself into a hole here. 641 01:03:00,530 --> 01:03:02,710 You've got too much math to think about. 642 01:03:02,790 --> 01:03:06,110 As a non-mathematician, I take great offense to this. 643 01:03:07,010 --> 01:03:08,290 Yeah, yeah. 644 01:03:08,290 --> 01:03:09,810 Laypeople is right, yeah. 645 01:03:09,810 --> 01:03:10,830 Rich has got it right. 646 01:03:10,850 --> 01:03:11,730 Laypeople. 647 01:03:11,990 --> 01:03:13,270 Yeah, laypeople. 648 01:03:13,510 --> 01:03:20,830 And if you are... I think the first book I read was Make Your Own Neural Network by Tariq Rashid. 649 01:03:22,370 --> 01:03:25,790 And that was... it was just the most... it was like 120 pages. 650 01:03:25,790 --> 01:03:33,830 It was just the most basic, most straightforward explanation of a neural network. 651 01:03:33,830 --> 01:03:48,750 I think there's a bajillion tutorials out there, and I think they are okay, but they're always so quick to get into a framework without actually explaining what's going on underneath. 652 01:03:50,010 --> 01:03:52,090 And that is definitely a hindrance. 653 01:03:52,090 --> 01:03:57,890 You don't have to be a mathematician to use machine learning, but you should at least spend time learning the basics. 654 01:04:00,890 --> 01:04:01,770 Okay. 655 01:04:03,010 --> 01:04:03,770 So. 656 01:04:04,830 --> 01:04:05,830 Let's see. 657 01:04:05,830 --> 01:04:07,570 We have a little explanation of machine learning. 658 01:04:07,570 --> 01:04:09,290 We have our training set. 659 01:04:09,290 --> 01:04:11,250 We're happy with the tokenization. 660 01:04:12,370 --> 01:04:13,690 To a point. 661 01:04:13,870 --> 01:04:15,830 Happy enough for now, anyway. 662 01:04:16,270 --> 01:04:18,370 You know, eventually... 663 01:04:18,370 --> 01:04:22,690 I think you always want to be moving forward, so you always kind of want to be thinking in pipelines. 664 01:04:22,690 --> 01:04:37,650 So I wouldn't spend too much time necessarily in one area, but when you build it, make it such that it is modular and can be put into a pipeline. 665 01:04:37,970 --> 01:04:38,650 Let's see. 666 01:04:38,650 --> 01:04:43,350 So now we need to tokenize all the documents. 667 01:04:43,350 --> 01:04:44,210 And 668 01:04:48,270 --> 01:04:53,750 this will take a list, 669 01:04:57,130 --> 01:04:59,130 which I think docs is. 670 01:05:01,230 --> 01:05:02,730 We'll find out. 671 01:05:07,320 --> 01:05:08,040 Nice. 672 01:05:08,040 --> 01:05:10,200 And then we can... let's just double check. 673 01:05:16,390 --> 01:05:17,630 Yeah, that's good. 674 01:05:21,470 --> 01:05:22,430 Alright. 675 01:05:22,530 --> 01:05:26,290 And now we're going to create our score array. 676 01:05:26,290 --> 01:05:28,270 So here we have... 677 01:05:28,270 --> 01:05:30,630 So this is a named tuple that we're going to go through. 678 01:05:30,630 --> 01:05:36,750 So we're referencing E, which is a terrible variable name, sorry. 679 01:05:36,890 --> 01:05:40,870 But alt text is the list that's holding all of our named tuples. 680 01:05:41,430 --> 01:05:45,090 And this is called list comprehension. 681 01:05:47,710 --> 01:05:49,850 Another favorite of mine. 682 01:05:50,130 --> 01:05:52,090 So it creates a list. 683 01:05:52,210 --> 01:05:56,710 Put a function inside of square brackets and it will create you a list. 684 01:05:56,710 --> 01:05:58,950 But you can see we're referencing the labels. 685 01:05:58,950 --> 01:06:00,830 So we're just going to create a score matrix. 686 01:06:00,830 --> 01:06:03,130 And actually you can see what that looks like. 687 01:06:06,010 --> 01:06:07,910 But they're just giant arrays. 688 01:06:11,830 --> 01:06:24,630 And the reason they're giant arrays is because mechanics of machine learning is kind of... 689 01:06:24,630 --> 01:06:27,670 Would you say rooted in matrix multiplication? 690 01:06:30,170 --> 01:06:35,830 No, because that ignores all of the decision trees and a bunch of other things. 691 01:06:35,830 --> 01:06:36,490 Yeah. 692 01:06:41,030 --> 01:06:47,270 So when I was talking about this picture being kind of dumb, it's the only picture we ever see. 693 01:06:47,350 --> 01:06:53,050 And it's just one of the smallest pieces. 694 01:06:53,330 --> 01:06:57,270 There's so much more out there that you should look at. 695 01:06:57,270 --> 01:07:00,430 And I probably could have introduced you to. 696 01:07:01,050 --> 01:07:03,170 So now we have our score matrix. 697 01:07:04,410 --> 01:07:06,570 Actually no, I'm looking at this. 698 01:07:17,230 --> 01:07:18,070 Anyway. 699 01:07:20,310 --> 01:07:22,670 So these are all our labels. 700 01:07:23,030 --> 01:07:31,310 So when the network is learning, it's going to calculate a loss. 701 01:07:31,310 --> 01:07:32,710 So it's going to have an input. 702 01:07:33,410 --> 01:07:40,150 And then at the end of that it's going to take whatever the label was and see how close it was to the label. 703 01:07:40,150 --> 01:07:43,970 So a large loss is bad and a small loss is good. 704 01:07:44,750 --> 01:08:00,950 And through gradient descent and back propagation, the network will update the weights such that the next time it sees or there's something labeled like that, it'll hopefully be closer. 705 01:08:01,290 --> 01:08:03,030 And we'll get into that. 706 01:08:06,250 --> 01:08:07,650 I like this. 707 01:08:07,650 --> 01:08:09,170 This is probably one of my favorites. 708 01:08:15,100 --> 01:08:15,760 So TAS vs. 709 01:08:15,760 --> 01:08:17,240 SPACES, NANO vs. 710 01:08:17,580 --> 01:08:20,500 VSCODE, MESSI vs. 711 01:08:20,500 --> 01:08:21,700 that other guy. 712 01:08:21,940 --> 01:08:24,360 Machine learning frameworks are no different. 713 01:08:26,020 --> 01:08:29,000 So do you guys have preferences for machine learning frameworks? 714 01:08:29,840 --> 01:08:36,800 Why do you choose the machine learning framework you do? 715 01:08:39,950 --> 01:08:46,330 I use PyTorch because it tends to look more like real code than TensorFlow. 716 01:08:46,490 --> 01:08:49,870 But Keras is super easy to get up and running. 717 01:08:50,090 --> 01:08:51,430 So it's a good choice. 718 01:08:54,130 --> 01:09:00,190 And then when you do the real web stuff, I reach into a compiled language like Rust or C. 719 01:09:00,970 --> 01:09:02,530 Oh, C, that's brave. 720 01:09:04,470 --> 01:09:06,610 Has anybody used ML.NET? 721 01:09:09,170 --> 01:09:11,510 Did anybody know ML.NET existed? 722 01:09:13,130 --> 01:09:14,090 No. 723 01:09:15,030 --> 01:09:16,510 Depends on what you want to do. 724 01:09:16,510 --> 01:09:19,590 I have a Win32, so DirectX. 725 01:09:19,630 --> 01:09:23,330 There's a Win32 machine learning implementation. 726 01:09:23,330 --> 01:09:29,430 Actually, it's just an interface for TensorFlow on X models. 727 01:09:31,290 --> 01:09:33,070 Yeah, I prefer Keras. 728 01:09:33,070 --> 01:09:34,050 It's simple. 729 01:09:34,170 --> 01:09:41,310 If all the math is the same, then you're really just looking at what you prefer. 730 01:09:44,350 --> 01:09:45,990 Keras is good. 731 01:09:45,990 --> 01:09:49,290 To get off the ground, but it may limit your customization. 732 01:09:51,530 --> 01:09:54,090 And I think that's exactly what an API... 733 01:09:54,090 --> 01:09:58,730 It doesn't limit you, it abstracts complexity. 734 01:09:58,990 --> 01:10:03,830 So I think the reason Keras is so easy to use is because it does a really good job of abstracting complexity. 735 01:10:03,830 --> 01:10:08,670 But if you want that complexity you want to dig in, it's still there for you. 736 01:10:08,670 --> 01:10:11,750 You just have to potentially dig a little deeper. 737 01:10:11,750 --> 01:10:15,910 Versus something like PyTorch, which is... 738 01:10:17,210 --> 01:10:20,610 pretty raw, I would say. 739 01:10:22,310 --> 01:10:24,150 That's probably not true. 740 01:10:24,650 --> 01:10:28,730 Some guy in the back is yelling about MATLAB right now. 741 01:10:29,510 --> 01:10:30,650 Oh, MATLAB. 742 01:10:30,650 --> 01:10:36,570 That's a whole other stack of words you'll have a little bit of PTSD about. 743 01:10:36,650 --> 01:10:39,450 Yeah, don't ever say MATLAB. 744 01:10:40,410 --> 01:10:48,170 Rich is saying Keras is good for 99% of your projects, and then PyTorch for when you're getting freaky. 745 01:10:48,170 --> 01:10:53,050 And I say PyTorch is good for 90% of your projects and Rust for when you're getting freaky. 746 01:10:53,430 --> 01:10:55,690 There's also JAX, all sorts of stuff. 747 01:10:55,690 --> 01:10:56,350 Oh yeah, JAX. 748 01:10:56,350 --> 01:10:57,350 Does anybody use JAX? 749 01:10:57,350 --> 01:10:58,310 Do they like it? 750 01:10:58,310 --> 01:10:59,370 I know Jason. 751 01:11:00,090 --> 01:11:00,930 Is he in here? 752 01:11:03,330 --> 01:11:06,130 Yeah, it's kind of the Wild West, I would say. 753 01:11:07,550 --> 01:11:10,050 There's a bajillion different frameworks. 754 01:11:10,050 --> 01:11:12,350 Everybody uses something different. 755 01:11:15,470 --> 01:11:17,550 I like TensorFlow. 756 01:11:17,550 --> 01:11:18,890 It has TensorFlow Serving. 757 01:11:18,890 --> 01:11:23,650 It seems to have a good ecosystem around it. 758 01:11:24,110 --> 01:11:26,750 But you obviously make trade-offs, right? 759 01:11:26,750 --> 01:11:35,890 But if your verbiage and your fundamentals are good, then I think you could probably use just about any language with enough practice. 760 01:11:37,650 --> 01:11:39,910 We're going to create our model now. 761 01:11:43,850 --> 01:11:50,030 It's the same as the picture effectively, but we're just going to create it in code. 762 01:11:50,030 --> 01:11:53,230 One thing we didn't talk about are activation functions. 763 01:11:55,090 --> 01:11:57,190 Actually, we didn't talk about it a lot. 764 01:12:00,030 --> 01:12:19,770 As your data traverses from weights into hidden layers and hidden nodes, weights, their job is to modulate inputs based on their inputs. 765 01:12:20,030 --> 01:12:23,730 Such that the output is relative. 766 01:12:31,090 --> 01:12:31,790 Sorry. 767 01:12:31,790 --> 01:12:33,730 I just lost him in the chat. 768 01:12:34,630 --> 01:12:35,950 We're just going to use Sigmoid. 769 01:12:35,950 --> 01:12:38,170 I think Sigmoid is super simple. 770 01:12:38,170 --> 01:12:39,590 It's a good place to start. 771 01:12:43,030 --> 01:12:45,630 What are some other favorites? 772 01:12:45,630 --> 01:12:49,770 I know Relu has replaced Sigmoid. 773 01:12:50,510 --> 01:12:52,810 Is there a good reason for this? 774 01:12:52,810 --> 01:12:58,250 Does everybody go, oh, this is better, so we're going to use it all the time now? 775 01:12:59,510 --> 01:13:01,070 The Relu paper 776 01:13:04,370 --> 01:13:08,850 basically said Relu gets better accuracy scores than Sigmoid. 777 01:13:08,850 --> 01:13:11,050 They just compared that across a bunch of things. 778 01:13:11,050 --> 01:13:20,630 For images, Relu tends to have a higher accuracy score than Sigmoid does. 779 01:13:20,630 --> 01:13:26,530 And that's basically why it won, because on images you can easily show that it's better. 780 01:13:26,690 --> 01:13:31,390 I don't know whether it's concretely better in all situations because of that. 781 01:13:32,130 --> 01:13:34,730 You're showing your age with Sigmoid here. 782 01:13:36,350 --> 01:13:42,110 Relu also handles the disappearing differential. 783 01:13:44,050 --> 01:13:45,650 Vanishing gradient. 784 01:13:47,330 --> 01:13:53,630 Where if you go too far into the negatives or too far into the positives, you're never going to crawl yourself back out. 785 01:13:55,990 --> 01:14:00,190 And then there's Leaky Relu that tries to help that even more. 786 01:14:00,710 --> 01:14:07,810 And there's Ellu who tries to say, hey guys, you could be Relu, you could be Leaky Relu, let's just combine the two. 787 01:14:07,810 --> 01:14:12,250 I think it never goes below negative one as a weight. 788 01:14:13,870 --> 01:14:18,770 I think this is actually, I like this discussion. 789 01:14:18,770 --> 01:14:23,250 I don't know how many of you listening are machine learning people to begin with. 790 01:14:25,130 --> 01:14:36,590 And this is why the tutorials are kind of they're nice to get you off the ground, but I think they're limiting in the fact that they're always using kind of the same architectures. 791 01:14:36,610 --> 01:14:42,110 So they're never to say, oh this is good for this and this is good for this, and that's true. 792 01:14:42,330 --> 01:14:45,230 And you might end up there anyway like they are. 793 01:14:45,230 --> 01:14:47,810 Maybe there's just lessons they've learned that you haven't. 794 01:14:48,010 --> 01:14:57,330 But I think it is important to explore different architectures, different losses, just play with numbers. 795 01:14:57,330 --> 01:15:04,690 I think machine learning is ultimately about iteration and experimentation at scale. 796 01:15:05,330 --> 01:15:13,450 And that includes activation functions, that includes output nodes, that includes any lever you can pull. 797 01:15:14,110 --> 01:15:16,810 You should pull it and see what happens. 798 01:15:18,210 --> 01:15:26,550 Also, as a data scientist, you should pull the levers and see what happens. 799 01:15:26,550 --> 01:15:31,890 Because you might find that on security data, sigmoid works better than relu in this case. 800 01:15:31,890 --> 01:15:37,970 And if you never tried sigmoid because you just go with standard relu, you'd never learn that. 801 01:15:40,970 --> 01:15:43,510 Read everything, try everything. 802 01:15:44,270 --> 01:15:47,830 Hang out at AI village. 803 01:15:49,010 --> 01:15:50,670 Super smart people. 804 01:15:50,810 --> 01:15:56,470 Just hang out at journal club and be a little fly on the wall. 805 01:15:56,470 --> 01:15:57,490 That's what I do. 806 01:15:58,250 --> 01:16:00,130 Okay, so we've got our model now. 807 01:16:00,130 --> 01:16:13,170 One thing we need to do is we need to put our documents, our vectors, into our model. 808 01:16:13,410 --> 01:16:18,810 And when I was first starting this was actually one of the harder pieces that I had to fit in my brain. 809 01:16:18,810 --> 01:16:20,470 I think that's true. 810 01:16:20,470 --> 01:16:27,570 It's just the shape of arrays and how they get introduced into models. 811 01:16:28,030 --> 01:16:36,910 Does anyone in the chat want to take a stab at what these three question marks should be? 812 01:16:56,060 --> 01:16:58,180 You can try it. 813 01:16:59,360 --> 01:17:01,740 I'm hung up on the missing parentheses. 814 01:17:04,180 --> 01:17:05,300 Hey, you're right. 815 01:17:09,030 --> 01:17:10,970 Yeah, but Rich has got it right. 816 01:17:10,970 --> 01:17:12,530 The feature size. 817 01:17:12,970 --> 01:17:15,210 Yeah, exactly. 818 01:17:15,250 --> 01:17:15,990 Let's see, what is that? 819 01:17:15,990 --> 01:17:17,430 That would be... 820 01:17:30,560 --> 01:17:32,060 I don't know. 821 01:18:02,140 --> 01:18:07,620 Pretty sure it's your matrix.shape variable. 822 01:18:18,060 --> 01:18:20,220 Text matrix shape. 823 01:18:23,250 --> 01:18:25,730 Man, that is one thing. 824 01:18:25,730 --> 01:18:30,530 What are the things that you guys google constantly? 825 01:18:38,700 --> 01:18:43,940 Sorry, you guys must be probably missing some imports. 826 01:18:45,020 --> 01:18:46,880 I'll push a new version. 827 01:18:46,880 --> 01:18:49,680 Alright, so if you're missing those imports you're going to want to add 828 01:19:19,660 --> 01:19:20,280 . 829 01:19:20,280 --> 01:19:20,940 Nice. 830 01:19:20,980 --> 01:19:23,700 We created our model. 831 01:19:23,700 --> 01:19:25,320 It's super simple. 832 01:19:26,540 --> 01:19:42,100 The text matrix, the input dim that we're doing is an array of let's see, probably like 80 86,000 tokens. 833 01:19:42,100 --> 01:19:44,480 So across this you're going to see 834 01:19:48,050 --> 01:19:51,590 that's going to look obviously like this. 835 01:19:51,590 --> 01:20:00,550 So we just have, I think, 1,200 samples times 80,000 tokens long. 836 01:20:04,260 --> 01:20:06,680 And we're just going to feed it in. 837 01:20:07,540 --> 01:20:09,000 Nice. 838 01:20:09,000 --> 01:20:12,720 And then we're going to do a test train split. 839 01:20:15,960 --> 01:20:21,080 And when you build a model, you obviously have test data and you want to keep some test data out. 840 01:20:21,120 --> 01:20:30,400 But the idea is eventually that your model will be deployed into the real world where it's not going to be trained on, it's not going to be seeing test data necessarily. 841 01:20:30,520 --> 01:20:36,260 So ideally you want to keep some data away or out of your training set. 842 01:20:36,260 --> 01:20:48,620 So when it sees real data or when it sees data it hasn't seen before it can make hopefully an accurate guess. 843 01:20:49,800 --> 01:20:51,440 So splitting them out 844 01:20:54,520 --> 01:20:56,420 for that reason. 845 01:20:56,620 --> 01:21:08,060 I've heard you guys talk about training leaking into your training data during training. 846 01:21:08,060 --> 01:21:09,720 How does that happen? 847 01:21:16,640 --> 01:21:33,960 One of the ways it could happen is you could have duplicate samples that are, normally you just say, pick a random set of indices or pick the last 20% of my indices and that's my test set. 848 01:21:34,000 --> 01:21:38,700 Or you do a cross-validation where you divide it up somehow. 849 01:21:38,900 --> 01:21:55,700 If you had duplicate data, say the last 20% of your data was actually duplicated with the first 20% of your data and you trained on the first four fifths and then you tested on the last one fifth well since it's duplicated it's included in your training set and you do really well. 850 01:21:56,100 --> 01:21:58,460 So you have to make sure that you don't have that sort of issue. 851 01:21:58,460 --> 01:22:00,720 And then there's other little things that you could have. 852 01:22:02,960 --> 01:22:07,300 It's basically a data cleaning issue a lot of the times. 853 01:22:07,300 --> 01:22:10,940 Sometimes it's a weird bug in your code. 854 01:22:11,480 --> 01:22:22,040 Sometimes you can just reverse the model itself and you'll say, oh, show me what this looks like and then it'll just print out an example from the training set. 855 01:22:22,220 --> 01:22:22,940 Nice. 856 01:22:23,760 --> 01:22:27,340 So we have early stopping twice. 857 01:22:27,380 --> 01:22:31,180 Early stopping is super nice. 858 01:22:31,180 --> 01:22:38,060 So if you have a really long running task and your model is not improving, early stopping will just stop your model. 859 01:22:39,280 --> 01:22:40,780 Part of me doesn't like it. 860 01:22:40,780 --> 01:22:43,980 I just feel like it could get better. 861 01:22:44,500 --> 01:22:48,460 But this is a tiny model so we don't really mind. 862 01:22:50,200 --> 01:22:50,880 Callbacks. 863 01:22:50,880 --> 01:22:53,740 So if you want to use TensorBoard, whatever. 864 01:22:53,740 --> 01:22:55,560 Batch size. 865 01:22:55,560 --> 01:23:02,580 This would be the frequency at which updates to the waits will happen. 866 01:23:03,040 --> 01:23:03,920 Epochs. 867 01:23:03,920 --> 01:23:07,060 This is just time that we're going to do. 868 01:23:07,480 --> 01:23:11,120 Sorry, the number of times that we're going to run through. 869 01:23:18,000 --> 01:23:19,780 We can train. 870 01:23:20,840 --> 01:23:23,800 It's obviously seems pretty accurate. 871 01:23:23,800 --> 01:23:29,360 I don't know I haven't actually tried to optimize this at all. 872 01:23:29,960 --> 01:23:34,960 But what do you guys do when a model trains really accurately at first? 873 01:23:35,480 --> 01:23:41,280 Do you think it's beneficial that you would try and overfit a model at first? 874 01:23:41,280 --> 01:23:45,740 Because that would at least indicate it could learn something. 875 01:23:48,300 --> 01:23:51,880 Rich and I both get very paranoid when the thing does too well. 876 01:23:54,280 --> 01:23:59,040 You've got an accuracy of 100% but something's wrong. 877 01:23:59,040 --> 01:24:00,500 Something must be wrong. 878 01:24:00,680 --> 01:24:02,280 Yes, something is wrong. 879 01:24:02,820 --> 01:24:05,880 There could be any number of things. 880 01:24:06,280 --> 01:24:16,280 This one says version 1 and I'm giving you the code so you can go and recreate the model. 881 01:24:16,660 --> 01:24:28,420 Do whatever you need to and I would love to see I'd love to see some blog post or some write up about everything I missed. 882 01:24:29,980 --> 01:24:32,640 So this is a visualization of the training loss. 883 01:24:32,760 --> 01:24:37,140 Obviously with the gradient going down you would like to see this going down. 884 01:24:37,140 --> 01:24:48,720 If this were inverted that would indicate that, well it could indicate a number of things but either it's not learning or it's overfitting. 885 01:24:48,720 --> 01:24:51,820 And it's stopped learning completely. 886 01:24:52,640 --> 01:24:55,280 There are some evaluation metrics. 887 01:24:56,240 --> 01:25:00,060 Obviously it's going to be like, yeah I did really well on this. 888 01:25:01,280 --> 01:25:02,680 As we saw up here. 889 01:25:02,680 --> 01:25:04,680 So that's a little suspect. 890 01:25:04,900 --> 01:25:16,980 But even after you have a model, I like to pull out a couple of the best and worst examples of a category. 891 01:25:16,980 --> 01:25:26,720 So we're just taking the first malicious document because we 892 01:25:29,980 --> 01:25:33,880 put them in a list such that they were malicious and then non-malicious. 893 01:25:33,880 --> 01:25:36,120 So we're taking the first, we're taking the second 894 01:25:39,280 --> 01:25:45,420 malicious document and then we're going to take the last non-malicious and we're just going to try and predict and see what they are. 895 01:25:46,120 --> 01:25:53,500 And yeah, they're a little too accurate for my liking. 896 01:25:53,820 --> 01:25:57,800 But yeah, that's kind of it. 897 01:25:57,860 --> 01:26:00,620 Okay, so this is kind of where we leave you. 898 01:26:00,620 --> 01:26:17,320 So the first Excel file that you're looking at here, when I did it on all 380,000 scripts, it took me well, and this would depend on whatever kind of potato you're running but it took me 17 hours to do. 899 01:26:17,840 --> 01:26:19,800 So we're probably not going to run it here. 900 01:26:19,880 --> 01:26:25,500 You might already be running it but have them reset a few times because you saw your thing froze. 901 01:26:26,080 --> 01:26:41,420 But effectively what we're doing is we're just toggling absolutely every possible combination and then making a base prediction and then a new prediction and then we're keeping a cumulative sum of those. 902 01:26:41,420 --> 01:26:55,620 And what you end up getting is a spread of scores across a number of predictions that will sort your tokens into malicious and non-malicious. 903 01:26:56,200 --> 01:26:59,900 This is the same code from the Proofpoint research. 904 01:26:59,900 --> 01:27:14,880 The Proofpoint research was easier in this regard because they had a wider range of 1 to 999, where these are hard labels and it's a 0 or a 1. 905 01:27:15,560 --> 01:27:34,680 As a first run through looking at the most malicious and the least malicious tokens without any optimization, if it were ever going to work, I would expect to see that at least they're being sorted to some degree. 906 01:27:34,680 --> 01:27:45,980 Because now you can go back and you can start tweaking the model or whatever it might be to really pull out, really hone in on what's accurate. 907 01:27:45,980 --> 01:27:51,620 I think a lot of times for attackers, this first version would be just fine. 908 01:27:53,140 --> 01:27:59,440 But as you go into the future you could even do this. 909 01:27:59,440 --> 01:28:21,820 You could always be collecting data and actually I remember after my first BSides talk about machine learning last year, Rob came up to me and was like, hey, you should have a separate data gathering campaign so you keep your ops and your data collection separate, 910 01:28:21,820 --> 01:28:33,000 but your data collection can support your ops and it doesn't necessarily burn you because collecting data can be noisy. 911 01:28:34,040 --> 01:28:37,640 So it's a bit over time, but do you guys have any questions? 912 01:28:39,960 --> 01:28:40,580 Comments? 913 01:28:40,580 --> 01:28:48,640 What I would love to see is someone to take this Defender model and absolutely crush it. 914 01:28:50,560 --> 01:28:55,240 I didn't... I mean it's a tiny model, I'm not sure Microsoft would care that much. 915 01:28:55,240 --> 01:28:59,280 There's a VBA dataset I have not touched. 916 01:28:59,800 --> 01:29:06,760 So if you guys want to race to whatever, I'd love to see what comes out of it. 917 01:29:07,680 --> 01:29:10,260 I appreciate everybody. 918 01:29:10,260 --> 01:29:11,940 Thanks for coming. 919 01:29:12,740 --> 01:29:27,980 Hit me up in the Slack or not Slack, Discord if you have any questions or you just want to rag on my terrible code that's fine too, but I will end it there. 920 01:29:29,980 --> 01:29:38,060 So I think this is the last stream of the night, so we're closing out the Twitch stream now. 921 01:29:38,400 --> 01:29:40,040 Tomorrow hopefully will go smoother. 922 01:29:40,040 --> 01:29:45,880 We learned some things today, but I'll see you guys all in the morning. 923 01:29:47,000 --> 01:29:48,120 Hopefully. 924 01:29:48,320 --> 01:29:49,520 Hopefully.