 Welcome to map analysis for head shocks for for today. I will try to replicate something I already didn't either pro that is writing a script to decrypt or decode the strings of Nighthawk And first off you can obtain the sample from map a bazaar. You just need to Login register for free and then you can get the sample if you search for Nighthawk With a tag. I will also put a link into the description below as usual what is nighthawk actually it's a paid penetration Testing framework and it seems that some threat actors have recently started to use it. So for this sample Let's start guide. I'm using the default options here and also I highly recommend that you do not do this when you The first time you obtain a sample Before you actually open up this assembly to compile or anything else Check the sample first and the PE viewer check it Check the strings open it and hex editor roughly look at the structure and the strings you see there Now one of the things that caught my eye where the strings in this sample and you open the strings we have a window defined strings and Now these does this does not show all of the strings in the file These are only the defined strings. So I Even though you can see strings in guide or Ida I Still recommend that you just run the strings exe from this internets or strings command from Linux first You can also see here it is the Analyzing and while it is analyzing more strings are being added to this defined strings list So here we see them this is something That immediately looks to me like there has been some either some X or or Substitution cipher being used Because you have repeating patterns in the code Commonly strings that are referenced by malware. They will have certain patterns like they might often end with Certain file endings dot exe They might reference Paths so you have often the same start of the path like see windows and What you see here is Patterns with you know, here's the same start of it and then There's There's a slightly different ending. So these are probably stings that start with the same substring if they are translated also, it seems to me here that the Slashes are maybe not substituted Because slashes are very common in paths and they are roughly in our location. You would expect them path and translations so the thing That surprised me about Guidera scripting it was way easier to write a script for the string translation here And make it put it into a state that I can work with the reason is One of the reasons is because of the strings representation here If you change this strings representation let's say it will shown like this in the disassembler and Also in the decompiler Okay, it's decompiling takes a while was probably a big function. So Yeah, anyways, you will see that yeah, now it's called foobar in here and It's like like this is the actual value of the string, but the binary is not changed The content the string variable is still this as you can verify it here it's just the representation and the code it changes and there's to my knowledge nothing like this in Ida and This is very very useful. So you can basically just Translate the strings and if you don't like it you can delete it again Clear translation value and now it's the previous value. So if you do any mistakes, no problem Now how does This work now we need to know how the string decryption works I The first thing I do is where is this string called if you click on it You get to the location where it's written to and you see the cross references and you can click on them so you find the location in the code and Here we see it now We will assume of course That this string It's still decompiling. So code is changing on the fly that this string must be passed into a Decryption function or some decryption function must be like right below that We see here it is here The reference to it and here's the function call. So that's the first function call we should check But what we see here is a typical For C++ string Construction function, so this will basically create an STD string type Out of the let's say C string type Why do I know this because I've seen this before? so We will have to add unfortunately Guidera does not have the type for this string Why did it hop back? Let's go Here we are it does not have the type the string type an STD string type for C++ So we will have to add it manually You do this here in the data type manager So you right-click on your project file and you say new Union we will have to Do an union for this first and then use this as an inner structure so the first one is the STD String union and we will say Data type char with the name Pointer to the string. So the way this works is if it's a long string we will have in this union a pointer to char array or to the actual string and If it's a short string We will just have an Array of characters directly in in the string struct. So Let's put it this way short string string Might be easier. So and this is also efficiently packed. So We save this type and Now we create the actual struct because it has some more information about the string and that is not a struct and we call it STD string without the U and the first data type is our STD string Union And we just call it Start because it's like the start of the struct and then We need the size Which is of the type size T Call it size and there's also a maximum size mentioned. That's the cap. So Packet one All right, and now This is our string Save it and we can now edit the function signature so that this is an actual Returning our STD string This is a new string now param one and you check this below It's being returned. That's a return value. So this is the return value and this is put inside and this is The the actual size of the string. So we have here a char array with the size and what we get back This is why you so let's edit this and This is the Outstring char and string and Size T and that's the size of the string and should be correct So I know the code is better readable But actually this is not the The dictionary function that we wanted to look at so we are going back Where it had been called you see here the string assignment And just below that, you know, this is the output string. Yeah So that's the actual and corrupted String and Can we put correct the type here? That looks better The encrypted string is passed to this function below. So this is the next candidate for being a decryption function And this looks let's looks better We see here There are two big strings being referenced This one you also see in the code. There is a search for an index The second one you do not see directly, but It's it's used here in this area That's because the decompiler is a little bit odd here with the Translation, but let's clean this up first so we can actually understand this better And first we will correct the function signature of this String this is a this is the Return string or out string this is the in string and It returns also an SDD string. So this Function here it searches for one character That it finds where in this one you can right click highlight Secondary highlights that highlight see where as this is being used. Now. This is an index This is an index because it's Yeah That's the same index actually so Let's rename this to index and that is also An index this is those are actually the same because here it is set Incremented plus one and set to the other index. So It's the same. Yeah now It iterates through this Set the highlight here and we see this is the same as the in string. So we can rename this to encroach it string and That's the string length of the encrypted string and these two They are recognized by Ida Not by guide or but I already know they are just some Memory setting functions you can ignore them Now what this is doing we have here a loop Inside and this loop is checking if this index is at the string size. So The string size of the encrypted string. So this one will Try Well iterate through all of the characters of the encrypted string and then try to find this character in this big Alphabet that's actually an alphabet here substitution alphabet. So let's rename this to No, that's a plain text alphabet Substitution is the other one Here is the substitution alphabet Because once it finds that it is like the found index for the plain text character and This one is then replaced with the same character that is at the the other alphabet, which is the Substitution alphabet But what is happening is also it's subtracting here from the found index 60 So it basically lands directly in the other alphabet. That's before that. So If you have let's say you found for five The index you jump back 60 you will land Here I guess somewhat or if you find H you will land Right here in this area. So this is a little bit hard to understand the way this is decompiled but If you use another decompiler you you get a little bit of a different representation for that, but Yeah, that's what it does. So it's just a substitution in the end and Now we are ready to write a script that Decrypt the strings for us. So we go to window script manager and there are Lots and lots of example Scripts that are already there. They're also Python examples So if you are more familiar with Python, you can do the same in Python. Just call the very same API Here's a in strings is a translate strings script So right click that edit with basic editor. You can use eclipse if you want to You can also use IntelliJ, which are IDEs for Java and Then it will, you know, have all the advantages that an ID has. This is not the case of the script right here, but I At least would like to have some form of Syntax highlight so I'm gonna do it in here and I can make the script a little bit bigger for you to read. So we're gonna rename this to Decrypt Nighthawk strings That's our class and you can see here most of the more complicated stuff is already done and We just write our string translation in here. So all we need to do is to replicate this String decryption function in Java or Python if you want to use Python. So we are doing that For that we need the alphabet. Vivo Substitution alphabet so S is our string and so we want to iterate through the encrypted string and That is The simple for loop that we use To access the character We can use index of Yeah, index of what? It's easier if we turn this into an array Because then we can deal with an array here whereas for this plain text alphabet I want to use the index of function Let's turn the string also in a char array. That's the encrypted string as to char Array and that is a Char. No, that's an index that we get and found So what are we gonna do with that? We do exactly the same as our Malware We need first need to check if there is if this one was found It could be that there's a character that wasn't found in that case index of a return minus one So we say if it is not Minus one Then we replace the actual string actually we will just do here an in-string replacement Let's just use some cryptic name So we can Replace it right here without having a confusing name index we replace this with the subs alphabet at found index and then we can return the string That we created by this Let's just check that I didn't forget anything we need we still need the alphabets. We are gonna Copy them from here For that one. I don't know yet if there's a good way to copy this other than No Making this part a little bit larger Get the proper array here So this is what we will use Let's open the script manager again, we are gonna copy this Midnight String decryptor you will just copy all of that wait we can use someone here Copy all of that That has to have done the same name as the file save this one And run it and it's compiling so did it work we will see this in the define strings section right it seems to work because We now decrypted all of these strings All of them like you see here in the string that the strings representation is what we changed and The problem is now we have also Basically and decrypted and in that case encrypted the plane strings into something else. So we say edit undo But That is because we didn't have a selection so The cool thing about this script is It will automatically check here The current selection and I guess if you don't have any selection it will just take all of the strings so Instead of Just running it we first No, it's better We first select the encrypted string area for instance like this without this and then Make selection Now We run the script again, and if you check it now These the plain text strings. They are still like the way they were but what we Where we made a selection those are translated so whenever you see or I forgot something doesn't matter now Let's say I Yeah, I have this use rx Right here say make selection and Run the script Now I encrypted this use rx. Well, I can just say Clear the translation value and it's back to where it was. So this is quite neat because that's something I don't have an IDa and Yeah, now we can start to Actually analyze it More properly because having the strings is a great way to find where certain things are done in the Binary so like finding the key logging function you would look into this area and check the cross references so That's it already for today Happy reversing