Jump to content
Sign in to follow this  
Nytro

Beginner RE and Cryptanalysis with cutter

Recommended Posts

Beginner RE and Cryptanalysis with cutter

This time Around we will be solving the MalwareTech’s Ransomware Challenge it is one of the easiest challenge but however it will be an exercise on reverse engineering and cryptanalysis .We will be using opensource tools cutter as far as possible for reverse engineering. I have previously done a detailed tutorial on solving the VM challenge by MalwareTech check it out HERE.

so the challenge description for this challenge is :

2020-05-03-10_16_02-window.png?w=884

Seems like we have a windows ransomware sample on our hand but written by skid?? we will see why the author says that further down the line on cryptanalysis section.

Reverse Engineering the binary.

now lets start our analysis by loading the binary in cutter and doing the normal analysis and check out the functions listings.

2020-05-03-18_16_43-window.png?w=417

we can see here that there are only two actual functions and two are imports from ntdll. now as always it is always good idea to start from entry0 if no function is labeled as main. lets check the assembly listing of the entry0 function.

2020-05-03-18_17_38-window.png?w=538

so looking at the assembly listing we can see in first two instructions it is setting up the stackframe the next instruction does not subtract anything from esp that means no space is reserved on the stack for local variables that means that this function does not use any local variables. The next 3 instructions are interesting it is pushing the value 0 twice and then calling section..text ??
why would the section be called?? actually its not the section being called but a function whose start coincides with the start of the section.we can double click on the symbol section..text to verify that . it indeed takes us to the function fcn.00401000 . These three lines in reality just called function fcn.00401000 as fcn.00401000(0,0);
and then in very next instruction it is adding 8 to esp, this tells us that the caller is clearing up argument from the stack which indicates the calling convention used here is cdecl. In next two instructions it is again pushing 0 and calling the ExitProcess which just exits the program returning 0. The next instruction pops ebp back from the stack to restore the previous stack frame and then the ret is executed to return. however these last two instructions are dead code since the execution never reaches here.
So the entry 0 function can be decompiled as:

entry0()
{
    fcn.00401000(0,0);
    ExitProcess(0);
}

since we already know what exit process does the only piece of puzzle remaining to be solved is the function fcn.00401000 lets jump into it and take a look at its assembly listing.

2020-05-03-18_32_18-window.png?w=592

The first two instructions as usual set up the stack frame and the next two instruction is used to call chkstk with the value 4380(0x111c) . checking msdn documentation for chkstk we see it is used by the compiler to save a stack size greater than 4KB. now in next instruction it moves the pointer to the filename into eax and pushes it . it then pushes the pointer to the format string and then pushes the value 260(0x104) and also pushes the pointer var_108h into the stack and calls the function snprintf which is used to make a string according to the format string and instead of displaying it like printf it saves it into the var_108 buffer. so this whole code takes the filename and prepares a new filename by appending “_encrypted” to the end of it.The next string clears the 16 bytes from stack according to cdecl calling convention.

2020-05-03-18_38_55-window.png?w=530

The code then goes on to push a few constants (flags) into the stacks and also pushes the name of the original file and call create file which creates a handle to the file with given filename/path. and again the same is repeated for the file with the new name which was prepared earlier.so hObject is handle to the old file and var_114h is the handle to the new file.

2020-05-03-18_45_11-window.png?w=679

Then it goes on to push some constants and pointer to buffer lpbuffer and calls the Readfile on original file with handle h0bject which then returns the no of bytes read into the lpNumberOfBytesWritten variable and the file content to lpBuffer.The value 4096(0x1000) is used to set the limit of data read to 4kb.for more info check documentation for ReadFile. The code than compares the return code with 1(boolean TRUE) to check if the read was successful if it wasnot it jumps to 0x401131 which will be discussed later.

it then goes on to load 0 into the counter var_11ch and then jumps to location which compares the counter with the total number of bytes read from the file and if the counter is greater or equal it breaks out of the loop .

this is typical for loop

for(int var_111ch=0;var_111ch<lpNumberOfBytesWritten;var_111ch++)
2020-05-03-20_41_10-window.png?w=634

The code then loads the value of counter into eax and zeros out the edx and loads 32(0x20) into ecx and calls for divide that divides edx:eax and then the remainder in edx is added with the base address in argc which is then used retrieve a key byte. this is equivalent to

argc[var_111ch%32]

it then xors this key with the byte indexed by the count thus encrypting the content , which is equivalent to

data[var_111ch]=data[var111ch]^argc[var_111ch%32]

this is the main encryption logic in the routine the code then loops doing this for all the bytes read from the file and then goes on to push diffrent arguments to the stack and write this encrypted data to the new file by calling the WriteFile function.

2020-05-03-20_51_06-window.png?w=514

the code then checks if the total number of bytes read was equal to 4096 bytes ie 4kb if it was it jumps back to read the remaining data in iteration till all data is read thus encrypting all the data in the file.

the code then pushes the handles of opened files and calls CloseHandle to close those file. it then restores the previous stack frame and then returns .

the c++ equivalent of this routine would be

int encrypt(char * filename, char * key)
{
char databuffer[4096];
char newname[206];
int nobytesread;
snprintf(newname,206,"%s_encrypted",filename); 
handle old=CreateFileA(filename,WRITE_OWNER,0,0,OPEN_EXISTING,0x80,0);
handle new=CreateFileA(newname,WRITE_DAC,0,0,CREATE_ALWAYS,0x80,0);
do{
ReadFile(old,data,4096,&nobytesread,NULL);
for(int count=0;count<=nobytesread;++count)
{
data[count]=data[count]^key[count%32];
}
WriteFile(new,data,&nobyteread,&nobytesread,NULL);
}while(nobytesread==4096);
CloseHandle(new);
CloseHandle(old);
return;
}

at this point we know all about how the given binary works but we still cannot decrypt the files provided because we do not have the key. but from above code we can see that the key index loops back after 32 bytes due to the modular division but we donot have that 32 bytes long key sequence.

Lets do some cryptanalysis to find the key:

Cryptanalysis

looking at the files provided we can see that we have one encrypted text file flag.txt_encrypted and also few encrypted sample pictures.but still we do not have the key but we know that the xor encryption scheme is perfectly secure if the key is as long as the data to be encrypted but in our case it is not . looking at the sample pictures these are the default sample pictures that come with win7 hence we know what the data was before encryption.

so we know both cipher text and plaintext so this encryption can be cryptanalysed using Known PlainText Attack since we know

cyphertext=plaintext^key

which also means that

key=plaintext^ciphertext

so we can write a simple python script to automate above logic and find us the keystring.

2020-05-03-21_30_04-window.png?w=572

Note: if you are not on win7 or do not have the chrysanthemum.jpg you can download from the internet archive here

Also you can use any file here i choose chrysanthemum.

Once we get the key array we can decrypt the files using the same logic as the malware used to encrypt the files. we can automate this by writing simple python script as:

2020-05-03-21_33_12-window.png?w=545

running this script we can successfuly decrypt the flag and the flag turns out to be

FLAG{XOR-MAKES-KNOWN-PLAINTEXT-AND-FREQUENCY-ANALYSIS-EASY}

follow me on twitter at @daring_joker for updates on new tutorials.

References and Links

 

Sursa: https://daringjoker.wordpress.com/2020/05/03/chransomware1/

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...