 Welcome to Melva Analysis for Hedgehogs. How do you unpack a file that's packed with a packer, whose packer stuff is a huge obfuscated autoid script? Let's explore this today. I received this sample from someone else. They requested me to showcase this, so that's what we're going to do now. So this is the sample that I received. And the first thing we see, it has a tag for FormBook Melva Family, which is an info sealer. So that's interesting. Let's look at the YARA results here. And here is one indicator that this is autoid. Now, the person who gave me this sample specifically requested that we look at the autoid script and how to unpack this file. So this might give us a first hint that this is an autoid executable. And what we also see here is other Melva families in FormBook. So this mentions Agent Tesla version 1 and 2. And here is some more like capability YARA rules, so some anti-debugging mechanisms that they find here, as well that it's generally packed. Browser references and confidential data store references, messaging clients. This is not unexpected from an information sealer. So this kind of fits into the whole idea that this might be an information sealer. And now we have a MelDoc signature. That's a little bit weird what it has to do with a MelDoc. But when you look into these signatures, you can search for the rule name, find the repo. These are pretty generic. They don't match only on documents. This doesn't make sense at all. I mean, no matter where you take this impage from, if it's from the autoid executable, you will match all autoid executables. And if it's on the .NET sample, you match all .NET samples or all .NET applications because they all have the same imports. So we have Agent Tesla again. So this is overwhelmingly hinting to Agent Tesla, whereas the submitter says it's FormBook. So we should probably take a look at this and find ourselves what kind of method this is. So this is the autoid sample. I already named that autoid packed because the person who gave it to me said they want to specifically know how to unpack this autoid executable and how to approach autoid in general. But usually you just put the sample into Detectin' Easy if you don't know what kind of sample it is. And then you will see here, okay, it's autoid. And let's look at the signature and something else you can see here in the signature is it checks for resource named script. And that's also how you can recognize that it's an autoid, compiled autoid script. So you use something like Resource Hacker. Put the file in there. And in the RC data you will find the script resource, which should start with AU3 and that's like the magic for autoid. Let's try to unpack it. So let's open Command Prompt here. And what you need is autoid wrapper. So this is how you would install it. I already have it here. It requires an output dir. So let's put dot there. It's complaining about the magic mismatch, but it's still extracting a script and two files with weird names. So here they are. And now just like when you get a new sample, you know nothing about it. Basically handle these samples the same. You do triage on them and see what you find there. The first thing you would probably do is look at the script because that seems to be the most interesting part here. But the script is pretty large. And it ended all the similar. So when you scroll through this, the code somewhat looks similarly structured. So let's look at those samples here also before we dive deeper into the script. So that looks interesting because here what you may notice is a repeating pattern. So this is encrypted and I guess we will have to find the portion where it's being decrypted. And the other file, similar thing, but here is where I just cheated. I'm going to show you two ways to deal with this sample. The first way I'm going to show you is more when you have a lot of experience, you will recognize this as what it is. And that is very, very typical for a PE file. Why? Because here you have kind of patterns. Like this is a repeating pattern right here. So repeating pattern may be some X or key, in this case that has a size of 10. So that's a 10 or A in hex. So this might be the key here, just from checking where it's repeated. And the pattern repeats because there are lots of areas in PE files that have zeros. So this is the actual plain text key you see here. And then above you see something that resembles like the DOS stop. MZ and here is probably the DOS stop message. And in between you have some values that are set in the header. So somewhere here it's probably where the PE header starts. So this is the way you would approach this as a... If you have some experience and recognize that this is just X or encrypted. I mean you can't be entirely sure about the key here. You could use some brute forcing tools, there are some. But in this case you can also just test it and see if it works. This has 10 as a size. So let's count it 10 until we know where this string actually starts. So here it starts with R, H, T, E. So that's basically where I would put the starting point here. So let's use this as a key. You can use Cybershare for anything else. I'm going to use binary refinery. So that was obviously not correct because it doesn't look like the DOS stop. So something's still wrong but we got the start of the key correct. So probably above we have this pattern. So there's probably one of the things that are a little bit different here. Let's look at this. I added one character here that the length was not correct. Let's look at this and we are done. So if you want to dump it, so when you analyze this then you will know it says like a malware or it says like an assisting file, like what's an assisting file. Sometimes you have like DRLs that perform injection or stuff like that. In this case it's a payload. Now this feels a lot like cheating probably. And of course I want to do what the person told me they want to know. So they want to know how to approach the script and there are good reasons why you may still want to analyze this autoid script. Now if unpacking is your only goal like of course this is the fastest way but if your goal is maybe writing a blogger ticker then you may want to write about the picker tool or let's say you want to know how to create a good signature for the antivirus product and the antivirus product is able to see processes, process memory then you may want to check how the picker works just so you can create an antivirus signature on some parts of the picker that do not change too soon. Anyhow there are always some good reasons why you still want to analyze this script. And of course next time this encryption may not be as easy to crack. So let's see how we could find out what kind of encryption is being used if you do not immediately see it from the file. So the question is now how do you approach huge scripts and how do you find the actually interesting code. Now the first thing I recommend is maybe get a little bit familiar with the language in this case autoid and then you should put this file into an automatic sandbox system. Put it there, see how it behaves, try to find out how the unpacking may work, how it may take place. So this file will be doing certain actions and certain things that have to be reflected in the code. Your goal would be to find any functions in autoid that correspond to what this script has to do when it does its unpacking part. Now you can already assume ok it could be something that's going to use file read mechanisms for these files so these are things you can already infer and that's actually also what I did. I just used this knowledge that this is going to touch or grab those files because it's the encrypted payload which I already knew by then but you can also just think ok these files are there for a certain purpose so let's just search for the file names here and the other thing you can do because this file is not extremely big if you're really desperate and you have no idea how to proceed just scroll through. This is not too big to do this, it takes a few minutes. Scroll through and at some point you may see something that pops out which could also have to do with experience, I don't know but in the beginning in the very first years a lot of scrolling was done from my part. Aimless scrolling and seeing if I find anything interesting but here I really recommend look for the file name and there you go. So here you know ok here it's going to touch those files and the very first thing that I see here is this code looks different to the parts that were before that and here is one function being called with a weird string and a number that is always 8 so this looks like a string decryption function and the function is here so this is something we should start with so we are going to create a string decryption in order to understand this code and without knowing those strings you also see ok it's creating some struct it's calling with DLL call some functions so this is going to be the interesting part so one of the ways you can approach this is by replicating replicating this function in a python script so let's do this. I'm going to copy this to second script here because I want to rename these variable names here we have here something that is being returned as a result so this is the result then this will iterate with this variable towards the string length of this argument so that is the index this has to be the encrypted string and we also know that it's being used in that way so this is a string and this is a number here and then this is the weird number here which is actually just 8 like in all of these cases this number was 8 you can now simply retype the very same algorithm in python even if it was a little bit more complicated you could just go line by line and try to translate the very same algorithm the biggest difficulty is probably here in translating unfamiliar things like if you're not familiar with order but simply Google those functions Google order it, string it, see what it does Google order it, ask and then understand what this is doing and similarly you need to understand like basic syntax this is the same as string concatenation here so the same in python would be plus equals you can understand the language that you're reading in order to reverse engineer properly so here we have a for loop and we are going to use this index and it starts from 1 and it goes up to the length of the string now what this line does it checks if the index is even or odd if it's even it's going to subtract this number and if it's odd it's going to add this number so we simply do the same but this simply takes the one character that is at the specified index because strings are treated as lists by python this part is the same as just accessing the list at position index now this is not going to work because of type system and that is what these two are doing so firstly it's going to change whatever is in this string whatever character is in this string into a number and in python this is odd and it is doing that so it can subtract this number but afterwards we actually want to have a string so afterwards it's going to change the result to a string conveniently this function is named the same in python as in order it for this one we can simply copy paste this and say plus and then we return the result string now all we got to do is test this so let's put this to the test by the way you see this execute function right here this is also something you could have searched for like and you know it's going to be executing something you can search for execute it simply choose one of the longer ones and see what happens I need to get out of the restricted mode here and now I can run it as a python file please and nothing will happen because I didn't print the result and an exception occurred what is this string index out of range here of course because of this one so this is not working and the reason is an off by one error so the array here it starts at zero whereas in order it I guess it starts at one so it is like those subtle differences that can make you crazy let's remove this part most of the time when you got problems with encryption or decryption it's because of off by one errors so the thing you do is you try those first and then see if it fixes the issue and in this case indeed we need to use one index less so that we start at zero when you look here it will start at one and this will decrypt the whole string so that means that these strings start at index one so this is like some of the oddities of between languages that some have like different indexing mechanisms and since we start at minus one we need to add here another index to the final length otherwise we will miss the very last character and now we're going to try again and what we get here is kernel32 as a decrypted string so this works and now we can decrypt all of these strings however you do not actually want to do this by hand I mean in this case it would work it's not that much if you check count how many times this is being used it's 21 times so you could do it by hand it's still boring so you don't do that if you can avoid it and because next time you get a similar sample you don't want to do this all again manually so this will be the next part just find a way to replace this and for that we are going to open this script in Python and find all of the function calls here actually not this one because here we do not see the contents easily but here these function calls and then we're going to replace them with the decrypted string so let's try to create a regex so that we can get all of these functions here I'm going to copy this out go to regex 101 and we want Python and now we try to build this regex so we want this part and the string is actually what we want to extract because the number 8 is always the same so we put a capture group here and the string will be this and the string ends at the quotes and now you got the problem that this is a greedy match so you see it's going to choose the biggest string that satisfies this and since we do not want it to be greedy we put the question mark here to choose the shortest match instead and afterwards we have some more stuff followed by the close and that also shouldn't be greedy now you can do some more things like put a question mark here just in case there's no space somewhere in the file that looks like a regular expression we can use so we need to import re this is our regex put our file here let's copy the path from here we want to read this let's actually put the path here so this is the script path so we read in this file and we need to find all matches for this regex so the way we can do this is say re compile this regex and now we say find all of the matches on our data and what we're going to find is the stuff in the capture group so we can just decrypt this and just print decrypt this and print it let's see if this works that's because I want to read it like that and here we get the decoded strings so this worked very well the only string that didn't really seem to work is this one but you can look into this later so in general it seems to work and now instead of just printing the decoded results we actually want to replace things in there so let's add another capture group because we need the whole string too now if you print the matched we'll see that it looks a little bit different now let's look, it's starting so this is a tuple now consisting of the first capture group and the second capture group so this is the string and this is the thing we want to replace this with so that's what we're going to do so decrypted string this match one and the original string match zero just some debugging print and then we call replace for original and replace it with the decrypted string but this part must be put into the quotes again original string and this is what we're going to use to write then we need to write the data basically so let's say dump data and in creating clean this up a little bit creating a function to dump the file output file where we want to dump it too is the script path plus something like decrypted or decoded, deopfuscated I'm calling it deopfus I think that's better and that should be it let's see if it works so these are the instances and what they were replaced with and we did some mistake here I think type error must be string not bytes of course WB but also the decrypted string yeah I forgot to decrypt of course decrypt now it should work so here we see all the replacements and now we got a look at the deopfuscated script here it is put this to order it find our location and it works so here you can now see or understand more closely what this code actually does it's going to put those files into temp folder it's reading this MBPERS file here here's some decoding happening with something that's from this file so this file you can decode it with our decryption function so everything that's inside this one and the other one that's the one where the payload is inside so this is going to be handled here or maybe not it's not going to be handled here I guess it's just putting the file into the temp folder and then it's doing something with this file so it's decoding it here we have the file here it takes the length of it and it calls virtual-alloc for this size and for this data it's going to execute this at asset 0 and then it creates some struct and then it's going to execute call window procedure at this offset it seems would probably be shellcode so this is the file you would have to look at to find out how this file is encrypted I guess because nothing much else is happening here this stuff here looks just like the garbage that's in front so this is just junk I don't think there's anything else happening in this file in this order script that is of interest so we have to look at decoding this we already know how to decode it it's like the very same decode function that we just created so you know what we have to do we have to extend our script to decode the shellcode right so now we have the shellcode path so all I did was replicates the part of the auto script that does the shellcode decryption so let's also do this and we run this and it says data written to mb-paras decrypt it let's take a look at the file here and you can see we still need to fully decode this so we have here hex strings but this looks like code it actually looks like code this part I'm not sure where this comes from we can probably just remove it let's do that and I'm now just save the changes I'm now opening this file in the notepad++ editor we can do a plug-in function with the hex to ascii converter do that save it and take a look at it again so this is going to be our code but it looks good you see the season here so this is probably code so I open this up as x86 because the code before that was also it's a 32-bit file so that's the reason so I'm guessing that this shell code is also 32-bit so one thing we can already look at is this here are some interesting strings you check this press R so this translates to pk32dll you can find more like these here so this is probably preparing everything to have some APIs available you may remember we had the script calling a certain offset which is here just translate this to hex so that's this and hex and let's go there let's find this address file of that doesn't matter here and that's where we arrive at so let's make this a function make function at this address default and here we are so this is copying some string and do you remember what this string is so this was our XOR key that you have seen earlier so we know this is the XOR key right now let's follow up where this key is being used and it's here so here we have the XOR key supplied to function and there are some other variables here inside I mean here's also one interesting part that I want to look at tree let's see so this is getting the encrypted payload that's the the file of the encrypted payload and this function doing something with the XOR key and if you go inside this function then you can see ah okay this is performing the XOR decryption here now the last part or mystery we need to solve is what kind of payload is this actually that's the payload right here and you will notice it's a .NET file so you can put it in the NSPY and look at it it's a little bit off-puscated but I have a whole lot of matter Java signatures and they identified this file as origin logger for me so origin logger is in agent Tesla variant and that is just this origin logger I'm just going to show you quickly how you get to the configurations I have a config extractor for this file on my github that you can use so if you also want to extract the config you can navigate to my github repository stropiGal Hedgehog tools and there you see the agent Tesla folder yeah I recommend just download the whole repository with the contents here like that with download zip then you extract this and I already did this here so I'm going to open PowerShell to run this file so when we extract this and you get an error message that looks like this system not supported and a temp was made to load an assembly from a network location of course the assembly to a sandbox and so on so this problem is because here is the zone identifier on the end of the year because we just just downloaded this so .NET doesn't trust this file as you downloaded this from your browser to fix this you can go to the properties and click on unblock and say okay and now it should work in general and the script is a little bit a little bit crude I don't know why but I expect here a folder name so this is kind of weird but I'm going to fix this I promise so let's just put our payload in a folder so we can specify a folder name which would be F now and here we get the config and the config is also saved in agent-tester-config so you can access it again and it's gonna save all of the configs or append configs when you execute the file so you find it on the bottom of this configuration list so that's our assemble config you see is an FTP host user password and so on so all of the data that you usually want to know when you analyze a sample so this is agent-tester-origin-logger it's not formbook but are some learnings from this session today well first they would say decryption in the original language is way easier so today we translated order it into Python and I had some troubles because of some certain differences between the languages namely the indexing of arrays or lists so sometimes these things take way longer than they should and if you simply copy and paste this into an order-decryption function then it might be easier secondly use your triage information to find the relevant code so you have a huge string then take the information that you already have of the sample or maybe gather some more you can put it into automatic sandbox systems executed, monitor it see what it does and then from there you have some data that you can use to find the relevant code in this case it was the filename that allowed us to find the code and certainly Jarrarolds are not really to be trusted at least not fully to be trusted so especially if these are just certain public Jarrarolds and you don't know exactly how they are intended to be used and on which constraints they were built you should always verify the data that you get from this is true if you have any samples that you find interesting that you think might be suitable for me to teach something, you can send them to me but no promises that I will create a video out of them because it takes a ton of time to do that so yeah, feel free and please if you have any questions put them below, I always put the sample into the description below with a link to something like Melsher or Melwe Baza so you can also download them if you want to learn Melwe analysis from the ground up then check the link in the description below there is a link to my Udemy course for beginners it contains 11 hours of video content and the link is a coupon link that's a little bit cheaper for you than buying it from Udemy itself so check it out and maybe I see you there