Malware's LAST Stand: SELF-DELETION

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
right welcome so you're back for more eh what what are you getting the itch in this video we're going to be taking a look at some of the ways that malware tries to hide itself or make it harder for you a pesky analyst to examine and dissect it we'll be taking a look at how malware can implement anti-debugging or anti-analysis features or even obliterate itself if it detects that you're looking somewhere where it thinks that you shouldn't be it's very cool stuff and you know what this video itself might accidentally follow suit and do a self-deletion cosplay because of the subject matter and how much YouTube despises slippery slope videos like this which is why mandatory disclaimer alert this video is solely meant for educational purposes through covering these techniques we'll uncover how certain malware tricks or bypasses antivirus or analysts more so the analysts we will talk about antivirus and edrs but we're not going to cover how to bypass them in this video shut up just so that you're aware of these inner workings and you can look out for it never use these techniques or anything that you might find on my channel blog posts on the Internet or whatever it for malicious purposes and only test against things that you have explicit written permission for we won't focus too much on bypassing antivirus but we'll definitely talk about it briefly since we're already on the topic of defensive measures you know it's actually a quite common question but I hear this a lot why would you want to start learning malware development isn't that just solely for the criminals I mean what good is malware well as a great philosopher diogenes once said how in the [ __ ] else are you supposed to defend against something if you don't want know what the aforementioned thing is capable of as well as its limitations they're in and most importantly two how it works we learned the stuff not to wreak havoc pun intended not to wreak havoc on the innocent rather to understand what the bad guys are doing so we can make our defensive solutions that much better that's why you'll even see some of these techniques being talked about in depth from actual defensive Solutions like Sentinel one for example not because they're trying to shoot themselves in the foot but because again it's important for you to understand something almost at an intimate level in order to destroy it otherwise how can you possibly defend yourself from it that's not all in terms of audits and engagements of someone's security posture we also develop our own malware to give our clients the best chance of a proper test if you try to load mimikats rubius msf Venom payloads or anything that's heavily signature like that then yeah most likely your clients would detect that but what about something that hasn't been signatured yet what about something custom and unknown that's a huge [ __ ] thing to just leave out of your testing don't you think that's where malware development is really big or most would even say required in red teaming a ton of our offensive tools are heavily cataloged and detected right out of the box which is where the malware development skill set comes into play but I but I digress just know that we're only learning this as ethical hackers and using this maliciously is not allowed and I do not nor would I ever condone such a bone-headed move I mean it use your powers for Good Guys anyways do you hear that Mr rat I'm sadio what's wrong I'm a mental anguish yo why buddy what's going on everyone seems to be so good and so far ahead of the curve meanwhile I'm over here trying to figure out what caused Microsoft to do this wait okay so you're telling me you're completely lost you don't know where to even begin with malware development and most importantly you're a complete beginner I wanted you to say so rat introducing maldev Academy gone Mr rat are the days where you're left behind because Maldive Academy is a brand spanking new module based learning platform founded by two legends in the field Mr docs and null you will be brought up from your current predicament to a god a rat amongst men the learning modules are organized in a linear fashion you'll start off learning the extreme Basics like the basics of c and the windows API to API hooking syscalls anti-detection all the way up to some crazy stuff like Hardware break points ntdll unhooking custom protocol handlers and even more planned for the future you will get access to a virtual machine with all the necessary tools already set up as well as the source code for the modules on there there are constant updates with so much planned for the future a thriving Discord Community filled to the brim with awesome people constantly learning and sharing not to mention all the stuff we get from the co-founders themselves just casually dropping in tidbits there and there and even this dork is here providing challenges to help you build and Implement what you've learned please spider give me back my car keys please I have to pick up my son there's a plan for everyone and just for you wonderful bastards we've gone ahead and given you 10 off if you use code Crow 10 for a limited time as you can see whether you're a complete beginner or a paprika seasoned veteran everyone can gain something from the academy thank you so much to Maldive Academy for graciously sponsoring this video as someone currently going through the modules I wholeheartedly recommend it again make sure to check out the pinned comment below or the first link in the description to get 10 off your order using Code Crow 10 now Mr rat how's about we get back to the video rat not now [ __ ] I'm making my own seat too ah perfect foreign [Music] things first we need to talk about what AVS even are and how they work after that we'll take a quick look at the differences between a typical antivirus solution and an EDR presumably you already know what an antivirus is due to how prevalent they are in pop culture or even better maybe you can even name a couple like this bit oh I mean like this wonderful amazing [ __ ] an antivirus is a defensive solution that is specifically designed to detect and remove malicious software from your device Windows Defender is an example of an antivirus perhaps one of the most famous examples aside from like Norton or some [ __ ] it does a bunch of hashtag quirky little things in an attempt to hashtag protect your ass from perilous heathens we'll cover some of the common ways that it protects you but generally speaking an antivirus uses the following four dimension for dementia for defensive measures an antivirus will read or scan your file and compare it to a database of known signatures to see if what you have there is malicious or not these signatures could be known hashes of some malicious programs that your father gets compared to to see if there's a match which would let the AV know like oh hey this file's malicious wait a minute this file is malicious or it could even be checked against predetermined characteristics or attributes of known malware or rules that your file matches with if you get flagged like that too these characteristics and rules could be something like human readable strings some sequence of bytes the file type itself the size of the file a ton of other metadata and etc etc a couple of you nerds might be thinking why don't we just use the file hashes themselves to check for malware all the time and I really like the way that this blog post from Sentinel one says it best signature bass detection offers a number of advantages over simple file hash matching first by means of a signature that matches commonalities among samples malware analysts can Target whole families of malware rather than just a single sample well signature based detection as prevalent as it is is not without its cons so let's be bullies and point out its insecurities number one signature based detection primarily only works well if you have a you know a signature to compare your bastard file with secondly although it's miles better than just hash comparing it's still pretty easy to evade signature based detection by simply just tweaking your malware a bit yeah back in the day malware was coming out slower than my videos so keeping a database of signatures which contains hashes and rules for these emotions programs was pretty effective for a walk however comma at the rate at which malware comes out nowadays it's simply just not efficient or possible to write effective signatures for all these unique malware samples that come out polymorphic malware really shines here since the whole premise of polymorphic malware is to create malware that's constantly changing its identifiable features in order to evade detection today right now live you could shoot your computer with the Desert Eagle hundreds of meters away yes some new unique malware that no one has ever even heard of will probably end up reaching it first anyways that's how common it is now not to mention that if a signature rule set is public it's just a matter of time before malware developers dance around or adapt to it oh and last but not least the fact that up most attacks nowadays are fireless anyways meaning that instead of dropping your payload onto disk which can very easily be detected you're most likely going to be executing your payload in memory never having a touch disk this crippled signature based detection that relies on file stuff so as you can see with all these points and more that I haven't even covered signature based detection Isn't So based after all it's definitely better than using nothing and an AV providers will use them but long gone are the days where you could just get by someone by just relying on this so This brings us to heuristic detection with signature based detection covered now we can move on to the meat and xylophones of these detection mechanisms to combat the sour taste a signature based detection left in the sarlacc pick that is your mouth a heuristic model is adopted and according to Kaspersky Casper sky according to this this is specifically designed to spot suspicious attributes or characteristics that can be found in unknown new viruses and modified versions of existing threads as well as known malware samples which is exactly what the static signature based detection was lacking so that's cool and all but how does this work well there's two waves underneath the blanket term of heuristic detection there's static heuristic detection and dynamic heuristic detection static heuristics this is a method all about file analysis the file in question is decompiled so that the source code of it can be tested against known viruses in the heuristic database if a portion of this examine code matches the database then it's flagged Dynamic heuristics in this method your file is sandbox and isolated to see see what it does and how it executes without putting the rest of your system devices or networks at risk with this section we're not looking for the file itself explicitly more so what the file does or it doesn't do Etc when it runs the main focus here is behavior when you start out in your ethical hacking Journey you'll no doubt be facing situations where you either have to Simply encode your payload or something to get your malware onto their target and while it's great for getting past those pesky static detections but a lot of people forget is that there's this whole other manner of heuristics that deals with behavior it won't mean a lot for you as a hacker if you can bypass the static detection only for you to end up with some signature and staged payload like a reverse shell from msf Venom or something and not to mention your target connecting back to you at some arbitrary report through TCP all willy-nilly I think you get where I'm getting at again this is very high level but it's necessary for us to cover AVS and their quirks a bit your urge to do some research as well there's a lot of resources on antiviruses and their mannerisms and their quirks and their toxic traits and all that stuff so let's be really clear here I'm not advocating that all of you uninstall your antiviruses and gamer Rebellion because you think I'm denouncing all AVS sure some AVS are better than others but that's not my point no not at all we're allowed to be critical and point out the flaws of the things that are supposed to protect us if it means that we can work towards making it better and certain AVS are pretty decent at protecting most people if I said most people already are pretty cyber hygienic to begin with so sure it's pretty easy to bypass Defender as it stands but I'd much rather have something than be bare and naked on the disgusting moldy sewage warfront that is the publicly facing internet with that being said it's important to note that antivirus isn't without its fault obviously right aside from the heuristics-based evasions for static and dynamic it seems like in the modern day with modern threats AV just might not be enough or it's just a generator of false positives for example one of my bestest friends ever zor or who you should go subscribe to right now once showed a simple program that just prints iterations and I got flagged by a vast but a [ __ ] injector was fine again it's nothing perfect but you can see how AV sometimes just melts when it comes to unknown threats out there and that sucks because Anon threats are primarily the biggest concern for most employees or employers especially when it comes to the big companies and because of that AV can seem rather lackluster one because of all the points that we've mentioned thus far and another because AVS are really meant for a per device model which isn't of much help to organizations with infrastructures comprised of hundreds if not thousands of devices or endpoints and this brings us to edrs [Music] well what's an end point to begin with anyways well you could say that anything connected to the network is an endpoint if you're a company with a lot of laptops smartphones servers remote controlled pip vipers or some [ __ ] those are all endpoints and tldr and EDR is this guy on turbo roid's rage symptoms and all and EDR typically does everything an AV already does except with way more ferocity and way more efficiency whereas antivirus deals with known threats primarily which again can just be bypassed using polymorphic techniques edrs are more focused on detecting unknown suspicious threats as well as known threats they're part of the real-time detection cult and they have a much wider protection surface since the whole point is to provide security teams a centralized area from which they can monitor an attacker's move as if they were shoulder surfing them and most importantly they try to protect a ton of devices some edrs even use AI or machine learning algorithm it looks like that nerdiest programmer you've ever said to learn from their efforts in order to improve and edr's accuracy to limit the number of false positives that's not to say that you won't get false positives of course course you will and some EDR Solutions like Sentinel 1 even claim that Ai and machine learning effectively identifies zero days and so much more and this video isn't intended to be a pseudo defensive Solutions tier list video so you're urged to go out and read more about this on your own but some of the ways that these defensive measures perform their defensive tasks is really really interesting antivirus is something that really complements an EDR as well which is why you might see AVS and edrs used in conjunction for protection with that being said enough theory that this video is already long as it is and we haven't even programmed a single line of code so let's take a look at some of the techniques that we can employ remember security isn't something that can just be outright but there are products yes however security itself is a mindset so with that roughly covered let's figure out how we can mess with some analysts we want to make the lives of analysts as difficult as possible when we make our malware and this brings us to our first anti-analysis technique [Music] surely the majority of you already know what a debugger is right they're just things that let you examine what's going on inside of an application well as an analyst you want to be able to examine malicious software and you're typically going to be doing that through a debugger the problem with that is semi-capable malware will often do its best to make your life as an analyst absolute help malware typically wants to do its best in one hide from you and two if found make examining it as hard as possible for you the worst part is that the most basic implementations of this anti-debugging behavior that malware uses can be done with just a single function however there are more ways to do this definitely speaking of which let's look at this extremely easy implementation a super simple check that we can do to see if we're being debugged is by using the aptly named is debugger present function here's what this might look like because we know that this function will return true if it's being defugged or false if it's not we can set up a check like this and we can see that if the debugger is not present we can run our super dangerous malware right what the [ __ ] are you trying to kick start the apocalypse I get we're making malware and [ __ ] but message box W as your payload isn't that a bit extreme you belligerent oh [ __ ] yeah sorry I'm getting ahead of myself okay nice so we can see that if we just run this program after compiling it normally the hyper malicious code will get executed however if we start this by debugging it and remember you can do this with any debugger you don't have to just use Visual Studio we can see that our malware shoots itself and it won't run so you can see this is very easy and it's just one function and this is cool and all but you should also put yourself in the shoes of the defense think about what an analyst might think if they try to debug your program and see this so another less suspicious thing that you might do is if a debugger is present have the program run something completely harmless like forcing the capacitors of your Target's motherboard to explode okay all right let's continue now this seems very easy and super straightforward and it's because it is however as you might have guessed by now having your malware call a function like is the bugger present inside of it is so [ __ ] suspicious and not even humorous okay this is like a bank robber trying to figure out how many cameras there are in a bank by asking the [ __ ] security guards so how about a more inconspicuous approach we will effectively be doing the same thing except at a lower level such as to not bring a giant gamer room LED spotlight on us another other little alternative for the is debugger function say you wanted to check if a different function a remote one something that you didn't start you can call the check remote debugger present function which does the same exact thing and this is how it might look like and another thing that you could even do is call a lower level ntapi function called anti-query information process to get some information about process including a pointer to our Target process PEB structure but we'll cover the pep very shortly don't worry if this is not confusing right now because we're going to go into depth very shortly here this function and the other functions by extension will make much more sense once we've covered two vital structures related to processes and threads knowing these structures will let us understand how these debug checking functions even work to begin with and you better be excited right now because we are about to start reverse engineering [Music] at this point you should be very familiar with what a process and a thread is if not go watch the first video in our series for malware development we need to talk about what the PEB and the tab are and how some functions like is debugger present or get last error to spoil down to reading values from these structures when a process gets created and the main thread runs and executes and all that jazz there's this very important structure that houses some information about that thread and this structure is called the thread environment block from this structure we can see some of the members in it you can see a lot of this juicy information you remember how in the last video we used the get last era API to tell us the error codes that we can look it up in documentation while that get last error function all it does is read the value from the tab at the last error value member that's all it's doing you can see it right here you can see how some of these windows API functions just end up reading from these very primitive structures they're not primitive in the sense of complexity or the lack thereof trust me these structures can get very very complex but in terms of how early on their present maybe Primal was a better word well this is great but let's dive deeper where exactly is a structure to begin with in memory in Windows there are certain registers that will always hold a reference to the tab and by extension the pep structure which we're going to talk about soon these structures are stored in the fs and GS segment registers the register that's used is dictated by the architecture you're on on 32-bit the tab structure is going to be located in the fs segment register at an offset of 18. on 64-bit it's located in the Gs segment register at an offset of 30. also note that on the 32-bit scenario you might hear of TI being the thread information block and The Tib is also known as the teb these terms are interchangeable they're the same thing if we revisit that get last error function boiled down to see how it's reading from the tab if we look at the NT current tab function itself we can go one step lower and see what this function is doing as you might expect yes it's literally just a pointer from the fs register at the 18 offset which we know is where the tab is if this was on 64-bit that would be a Regis keyword at offset 30. because this is being referenced by the fs register we know that this is for 32-bit another thing you might notice is how Barren the tab structure looks like when you consult the msdn versus when you manually dump it from something like wind debugger you get it from a site like virginius and the first thing we notice is how itsy bitsy this one is here and after noticing that we can see how a lot of these fields are just set to reserved and Microsoft I found does this for a lot of the undocumented stuff see Microsoft doesn't particularly like us doing this stuff and getting our hands dirty with the lower level stuff it doesn't like us poking around when we eventually replace that is being debugged function with our own alternative we'll see that Microsoft doesn't recommend this and they'll tell you not to use it like this well from their side it's pretty easy to see why they do this if firstly the unspoken rule of undocumented internals is that they can and eventually most likely will change without prior warning and some structures gain new fuels with newer version of Windows and a lot of syscall numbers change what versions and we'll do a little spoiler alert and look at the pep structure from the msdn to see what the reserved word actually means and it's just firstly they give this warning the structure might be altered in future versions of Windows and then for all the reserved members they just say it's reserved for internal use by the operating system this this is basically Microsoft's thing and I'm just paraphrasing here hey dumbass we don't want you messing around with this stuff leave it for the goddamn computer to handle this stuff is prone to change without warning as is the case with most of the low-level undocumented stuff out there does this stop us nay not at all in an attempt to consolidate our learning what we're going to do is create a new project in which we create our own rendition of the get last error function that we were using in the previous video when we were making our injector and we're going to do this to understand exactly how that function works and how the tab is tied in with all of this we're at the base of all of this so we can just start off by making a new project but because we're going to be using assembly in this project there's going to be a little bit of setup that we have to do in order to get our project you know capable of using assembly so what we have to do first and foremost is you'll right click on our project go to build dependencies and build customizations in this menu in this box what we're going to do is enable this will let us use assembly in our program and now we're going to have the option to select the Microsoft Macro assembler option for any assembly files that we choose to add into our project speaking of which what we're going to do is make an assembly file that's going to get the tab for us and then read in that last error value should a function fail which we're going to purposely make fail just to prove our point call this last error.asm and before we can actually start incorporating this we have to make sure that it's set properly so right click on this go to properties and if this item type isn't already selected as Microsoft Macro assembler sometimes it might be for me in this case it was already all you'd have to do is go to the drop down menu and find it if you didn't enable the maximum selection in the project build dependencies this option will not show up so make sure that's enabled first before trying this and then select it once that's done you should be able to start now unfortunately this is not going to be an assembly 101 or an introduction to assembly programming with that being said I will try my best to explain what's going on while still you know making everything compact so what we're going to do first is create a code section for our assembly program and then in this code section we're going to start making a procedure which you can just think of as like a little function we're going to start off by creating a procedure that gets the tab and puts it into a register and then after we get that procedure done and made we'll make a new procedure in which we retrieved that last error value member or field from the tab so what we've done here is move the the address of the tab which is located in the Gs register the offset of 30 into Rax so we've effectively just retrieved the tab and somewhere down the line you might see that people don't use any offset when they get the tab and that's perfectly fine too you could do it like that as this article says it's not common to do it but you can do it and for all intents and purposes it should work fine it's just that if you self-reference it or get the actual member of the tab itself then it allows for other things like pointer arithmetic and stuff like that but I just like doing it this way so that's what we're going to do so with this procedure defined now we can start making another procedure that will get that last error value from the tab with this done we can use the end keyword to let it know that we're done with this and let's talk about this procedure so in custom error what we're doing is defining a procedure in which we first zor out or just create a blank slate for this register because this is going to be zorbed by itself it's going to zero it out and then we call this procedure so remember what we're doing here is getting the pet or sorry the tab after we get the tab what we're going to do is move the tab is located at Rex the reason we chose 68 to move into the eax register was because 68 is at the offset at which this last error value member lives and that's what error code that we retrieve and we can see that it's of the Type U long of the Type U long so we're going to do a d word pointer oh so yeah that should be end procedure well now what we can do is make a C file in which we will actually utilize these two procedures and so straight from assembly Isn't that cool and also don't worry too much you can find all of this code that we talked about in this video in the description on my GitHub I'll have it there so don't worry too much all right now let's make our C file okay and I'll also I don't like putting all my includes and everything in my C file so what I'm going to do is also make a header file you don't have to do this you really don't but I just like to do it like this in here I'll include all the libraries that we're going to need since we're doing a bunch of Windows [ __ ] we're gonna have to include the windows header as well as another header that we'll talk about once I include it so the reason that I've included when internal is because without when internal what we'd have to do is supply our own structures for the tab and the PEB and those can get very very tedious but I do urge that you go do that just so you get a better appreciation of these structures and what those structures require next I'm just going to put out some of these macros that I've been using Lifesavers for debugging okay very nice now in order to use the assembly procedures that we've defined in the assembly file we're going to have to use the extern keyboard to let this program know that it's supposed to get it from somewhere else more specifically from here so we want this function to return a point to the tab because that's what we're doing we're getting the tab so I've just set that as a data type and it isn't taking an argument or anything so we're just going to close that off by doing void inside of the parentheses the next one is the custom error foreign so the reason it's a d word is because if we come back to this or any other thing that you dump the tab from it's going to show you this as the type you want right or unsigned long and we already know that the d word is just a fancy way of saying unsigned long so instead of d word what you could do is just put that there as well but I mean it's up to you I'ma just do this with that done let's start off by printing the value of the tab after we get it just to make sure that we actually got the tab after that we will purposely make a function fail and the reason we're doing this is because we want to compare our custom error function what something that we will know that will work like the get last error function so let's do that okay I know this formatting looks insane and crazy from this but it's just the way I like to format my structures or functions and whatever values get stored in them like my handles to my processes and threads and and handles to modules or addresses of functions I like to do this and this should not be uh so we're going to be printing out the value of the tab here let's actually just see if that works real quick okay cool yeah that's really cool so we can see that it's working this is the address of the tab at this point where no strangers to opening handles to processes so that's what we're going to do except in this one we're going to make it purposely fail so for the PID value we're going to set it to something completely wrong foreign so this is not going to be a legitimate process ID and so it's going to fail and we know what error value to expect already because we've talked about this before remember if you don't have no idea what I'm talking about go back to the other videos and watch them we know from our previous time in which we got bad parameter to this function it's going to return the following error code it's going to return the error invalid parameter error code which is just 87 decimal or hex 57 and this is the value that we're going to be looking out for to see if our function Returns the same thing that which is just this why did I have this returning except failure from the get-go what and that should be it so what we're doing is we're going to check to see if it's going to be null which it's going to be we know what's going to be because if this function ever fails what it's going to return is null in the case that it inevitably fails we're going to say okay it failed this is a good thing don't worry and then we're going to print out the value of our custom error function and then the value from a get last error function and if these two match up we'll see that it's matched our function will be working properly otherwise something went wrong and just print out what the value is actually supposed to be so that we can troubleshoot let's run this and see what happens cool okay so yeah it works perfectly we get a value of 57 and it prints out a value of 57 that's working fantastically and this isn't just a fluke say we wanted to get access to a privileged process something like the process of system which is going to be referenced by the process ID of four what we're going to be expecting is an error code of 5 for access denied so let's see if that works it works incredibly there we go and yeah just to prove it five is access to nine so yeah this is working properly amazing stuff another important member that we can see within the tab structure is the PEB structure and this is a very very Infamous and shiny structure for malware developers and analysts alike you'll see this reference a lot as you progress on your journey the process environment block is a structure very similar to the tab it gives you a user mode representation of the current process it has a lot of members and it can let you figure out a lot of cool things we see that on 32-bit systems a pep can be found from the tub at an offset of 30. in other words we can find the pep structure on 32-bit systems in the fs segment register at an offset of 30. what do you think it is for the 64-bit let's give you a second here let's just guess foreign that's right on 64-bit it will be located in the Gs segment register at an offset of 60. now what makes this structure so special well let's look at some case scenarios you want to figure out what command line arguments the process was given this member tells you that you want to figure out what dlls and modules have been loaded by your process well that's no further than this and there's a lot more one member in particular that's going to be at the Vanguard of our purposes is the being to bug the member this member is located in the PEB at the offset of two so you know how I mentioned that there is debugger present just reads a value from the pep structure while I wasn't lying take a look at this we get the pep structure which is just going to be reading in a value from one of those segment registers depending on what architecture on and then it checks that being debugged member from that structure and it's Boolean it's being debugged or it's not and we can see that all along that this function was just reading the value and instead of calling this debugger present we can instead just program something very similar so that way we're not calling the super suspicious API and there are many other ways we can go about this one common way is doing the following in the c or C plus plus file right we just give the PEB here we read the value from the GS register at the 60 offset which by now we know is a pep on 64-bit we Typecast this to a pointer to this pep structure so that our pep will now let us interact with the pep and subsequently its members so let's begin by checking the value of being debugged member and see if we're being debugged or not remember this is exactly what the win API function was doing all along and now as expected if we run it without debugging it will report back to us as such however if we run the debugger option it will tell us that we're being debugged and all without calling that is debugger function now another thing that we could do is just get the pep directly using assembly in our program alright here's where we get started with some direct PEB assembly [ __ ] what we're gonna do is we're going to get the pep straight up from assembly luckily we've already covered how to get our project ready for assembly development so I'm going to skip over that and this is pretty cookie cutter stuff from the tab instead of getting the tab what we're going to do is just get the pep and then get the the being debugged member from that PEB so let's do that okay in our assembly file start working out the code apparently seems to be good we know that this member is just a Char size or bite size so that's we're doing a bite pointer oh we're getting the PEB and then we're checking the dismember and whatever member it is we're gonna do something from here so remember because we're using azim we're gonna have to externally call it okay you should understand why we're pre-facing these two all right let's set up the main function and I'm sure this can be streamlined instead of having to by no means of an expert in assembly programming and we'll also have a payload here and that's stupid right is in here so I can use message box W if I want to okay with that we should be good to go let's start this regularly ah damn okay yeah cool uh we can see that it's not being debugged right that it will execute our payload however if we started with the debugger debugger detected and all without calling the is debugger present we just sort of emulated that function by using Straight Up assembly that's cool awesome and this is where I'm a level with you okay it doesn't really matter if we get the PEB like this instead of using the the bloated win API function because an analyst will see this line and anything that's usually referencing the GS register at 60 offset or the fs at 30 offset a decent analyst will know that the PEB is being referenced or being populated somewhere so again it's just one technique that you can use now the question arises it's very easy for us since we're debugging our own program but how in the hell can we check to see if the being debugged member is enabled for another process that we don't own well let me introduce you to the NT query information function I won't cover this function in depth as this will be your homework from this video although note that you're going to have to touch up on your NT API ntdll understanding you can get information about the process including the PEB of the target process and once you have the pep you should just be able to check the being debugged value to see if the remote process is being debugged or not again that's left as an exercise for you to go and perform now let's discuss how we as analysts and developers might be able to bypass this anti-analysis technique through a means of patching what if we want to be anti anti-debuggers okay what if we want to put on our little blue teaming Lantern rings and for some malware to run while it's being debugged but it's being pesky and it keeps exiting before we can do anything well fear not as you know by now most of these anti-debugging functions or whatever just boil down to the PEB at the offset of two I.E the being debugged member so all these functions are just reading this value to see if it's being set to one so if our malware is doing the same thing we can just patch that member to zero and trick the malware into thinking that it's not being debugged when it actually is I'll do this for a local process but the logic is the same thing for a remote Target process but again I'll leave that for you to go and Tinker with and we're going to be doing this in assembly now the great thing about this assembly patching thing is that 95 of our groundwork is already done for us over here we get the pep the only thing that we have to do in assembly now is check to see whether being debugged is zero or not and if it's not zero we'll jump to a different section in this code which we will program out so firstly over here we're going to test to see if e x is zero or not and if it's not zero we're going to do a jump plot 0 to this patch section that we're going to program up and there we go what we would have done is gotten the pep overwriting what's on there on being divided with a zero effectively patching it so if the malware was to detect if it was being debugged or not if it's checking through being debugged it's not going to show up as that and they're going to bypass the check so let's see how we can program that out here firstly I think we should change the name of this because it's going to get kind of confusing if we're trying to do that so I will just call it ped Patcher or something now what we'll do is the classic little tab member check instead of check debugger remember it's pretty much doing the same exact thing honestly and because we want our malware to run even though we're patching it if for some reason the pet being a bug isn't set to zero after this patch will return exit foreign yeah we'll be able to check the before and after so we'll see that if we start it with a debugger it's going to detect that it's being debugged obviously right but after that it's going to go into our PEB Patcher procedure which is going to test it to see if it's going to be set to zero or not and if it's not set to zero meaning that it is being debugged I'm going to jump to this patch area and Patch it after which it should print out that should rename these now let's see okay so amazingly we started with the debugger we can see that the debugger is currently running see how it's being debugged and then it goes into the patch and it patches it at this point the malware is none the wiser and it runs letting us analyze it now I know with this being something that we program out ourselves a lot of you might be wondering bro why are you programming this out and why are you telling us this useless information I mean you literally have the source code of the malware if you are in control if it runs or not I get what you're saying and the reason I'm teaching you this as useless as it might seem is because even if it's for a remote program something that you do not start or you have no control over the way you're going to be doing this is the exact same way but we're done with this now and we can see that we've just implemented a custom pep Patcher and assembly that's really fun stuff foreign before delving into this Arcane knowledge let's see what happened if we attempt to delete a file while it's opened somewhere or currently in use you've probably run into this before where you're trying to delete something but it's being used somewhere where the [ __ ] is this file being used you think to yourself while cursing out computers in the same breath well yeah you're not able to delete a file if it's open somewhere or in use we can show it off this way or we can even do it with the windows API itself and see what error code we get so what are we doomed if our malware detects that it's being debugged are we condemned are we destined to leave it in the hands of this sorry almost barfed leave it to the hands of the analysts those heathens well of course not otherwise the video would end here we'll look at a really cool technique of anti-analysis self-delution and in order to do this we must really quickly talk about NTFS I know this seems like it's coming totally out of left field but it'll make sense don't worry NTFS or the new technology file system is a file system that Windows OS uses they offers features like file and folder permissions compression encryption hard links symbolic links and transactional operations in NTFS when you make a file it's represented by a record in the master file table or the mft and for each file record the mft allocates a certain amount of space for it but in this allocated space the attributes of the file are found take a look at some of these these are all pretty cool in their own rights but the one we're going to pay special attention to is the data attribute of our file this is the content of our file this is the data of our files and why do I bring this up well NTFS has this really cool thing that I'm ability which is the ability to Define your own alternate data streams meaning you can have hidden information or even an entire hidden executable put away in a new data stream on a seemingly innocent file so let's take a look at this I think that the best way we can figure out what these alternate data streams are are by just going ahead and messing around with them so what we'll do is we'll create a humble text file right nothing to look at but we'll hide some data in it and then we'll discuss some little things about alternate data streams like how we'd go about finding it or get there when the time comes so let's start off by creating a simple I don't know a simple file so when we open up this notepad we've currently opened up the hello.txt file in here if we were just to write our normal message and save it this is our file so we can just do and then wait forgot to so yeah if we were to type this out we'd get our original message but what if we did the same thing except we write to an alternate data stream let's see what that would look like so we start off by putting in a colon and defining the name of the data stream and the reason we do this colon if we take a look at this post from msdn or Microsoft we can see that these streams take on the following form so we have the file name the stream name and the stream type when you do a regular file the stream name is empty now this is just a default Behavior this is just if we were to Define it start off by doing this we don't have to put in the Stream type let's do let me save that and now we can see hey wait we wrote to something where the hell is it if we do a dirk it's not being shown here and how come well the command that we used to list the directory and include the streams the data streams or the alternate tab streams is what the slash are so and if we look at the documentation once again for dur we can see that the slash R is just a way for us to display the alternate data streams of the file in our directory and that's what we're doing here so if we do oh would you look at that there it goes and so and even if we open up a directory to here we don't see anything out of the norm we don't see that alternate data stream and even if we do open this we just get a regular ass message back right are we gonna hidden message we've covered how we can add these and there's no limit to how many we can add but how would we get rid of these alternate data streams or how would we seek them out well there's a couple of ways we can seek them out number one is using this tool by Microsoft called streams which will enumerate these streams for you alternate data streams and a directory or file or like with get item as we can see on Malwarebytes blog over here okay item or search for all this stuff the way that we can remove these is first of all by deleting the original file that will get rid of the streams or if we move the file with all these streams attached to it onto a file system that's not of NTFS because remember alternate data streams like this are only a feature of NTFS so we could do is I just open up my USB here and I'm pretty sure this is yeah so it's X fat so basically if we try to move this file onto here it's going to strip that alternate data stream from it and let's try that real quick so you move the file but if I pop it up here there's no more alternate data stream no more if we were to do this if we were to move this through like actually dragging and dropping it would actually get a little message so let's try that as well you see we get this little pop-up warning that says are you sure you want to copy this file without its properties its properties that it's referring to here are the alternate data streams and we can say yeah and once we do goodbye alternate data streams now hi program this out I'm going to do this in a manner which combines everything that we've learned so far for checking to see if we're being debugged we'll be using our own custom assembly Pub detector to get the last error value in case something goes wrong I'll use our custom get last error function which just reads the last error value from the tab you see how everything comes so nicely together alright it's finally time for us to figure out how we can make this malware that will end up deleting itself we talked a bit about data streams right and and that's fine the way that we're gonna make our program delete itself is by renaming the default data stream to another name and then deleting that newly renamed data stream which will make our program disappear well be erased even while we're running it which on other normal circumstances that wouldn't be possible as we've seen so there are a lot of moving Parts we've only covered one tiny aspect of importance like the data streams but there's a lot more to this so just bear with me while I program this out and I'll just do what I always do which is program something out and explain what it is why it's necessary okay it gets trapped in guys it's going to be a long one now there are a lot of names I can choose for this project most of them will probably get me banned off of this site it's just a joke I'm just gonna say something simple you know let's just call it Operation game end now like I said we're going to be doing this in such a manner in which we consolidate all of the topics covered in this video by including everything for error handling we're going to do a custom function that we made in assembly and then for checking if we're being debugged or not we're going to do the same thing so let's just get our project ready for maximum development or ASM development before we start doing all that jazz all right so in our last error function we've already covered this I'm just going to copy and paste this cool and for our debugger same thing except we're going to get rid of the patching line just because you know we're just checking to see if we're being debugged or not right now so we have our two custom assembly functions now we can just now what we could do is well first I'm gonna put on my macros and all that stuff okay so the first thing that we want to do is Define out a new name for our data stream right okay remember how the syntax of streams are and then we're gonna or externally Define our functions what I'm going to do next is make the debug checking thing into its own function so we can just call it within Main all right very standard here uh we're just checking to see if we're being debugged if we're being debugged this will return true as bull or it will return false so let's just do a main setup let's just see what that returns let's get started with debugging why did it fail for God's sake foreign [Music] so now if we run this we'll be able to see that it's working properly without debugging it's nothing debugged if it's not being debugged we'll have it execute our payload or start debugging there we go in the case that our program finds out it's being debugged we're gonna have the self-delete function run over here or I guess we don't even really need to return anything here because we're going to have our function deal with that let's start working on our self-delete function well let's just start initializing some stuff okay well we'll relax and don't freak out we're gonna talk about these These are necessary for us to Define because we're going to be using them so we'll start off doing this one by one so firstly in this function we're going to be getting a handle to our file and because of that we're gonna have to initialize a handle to the file next we're just going to Typecast our stream up here into a wide chart just so that we can use it with our functions later what we're going to do as well is take the path size of our file and we're talking about two because we want to get the path size for y Char okay now we're going to start talking about some of these we can see that there's a pointer to a file rename info structure that we've initialized to node P file rename info thing here's what it looks like and then you can probably see why we're using this here as you can see this contains the target name to which the source file should be renamed so because we're going to be using this function we're going to supply it with the file rename infrastructure and over here you can see that there's file name length and file name itself and that's what we're going to use to change the name of the file but if we we scroll down here for this file name member or field we can see that it could be one of the following an absolute path like a relative path to the process's current directory or the new name of an NTFS file stream starting with colon do you see what we're about to do here that's why we include this nextly it's not even a word we have this file disposition info now what the hell is file disposition info well also before getting to that we have this rename size and this is just the size of this structure with the size of our stream data stream name and it's just it's just for some space stuff after and what is file disposition info we can see that it's only got this in here a Bool delete file so like what is this in the msdn this structure it just indicates whether file should be deleted or not use only when we use this function we've seen this for the second time now this is going to be our main operator and we can see that if we set this to True file disposition info will Mark the file for deletion when we close the handle to it so firstly what we'll do is we'll allocate a buffer for some structures just for the file rename info just to make sure everything's working there's no memory related stuff and I'll use these little comment separators I guess just to make it easier for us because this is going to be a pretty lengthy program so over here we can see that we're making a call to Heap alloc the first parameter is just a handle to the Heap from which the memory will be allocated you can get it from Heap crate or get process Heap function which is what we've been doing these are the allocation options the second parameter and if we do heaps your memory it basically allocates the memory but then initializes it to zero and then the last parameter is just how many bytes we'll also do some error checking because I want to get to use our function and it's also good just in case something goes wrong right so I'll also be littering this with a bunch of like debug prints just because I want this to be as clear as possible if you get annoyed at how much I'm putting this out there just it's for the sake of clarity in a normal program like this I wouldn't I don't think I would have this many but yeah allocate some memory for the file rename info structure which is just the combination of file rename info and the new stream so it's a little bit more than this file next up we'll just also clean up some structures you know just to get it primed and ready for us to use all right so I'm saying we're going to clean up some structures and then we're going to zero out the memory and we're gonna zero out the file disposition info structure as well and with that done we're ready to use all this stuff so the first thing I want to do is set this member this Boolean member from the file disposition infrastructure to just have it set to true so that way we can indicate that the file is going to be deleted or should be deleted okay so let's do that first and foremost so yeah set the file for deletion there we go and I'm sorry that I'm not coding this through and through I'm gonna try to explain a line for linuses if I do that this video will literally get 14 World Records straight away for length of media also it's a bit in the ass to edit so okay next up what we're gonna do is in the file rename info over here we're going to initialize those two members that we had to do which if you remember there was two things in here of notice or of note which is the file name length and the file name itself and these are the two next things that we're gonna set let's get on that right so you can see first things first we set the length of this member the file name length to the size of our new stream which at this point you know is just over here right there we go after that what we're going to do is take that new stream and then right over the file name so basically we're overwriting the file name with our data stream and once we've done that we can print out the value of this member to see what it's going to be okay now after this what we're going to do is get the current file name an RTL memory copy is just a very glorified version of mem copy you're basically just copying some memory from your destination putting it into your Source but you also have to Define how big it is that's basically what we're doing right we're trying to take our new stream member and overwrite or copy it over to this member for this address I hope that's making sense next up we have to get the current file name and this is just for us later down the line you know we're working with wide charts and this is just an easy way to do that it gets a fully qualified path for the file it contains the specified module so if the first parameter if we set it to null it just gets the path of the executable file of the current process which is what we wanted to do and then the second parameter is where we store that path which is going to be in our path size kind of weird naming but I guess so as you can see we're getting the fully qualified path of the executable and we're putting it into here and if that fails we get to use our lovely custom error function again and print out the value now this is where it starts getting juicy so so what's going to happen here is we're going to get a handle to this file after we get a handle to that file or this file what we're going to do is use this function on it to set file information by handle function it sets the file information for specified file so we can see the first parameter is the handle to the file the second one is a file information class this is a type of information that we want to be changing or setting for our file and then a bunch of other stuff which we'll talk let's we can see for the second parameter so enumeration class for this file info by handle stuff there's so many of these there's a file name info file this position info remember this is just setting it for deletion and then there's also the file rename info where the hell did it go look at file rename info what we're going to be doing when we call this function and we set the file rename info for this file info by handle class we're just going to be setting the file's name just so we get a handle to the file we call set file information by handle on it and it's going to be using the file rename info structure and we're going to be supplying our file name length and our file name and our file name is just an alternate data stream now after that's done what we do is we close the handle after this function we do that because that's how we really confirm our changes with this because this function will set information for the file or make a change for it and then depending on what we do sometimes it works when we close the handle to it to really crystallize that change so after we close the handle this what we're going to do is open another handle to it and once we do that the change is going to be made and we're going to be opening a handle to this file that's got an alternate data stream in it now let's get started on that so we start by getting a handle to the file right we're gonna this is where we start the actual renaming process we're using Create file the first parameter is the file name in which we specify our path size which by now would have been populated by get module file name remember it's going to store the full path of it into path size and we're using that here when you're doing a delete file thing like this the minimum amount of access rights that you need is delete and synchronize and so that's what we're supplying here so you need this delete next up and let's take a look at this function in msdn now we're going to be supplying it with file share read this is just setting the sharing mode of the file it just tells you what you're allowed to access or not so if we do something like file share read which is what we did we're allowed to open operations on the file or request read access otherwise no process can open the file or device if it requests re-access which is what we have here the next parameter is just this attribute stuff okay so this parameter over here where it says open existing so it's kind of fun to learn about this is just what happens in the event that a file doesn't exist or does already exist what do you want this function to do we're only going to open the file if it exists so it says open existing opens a file or device only if it exists so that's what we're going to be using here and the rest two are just no flags and attributes and this template file which we don't need remember this is create file is one of the only like win API functions that I've seen so far that actually return invalid handle value so that's why we're having it set to this and then we fancy print out our little handle to the file and then we say I guess this should be called rename is probably better this is where I was talking about it so we use this function right we're going to set the information on this file we get the handle to the file we give it and then we use the file rename info this is the guy with the file name right the file name and the file name size and that's what we're setting here so after this we would have effectively given our file the data stream and set that for it and to actually push out the changes in quote unquote refresh this file so that it actually you know does this change we close the handle to it because this function you set a change to it and it'll change on exit pretty much or change on handle closing and so that's what we do so after we close the handle on it it would have had this new alternate data stream foreign for deletion here but this over here this brand new section this is where we actually what the hell is this now this is the point where we actually delete the file so what's happening here is because we're gonna get a handle to the file again because at this point we've already discussed it the changes are going to be set after the handle is closed so that it refreshes it and now when we open a handle to it again we have a handle to the file with the alternate data stream on it there we go and then what we're going to do is use this function once again except instead of doing a rename info what we're doing is the file disposition info and if we remember file disposition info all it does is set a file or Mark a file for deletion and we've already set that to True right since we've already set that to True what's going to happen now is it's going to run that and if it works it's going to set the file for deletion like actually set it because we didn't do that here all we did was we set this member of the structure to true but over here is where we're actually pushing out that change or trying to make that change and then once that's done remember because it's like set file information by handle the changes kind of work when you exit out we're going to close the handle to it and by then once we close this handle the file should have been deleted and we also just do some regular cleanup frame the allocated heat buffer and all that stuff I'm closing the handles of the file and with that done this this is it this is all our program does I know it's a bit crazy looking it's probably because of the bunch of debug Prints but take a second or two to re-watch it if you don't understand this it's not that crazy once you understand what's going on and it really clears up once you go into depth with these functions and and you really understand alternative Industries and stuff what we can do now with this function created is okay a debugger is not present execute our payload but if a debugger is present we'll self-delete so let's do that then this will already exit for us so we don't need to do that and now if we run this this oh my God I'm so excited for this okay so if we run this normally it's going to run our malware because we're not debugging it look at that right executes our payload exits properly and now if we run this with the debugger let's see what kind of output we get [Music] okay all right so yeah holy [ __ ] this looks so cool so we start off like in the pub we checked the debugger presence we see that we are being debugged and because we're being debugged we're gonna stop DeLay So what happens in the self-delay thing right we allocate the Heap for the file name info we clean up the structures after we're done that we set the file for deletion we don't push that change but we just set that file disposition info Boolean remember to True after that's done we change the name the file name length I guess oh come on I printed that out wrong let me just okay yeah not file name file name sorry about that so ignore it I'll just run that again set the file name of this structure to our alternate data stream and then we overwrote this original one with our new stream over here right and it prints out weirdly but you get the gist of it and then we get the current file name this is just going to be populated over here we get the file name which we put into this variable here a size badly named I know but whatever and then we start the renaming process right first we get a handle through the file this is the first handle we got on the file and then we start renaming it what happens here is we use set file information by handle with the handle class and this is just where we push out the name and length of our data stream right and after that's done we close out the handle to push a change and that's done we get a handle to it again except this time we use the file disposition info instead which will mark it for deletion because we already set the value for that to true and once that's done all we have to do is close the handle once again to push out the change and it should have deleted the file let's see this in action well I mean we've seen a run but let's actually see this in action alright so if we run this normally right cool cool cool awesome there's our executable now let's run this with the debugger say we are an analyst right now I wanted to see this okay I want to debug this let's see what it does it just deletes itself it's gone it's gone let's do that again I'm sorry oh it's the least too fast before you can okay it deletes too fast before we can get put in the chart here just put that there just so we get a little buffer time all right look at that right it's right there and now it's like oh press enter to exit it's gone there one more time there it is there it is press enter to exit right guys that's it that's all there is to this it's so cool this is such incredible stuff like all the stuff will be done to get to this point we've looked into the inner workings of the PEB and the tub and then NTFS and data streams and all that combined into this nice you know the couple of anti-debugging techniques that we literally just talked about well that's not even close to how many you can find covered in the course modules on Maldive Academy so once again make sure to check out the first link in the description or the pinned comment below to get 10 off your order and start becoming an anti-debugging wizard right now as well as leveling up your skills as a professional malware developer a huge thank you once again to Maldive Academy for sponsoring this video and this brings us to the end of the video thank you guys so much for watching I know that the head Cannon was supposed to be maldef part 3 but I wanted to get this video out before that one as a little treat to you all and don't worry Maldive part 3 shall be out eventually but for now I'm going back into hibernation see ya [Music]
Info
Channel: crow
Views: 53,098
Rating: undefined out of 5
Keywords: crow, hacking, maldev, winapi, c++, programming, malware development, malware, virus, tutorial, how to, pentesting, penetration testing, kali, windows, win32 api, security, hack, hacked, developing malware, making malware, making viruses, pentester, red teaming, red team, offsec, oscp, certification, research, developing, hacker, active directory, blue team, ad hacking, ad, binexp, binary exploitation, compsci, computer science, computer, pc, linux, os, operating system, 2023, fun, live, memes, trending, evasion
Id: lcJdlzKS_5o
Channel Id: undefined
Length: 61min 57sec (3717 seconds)
Published: Sun Jul 30 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.