Analyzing Ransomware - Reversing a CryptoAPI Decrypter

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello everyone my name is Michael and today we're gonna take a look at something ransomware related now today I have a sample that is actually a decrypter from the criminals unfortunately this victim paid for you know paid for decryption and received an executable from them and there's a couple reasons we would want to take a look at the Decrypter the most common maybe we don't have access to the original malware perhaps maybe it's a new sample that no one has found a sample for yet so the Decrypter can still give us some information on how the operations work maybe what what cryptographic functions it's using what file format so it still can be very useful to reverse sometimes I also will reverse it in order to make my own decryptor because the criminals may have a bug in their Decrypter or it's not very user friendly or I might want to add some extra features to help the victim out so in this case let's go ahead and run the decrypt or now we'll see this is a Hermes 2.1 Decrypter software and they give us a few options here for decrypting a single file or starting a full automatic decryption I'm assuming number two is he going to just enumerate over all the drives and look for all files and try to decrypt everything which could be very slow for this example so I'm gonna go ahead and hit one and it says you need to write the full address of the file this can be very not user friendly especially you know you might not want to just gung-ho go and decrypt the whole system you might want to decrypt a folder first to test so already this would give me some incentive to maybe write eight my own decryptor so I have some sample files here that are anonymous data from that same victim I can actually drag that into the console here luckily I don't have to type it out so we'll hit enter we'll say ok that was pretty quick choose next file we'll see ok it looks like it's been decrypted at least it doesn't have the extension let's take a look at that in the hex editor and yeah this looks like ASCII data with you know it's a CSV so I'd expect there to be commas and this is a newline character so I guess that worked if we compare it to this is just a copy of it we'll see you know this was very obviously encrypted lots of garbage there so let's go ahead and close those files now let's take a look at this in PE studio once again just for a quick static analysis will kind of go over just a couple points on this one so we'll see signatures visual C++ it's an executable console app it's 32 bit entropy is low so it's probably not packed so this means we get to go into a disassembler to is to analyze it I'll take a quick look at the libraries just so you can see advanced windows 32 base api the ADV api 32 dll this dll actually contains all the crypto API functions if we go to imports we can confirm that we can sort by name let's take a look so we have crypt acquire context we have cryptic crypt crypt destroyed key crypt import key so that can already tell us that's going to use the crypto API it usually can be pretty simple to kind of see what is going on when it's using this API luckily so we'll go ahead and I'm gonna go ahead and use a disassembler called Ida there is a freeware version that's the one I use since I don't work for a corporation once again disclaimer I'm not a professional malware analyst just a guy that likes to try to reverse ransomware on my own so we're gonna go ahead and open this up it can definitely be very can be very intimidating for a beginner I'm still learning how to use this tool definitely so apologies if I offend anyone trying to that'll kind of stutter through this so when we first opened up Ida it's going to take us to the entry point this is where the you know where the malware just gonna start running when as soon as you execute it this is what happens usually there's not too much useful stuff here in my experience at least unless it's like pact or something you'll see this is where you'd maybe try to unpack it we'll take a look down here I've already kind of gone through this executable on my own to try speed up where I'm going I did identify the most of what's going on here is in this one function called that I called main function the rest of this is probably like just set up the actual maybe the actual main function will see there's a get command line that's maybe if there was parameters passed we have maybe look into what they do with those parameters but when you first launch this executable I don't think it I don't think it took anything or it didn't ask for us to rather so we're going to take a look at this main function and this is where I found the the strings that we saw when we launched it will see Hermes 2.1 decrypt our software and we'll see they're just using the console command color to change it background black foreground a is green the way that I originally located this is the strings window once again just like PE studio we can look at the strings and I just found you know some of the interesting strings we wanted to see decrypt start group door software if I double click on that it'll take me into the actual like hex of it kind of if I press X on my keyboard that takes us to xrefs cross-references and we'll see where that was actually referenced and it takes us back where we were a quick newbie tip for for Ida I think by default for some reason the strings window is not normally there you can get that by going to view open subviews and then strings is right here there's also a couple of other ones here and some of these I closed cuz I don't really use them so we'll take a look here here's all those strings this is probably like a printf or something just based on how it's used so we'll see I've renamed this variable input number because I at least I think that's where your input gets saved to so we'll see all right so first off we compare it to one and the first option was decrypt a single file and if that if jay-z is a jump condition basically compare if one equals one it'll compare we'll set a zero flag so just like in programming where you use the compare like STR compare or something like that if two inputs are exactly the same the output of the function will be 0 otherwise it'll be a one or negative one depending on which one is different or greater than or something so in this case 0 if it was successful so if our input is one we're gonna fought we're gonna go this path which we can get a little hint as to that if I double click on it it takes us down to there we're gonna look at that later if we press number two we okay so if it's not one will go to the red one which comes to here compares it to the number two if that doesn't work we compare it to number three so we can actually see the pass for two and three come down here as well so they have like a hidden hidden menu option number three does the same thing as two and then we'll see if we didn't enter a one two or three incorrect try one more time I think it it just basically like loops back up we'll see this thick line kind of loops back up here after it does some comparing some other mess so we'll take a look down here as to where our when we hit one or two or apparently three will come down to this block of code here now it looks like get module file name okay so this this variable filename we're gonna open a file desired access this is like open access create a file create file doesn't always create a file depending on what Flags you pass it it actually is just used for opening a file in general so we'll see the file name I had traced this back earlier and a debugger and I found that this is actually the executable path so this is actually the file name of our executable so if I ran it from my desktop it would have this path slash decryptor dot exe so apparently we're gonna open our own executable here we're gonna get the file size while we got the handle we're gonna set a file pointer so we're not reading from the beginning of the file we're gonna go somewhere else in the file now this is a very large what looks like a very large hexadecimal number for example if I if I hit the H key on my keyboard I can turn that from hex to decimal now that looks like a very big number for set file pointer you know not not many files are gonna be 4.2 billion bytes so this is actually a negative number in hexadecimal form the way that works is because it's a it's a third you treat it as a signed 32-bit integer and this actually wraps around to the negative part so if we actually copy this take it into a calculator take it to hex mode I'm in I'm in the programmer mode the way I went to this is view programmer and input hexadecimal let's go to Q word is a 64-bit as you see here 64-bit number if we go to D word that's a 32-bit number so a signed integer will go to decimal and we'll see it's a negative 100 or 1172 you'll see I've added a comment of that since so I already calculated that before so we actually since we're passing a negative to set file pointer what that does is it is a it does relative to the end of the file so we're gonna read basically we're gonna point to one thousand one hundred and seventy two bytes from the end of the file and then if we go to read file we're gonna read that same same amount of bytes so we're basically reading the last that many bytes from the file it's going to go into this buffer as we see here the arguments for read file the first is handled to the file which was just whoops yes I here which was just our handle that we got from create file and our buffer is being used in this register which is actually loaded as we see right above this variable so this is a local variable buffer that we're going to use for whatever rereading from our executable here so we'll take a look down here and we're this cryptic wire context is going to be kind of our setup this is where we we acquired in the context in order to do anything with the crypto API so we'll see here this is pretty standard for all kind of standard for how this function is used they kind of go overkill with it here but typically you will see it called at least twice with different flags I've kind of filled in what these flags are we have the the flags and the provider type will see the provider type each time is provider RSA AES so that already can give us a clue that we're probably going to be using RSA and/or AES now the way that I found what these flag values are is luckily Microsoft's pretty public on their function you know because obviously developers have to be able to use these functions so we'll see here sorry if we go back to here okay so require we'll see these are the flag values now unfortunately they don't just show the hex value here too they just show this is a constant that you'd use now I cross-reference this with the source code so I just I just looked up the wind crypt file this is this is the header file that you would include as a developer to use these functions we'll see here I just searched for that constant and it has value F zero we'll see if I take a look back here our flag is actually hexadecimal 10 which is delete key set and we can come back to here and if we were really interested in a wall of text here we can see you deletes a container so this very first call they're just deleting whatever context there is that's kind of an odd move but okay and then the same thing with this 24 I just looked up I just looked up in here what those values are in the header file so it is typical that they'll call it typically one of these blocks would be what I'd call normal you'll call it the first time to try to get a new key set and if that fails you'll probably call it a second time to try it with different flags because most of the time if the first one fails it's probably like a permissions thing so you can still get in a context using different flags but they call it a whole bunch of times here so okay so then we'll see once again we had that buffer the same variable buffer that we read once again this the same value 1172 bytes from the end of our own file and we're going to import that as a so that can already tell me that the whatever this 11 or 100 1172 bytes at the end of our executable is a crypto API blob because the key the import key function relies on a certain format called the blob format we take a look here at our parameters for import key we have provider that's just our cryptic wire context okay so the PB data is a byte array that contains a public key blob header followed by the encrypted key big hint right there so we have an encrypted key possibly key blob is created by export key blah blah this is probably what how it was used in the ransomware and then next parameter is just how long of this buffer is and then this is a way you can actually import a key and decrypt it using another key which will actually probably see that later we have some flags we'll see here here they they're not using a public key because this spoilers is the public key that we're importing the flag one is actually cryptex portable I know that one that just means that later on if we wanted to we can export this key they don't so they really didn't have to set one here so we're gonna import this key and apparently if that fails then we're gonna ask the user for another file or something alright so if it succeeds then we go to some extra oh ok I think I see what's going on here I mean I've realized this before the EBX register here I think is our input yeah that's our input number still all the way down here so this is where they determine whether you had selected 1 or 2 or 3 okay so one is going take us over here and we're gonna get logical drives and we're gonna get drive type I'm not sure what five is and we're gonna probably start enumerated over those drives okay so if we had actually selected two or was it or was it two okay one is per file okay okay I'm getting these backwards my apologies all right so if it is one okay so if we're doing a single file we're gonna come over here okay so here's our prompt where it said please write the full address for example C slash whatever choose zero for exit okay so this is probably like a print function okay so let's follow this down it's actually this line we're gonna come all the way down here yeah that's actually gonna be a loop condition whoops this is the annoyance when it's a really big function they don't break it up okay so where was that I want to see where that okay string was because that probably tells us when the inker the decryption was finished let's see actually taking a look in the strings here we can see the way they rename the file after it's done is they just use a rename command at the command line it should be pretty close here choose next file okay that's probably when it's done what I did was a hit X for a cross references go to here okay choose next file okay somewhere nestled in here they do call another function okay there's our okay there we go not sure why they didn't show up in the strings very easily but alright so we'll see here we're gonna go to the decrypt function now we're gonna pass in a couple paren here this is this is a function they wrote so it doesn't always show me all the parameters but it looks like it did kind of rename a couple things for me there's existing file name so that's the we're gonna pass it the file we're gonna pass it to providers here now that's probably because they're using one provider for AES and another provider for RSA I'm not quite sure I'd have to look at a little more deeply but I renamed this function decrypt file if it seems where they're actually decrypting one file now what kind of snoop around here so all right so we have create file once again this is a thing this is open access we could look at documentation for create file and see what these desired accesses are but pretty sure it means open and all right so if it fails close the handle it succeeds go over here get the file size and once again we have a big old mess of functions all in one function all right so here we go setting a file pointer reading hex 30 to just 50 bytes okay so it's it's gonna do some stuff to the file here's asleep for some reason okay so I'm not part too interested in what's going on there what I'm looking for is gonna be where they're using another key and I've marked it here for myself since this is a tangled mess here okay so we'll see all right so this is our function where we have the key or we have the file rather and we're gonna set a pointer once again we're gonna have a negative hex number so this is actually negative 16 okay so we're reading part of the file okay here's where I'm looking for all right so we're gonna read apparently we're gonna read 268 bytes from in the file which if I recall here should be okay this is probably a conditional to see if the file is like tool are too small and it changes how much of the file it's reading so here we're reading 268 bytes keep losing focus there and we're actually importing a key here so that I've already identified this is actually our step where we're importing the AES key now there's something interesting you'll see here this H pub key parameter is actually filled with this pub key variable now that is actually our RSA key so the way this works if we go back to our cross reference up here where we import the RSA key this provider in EDX is our pH prov that's you that's just kind of standard what you name the variable so if we take a look back here at import this is where we can see if we pass it a public key this is a handle to a cryptographic key that decrypts the data so what we're importing here in pb data is an encrypted blob and we're going to as we import it it's going to be decrypted using whatever key we defined in here so what we have here is an aes key that's being decrypted by RSA this is very very standard for not just ransomware but a lot of cryptographic usages so we'll see here if it's encrypted with a session key parameter can't contains handle that key okay you can read more on this documentation then they have some examples at the bottom or you can just google some samples of this so that basically tells us exactly how they are storing keys it seems like there's one key per file and there's like a master RSA key that unlocks all the individual keys let's take a jump back to our AES key all right so we're importing that key and we're gonna have it in this register which is this key so this pH key is what we're gonna use to decrypt a file where am I on the graph okay I'm way over here now if we take a look back now we're gonna set the file pointer back to zero we're gonna go back to the beginning of the file and it looks like some virtual a lock we're probably gonna like build a buffer just start reading and I'm going the wrong way on the tree okay set file pointer read okay so here we read the file destroy a key so when we're done with the key we destroy it it's just standard practice to make sure you don't have a memory leak okay so here's the decrypt so we are moving this pH key and we're going to use that in the edx register which is our H key this is what we're passing to crypt decrypt and this is the bread-and-butter function I want to call it so we're going to use that key and we're gonna decrypt what's in this register which I'm assuming is what we're messing with yeah we're okay yes I is the buffer that we read from so from this information we can already tell exactly how this this decrypter works so at this point it's just a lot of boilerplate code to kind of recreate this but I can actually you know you can read through the documentation here to see exactly how these functions are used let me gonna go ahead and take a look at this decryptor in a hex editor let's so we already knew at the end of the file there's something interesting I'll scroll through here and there we are okay our essay to this is something that I would you know recognized as a a key so we have zero seven oh two zero seven is the blob type I'll kind of pull up the documentation for the blob type so I believe I believe this is a simple blob crypto API base provider key blobs okay here we go so this documentation once again in on Microsoft's website will tell you exactly how to read this blob so I'm gonna go ahead and this is just some type of delimiter it looks like let's go ahead and copy that all let's just make a new yes I know it's going to change the file size close that one so let's go ahead and save this this is our RSA key binary okay so let's take a quick look at how this blob is formatted so we have a public key structure then we have I'm sorry that's the public key blob I know for a fact this is a private key just even just based on the way we're using it you have to have the private key to decrypt what the public key has encrypted that's basically how a symmetric encryption works so we have a private keyblob so we actually have the public key structure which is the same as the public key and then we have all this all this stuff about we have actually this is the the public key format then we have the modulus to prime the prime the exponents that coefficient private exponents all that stuff this is all basically how RSA works so we can see that's why this blob is so big there's a bunch of very large numbers that are basically represented in hexadecimal in this so what we want to take a look at is this public key structure which it seems to be what it starts out with indicates a keys blob type all right so here's the beginning here so we have a B type as we see it contains what type of blob it is which tells us basically how to interpret the rest of it so we have a plaintext blob key blob we can see private key blob this is used for public private key pair a.k.a asymmetric encryption pretty much you'll always see this was our RSA we also have public key this is probably going to be just the public key that would be what's in the malware itself and then we have simple blob which is usually what you see an aes key in so we took a look back at our key here we have 7 which is the private key blob so that tells us what type of key it is version blah should always be number 2 and it is ok next part is very important this is the algorithm that is used and if we take a back look back at our structure here I'll guy D actually that sorry there's there's a reserved byte of 0 let's take a look here so all right yeah must be set to 0 all right so our key algorithm is gonna be what type of key this is what algorithm it represents so if we take a look at this al guy D it's kind of like a enumerable they have a bunch of constants here now because of I believe it's the Indian Asst of how this is represented the bytes will be kind of flipped from what you see here so this is actually this is our our D word that represents algorithms so a four I would just look for a four and you'll see it's it's kind of flipped just based on how its represented these two bytes you flip it over here so we'll see RSA key X okay it's public exchange algorithm so we can tell this is a private RSA key at that point further on if we go back to our private key structure once again that was just the beginning of it we have back down to the private key let's see so we'll see here part of that structure once again RSA pub key magic must be this value as we'll see here so basically a public key has this ASCII of RSA one and the private key should say there it is magic must be this 32 blahblah hexadecimal of ASCII of RSA - so once again that's how we know this is a RSA - or it's a private key because of that RSA - you can further then if you want to you know read through the structure here and how many bytes or what and pull out the exponents and and all that fun stuff this is why I wrote a program that does this once again once when I release this I'll make a video on it but if we go to our key pull this all out pop it in here we'll see once again it confirms it's a private key blob an RSA key further on because of that structure you can actually tell how you know what size RSA it is so this is actually our our key with you all the exponents and all that and we'll see it's an RSA 2048 key so right here we can tell we can't break that realistically so let's take a look the other thing was that they had they had a key blob in the encrypted file so if we take a look at one of our encrypted files they were reading at the end of the file once again we have a Hermes file marker here that's one way of identifying this ransomware other than the extension dot HRM we'll see here all right yep this looks like a crypto blob and once again the one is a simple blob to the version these two bytes are reserved this 1066 we can actually look that up once again in the algorithms here can actually flip it 6610 and we'll see okay this is an aes 256 key and furthermore if you look further down in the documentation of the encrypted blob I believe because it should be a simple blob sometimes I find the docs a little hard to go through sometimes okay so this is where we're at we're at that public key structure algorithm encrypted key okay actually I'm sorry what we what we looked at once again this beginning part here with the AES saying that's an AES key is the public key structure now there's a second algorithm ID here and as we'll see here it is once again our a for number which matches up here the zero a for a zero zero zero so what that means is this key is encrypted with RSA so we have an aes key encrypted with RSA and once again I can take a look at that in my blob analyzer paste that here we confirm it's a simple simple blob aes-256 encrypted by RSA now the length in this context is how long the encrypted key is and we'll see this is this is what's encrypted this is what's actually encrypted by RSA now I have a extra little function we can kind of without having to write code I can kind of test that I have you know this inner workings in my head correct so if we take this encrypted blob that was at the end of the encrypted file and let's grab our RSA key I can go to decrypt blob paste that in here and here's our plaintext blob key this is actually the key that was at that final crypt import this is what key is basically going to be used to actually decrypt the file so we'll see it's plain that now it's a plaintext es 256 no encryption and we'll see the length of the key this is actually the plaintext key that we can actually use directly it's 32 bytes which matches up a AES 256 always uses 32 byte keys aka 256 bits so we can actually take this blob let's go ahead and open up that encrypted file so over here we have the encrypted file let's go ahead and paste that blob in here tell it that the blob we'll see we automatically selected it's an AES key and we need to account for padding is not gonna be correct in our case let's just decrypt a couple blocks here so we'll see this actually looks like our decrypted data let's do a little more let's do 256 bytes and let's go ahead and save that decrypted CSV let's take a look at that in the hex editor and it looks like we've decrypted it on our own so once again like I said you know I would maybe like make a decryptor that's a little more friendly it lets you you know has a graphical you you use your interface lets you select a folder to test with or something but in this little you know this little analysis here we can see exactly how the Decrypter works and that gives us more information thank you for watching and let me know in the comments if you have any any tips for me in Ida since like I said I'm a very beginner so I think I can make more beginner relatable videos with some interesting samples here tune in next time for some more interesting ransomware analysis thank you
Info
Channel: Michael Gillespie
Views: 3,156
Rating: 4.9436622 out of 5
Keywords: ransomware, malware analysis, cryptoapi
Id: LpBlAr2jPM8
Channel Id: undefined
Length: 38min 24sec (2304 seconds)
Published: Sat Nov 24 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.