Showing posts with label reversing. Show all posts
Showing posts with label reversing. Show all posts

Sunday, December 21, 2014

FireEye - FlareOn Challenge 6 Argument 2

So if you read my previous post..you'd know I was stuck on Argument 2 last time. I finally managed to crack it with a little help. The answer had been staring at me all the time and somehow I'd overcomplicated things. Oh well. I learnt a lot.

So..the last time in the previous post, I was stuck at the function 401164. I went through it multiple times, sat and marked blocks out in IDA, used Hexrays on it to get C code (I don't do this until it's an absolute last resort) but all I could see was loads of operations on a big chunk of encrypted text.

Yeah. So I found this chunk of text at 729900..and this is exactly what it looked like.

---------------------------
SIn46AAAAABIixwkSIPDCusKSDHSSDHAsDwPBcAI8oA4G3QC/+NIg8ABgDBAgDDygDCzgDgwdAL/40iDwAGAMHGAOB90Av/jSIPAAYAAo8AIvIA4sHQC/+NIg8ABgCh5gDjodAL/40iDwAHACIKAKCiAOPZ0Av/jSIPAAYAosMAITYAALIA4H3QC/+NIg8ABgABUwACZgDC4wAgqgAA/gDivdAL/40iDwAHACLqAOF10Av/jSIPAAYAw7cAIbIAAMIA4KXQC/+NIg8ABgCi/gDi1dAL/40iDwAHAALyAAIzAAHuAKDGAAGOAOKV0Av/jSIPAAcAAIMAAFoAwrsAAmIA483QC/+NIg8ABwAhugADSgDimdAL/40iDwAGAADSAOGJ0Av/jSIPAAYAAzYAoEIAAYoAwsoA4MnQC/+NIg8ABgDC3gDBzwAgHgDjrdAL/40iDwAGAADSAKGHACDaAAFuAKEyAOAt0Av/jSIPAAYAAWoA4mnQC/+NIg8ABwAiigDiZdAL/40iDwAGAMH6AKOeAOCt0Av/jSIPAAYAouIAwhoAATsAISsAAV4A4r3QC/+NIg8ABwAiGgDDowACVgDBKgDCtgDjDdAL/40iDwAHACEWAMMyAAByAOAN0Av/jSIPAAYAoSoA443QC/+NIg8ABgDClwAiQgDjKdAL/40iDwAHACN7AADaAMHiAKNiAOD50Av/jSIPAAYAAtYAorcAIicAAosAAEYA42HQC/+NIg8ABgABAgCghwAjAgDiCdAL/40iDwAHAAOOAOHt0Av/jSIPAAYAoeMAI9oA413QC/+NIg8ABSDHASDH/SDH2SDHSTTHAagJfagFeagZaailYDwVJicBIMfZNMdJBUsYEJAJmx0QkApoCx0QkBAkeS1ZIieZqEFpBUF9qKlgPBUgx9moDXkj/zmohWA8FdfZIMf9XV15aSL8vL2Jpbi9zaEjB7whXVF9qO1gPBZDr/pA=
------------------------------

The function iterated for the length of this string and performed some operation on it ... using a byte array at 4F4000. But I couldn't understand what it was doing....with all that math. Specially because the very next function, was just an exit function.

Now I'd marked it as an exit function a long time back...and forgotten about it...and not analyzed its code carefully at all. After all, it's exit() ffs... what's there to look into? I was wrong :(

I pinged a person on reddit for a pointer. He/she said I was close...and should think about encoding and the = sign. Sure, I think. Base64. Obviously. But why is that relevant here? Yeah the encrypted text had an = at the end...but so what? It's too big for an Email address. So what's the damn point of decoding it? That's what I'd thought...a long time back.

Anyway I copied the text and threw it into an online Base64 decoder...





and my eyes popped out when I saw what I did.









Look at the screenshot...the right pane..towards the bottom. You'll see some ASCII text called /bin/sh. It's trying to call a shell.... it's shell code. And I'd been staring at it for at least 2-3 days. #-o. Serves me right for assuming things. Sigh.

Anyway, if there's shell code, that means the program is going to jump to it at some point. And I think...wtf.... all that's left is that exit() call at 44bb2b. When the hell is it jumping? And where's that code?

So I then decide to separately throw the shellcode into a disassembler and analyze it. Since it didn't have the ELF header and I was in no mood to recreate one (if I could :D) I threw the code into an awesome online disassembler at http://www2.onlinedisassembler.com/.













...and the code there looked very very familiar. I'd seen it somewhere. Where? Then it hit me...it was IN the exit function.

The exit function had code that compared something with '1b' at the offset cfc4... and exit if it didn't match. And what was it comparing it with? The 2nd argument. And if you didn't enter that correctly..which I wasn't...it'd fail.

So at this point...it was just about reversing the algorithm inside. Here I have a confession to make. While searching for hints and verifying the 1st argument, I'd accidentally seen part of the 2nd argument on one of the solutions, so I knew it started with lin. That sucked. But anyway... just to verify I entered 'l' and..yes..it passed the jump. So the I just needed to solve that entire algorithm...which was just different basic math at every step. Rotate right an left, xor, add, and sub..with binary and hex. I started doing it manually...but was just horribly bored as the pace was very slow guessing it.

So I decided I'd write code for it and solve it. It's basically mind numbing work predicting character by character...and the algorithm is different each time. An utter waste of time really... and this made no sense to me from FireEye's perspective. Oh well I guess that's how real malware is :shrug

Here's the code I wrote - it's just a very quickly written piece of code. Not great at all. But it works:

https://gist.github.com/arvinddoraiswamy/846de119b09dcbb8ea92

I wrote code till the "@" character...and then just guessed the rest. Here too...out of sheer tedium...I guessed 1 character...manually added it to my flag..and then proceeded to solve the algorithm again for the same character. And wondered wtf was wrong now...and why gdb kept throwing me out.

Only googling the exact answer showed me the error of my ways :|. Obviously, that's not how it works in real life...but really I was done...and there was nothing left to solve in the challenge, so I think it was ok.

The final flag was:- l1nhax.hurt.u5.a1l@flare-on.com

Oh you bet. This was a painful painful challenge. What an utter load of junk there was inside. 7 or 8 functions out of some 2700+ that were useful. Sheesh :)

p.s..The bad thing was that someone had written the flag of challenge 7 underneath challenge 6... :( but luckily I have already forgotten it :D. I won't solve challenge 7 for a few days till I am sure I don't remember anything.

Sunday, November 30, 2014

Fireeye - Flare-On Challenge 3

Number 3 was another EXE file. Apart from CFF Explorer, I also load these EXEs into PEid, RDG Packer detector and Protection ID... just to get a feel of how hard it's going to be. These tools are great...but again they only compare against a signature database... so they will miss stuff too. Anyway this time...nothing was detected, all clear.

You can reverse stuff statically...in IDA or you can run it in a debugger like OllyDbg. I always prefer running things... its much quicker. And then use IDA side by side to understand the flow of code..so I can set breakpoints in the right places. Always make sure though...that you run all this stuff inside a virtual machine :D and turn outbound connections off unless you're absolutely sure of what you're doing.

So anyway I loaded this up in OllyDbg and ran it...and it crashed with an error message. Time to Step In (F7). The function exits inside 401000. Something inside this.

401000 copies a lot of code into memory. Nothing looks like ASCII. The start address (18FD47) of this "encrypted" block is then called. This means that an entire function was moved at run-time into memory and then called. Code between 18FD57 and 18FD61 XORs memory with hex 66 (f) and obtains an ASCII string in memory "and so it begins".

So already this points to...the flag eventually being in memory. The start of another encrypted block is at 18FD78. The word "nopasaurus" is compared for some reason :) and some more math results in "get ready to get no'ped..."

Slowly going through all code gives the 3rd flag ... in one of the registers (EAX I think).

The Email address is: such.5h311010101@flare-on.com

Trying to run further causes a crash at 18FF47. That's why you have to Step into and not F9 :).

It's easier to just find out where the crash happened and set a break point just before that... but I just did this slowly to show how to debug things manually.

Wednesday, November 19, 2014

Deeper dive - Malware analysis :)

I've not been blogging for a while..sadly, but I've been learning quite a few things over the last few months and in general continue to keep getting better slowly at reversing and malware analysis - something I always enjoy doing :)

So now, I've decided that now that I know much more about reversing things - than I did a few years ago, I'm going to get deeper into malware analysis and debug all the different types of malware that are found over a period of time and learn ways of anlayzing all of them.

So I  made a list of topics that I'd like to learn over the next few months. I'm familiar with quite a few of them - but not all of them. It probably isn't comprehensive nor do I claim it is - but it's a nice starting point for me. Also, as I learn new things - small or big - I am going to be posting all of that regularly.

So, here's my list :) - do suggest other stuff that you feel could potentially be important and is different from the rest.
  • Disk monitoring
  • Network monitoring
  • Docx
  • VBA
  • Powershell
  • AutoIT
  • PDF
  • DLL
  • JS
  • PHP
  • ELF
  • Flash
  • Packed executables
  • Routers
  • POS
  • Memory analysis (Volatility)
  • Credit card extractors
  • ATM
  • Virtual Machine detection
  • Bootkits
  • Exploit Kits
  • Steganography
  • Learn to write better signatures (Clamav, Yara, Snort, Suricata)

Thursday, December 26, 2013

Patching and Code Caves - Reverse Engineering

The previous post where I solved a reversing challenge was a good example of a place where I could demonstrate a little bit of patching and also use something called a code cave [Thanks Dns]

Patching a program effectively means, change something in the program so that it behaves a little differently - usually this is a change in control flow. In the CSAW example, there's 3 places we can patch the code. We can change the flow of the code so it always chooses 1 in the first switch-case (40109A), 3 in the 2nd switch-case (401120) and we can finally NOP the jump out at 401171 so it calls 401000, no matter what.

Here are 3 screen-shots showing the 3 patches.





If you remember, towards the end of the previous blog, we had to look for the flag inside Olly and the pop-up wouldn't get populated with the flag.The solution that I suggested there was to manually increment the address inside ESI so that it populated the pop-up. There's another cooler solution called a code cave, that will enable us to automatically increment ESI and cause the message box to be displayed.

Here is a screen-shot of the patch that I use, to force the code to jump to a different location, increment ESI, jump back and then call the message box.


This causes the flag to be displayed inside the Message Box itself.


CSAW Finals - CSAW Reversing - csaw2013reversing3.exe

The CSAW Finals VMs were out a while ago and I for one was super happy they did that. So I downloaded all the challenges related to reversing (obviously :)) and started working on them.

The first one was a PE executable called csaw2013reversing3.exe. Initial notes showed that it was a small EXE at 7 KB, didn't have any strings to help you out and imported just 3 DLLs. Quickly loading up the program in IDA showed that Msgbox with a Flag popup was eventually called. So maybe it's not too big.

I learnt about something called rebasing during this challenge. Every EXE has something called an ImageBase. It's just a location in memory where the EXE starts loading itself into and starts running from. Now the Image Base in IDA is 400000 by default. So when I loaded the program in, I found that interesting functions started at 401030. This was fine. Now though I wanted to start running the binary in Olly, I don't particularly enjoy studying pure static disassembly listings.. ;)..

The moment I loaded it in Olly though...I couldn't find 401030 at all. It started loading at a number of random locations, which kept changing every time. So I started reading. Turns out, that Win 7 has ASLR (Address Space Layout Randomization) on by default. In short, this just means that the OS randomizes the locations that your program loads at..every time. So even if you tell your program to load at 400000 every time..the OS will say. Nope.. and load you elsewhere. I found this out by using a tool called CFF Explorer to edit and save the Image Base to 400000..which didn't work. So I ended up turning ASLR off for my reversing VM (Don't do this on any machine which matters to you..ASLR is a good thing to leave on :)). On a Win 7 machine, ASLR can be turned off by creating a key HKLM\SYSTEM
\CurrentControlSet\Control\Session Manager\Memory Management\MoveImages and setting it to 0. Reboot to make sure - it's Windows :)

Ok good. Now Olly started loading at 400000 and I could see my functions in Olly and IDA - at the same places - easier. Stepping through the function quickly I found that srand() was called to seed the random number generator..so that rand() could be called later on and generate 2 random numbers - one at 40107D and one at 40110A.The last bit from both these is extracted and used as an input into a switch - case structure.

So the first switch-case structure is for hex 0-F and the second is for hex 0-7. A jump to that specific structure happens..based on input .. as follows.


Eventually there is a jump to a call at 401000 which performs some simple XOR operations and stores the result at a predefined memory location (decided by HeapCreate and HeapAlloc). As shown in the screen-shot below, the encrypted text is stored at 1DE07E0.

Right click on the highlighted location and click Follow in Dump to look at the content in the bottom pane as shown below. You can see this text changing after the CALL to 401000 is made.


The second switch case chooses a number between 0 and 7 and calls 401000 as before. It operates and stores content in the same location as before, acting on the encrypted text. Eventually a flag is popped up with the contents at 1DE07E0.


Notice that the text is all junk. It's certainly not the flag. This means that the numbers we chose were incorrect. Wait..what do you mean.."chose?". After all rand() was called..rt? I didn't choose anything. Well...it's a CTF - means you have to play with the output of rand and make it select the right numbers. Okay..let's think how to do this..

What do we have now? 1 switch case with 4 possible paths (one each for 0,1,2,3) and a 2nd switch case again with 4 paths (again for 0,1,2,3). This means there are a total of 16 possible paths if we call 401000 twice. The other options are to call 401000 only once..either for the first rand() call or the send rand() call. That's 4+4=8. And a total..of 24 cases. Here's a list of all possibilities:

Only Switch case 1 - 0,1,2,3
Only Switch case 3 - 0,1,2,3
Both switch cases - 00,01,02,03,10,11,12,13,20,21,22,23,30,31,32,33

The chances are that it's encrypted twice. That's just a guess from someone who's done a few challenges. It could well be wrong..but let's try. Remember we want the encryption to be called twice..

Set a breakpoint on 401093 and change EAX to 1 (I know this as I solved it :)) but you would try to get all those combinations in your switch case structure..and conclude. So lets change EAX to 1 and go in. Notice that there is a jump at 4010C9 which jumps right over the CALL 401000 which does the encryption. So there's something there..which we need to do...and force it to CALL 401000. What?

Look at 4010C3 - it's copying fs:30 + 2 into EAX. That location is the PEB (something every process has) and field 2 stores a flag which is set to 1 if we're inside a debugger. So EAX will have 1 after this statement. And the TEST EAX,EAX will fail (from our perspective) and we make the JMP at 4010C9. We want to NOT jump here but a little later..at 4010D1. So we need to tell the program that we're not inside a debugger. There's a few ways to do it... but I used the Olly Advanced Plugin for Olly 1.10 and checked the IsDebuggerPresent box. This clears the fs:30+2 bit...and makes it 0. The TEST EAX, EAX "succeeds" this time and we jump to 401103 instead and CALL 401000 and perform an operation on the encrypted text. Here you see that the bit is 0 and not 1.











The same logic repeats for the 2nd switch case, only this time we want to take the branch for 3,7 instead. Note that the fs:30+2 location is accessed there as well. Eventually you want to jump to 401179 and NOT 401180 so that the CALL 401000 is triggered.

The CALL is made and the encrypted text (which was already encrypted once) is "re-encrypted". Run the program now and look at the flag popup. Oops. Blank :(. No worry.. go to the actual location where the encrypted text is stored.

  

Yay :). You could also adjust ESI to ESI+1 by right clicking on ESI and saying Increment. Then the flag would be displayed in the popup box as well. Have fun.

Monday, October 7, 2013

Sharif University CTF - 2013

I played the Sharif University CTF 2013 with my CTF team. Wrote up a short summary on the challenges I could complete successfully. I could complete the following:

3 Trivia
Web 100
Rev 100
Forensics 100

Write ups for all of these is available here - https://www.dropbox.com/s/lyzm0rbxn2xa50n/SharifUniv_2013.docx